// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/browser/site_per_process_browsertest.h"

#include <stddef.h>
#include <stdint.h>

#include <algorithm>
#include <cmath>
#include <list>
#include <map>
#include <memory>
#include <set>
#include <string>
#include <tuple>
#include <utility>
#include <vector>

#include "base/command_line.h"
#include "base/containers/contains.h"
#include "base/feature_list.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/functional/callback_helpers.h"
#include "base/json/json_reader.h"
#include "base/location.h"
#include "base/memory/ptr_util.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/raw_ref.h"
#include "base/memory/scoped_refptr.h"
#include "base/path_service.h"
#include "base/run_loop.h"
#include "base/scoped_observation.h"
#include "base/strings/pattern.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/to_string.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task/sequenced_task_runner.h"
#include "base/task/single_thread_task_runner.h"
#include "base/test/bind.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/run_until.h"
#include "base/test/test_future.h"
#include "base/test/test_timeouts.h"
#include "base/test/test_trace_processor.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "build/build_config.h"
#include "cc/base/math_util.h"
#include "cc/input/touch_action.h"
#include "components/input/features.h"
#include "components/input/input_constants.h"
#include "components/input/input_router.h"
#include "components/input/render_widget_host_input_event_router.h"
#include "components/input/switches.h"
#include "components/input/utils.h"
#include "components/viz/host/host_frame_sink_manager.h"
#include "content/browser/child_process_security_policy_impl.h"
#include "content/browser/compositor/surface_utils.h"
#include "content/browser/gpu/compositor_util.h"
#include "content/browser/gpu/gpu_data_manager_impl.h"
#include "content/browser/process_lock.h"
#include "content/browser/process_reuse_policy.h"
#include "content/browser/renderer_host/agent_scheduling_group_host.h"
#include "content/browser/renderer_host/cross_process_frame_connector.h"
#include "content/browser/renderer_host/frame_navigation_entry.h"
#include "content/browser/renderer_host/frame_tree.h"
#include "content/browser/renderer_host/navigation_controller_impl.h"
#include "content/browser/renderer_host/navigation_entry_impl.h"
#include "content/browser/renderer_host/navigation_entry_restore_context_impl.h"
#include "content/browser/renderer_host/navigation_request.h"
#include "content/browser/renderer_host/navigator.h"
#include "content/browser/renderer_host/render_frame_host_impl.h"
#include "content/browser/renderer_host/render_frame_proxy_host.h"
#include "content/browser/renderer_host/render_process_host_impl.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_view_child_frame.h"
#include "content/browser/site_info.h"
#include "content/browser/storage_partition_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/common/content_navigation_policy.h"
#include "content/common/frame.mojom-test-utils.h"
#include "content/common/input/actions_parser.h"
#include "content/common/input/synthetic_gesture.h"
#include "content/common/input/synthetic_gesture_target.h"
#include "content/common/input/synthetic_pinch_gesture_params.h"
#include "content/common/input/synthetic_pointer_action.h"
#include "content/common/input/synthetic_tap_gesture.h"
#include "content/common/input/synthetic_touchscreen_pinch_gesture.h"
#include "content/common/renderer.mojom.h"
#include "content/common/renderer_host.mojom-test-utils.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/context_menu_params.h"
#include "content/public/browser/global_routing_id.h"
#include "content/public/browser/gpu_data_manager_observer.h"
#include "content/public/browser/gpu_utils.h"
#include "content/public/browser/javascript_dialog_manager.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/render_process_host_priority_client.h"
#include "content/public/browser/site_isolation_policy.h"
#include "content/public/common/content_client.h"
#include "content/public/common/content_features.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/url_constants.h"
#include "content/public/test/back_forward_cache_util.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test_content_browser_client.h"
#include "content/public/test/content_browser_test_utils.h"
#include "content/public/test/content_mock_cert_verifier.h"
#include "content/public/test/fenced_frame_test_util.h"
#include "content/public/test/hit_test_region_observer.h"
#include "content/public/test/navigation_handle_observer.h"
#include "content/public/test/policy_container_utils.h"
#include "content/public/test/render_frame_host_test_support.h"
#include "content/public/test/test_devtools_protocol_client.h"
#include "content/public/test/test_frame_navigation_observer.h"
#include "content/public/test/test_navigation_observer.h"
#include "content/public/test/test_navigation_throttle.h"
#include "content/public/test/test_navigation_throttle_inserter.h"
#include "content/public/test/test_utils.h"
#include "content/public/test/url_loader_interceptor.h"
#include "content/shell/browser/shell.h"
#include "content/shell/common/main_frame_counter_test_impl.h"
#include "content/shell/common/shell_switches.h"
#include "content/test/content_browser_test_utils_internal.h"
#include "content/test/did_commit_navigation_interceptor.h"
#include "content/test/render_document_feature.h"
#include "ipc/constants.mojom.h"
#include "media/base/media_switches.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/sync_call_restrictions.h"
#include "mojo/public/cpp/test_support/test_utils.h"
#include "net/base/url_util.h"
#include "net/dns/mock_host_resolver.h"
#include "net/http/mock_http_cache.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/test/embedded_test_server/http_request.h"
#include "net/test/embedded_test_server/http_response.h"
#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "services/network/public/cpp/features.h"
#include "services/network/public/cpp/permissions_policy/origin_with_possible_wildcards.h"
#include "services/network/public/cpp/permissions_policy/permissions_policy_declaration.h"
#include "services/network/public/cpp/web_sandbox_flags.h"
#include "services/network/public/mojom/permissions_policy/permissions_policy_feature.mojom-shared.h"
#include "services/network/public/mojom/web_sandbox_flags.mojom-shared.h"
#include "services/viz/privileged/mojom/compositing/features.mojom-features.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/common/input/web_input_event.h"
#include "third_party/blink/public/common/permissions_policy/policy_value.h"
#include "third_party/blink/public/common/switches.h"
#include "third_party/blink/public/common/tokens/tokens.h"
#include "third_party/blink/public/mojom/frame/frame.mojom-test-utils.h"
#include "third_party/blink/public/mojom/frame/frame.mojom.h"
#include "third_party/blink/public/mojom/frame/frame_replication_state.mojom.h"
#include "third_party/blink/public/mojom/leak_detector/leak_detector.mojom-test-utils.h"
#include "third_party/blink/public/mojom/leak_detector/leak_detector.mojom.h"
#include "third_party/blink/public/mojom/page/widget.mojom-test-utils.h"
#include "third_party/blink/public/mojom/security_context/insecure_request_policy.mojom.h"
#include "ui/display/display_switches.h"
#include "ui/display/screen.h"
#include "ui/events/base_event_utils.h"
#include "ui/events/blink/blink_features.h"
#include "ui/events/event.h"
#include "ui/events/event_utils.h"
#include "ui/events/keycodes/dom/dom_code.h"
#include "ui/events/keycodes/dom/dom_key.h"
#include "ui/events/keycodes/keyboard_codes.h"
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/transform.h"
#include "ui/latency/latency_info.h"
#include "ui/native_theme/features/native_theme_features.h"

#if defined(USE_AURA)
#include "content/browser/renderer_host/render_widget_host_view_aura.h"
#include "ui/aura/window.h"
#endif

#if BUILDFLAG(IS_ANDROID)
#include "base/android/jni_android.h"
#include "base/android/jni_string.h"
#include "base/android/scoped_java_ref.h"
#include "content/browser/android/gesture_listener_manager.h"
#include "content/browser/android/ime_adapter_android.h"
#include "content/browser/renderer_host/input/touch_selection_controller_client_manager_android.h"
#include "content/browser/renderer_host/render_widget_host_view_android.h"
#include "content/browser/web_contents/web_contents_view_android.h"
#include "content/public/browser/android/child_process_importance.h"
#include "content/test/mock_overscroll_refresh_handler_android.h"
#include "ui/android/view_android.h"
#include "ui/android/window_android.h"
#include "ui/events/android/event_handler_android.h"
#include "ui/events/android/motion_event_android_factory.h"
#include "ui/events/android/motion_event_android_java.h"
#include "ui/events/motionevent_jni_headers/MotionEvent_jni.h"
#include "ui/gfx/geometry/point_f.h"
#endif

using ::testing::SizeIs;
using ::testing::WhenSorted;
using ::testing::ElementsAre;

namespace content {

namespace {

void VerifyChildProcessHasMainFrame(
    mojo::Remote<mojom::MainFrameCounterTest>& main_frame_counter,
    bool expected_state) {
  main_frame_counter.FlushForTesting();
  base::test::TestFuture<bool> has_main_frame_future;
  main_frame_counter->HasMainFrame(has_main_frame_future.GetCallback());
  EXPECT_EQ(expected_state, has_main_frame_future.Get());
}

using CrashVisibility = CrossProcessFrameConnector::CrashVisibility;

// Helper function to send a postMessage and wait for a reply message.  The
// |post_message_script| is executed on the |sender_ftn| frame, and the sender
// frame is expected to post |reply_status| from the DOMAutomationController
// when it receives a reply.
void PostMessageAndWaitForReply(FrameTreeNode* sender_ftn,
                                const std::string& post_message_script,
                                const std::string& reply_status) {
  // Subtle: msg_queue needs to be declared before the EvalJs below, or
  // else it might miss the message of interest.  See https://crbug.com/518729.
  DOMMessageQueue msg_queue(sender_ftn->current_frame_host());

  EXPECT_EQ(true, EvalJs(sender_ftn, "(" + post_message_script + ");"));

  std::string status;
  while (msg_queue.WaitForMessage(&status)) {
    if (status == reply_status)
      break;
  }
}

// Helper function to extract and return "window.receivedMessages" from the
// |sender_ftn| frame.  This variable is used in post_message.html to count the
// number of messages received via postMessage by the current window.
int GetReceivedMessages(FrameTreeNode* ftn) {
  return EvalJs(ftn, "window.receivedMessages;").ExtractInt();
}

// Helper function to perform a window.open from the |caller_frame| targeting a
// frame with the specified name.
void NavigateNamedFrame(const ToRenderFrameHost& caller_frame,
                        const GURL& url,
                        const std::string& name) {
  EXPECT_EQ(true, EvalJs(caller_frame,
                         JsReplace("!!window.open($1, $2)", url, name)));
}

// Helper function to generate a click on the given RenderWidgetHost.  The
// mouse event is forwarded directly to the RenderWidgetHost without any
// hit-testing.
void SimulateMouseClick(RenderWidgetHost* rwh, int x, int y) {
  blink::WebMouseEvent mouse_event(
      blink::WebInputEvent::Type::kMouseDown,
      blink::WebInputEvent::kNoModifiers,
      blink::WebInputEvent::GetStaticTimeStampForTests());
  mouse_event.button = blink::WebPointerProperties::Button::kLeft;
  mouse_event.SetPositionInWidget(x, y);
  rwh->ForwardMouseEvent(mouse_event);
}

// Retrieve self.origin for the frame |ftn|.
EvalJsResult GetOriginFromRenderer(FrameTreeNode* ftn) {
  return EvalJs(ftn, "self.origin;");
}

// This observer detects when WebContents receives notification of a user
// gesture having occurred, following a user input event targeted to
// a RenderWidgetHost under that WebContents.
class UserInteractionObserver : public WebContentsObserver {
 public:
  explicit UserInteractionObserver(WebContents* web_contents)
      : WebContentsObserver(web_contents), user_interaction_received_(false) {}

  UserInteractionObserver(const UserInteractionObserver&) = delete;
  UserInteractionObserver& operator=(const UserInteractionObserver&) = delete;

  ~UserInteractionObserver() override {}

  // Retrieve the flag. There is no need to wait on a loop since
  // DidGetUserInteraction() should be called synchronously with the input
  // event processing in the browser process.
  bool WasUserInteractionReceived() { return user_interaction_received_; }

  void Reset() { user_interaction_received_ = false; }

 private:
  // WebContentsObserver
  void DidGetUserInteraction(const blink::WebInputEvent& event) override {
    user_interaction_received_ = true;
  }

  bool user_interaction_received_;
};

// Supports waiting until a WebContents notifies its observers that the visible
// security state changed, and a test-specific condition is true at that time.
class VisibleSecurityStateObserver : public WebContentsObserver {
 public:
  // Invoked at Wait() start and when the visible security state changes.
  // If the callback returns true, stops waiting.
  using ConditionCallback = base::RepeatingCallback<bool(WebContents*)>;

  // Creates a VisibleSecurityStateObserver which will wait until
  // a visible security state change is announced by |web_contents| and
  // |condition_callback| returns true (unless |condition_callback| returns true
  // in Wait() already, when it will not wait at all).
  VisibleSecurityStateObserver(WebContents* web_contents,
                               ConditionCallback condition_callback)
      : WebContentsObserver(web_contents),
        condition_callback_(condition_callback) {}
  ~VisibleSecurityStateObserver() override = default;

  VisibleSecurityStateObserver(const VisibleSecurityStateObserver& other) =
      delete;
  VisibleSecurityStateObserver& operator=(
      const VisibleSecurityStateObserver& other) = delete;

  // If the |condition_callback| passed to the constructor returns true, this
  // returns immediately. Otherwise, blocks until the |web_contents| passed to
  // the constructor notifies about a visible security state change and the
  // |condition_callback| evaluates to true.
  void Wait() {
    if (condition_callback_.Run(web_contents()))
      return;
    run_loop_.Run();
  }

  void DidChangeVisibleSecurityState() override {
    if (condition_callback_.Run(web_contents()))
      run_loop_.Quit();
  }

 private:
  ConditionCallback condition_callback_;
  base::RunLoop run_loop_;
};

// Helper function to focus a frame by sending it a mouse click and then
// waiting for it to become focused.
void FocusFrame(FrameTreeNode* frame) {
  FrameFocusedObserver focus_observer(frame->current_frame_host());
  SimulateMouseClick(frame->current_frame_host()->GetRenderWidgetHost(), 1, 1);
  focus_observer.Wait();
}

bool ConvertJSONToPoint(const std::string& str, gfx::PointF* point) {
  std::optional<base::Value::Dict> value = base::JSONReader::ReadDict(str);
  if (!value) {
    return false;
  }
  std::optional<double> x = value->FindDouble("x");
  std::optional<double> y = value->FindDouble("y");
  if (!x || !y) {
    return false;
  }
  point->set_x(x.value());
  point->set_y(y.value());
  return true;
}

// Helper function to generate a permissions policy for a single feature and a
// list of origins. (Equivalent to the declared policy "feature origin1 origin2
// ...".) If the origins list is empty, it's treated as matches all origins
// (Equivalent to the declared policy "feature *")
network::ParsedPermissionsPolicyDeclaration
CreateParsedPermissionsPolicyDeclaration(
    network::mojom::PermissionsPolicyFeature feature,
    const std::vector<GURL>& origins,
    bool match_all_origins = false,
    const std::optional<GURL> self_if_matches = std::nullopt) {
  network::ParsedPermissionsPolicyDeclaration declaration;

  declaration.feature = feature;
  if (self_if_matches.has_value()) {
    declaration.self_if_matches = url::Origin::Create(*self_if_matches);
  }
  declaration.matches_all_origins = match_all_origins;
  declaration.matches_opaque_src = match_all_origins;

  for (const auto& origin : origins)
    declaration.allowed_origins.emplace_back(
        *network::OriginWithPossibleWildcards::FromOrigin(
            url::Origin::Create(origin)));

  std::sort(declaration.allowed_origins.begin(),
            declaration.allowed_origins.end());

  return declaration;
}

network::ParsedPermissionsPolicy CreateParsedPermissionsPolicy(
    const std::vector<network::mojom::PermissionsPolicyFeature>& features,
    const std::vector<GURL>& origins,
    bool match_all_origins = false,
    const std::optional<GURL> self_if_matches = std::nullopt) {
  network::ParsedPermissionsPolicy result;
  result.reserve(features.size());
  for (const auto& feature : features)
    result.push_back(CreateParsedPermissionsPolicyDeclaration(
        feature, origins, match_all_origins, self_if_matches));
  return result;
}

network::ParsedPermissionsPolicy CreateParsedPermissionsPolicyMatchesSelf(
    const std::vector<network::mojom::PermissionsPolicyFeature>& features,
    const GURL& self_if_matches) {
  return CreateParsedPermissionsPolicy(features, {}, false, self_if_matches);
}

network::ParsedPermissionsPolicy CreateParsedPermissionsPolicyMatchesAll(
    const std::vector<network::mojom::PermissionsPolicyFeature>& features) {
  return CreateParsedPermissionsPolicy(features, {}, true);
}

network::ParsedPermissionsPolicy CreateParsedPermissionsPolicyMatchesNone(
    const std::vector<network::mojom::PermissionsPolicyFeature>& features) {
  return CreateParsedPermissionsPolicy(features, {});
}

// Check frame depth on node, widget, and process all match expected depth.
void CheckFrameDepth(unsigned int expected_depth, FrameTreeNode* node) {
  EXPECT_EQ(expected_depth, node->current_frame_host()->GetFrameDepth());
  RenderProcessHostPriorityClient::Priority priority =
      node->current_frame_host()->GetRenderWidgetHost()->GetPriority();
  EXPECT_EQ(expected_depth, priority.frame_depth);
  EXPECT_EQ(expected_depth,
            node->current_frame_host()->GetProcess()->GetFrameDepth());
}

void GenerateTapDownGesture(RenderWidgetHost* rwh) {
  blink::WebGestureEvent gesture_tap_down(
      blink::WebGestureEvent::Type::kGestureTapDown,
      blink::WebInputEvent::kNoModifiers,
      blink::WebInputEvent::GetStaticTimeStampForTests(),
      blink::WebGestureDevice::kTouchscreen);
  gesture_tap_down.is_source_touch_event_set_blocking = true;
  rwh->ForwardGestureEvent(gesture_tap_down);
}

// Overrides process reuse preference based on URL for testing purposes.
class SitePerProcessWithMainFrameThresholdAndSiteRestrictionBrowserClient
    : public ContentBrowserTestContentBrowserClient {
 public:
  SitePerProcessWithMainFrameThresholdAndSiteRestrictionBrowserClient() =
      default;
  ~SitePerProcessWithMainFrameThresholdAndSiteRestrictionBrowserClient()
      override = default;

  SitePerProcessWithMainFrameThresholdAndSiteRestrictionBrowserClient(
      const SitePerProcessWithMainFrameThresholdAndSiteRestrictionBrowserClient&) =
      delete;
  SitePerProcessWithMainFrameThresholdAndSiteRestrictionBrowserClient&
  operator=(
      const SitePerProcessWithMainFrameThresholdAndSiteRestrictionBrowserClient&) =
      delete;

  // Controls whether reuse is preferred under the main frame threshold policy.
  bool ShouldReuseExistingProcessForNewMainFrameSiteInstance(
      content::BrowserContext* browser_context,
      const GURL& site_instance_original_url) override {
    // Only reuse for foo.com/title1.html specifically.
    if (site_instance_original_url.DomainIs("foo.com") &&
        site_instance_original_url.path_piece() == "/title1.html") {
      return true;
    }
    // For all other URLs, including other paths on foo.com or other domains,
    // do not force reuse via this override. Let default policies apply.
    return false;
  }
};

}  // namespace

//
// SitePerProcessBrowserTestBase
//

SitePerProcessBrowserTestBase::SitePerProcessBrowserTestBase() {
#if !BUILDFLAG(IS_ANDROID)
  // TODO(bokan): Needed for scrollability check in
  // FrameOwnerPropertiesPropagationScrolling. crbug.com/662196.
  // Overlay scrollbar will be turned off with both conditions satisfied:
  // 1) feature flag `kOverlayScrollbar` is off
  // 2) always show scrollbar preference setting on.
  feature_list_.InitWithFeatures(
      /*enabled_features=*/{},
      /*disabled_features=*/{features::kOverlayScrollbar});
#endif
}

std::string SitePerProcessBrowserTestBase::DepictFrameTree(
    FrameTreeNode* node) {
  return visualizer_.DepictFrameTree(node);
}

std::string SitePerProcessBrowserTestBase::WaitForMessageScript(
    const std::string& result_expression) {
  return base::StringPrintf(
      "var onMessagePromise = new Promise(resolve => {"
      "  window.addEventListener('message', function(event) {"
      "    resolve(%s);"
      "  });"
      "});",
      result_expression.c_str());
}

void SitePerProcessBrowserTestBase::SetUpCommandLine(
    base::CommandLine* command_line) {
  IsolateAllSitesForTesting(command_line);

  command_line->AppendSwitch(input::switches::kValidateInputEventStream);
  // Without this, FocusFrame can be flaky. It depends on dispatching input
  // events which can inadventently get dropped.
  command_line->AppendSwitch(blink::switches::kAllowPreCommitInput);
}

void SitePerProcessBrowserTestBase::SetUpOnMainThread() {
  host_resolver()->AddRule("*", "127.0.0.1");
  SetupCrossSiteRedirector(embedded_test_server());
  ASSERT_TRUE(embedded_test_server()->Start());
}

void SitePerProcessBrowserTestBase::ForceUpdateViewportIntersection(
    FrameTreeNode* frame_tree_node,
    const blink::mojom::ViewportIntersectionState& intersection_state) {
  frame_tree_node->render_manager()
      ->GetProxyToParent()
      ->cross_process_frame_connector()
      ->UpdateViewportIntersectionInternal(intersection_state, false);
}

void SitePerProcessBrowserTestBase::RunPostedTasks() {
  base::RunLoop loop;
  base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
      FROM_HERE, loop.QuitClosure());
  loop.Run();
}

// SitePerProcessBrowserTest

SitePerProcessBrowserTest::SitePerProcessBrowserTest() {
  InitAndEnableRenderDocumentFeature(&feature_list_, GetParam());
}

SitePerProcessBrowserTest::~SitePerProcessBrowserTest() = default;

std::string SitePerProcessBrowserTest::GetExpectedOrigin(
    const std::string& host) {
  GURL url = embedded_test_server()->GetURL(host, "/");
  return url::Origin::Create(url).Serialize();
}

// SitePerProcessIgnoreCertErrorsBrowserTest

void SitePerProcessIgnoreCertErrorsBrowserTest::SetUpOnMainThread() {
  SitePerProcessBrowserTest::SetUpOnMainThread();
  mock_cert_verifier_.mock_cert_verifier()->set_default_result(net::OK);
}

void SitePerProcessIgnoreCertErrorsBrowserTest::SetUpCommandLine(
    base::CommandLine* command_line) {
  SitePerProcessBrowserTest::SetUpCommandLine(command_line);
  mock_cert_verifier_.SetUpCommandLine(command_line);
}

void SitePerProcessIgnoreCertErrorsBrowserTest::
    SetUpInProcessBrowserTestFixture() {
  SitePerProcessBrowserTest::SetUpInProcessBrowserTestFixture();
  mock_cert_verifier_.SetUpInProcessBrowserTestFixture();
}

void SitePerProcessIgnoreCertErrorsBrowserTest::
    TearDownInProcessBrowserTestFixture() {
  SitePerProcessBrowserTest::TearDownInProcessBrowserTestFixture();
  mock_cert_verifier_.TearDownInProcessBrowserTestFixture();
}

// SitePerProcessAutoplayBrowserTest

class SitePerProcessAutoplayBrowserTest : public SitePerProcessBrowserTest {
 public:
  SitePerProcessAutoplayBrowserTest() = default;

  void SetUpCommandLine(base::CommandLine* command_line) override {
    SitePerProcessBrowserTestBase::SetUpCommandLine(command_line);
    command_line->AppendSwitchASCII(
        switches::kAutoplayPolicy,
        switches::autoplay::kDocumentUserActivationRequiredPolicy);
  }

  bool AutoplayAllowed(const ToRenderFrameHost& adapter,
                       bool with_user_gesture) {
    return EvalJs(adapter, "attemptPlay();",
                  with_user_gesture ? EXECUTE_SCRIPT_DEFAULT_OPTIONS
                                    : EXECUTE_SCRIPT_NO_USER_GESTURE)
        .ExtractBool();
  }
};

// Certain tests require the speculative RFH to be created before the browser
// receives any data from the server. The delay of creating the RFH is set to 0
// in these tests so that the speculative RFH is created when the request is
// sent.
class SitePerProcessBrowserTestWithoutSpeculativeRFHDelay
    : public SitePerProcessBrowserTest {
 public:
  SitePerProcessBrowserTestWithoutSpeculativeRFHDelay() {
    feature_list_for_defer_speculative_rfh_.InitAndEnableFeatureWithParameters(
        features::kDeferSpeculativeRFHCreation,
        {{"create_speculative_rfh_delay_ms", "0"}});
  }

 private:
  base::test::ScopedFeatureList feature_list_for_defer_speculative_rfh_;
};

// Ensure that navigating subframes in --site-per-process mode works and the
// correct documents are committed.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest, CrossSiteIframe) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(a,a(a,a(a)))"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  // It is safe to obtain the root frame tree node here, as it doesn't change.
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();

  TestNavigationObserver observer(shell()->web_contents());

  // Load same-site page into iframe.
  FrameTreeNode* child = root->child_at(0);
  GURL http_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
  EXPECT_TRUE(NavigateToURLFromRenderer(child, http_url));
  EXPECT_EQ(http_url, observer.last_navigation_url());
  EXPECT_TRUE(observer.last_navigation_succeeded());
  {
    // There should be only one RenderWidgetHost when there are no
    // cross-process iframes.
    std::set<RenderWidgetHostViewBase*> views_set =
        web_contents()->GetRenderWidgetHostViewsInWebContentsTree();
    EXPECT_EQ(1U, views_set.size());
  }

  EXPECT_EQ(
      " Site A\n"
      "   |--Site A\n"
      "   +--Site A\n"
      "        |--Site A\n"
      "        +--Site A\n"
      "             +--Site A\n"
      "Where A = http://a.com/",
      DepictFrameTree(root));

  // Load cross-site page into iframe.
  GURL url = embedded_test_server()->GetURL("foo.com", "/title2.html");
  {
    RenderFrameDeletedObserver deleted_observer(child->current_frame_host());
    EXPECT_TRUE(NavigateToURLFromRenderer(root->child_at(0), url));
    deleted_observer.WaitUntilDeleted();
  }
  // Verify that the navigation succeeded and the expected URL was loaded.
  EXPECT_TRUE(observer.last_navigation_succeeded());
  EXPECT_EQ(url, observer.last_navigation_url());

  // Ensure that we have created a new process for the subframe.
  ASSERT_EQ(2U, root->child_count());
  SiteInstance* site_instance = child->current_frame_host()->GetSiteInstance();
  RenderViewHost* rvh = child->current_frame_host()->render_view_host();
  RenderProcessHost* rph = child->current_frame_host()->GetProcess();
  EXPECT_NE(shell()->web_contents()->GetPrimaryMainFrame()->GetRenderViewHost(),
            rvh);
  EXPECT_NE(shell()->web_contents()->GetSiteInstance(), site_instance);
  EXPECT_NE(shell()->web_contents()->GetPrimaryMainFrame()->GetProcess(), rph);
  {
    // There should be now two RenderWidgetHosts, one for each process
    // rendering a frame.
    std::set<RenderWidgetHostViewBase*> views_set =
        web_contents()->GetRenderWidgetHostViewsInWebContentsTree();
    EXPECT_EQ(2U, views_set.size());
  }
  mojo::Remote<mojom::MainFrameCounterTest> main_frame_counter;
  shell()->web_contents()->GetPrimaryMainFrame()->GetProcess()->BindReceiver(
      main_frame_counter.BindNewPipeAndPassReceiver());

  VerifyChildProcessHasMainFrame(main_frame_counter, true);

  mojo::Remote<mojom::MainFrameCounterTest> main_frame_counter_child;
  rph->BindReceiver(main_frame_counter_child.BindNewPipeAndPassReceiver());

  VerifyChildProcessHasMainFrame(main_frame_counter_child, false);

  RenderFrameProxyHost* proxy_to_parent =
      child->render_manager()->GetProxyToParent();
  EXPECT_TRUE(proxy_to_parent);
  EXPECT_TRUE(proxy_to_parent->cross_process_frame_connector());
  // The out-of-process iframe should have its own RenderWidgetHost,
  // independent of any RenderViewHost.
  EXPECT_NE(
      rvh->GetWidget()->GetView(),
      proxy_to_parent->cross_process_frame_connector()->get_view_for_testing());
  EXPECT_TRUE(child->current_frame_host()->GetRenderWidgetHost());

  EXPECT_EQ(
      " Site A ------------ proxies for B\n"
      "   |--Site B ------- proxies for A\n"
      "   +--Site A ------- proxies for B\n"
      "        |--Site A -- proxies for B\n"
      "        +--Site A -- proxies for B\n"
      "             +--Site A -- proxies for B\n"
      "Where A = http://a.com/\n"
      "      B = http://foo.com/",
      DepictFrameTree(root));

  // Load another cross-site page into the same iframe.
  url = embedded_test_server()->GetURL("bar.com", "/title3.html");
  {
    RenderFrameDeletedObserver deleted_observer(child->current_frame_host());
    EXPECT_TRUE(NavigateToURLFromRenderer(root->child_at(0), url));
    deleted_observer.WaitUntilDeleted();
  }
  EXPECT_TRUE(observer.last_navigation_succeeded());
  EXPECT_EQ(url, observer.last_navigation_url());

  // Check again that a new process is created and is different from the
  // top level one and the previous one.
  ASSERT_EQ(2U, root->child_count());
  child = root->child_at(0);
  EXPECT_NE(shell()->web_contents()->GetPrimaryMainFrame()->GetRenderViewHost(),
            child->current_frame_host()->render_view_host());
  EXPECT_NE(rvh, child->current_frame_host()->render_view_host());
  EXPECT_NE(shell()->web_contents()->GetSiteInstance(),
            child->current_frame_host()->GetSiteInstance());
  EXPECT_NE(site_instance,
            child->current_frame_host()->GetSiteInstance());
  EXPECT_NE(shell()->web_contents()->GetPrimaryMainFrame()->GetProcess(),
            child->current_frame_host()->GetProcess());
  EXPECT_NE(rph, child->current_frame_host()->GetProcess());
  VerifyChildProcessHasMainFrame(main_frame_counter, true);
  {
    std::set<RenderWidgetHostViewBase*> views_set =
        web_contents()->GetRenderWidgetHostViewsInWebContentsTree();
    EXPECT_EQ(2U, views_set.size());
  }
  EXPECT_EQ(proxy_to_parent, child->render_manager()->GetProxyToParent());
  EXPECT_TRUE(proxy_to_parent->cross_process_frame_connector());
  EXPECT_NE(
      child->current_frame_host()->render_view_host()->GetWidget()->GetView(),
      proxy_to_parent->cross_process_frame_connector()->get_view_for_testing());
  EXPECT_TRUE(child->current_frame_host()->GetRenderWidgetHost());

  EXPECT_EQ(
      " Site A ------------ proxies for C\n"
      "   |--Site C ------- proxies for A\n"
      "   +--Site A ------- proxies for C\n"
      "        |--Site A -- proxies for C\n"
      "        +--Site A -- proxies for C\n"
      "             +--Site A -- proxies for C\n"
      "Where A = http://a.com/\n"
      "      C = http://bar.com/",
      DepictFrameTree(root));
}

// Simple test to set up a A(B,C) page and then navigate the C subframe to D.
// This can be used to study performance of proxy creation code.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest, NavigateABCToABD) {
  GURL main_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();

  // Add a new child frame and navigate it to B.
  RenderFrameHostCreatedObserver frame_observer(shell()->web_contents(), 1);
  EXPECT_TRUE(ExecJs(
      root, "document.body.appendChild(document.createElement('iframe'));"));
  frame_observer.Wait();

  FrameTreeNode* child1 = root->child_at(0);
  {
    RenderFrameDeletedObserver deleted_observer(child1->current_frame_host());
    GURL b_url(embedded_test_server()->GetURL("b.com", "/title1.html"));
    EXPECT_TRUE(NavigateToURLFromRenderer(child1, b_url));
    deleted_observer.WaitUntilDeleted();
  }

  // Add a second child frame and navigate it to C.
  RenderFrameHostCreatedObserver frame_observer2(shell()->web_contents(), 1);
  EXPECT_TRUE(ExecJs(
      root, "document.body.appendChild(document.createElement('iframe'));"));
  frame_observer2.Wait();

  FrameTreeNode* child2 = root->child_at(1);
  {
    RenderFrameDeletedObserver deleted_observer(child2->current_frame_host());
    GURL c_url(embedded_test_server()->GetURL("c.com", "/title1.html"));
    EXPECT_TRUE(NavigateToURLFromRenderer(child2, c_url));
    deleted_observer.WaitUntilDeleted();
  }
  EXPECT_EQ(
      " Site A ------------ proxies for B C\n"
      "   |--Site B ------- proxies for A C\n"
      "   +--Site C ------- proxies for A B\n"
      "Where A = http://a.com/\n"
      "      B = http://b.com/\n"
      "      C = http://c.com/",
      DepictFrameTree(root));

  // Navigate second child frame from C to D.
  {
    RenderFrameDeletedObserver deleted_observer(child2->current_frame_host());
    GURL d_url(embedded_test_server()->GetURL("d.com", "/title1.html"));
    EXPECT_TRUE(NavigateToURLFromRenderer(child2, d_url));
    deleted_observer.WaitUntilDeleted();
  }
  EXPECT_EQ(
      " Site A ------------ proxies for B D\n"
      "   |--Site B ------- proxies for A D\n"
      "   +--Site D ------- proxies for A B\n"
      "Where A = http://a.com/\n"
      "      B = http://b.com/\n"
      "      D = http://d.com/",
      DepictFrameTree(root));
}

// Ensure that processes for iframes correctly track whether or not they have a
// local main frame.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       CrossSiteIframeMainFrameCount) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(a,a,a(a,a))"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();

  TestNavigationObserver observer(shell()->web_contents());

  EXPECT_EQ(
      " Site A\n"
      "   |--Site A\n"
      "   |--Site A\n"
      "   +--Site A\n"
      "        |--Site A\n"
      "        +--Site A\n"
      "Where A = http://a.com/",
      DepictFrameTree(root));

  mojo::Remote<mojom::MainFrameCounterTest> main_frame_counter;
  shell()->web_contents()->GetPrimaryMainFrame()->GetProcess()->BindReceiver(
      main_frame_counter.BindNewPipeAndPassReceiver());
  VerifyChildProcessHasMainFrame(main_frame_counter, true);

  GURL url = embedded_test_server()->GetURL(
      "b.com", "/cross_site_iframe_factory.html?b(a,a)");
  {
    RenderFrameDeletedObserver deleted_observer(
        root->child_at(2)->current_frame_host());
    EXPECT_TRUE(NavigateToURLFromRenderer(root->child_at(2), url));
    deleted_observer.WaitUntilDeleted();
  }

  EXPECT_EQ(
      " Site A ------------ proxies for B\n"
      "   |--Site A ------- proxies for B\n"
      "   |--Site A ------- proxies for B\n"
      "   +--Site B ------- proxies for A\n"
      "        |--Site A -- proxies for B\n"
      "        +--Site A -- proxies for B\n"
      "Where A = http://a.com/\n"
      "      B = http://b.com/",
      DepictFrameTree(root));

  VerifyChildProcessHasMainFrame(main_frame_counter, true);

  mojo::Remote<mojom::MainFrameCounterTest> main_frame_counter_child;
  root->child_at(2)->current_frame_host()->GetProcess()->BindReceiver(
      main_frame_counter_child.BindNewPipeAndPassReceiver());
  VerifyChildProcessHasMainFrame(main_frame_counter_child, false);
}

// Ensure that title updates affect the correct NavigationEntry after a new
// subframe navigation with an out-of-process iframe.  https://crbug.com/616609.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest, TitleAfterCrossSiteIframe) {
  // Start at an initial page.
  GURL initial_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
  EXPECT_TRUE(NavigateToURL(shell(), initial_url));

  // Navigate to a same-site page with a same-site iframe.
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(a)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();

  // Make the main frame update its title after the subframe loads.
  EXPECT_TRUE(ExecJs(shell()->web_contents(),
                     "document.querySelector('iframe').onload = "
                     "    function() { document.title = 'loaded'; };"));
  EXPECT_TRUE(
      ExecJs(shell()->web_contents(), "document.title = 'not loaded';"));
  std::u16string expected_title(u"loaded");
  TitleWatcher title_watcher(shell()->web_contents(), expected_title);

  // Navigate the iframe cross-site.
  TestNavigationObserver load_observer(shell()->web_contents());
  GURL frame_url = embedded_test_server()->GetURL("b.com", "/title2.html");
  EXPECT_TRUE(ExecJs(root->child_at(0)->current_frame_host(),
                     JsReplace("window.location.href = $1", frame_url)));
  load_observer.Wait();

  // Wait for the title to update and ensure it affects the right NavEntry.
  EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
  NavigationEntry* entry =
      shell()->web_contents()->GetController().GetLastCommittedEntry();
  EXPECT_EQ(expected_title, entry->GetTitle());
}

// This test verifies that scroll bubbling from an OOPIF properly forwards
// GestureFlingStart events from the child frame to the parent frame. This
// test times out on failure.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       GestureFlingStartEventsBubble) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
                            ->GetPrimaryFrameTree()
                            .root();
  ASSERT_EQ(1U, root->child_count());

  FrameTreeNode* child_iframe_node = root->child_at(0);

  RenderWidgetHost* child_rwh =
      child_iframe_node->current_frame_host()->GetRenderWidgetHost();

  // The fling start won't bubble since its corresponding GSB hasn't bubbled.
  InputEventAckWaiter gesture_fling_start_ack_observer(
      child_rwh, blink::WebInputEvent::Type::kGestureFlingStart);

  WaitForHitTestData(child_iframe_node->current_frame_host());

  gesture_fling_start_ack_observer.Reset();

  GenerateTapDownGesture(child_rwh);

  // Send a GSB, GSU, GFS sequence and verify that the GFS bubbles.
  blink::WebGestureEvent gesture_scroll_begin(
      blink::WebGestureEvent::Type::kGestureScrollBegin,
      blink::WebInputEvent::kNoModifiers,
      blink::WebInputEvent::GetStaticTimeStampForTests(),
      blink::WebGestureDevice::kTouchscreen);
  gesture_scroll_begin.data.scroll_begin.delta_hint_units =
      ui::ScrollGranularity::kScrollByPrecisePixel;
  gesture_scroll_begin.data.scroll_begin.delta_x_hint = 0.f;
  gesture_scroll_begin.data.scroll_begin.delta_y_hint = 5.f;

  child_rwh->ForwardGestureEvent(gesture_scroll_begin);

  blink::WebGestureEvent gesture_scroll_update(
      blink::WebGestureEvent::Type::kGestureScrollUpdate,
      blink::WebInputEvent::kNoModifiers,
      blink::WebInputEvent::GetStaticTimeStampForTests(),
      blink::WebGestureDevice::kTouchscreen);
  gesture_scroll_update.data.scroll_update.delta_units =
      ui::ScrollGranularity::kScrollByPrecisePixel;
  gesture_scroll_update.data.scroll_update.delta_x = 0.f;
  gesture_scroll_update.data.scroll_update.delta_y = 5.f;

  child_rwh->ForwardGestureEvent(gesture_scroll_update);

  blink::WebGestureEvent gesture_fling_start(
      blink::WebGestureEvent::Type::kGestureFlingStart,
      blink::WebInputEvent::kNoModifiers,
      blink::WebInputEvent::GetStaticTimeStampForTests(),
      blink::WebGestureDevice::kTouchscreen);
  gesture_fling_start.data.fling_start.velocity_x = 0.f;
  gesture_fling_start.data.fling_start.velocity_y = 5.f;

  child_rwh->ForwardGestureEvent(gesture_fling_start);

  // We now wait for the fling start event to be acked by the parent
  // frame. If the test fails, then the test times out.
  gesture_fling_start_ack_observer.Wait();
}

// Test that fling on an out-of-process iframe progresses properly.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       TouchscreenGestureFlingStart) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
                            ->GetPrimaryFrameTree()
                            .root();
  ASSERT_EQ(1U, root->child_count());

  FrameTreeNode* child_iframe_node = root->child_at(0);

  RenderWidgetHost* child_rwh =
      child_iframe_node->current_frame_host()->GetRenderWidgetHost();
  WaitForHitTestData(child_iframe_node->current_frame_host());

  GenerateTapDownGesture(child_rwh);
  // Send a GSB to start scrolling sequence.
  blink::WebGestureEvent gesture_scroll_begin(
      blink::WebGestureEvent::Type::kGestureScrollBegin,
      blink::WebInputEvent::kNoModifiers,
      blink::WebInputEvent::GetStaticTimeStampForTests());
  gesture_scroll_begin.SetSourceDevice(blink::WebGestureDevice::kTouchscreen);
  gesture_scroll_begin.data.scroll_begin.delta_hint_units =
      ui::ScrollGranularity::kScrollByPrecisePixel;
  gesture_scroll_begin.data.scroll_begin.delta_x_hint = 0.f;
  gesture_scroll_begin.data.scroll_begin.delta_y_hint = 5.f;
  child_rwh->ForwardGestureEvent(gesture_scroll_begin);

  // Send a GFS and wait for the ack of the first GSU generated from progressing
  // the fling on the browser.
  InputEventAckWaiter gesture_scroll_update_ack_observer(
      child_rwh, blink::WebInputEvent::Type::kGestureScrollUpdate);
  gesture_scroll_update_ack_observer.Reset();
  blink::WebGestureEvent gesture_fling_start(
      blink::WebGestureEvent::Type::kGestureFlingStart,
      blink::WebInputEvent::kNoModifiers,
      blink::WebInputEvent::GetStaticTimeStampForTests());
  gesture_fling_start.SetSourceDevice(blink::WebGestureDevice::kTouchscreen);
  gesture_fling_start.data.fling_start.velocity_x = 0.f;
  gesture_fling_start.data.fling_start.velocity_y = 50.f;
  child_rwh->ForwardGestureEvent(gesture_fling_start);
  gesture_scroll_update_ack_observer.Wait();
}

// Test that fling on an out-of-process iframe progresses properly.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest, TouchpadGestureFlingStart) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
                            ->GetPrimaryFrameTree()
                            .root();
  ASSERT_EQ(1U, root->child_count());

  FrameTreeNode* child_iframe_node = root->child_at(0);

  RenderWidgetHost* child_rwh =
      child_iframe_node->current_frame_host()->GetRenderWidgetHost();

  // Send a wheel event with phaseBegan to start scrolling sequence.
  InputEventAckWaiter gesture_scroll_begin_ack_observer(
      child_rwh, blink::WebInputEvent::Type::kGestureScrollBegin);
  blink::WebMouseWheelEvent scroll_event(
      blink::WebInputEvent::Type::kMouseWheel,
      blink::WebInputEvent::kNoModifiers,
      blink::WebInputEvent::GetStaticTimeStampForTests());
  scroll_event.delta_units = ui::ScrollGranularity::kScrollByPrecisePixel;
  scroll_event.delta_x = 0.0f;
  scroll_event.delta_y = 5.0f;
  scroll_event.phase = blink::WebMouseWheelEvent::kPhaseBegan;
  child_rwh->ForwardWheelEvent(scroll_event);
  gesture_scroll_begin_ack_observer.Wait();

  // Send a GFS and wait for the ack of the first GSU generated from progressing
  // the fling on the browser.
  InputEventAckWaiter gesture_scroll_update_ack_observer(
      child_rwh, blink::WebInputEvent::Type::kGestureScrollUpdate);
  gesture_scroll_update_ack_observer.Reset();
  blink::WebGestureEvent gesture_fling_start(
      blink::WebGestureEvent::Type::kGestureFlingStart,
      blink::WebInputEvent::kNoModifiers,
      blink::WebInputEvent::GetStaticTimeStampForTests());
  gesture_fling_start.SetSourceDevice(blink::WebGestureDevice::kTouchpad);
  gesture_fling_start.data.fling_start.velocity_x = 0.f;
  gesture_fling_start.data.fling_start.velocity_y = 50.f;
  child_rwh->ForwardGestureEvent(gesture_fling_start);
  // The test will pass when the GSU ack arrives, since it shows that the fling
  // controller has properly generated a GSU event from progressing the fling.
  gesture_scroll_update_ack_observer.Wait();
}

// Tests OOPIF rendering by checking that the RWH of the iframe generates
// OnSwapCompositorFrame message.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest, CompositorFrameSwapped) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(baz)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  // It is safe to obtain the root frame tree node here, as it doesn't change.
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  ASSERT_EQ(1U, root->child_count());

  FrameTreeNode* child_node = root->child_at(0);
  GURL site_url(embedded_test_server()->GetURL(
      "baz.com", "/cross_site_iframe_factory.html?baz()"));
  EXPECT_EQ(site_url, child_node->current_url());
  EXPECT_NE(shell()->web_contents()->GetSiteInstance(),
            child_node->current_frame_host()->GetSiteInstance());
  // Wait for CompositorFrame submission.
  RenderFrameSubmissionObserver observer(
      child_node->current_frame_host()
          ->GetRenderWidgetHost()
          ->render_frame_metadata_provider());
  observer.WaitForAnyFrameSubmission();
}

// Ensure that OOPIFs are deleted after navigating to a new main frame.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest, CleanupCrossSiteIframe) {
  // The test assumes the previous page gets deleted after navigation. Disable
  // back-forward cache to ensure that it doesn't get preserved in the cache.
  DisableBackForwardCacheForTesting(
      web_contents(), content::BackForwardCache::TEST_REQUIRES_NO_CACHING);
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(a,a(a,a(a)))"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  // It is safe to obtain the root frame tree node here, as it doesn't change.
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();

  TestNavigationObserver observer(shell()->web_contents());

  // Load a cross-site page into both iframes.
  GURL foo_url = embedded_test_server()->GetURL("foo.com", "/title2.html");
  EXPECT_TRUE(NavigateToURLFromRenderer(root->child_at(0), foo_url));
  EXPECT_TRUE(observer.last_navigation_succeeded());
  EXPECT_EQ(foo_url, observer.last_navigation_url());
  EXPECT_TRUE(NavigateToURLFromRenderer(root->child_at(1), foo_url));
  EXPECT_TRUE(observer.last_navigation_succeeded());
  EXPECT_EQ(foo_url, observer.last_navigation_url());

  // Ensure that we have created a new process for the subframes.
  EXPECT_EQ(
      " Site A ------------ proxies for B\n"
      "   |--Site B ------- proxies for A\n"
      "   +--Site B ------- proxies for A\n"
      "Where A = http://a.com/\n"
      "      B = http://foo.com/",
      DepictFrameTree(root));

  int subframe_process_id = root->child_at(0)
                                ->current_frame_host()
                                ->GetSiteInstance()
                                ->GetProcess()
                                ->GetDeprecatedID();
  int subframe_rvh_id = root->child_at(0)
                            ->current_frame_host()
                            ->render_view_host()
                            ->GetRoutingID();
  EXPECT_TRUE(RenderViewHost::FromID(subframe_process_id, subframe_rvh_id));

  // Use Javascript in the parent to remove one of the frames and ensure that
  // the subframe goes away.
  EXPECT_TRUE(ExecJs(shell(),
                     "document.body.removeChild("
                     "document.querySelectorAll('iframe')[0])"));
  ASSERT_EQ(1U, root->child_count());

  // Load a new same-site page in the top-level frame and ensure the other
  // subframe goes away.
  GURL new_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
  EXPECT_TRUE(NavigateToURL(shell(), new_url));
  ASSERT_EQ(0U, root->child_count());

  // Ensure the RVH for the subframe gets cleaned up when the frame goes away.
  EXPECT_FALSE(RenderViewHost::FromID(subframe_process_id, subframe_rvh_id));
}

IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest, NavigateRemoteFrame) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(a,a(a,a(a)))"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  // It is safe to obtain the root frame tree node here, as it doesn't change.
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();

  TestNavigationObserver observer(shell()->web_contents());

  // Load same-site page into iframe.
  FrameTreeNode* child = root->child_at(0);
  GURL http_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
  EXPECT_TRUE(NavigateToURLFromRenderer(child, http_url));
  EXPECT_EQ(http_url, observer.last_navigation_url());
  EXPECT_TRUE(observer.last_navigation_succeeded());

  // Load cross-site page into iframe.
  GURL url = embedded_test_server()->GetURL("foo.com", "/title2.html");
  {
    RenderFrameDeletedObserver deleted_observer(child->current_frame_host());
    EXPECT_TRUE(NavigateToURLFromRenderer(root->child_at(0), url));
    deleted_observer.WaitUntilDeleted();
  }
  EXPECT_TRUE(observer.last_navigation_succeeded());
  EXPECT_EQ(url, observer.last_navigation_url());

  // Ensure that we have created a new process for the subframe.
  EXPECT_EQ(
      " Site A ------------ proxies for B\n"
      "   |--Site B ------- proxies for A\n"
      "   +--Site A ------- proxies for B\n"
      "        |--Site A -- proxies for B\n"
      "        +--Site A -- proxies for B\n"
      "             +--Site A -- proxies for B\n"
      "Where A = http://a.com/\n"
      "      B = http://foo.com/",
      DepictFrameTree(root));
  SiteInstance* site_instance = child->current_frame_host()->GetSiteInstance();
  EXPECT_NE(shell()->web_contents()->GetSiteInstance(), site_instance);

  // Emulate the main frame changing the src of the iframe such that it
  // navigates cross-site.
  url = embedded_test_server()->GetURL("bar.com", "/title3.html");
  {
    RenderFrameDeletedObserver deleted_observer(child->current_frame_host());
    NavigateIframeToURL(shell()->web_contents(), "child-0", url);
    deleted_observer.WaitUntilDeleted();
  }
  EXPECT_TRUE(observer.last_navigation_succeeded());
  EXPECT_EQ(url, observer.last_navigation_url());

  // Check again that a new process is created and is different from the
  // top level one and the previous one.
  EXPECT_EQ(
      " Site A ------------ proxies for C\n"
      "   |--Site C ------- proxies for A\n"
      "   +--Site A ------- proxies for C\n"
      "        |--Site A -- proxies for C\n"
      "        +--Site A -- proxies for C\n"
      "             +--Site A -- proxies for C\n"
      "Where A = http://a.com/\n"
      "      C = http://bar.com/",
      DepictFrameTree(root));

  // Navigate back to the parent's origin and ensure we return to the
  // parent's process.
  {
    RenderFrameDeletedObserver deleted_observer(child->current_frame_host());
    EXPECT_TRUE(NavigateToURLFromRenderer(child, http_url));
    deleted_observer.WaitUntilDeleted();
  }
  EXPECT_EQ(http_url, observer.last_navigation_url());
  EXPECT_TRUE(observer.last_navigation_succeeded());
  EXPECT_EQ(shell()->web_contents()->GetSiteInstance(),
            child->current_frame_host()->GetSiteInstance());
}

IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       NavigateRemoteFrameToBlankAndDataURLs) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(a,a(a))"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  // It is safe to obtain the root frame tree node here, as it doesn't change.
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();

  TestNavigationObserver observer(shell()->web_contents());

  // Load same-site page into iframe.
  FrameTreeNode* child = root->child_at(0);
  GURL http_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
  EXPECT_TRUE(NavigateToURLFromRenderer(child, http_url));
  EXPECT_EQ(http_url, observer.last_navigation_url());
  EXPECT_TRUE(observer.last_navigation_succeeded());
  EXPECT_EQ(
      " Site A\n"
      "   |--Site A\n"
      "   +--Site A\n"
      "        +--Site A\n"
      "Where A = http://a.com/",
      DepictFrameTree(root));

  // Load cross-site page into iframe.
  GURL url = embedded_test_server()->GetURL("foo.com", "/title2.html");
  EXPECT_TRUE(NavigateToURLFromRenderer(child, url));
  EXPECT_TRUE(observer.last_navigation_succeeded());
  EXPECT_EQ(url, observer.last_navigation_url());
  EXPECT_EQ(
      " Site A ------------ proxies for B\n"
      "   |--Site B ------- proxies for A\n"
      "   +--Site A ------- proxies for B\n"
      "        +--Site A -- proxies for B\n"
      "Where A = http://a.com/\n"
      "      B = http://foo.com/",
      DepictFrameTree(root));

  // Navigate iframe to a data URL. The navigation happens from a script in the
  // parent frame, so the data URL should be committed in the same
  // SiteInstanceGroup as the parent frame. If kSiteInstanceGroupsForDataUrls is
  // enabled, the data URL should be in its own SiteInstance. Otherwise it
  // shares a SiteInstance with its parent.
  RenderFrameDeletedObserver deleted_observer1(
      root->child_at(0)->current_frame_host());
  GURL data_url("data:text/html,dataurl");
  NavigateIframeToURL(shell()->web_contents(), "child-0", data_url);
  EXPECT_TRUE(observer.last_navigation_succeeded());
  EXPECT_EQ(data_url, observer.last_navigation_url());

  // Wait for the old process to exit, to verify that the proxies go away.
  deleted_observer1.WaitUntilDeleted();

  // Ensure that we have navigated using the top level process.
  if (ShouldCreateSiteInstanceForDataUrls()) {
    // Site A and Site C are in the same SiteInstanceGroup, so there are no
    // proxies for each other.
    // TODO(crbug.com/341741267, yangsharon): Update output to show that A and C
    // are in the same SiteInstanceGroup.
    EXPECT_EQ(
        " Site A\n"
        "   |--Site C\n"
        "   +--Site A\n"
        "        +--Site A\n"
        "Where A = http://a.com/\n"
        "      C = data:nonce_C",
        DepictFrameTree(root));
  } else {
    EXPECT_EQ(
        " Site A\n"
        "   |--Site A\n"
        "   +--Site A\n"
        "        +--Site A\n"
        "Where A = http://a.com/",
        DepictFrameTree(root));
  }

  // Load cross-site page into iframe.
  url = embedded_test_server()->GetURL("bar.com", "/title2.html");
  EXPECT_TRUE(NavigateToURLFromRenderer(child, url));
  EXPECT_TRUE(observer.last_navigation_succeeded());
  EXPECT_EQ(url, observer.last_navigation_url());
  if (ShouldCreateSiteInstanceForDataUrls()) {
    EXPECT_EQ(
        " Site A ------------ proxies for D\n"
        "   |--Site D ------- proxies for {A,C}\n"
        "   +--Site A ------- proxies for D\n"
        "        +--Site A -- proxies for D\n"
        "Where A = http://a.com/\n"
        "      C = data:nonce_C\n"
        "      D = http://bar.com/",
        DepictFrameTree(root));
  } else {
    EXPECT_EQ(
        " Site A ------------ proxies for C\n"
        "   |--Site C ------- proxies for A\n"
        "   +--Site A ------- proxies for C\n"
        "        +--Site A -- proxies for C\n"
        "Where A = http://a.com/\n"
        "      C = http://bar.com/",
        DepictFrameTree(root));
  }

  // Navigate iframe to about:blank. The navigation happens from a script in the
  // parent frame, so it should be committed in the same SiteInstance as the
  // parent frame.
  RenderFrameDeletedObserver deleted_observer2(
      root->child_at(0)->current_frame_host());
  GURL about_blank_url("about:blank#foo");
  NavigateIframeToURL(shell()->web_contents(), "child-0", about_blank_url);
  EXPECT_TRUE(observer.last_navigation_succeeded());
  EXPECT_EQ(about_blank_url, observer.last_navigation_url());

  // Wait for the old process to exit, to verify that the proxies go away.
  deleted_observer2.WaitUntilDeleted();

  // Ensure that we have navigated using the top level process.
  EXPECT_EQ(
      " Site A\n"
      "   |--Site A\n"
      "   +--Site A\n"
      "        +--Site A\n"
      "Where A = http://a.com/",
      DepictFrameTree(root));

  // Load cross-site page into iframe again.
  url = embedded_test_server()->GetURL("f00.com", "/title3.html");
  EXPECT_TRUE(NavigateToURLFromRenderer(child, url));
  EXPECT_TRUE(observer.last_navigation_succeeded());
  EXPECT_EQ(url, observer.last_navigation_url());
  if (ShouldCreateSiteInstanceForDataUrls()) {
    EXPECT_EQ(
        " Site A ------------ proxies for E\n"
        "   |--Site E ------- proxies for {A,C}\n"
        "   +--Site A ------- proxies for E\n"
        "        +--Site A -- proxies for E\n"
        "Where A = http://a.com/\n"
        "      C = data:nonce_C\n"
        "      E = http://f00.com/",
        DepictFrameTree(root));
  } else {
    EXPECT_EQ(
        " Site A ------------ proxies for D\n"
        "   |--Site D ------- proxies for A\n"
        "   +--Site A ------- proxies for D\n"
        "        +--Site A -- proxies for D\n"
        "Where A = http://a.com/\n"
        "      D = http://f00.com/",
        DepictFrameTree(root));
  }

  // Navigate the iframe itself to about:blank using a script executing in its
  // own context. It should stay in the same SiteInstance as before, not the
  // parent one.
  TestFrameNavigationObserver frame_observer(child);
  EXPECT_TRUE(ExecJs(child, "window.location.href = 'about:blank#foo';"));
  frame_observer.Wait();
  EXPECT_EQ(about_blank_url, child->current_url());

  // Ensure that we have navigated using the top level process.
  if (ShouldCreateSiteInstanceForDataUrls()) {
    EXPECT_EQ(
        " Site A ------------ proxies for E\n"
        "   |--Site E ------- proxies for {A,C}\n"
        "   +--Site A ------- proxies for E\n"
        "        +--Site A -- proxies for E\n"
        "Where A = http://a.com/\n"
        "      C = data:nonce_C\n"
        "      E = http://f00.com/",
        DepictFrameTree(root));
  } else {
    EXPECT_EQ(
        " Site A ------------ proxies for D\n"
        "   |--Site D ------- proxies for A\n"
        "   +--Site A ------- proxies for D\n"
        "        +--Site A -- proxies for D\n"
        "Where A = http://a.com/\n"
        "      D = http://f00.com/",
        DepictFrameTree(root));
  }
}

// This test checks that killing a renderer process of a remote frame
// and then navigating some other frame to the same SiteInstance of the killed
// process works properly.
// This can be illustrated as follows,
// where 1/2/3 are FrameTreeNode-s and A/B are processes and B* is the killed
// B process:
//
//     1        A                  A                           A
//    / \  ->  / \  -> Kill B ->  / \  -> Navigate 3 to B ->  / \  .
//   2   3    B   A              B*  A                       B*  B
//
// Initially, node1.proxy_hosts_ = {B}
// After we kill B, we make sure B stays in node1.proxy_hosts_, then we navigate
// 3 to B and we expect that to complete normally.
// See http://crbug.com/432107.
//
// Note that due to http://crbug.com/450681, node2 cannot be re-navigated to
// site B and stays in not rendered state.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       NavigateRemoteFrameToKilledProcess) {
  GURL main_url(embedded_test_server()->GetURL(
      "foo.com", "/cross_site_iframe_factory.html?foo.com(bar.com, foo.com)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  // It is safe to obtain the root frame tree node here, as it doesn't change.
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();

  TestNavigationObserver observer(shell()->web_contents());
  ASSERT_EQ(2U, root->child_count());

  // Make sure node2 points to the correct cross-site page.
  GURL site_b_url = embedded_test_server()->GetURL(
      "bar.com", "/cross_site_iframe_factory.html?bar.com()");
  FrameTreeNode* node2 = root->child_at(0);
  EXPECT_EQ(site_b_url, node2->current_url());

  // Kill that cross-site renderer.
  RenderProcessHost* child_process = node2->current_frame_host()->GetProcess();
  RenderProcessHostWatcher crash_observer(
      child_process, RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
  child_process->Shutdown(0);
  crash_observer.Wait();

  // Now navigate the second iframe (node3) to the same site as the node2.
  FrameTreeNode* node3 = root->child_at(1);
  EXPECT_TRUE(NavigateToURLFromRenderer(node3, site_b_url));
  EXPECT_TRUE(observer.last_navigation_succeeded());
  EXPECT_EQ(site_b_url, observer.last_navigation_url());
}

// This test ensures that WebContentsImpl::FocusOwningWebContents does not crash
// the browser if the currently focused frame's renderer has disappeared.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest, RemoveFocusFromKilledFrame) {
  GURL main_url(embedded_test_server()->GetURL(
      "foo.com", "/cross_site_iframe_factory.html?foo.com(bar.com)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  // It is safe to obtain the root frame tree node here, as it doesn't change.
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();

  TestNavigationObserver observer(shell()->web_contents());
  ASSERT_EQ(1U, root->child_count());

  // Make sure node2 points to the correct cross-site page.
  GURL site_b_url = embedded_test_server()->GetURL(
      "bar.com", "/cross_site_iframe_factory.html?bar.com()");
  FrameTreeNode* node2 = root->child_at(0);
  EXPECT_EQ(site_b_url, node2->current_url());

  web_contents()->SetFocusedFrame(
      node2, node2->current_frame_host()->GetSiteInstance()->group());

  // Kill that cross-site renderer.
  RenderProcessHost* child_process = node2->current_frame_host()->GetProcess();
  RenderProcessHostWatcher crash_observer(
      child_process, RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
  child_process->Shutdown(0);
  crash_observer.Wait();

  // Try to focus the root's owning WebContents.
  web_contents()->FocusOwningWebContents(
      root->current_frame_host()->GetRenderWidgetHost());
}

// This test is similar to
// SitePerProcessBrowserTest.NavigateRemoteFrameToKilledProcess with
// addition that node2 also has a cross-origin frame to site C.
//
//     1          A                  A                       A
//    / \        / \                / \                     / \  .
//   2   3 ->   B   A -> Kill B -> B*   A -> Navigate 3 -> B*  B
//  /          /
// 4          C
//
// Initially, node1.proxy_hosts_ = {B, C}
// After we kill B, we make sure B stays in node1.proxy_hosts_, but
// C gets cleared from node1.proxy_hosts_.
//
// Note that due to http://crbug.com/450681, node2 cannot be re-navigated to
// site B and stays in not rendered state.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       NavigateRemoteFrameToKilledProcessWithSubtree) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(bar(baz), a)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  // It is safe to obtain the root frame tree node here, as it doesn't change.
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  TestNavigationObserver observer(shell()->web_contents());

  ASSERT_EQ(2U, root->child_count());

  GURL site_b_url(embedded_test_server()->GetURL(
      "bar.com", "/cross_site_iframe_factory.html?bar(baz())"));
  // We can't use a TestNavigationObserver to verify the URL here,
  // since the frame has children that may have clobbered it in the observer.
  EXPECT_EQ(site_b_url, root->child_at(0)->current_url());

  // Ensure that a new process is created for node2.
  EXPECT_NE(shell()->web_contents()->GetSiteInstance(),
            root->child_at(0)->current_frame_host()->GetSiteInstance());
  // Ensure that a new process is *not* created for node3.
  EXPECT_EQ(shell()->web_contents()->GetSiteInstance(),
            root->child_at(1)->current_frame_host()->GetSiteInstance());

  ASSERT_EQ(1U, root->child_at(0)->child_count());

  // Make sure node4 points to the correct cross-site page.
  FrameTreeNode* node4 = root->child_at(0)->child_at(0);
  GURL site_c_url(embedded_test_server()->GetURL(
      "baz.com", "/cross_site_iframe_factory.html?baz()"));
  EXPECT_EQ(site_c_url, node4->current_url());

  // |site_instance_c| is expected to go away once we kill |child_process_b|
  // below, so create a local scope so we can extend the lifetime of
  // |site_instance_c| with a refptr.
  {
    // Initially each frame has proxies for the other sites.
    EXPECT_EQ(
        " Site A ------------ proxies for B C\n"
        "   |--Site B ------- proxies for A C\n"
        "   |    +--Site C -- proxies for A B\n"
        "   +--Site A ------- proxies for B C\n"
        "Where A = http://a.com/\n"
        "      B = http://bar.com/\n"
        "      C = http://baz.com/",
        DepictFrameTree(root));

    // Kill the render process for Site B.
    RenderProcessHost* child_process_b =
        root->child_at(0)->current_frame_host()->GetProcess();
    RenderProcessHostWatcher crash_observer(
        child_process_b, RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
    child_process_b->Shutdown(0);
    crash_observer.Wait();

    // The Site C frame (a child of the crashed Site B frame) should go away,
    // and there should be no remaining proxies for site C anywhere.
    EXPECT_EQ(
        " Site A ------------ proxies for B\n"
        "   |--Site B ------- proxies for A\n"
        "   +--Site A ------- proxies for B\n"
        "Where A = http://a.com/\n"
        "      B = http://bar.com/ (no process)",
        DepictFrameTree(root));
  }

  // Now navigate the second iframe (node3) to Site B also.
  FrameTreeNode* node3 = root->child_at(1);
  GURL url = embedded_test_server()->GetURL("bar.com", "/title1.html");
  EXPECT_TRUE(NavigateToURLFromRenderer(node3, url));
  EXPECT_TRUE(observer.last_navigation_succeeded());
  EXPECT_EQ(url, observer.last_navigation_url());

  EXPECT_EQ(
      " Site A ------------ proxies for B\n"
      "   |--Site B ------- proxies for A\n"
      "   +--Site B ------- proxies for A\n"
      "Where A = http://a.com/\n"
      "      B = http://bar.com/",
      DepictFrameTree(root));
}

// Ensure that the renderer process doesn't crash when the main frame navigates
// a remote child to a page that results in a network error.
// See https://crbug.com/558016.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest, NavigateRemoteAfterError) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(a)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  // It is safe to obtain the root frame tree node here, as it doesn't change.
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();

  // Load same-site page into iframe.
  {
    TestNavigationObserver observer(shell()->web_contents());
    FrameTreeNode* child = root->child_at(0);
    GURL http_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
    EXPECT_TRUE(NavigateToURLFromRenderer(child, http_url));
    EXPECT_EQ(http_url, observer.last_navigation_url());
    EXPECT_TRUE(observer.last_navigation_succeeded());
    observer.Wait();
  }

  // Load cross-site page into iframe.
  {
    TestNavigationObserver observer(shell()->web_contents());
    FrameTreeNode* child = root->child_at(0);
    GURL url = embedded_test_server()->GetURL("foo.com", "/title2.html");
    EXPECT_TRUE(NavigateToURLFromRenderer(root->child_at(0), url));
    EXPECT_TRUE(observer.last_navigation_succeeded());
    EXPECT_EQ(url, observer.last_navigation_url());
    observer.Wait();

    // Ensure that we have created a new process for the subframe.
    EXPECT_EQ(
        " Site A ------------ proxies for B\n"
        "   +--Site B ------- proxies for A\n"
        "Where A = http://a.com/\n"
        "      B = http://foo.com/",
        DepictFrameTree(root));
    SiteInstance* site_instance =
        child->current_frame_host()->GetSiteInstance();
    EXPECT_NE(shell()->web_contents()->GetSiteInstance(), site_instance);
  }

  // Stop the test server and try to navigate the remote frame.
  {
    GURL url = embedded_test_server()->GetURL("bar.com", "/title3.html");
    EXPECT_TRUE(embedded_test_server()->ShutdownAndWaitUntilComplete());
    NavigateIframeToURL(shell()->web_contents(), "child-0", url);
  }
}

// Ensure that a cross-site page ends up in the correct process when it
// successfully loads after earlier encountering a network error for it.
// See https://crbug.com/560511.
// TODO(creis): Make the net error page show in the correct process as well,
// per https://crbug.com/588314.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest, ProcessTransferAfterError) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(a)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  // It is safe to obtain the root frame tree node here, as it doesn't change.
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  FrameTreeNode* child = root->child_at(0);
  GURL url_a = child->current_url();

  // Disable host resolution in the test server and try to navigate the subframe
  // cross-site, which will lead to a committed net error.
  GURL url_b = embedded_test_server()->GetURL("b.com", "/title3.html");
  auto url_loader_interceptor = std::make_unique<URLLoaderInterceptor>(
      base::BindRepeating([](URLLoaderInterceptor::RequestParams* params) {
        network::URLLoaderCompletionStatus status;
        status.error_code = net::ERR_NOT_IMPLEMENTED;
        params->client->OnComplete(status);
        return true;
      }));

  TestNavigationObserver observer(shell()->web_contents());
  NavigateIframeToURL(shell()->web_contents(), "child-0", url_b);
  EXPECT_FALSE(observer.last_navigation_succeeded());
  EXPECT_EQ(url_b, observer.last_navigation_url());
  EXPECT_EQ(2, shell()->web_contents()->GetController().GetEntryCount());

  // Ensure that we have created a new process for the subframe.
  EXPECT_EQ(
      " Site A ------------ proxies for B\n"
      "   +--Site B ------- proxies for A\n"
      "Where A = http://a.com/\n"
      "      B = http://b.com/",
      DepictFrameTree(root));
  EXPECT_NE(shell()->web_contents()->GetSiteInstance(),
            child->current_frame_host()->GetSiteInstance());

  // We have switched RenderFrameHosts for the subframe, so the last successful
  // url should be empty (since the frame only loaded an error page).
  EXPECT_EQ(GURL(), child->current_frame_host()->last_successful_url());
  EXPECT_EQ(url_b, child->current_url());
  EXPECT_EQ("null", child->current_origin().Serialize());

  // Try again after re-enabling host resolution.
  url_loader_interceptor.reset();

  // Activate the root frame by executing a dummy script.
  //
  // TODO(mustaq): Why does the |back_load_observer.Wait()| below time out
  // without the user activation?
  EXPECT_TRUE(ExecJs(root, "// No-op script"));
  NavigateIframeToURL(shell()->web_contents(), "child-0", url_b);
  EXPECT_TRUE(observer.last_navigation_succeeded());
  EXPECT_EQ(url_b, observer.last_navigation_url());

  // The FrameTreeNode should have updated its URL and origin.
  EXPECT_EQ(url_b, child->current_frame_host()->last_successful_url());
  EXPECT_EQ(url_b, child->current_url());
  EXPECT_EQ(url_b.DeprecatedGetOriginAsURL().spec(),
            child->current_origin().Serialize() + '/');

  // Ensure that we have created a new process for the subframe.
  EXPECT_EQ(
      " Site A ------------ proxies for B\n"
      "   +--Site B ------- proxies for A\n"
      "Where A = http://a.com/\n"
      "      B = http://b.com/",
      DepictFrameTree(root));
  EXPECT_NE(shell()->web_contents()->GetSiteInstance(),
            child->current_frame_host()->GetSiteInstance());

  // Make sure that the navigation replaced the error page and that going back
  // ends up on the original site.
  EXPECT_EQ(2, shell()->web_contents()->GetController().GetEntryCount());
  {
    RenderFrameDeletedObserver deleted_observer(child->current_frame_host());
    TestNavigationObserver back_load_observer(shell()->web_contents());
    shell()->web_contents()->GetController().GoBack();
    back_load_observer.Wait();

    // Wait for the old process to exit, to verify that the proxies go away.
    deleted_observer.WaitUntilDeleted();
  }
  EXPECT_EQ(
      " Site A\n"
      "   +--Site A\n"
      "Where A = http://a.com/",
      DepictFrameTree(root));
  EXPECT_EQ(shell()->web_contents()->GetSiteInstance(),
            child->current_frame_host()->GetSiteInstance());
  EXPECT_EQ(url_a, child->current_frame_host()->last_successful_url());
  EXPECT_EQ(url_a, child->current_url());
  EXPECT_EQ(url_a.DeprecatedGetOriginAsURL().spec(),
            child->current_origin().Serialize() + '/');
}

// Verify that killing a cross-site frame's process B and then navigating a
// frame to B correctly recreates all proxies in B.
//
//      1           A                    A          A
//    / | \       / | \                / | \      / | \  .
//   2  3  4 ->  B  A  A -> Kill B -> B* A  A -> B* B  A
//
// After the last step, the test sends a postMessage from node 3 to node 4,
// verifying that a proxy for node 4 has been recreated in process B.  This
// verifies the fix for https://crbug.com/478892.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       NavigatingToKilledProcessRestoresAllProxies) {
  // Navigate to a page with three frames: one cross-site and two same-site.
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/frame_tree/page_with_three_frames.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  // It is safe to obtain the root frame tree node here, as it doesn't change.
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  TestNavigationObserver observer(shell()->web_contents());

  EXPECT_EQ(
      " Site A ------------ proxies for B\n"
      "   |--Site B ------- proxies for A\n"
      "   |--Site A ------- proxies for B\n"
      "   +--Site A ------- proxies for B\n"
      "Where A = http://a.com/\n"
      "      B = http://b.com/",
      DepictFrameTree(root));

  // Kill the first subframe's b.com renderer.
  RenderProcessHost* child_process =
      root->child_at(0)->current_frame_host()->GetProcess();
  RenderProcessHostWatcher crash_observer(
      child_process, RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
  child_process->Shutdown(0);
  crash_observer.Wait();

  // Navigate the second subframe to b.com to recreate the b.com process.
  GURL b_url = embedded_test_server()->GetURL("b.com", "/post_message.html");
  EXPECT_TRUE(NavigateToURLFromRenderer(root->child_at(1), b_url));
  EXPECT_TRUE(observer.last_navigation_succeeded());
  EXPECT_EQ(b_url, observer.last_navigation_url());
  EXPECT_TRUE(root->child_at(1)->current_frame_host()->IsRenderFrameLive());

  EXPECT_EQ(
      " Site A ------------ proxies for B\n"
      "   |--Site B ------- proxies for A\n"
      "   |--Site B ------- proxies for A\n"
      "   +--Site A ------- proxies for B\n"
      "Where A = http://a.com/\n"
      "      B = http://b.com/",
      DepictFrameTree(root));

  // Check that third subframe's proxy is available in the b.com process by
  // sending it a postMessage from second subframe, and waiting for a reply.
  PostMessageAndWaitForReply(root->child_at(1),
                             "postToSibling('subframe-msg','frame3')",
                             "\"done-frame2\"");
}

// Verify that proxy creation doesn't recreate a crashed process if no frame
// will be created in it.
//
//      1           A                    A          A
//    / | \       / | \                / | \      / | \    .
//   2  3  4 ->  B  A  A -> Kill B -> B* A  A -> B* A  A
//                                                      \  .
//                                                       A
//
// The test kills process B (node 2), creates a child frame of node 4 in
// process A, and then checks that process B isn't resurrected to create a
// proxy for the new child frame.  See https://crbug.com/476846.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       CreateChildFrameAfterKillingProcess) {
  // Navigate to a page with three frames: one cross-site and two same-site.
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/frame_tree/page_with_three_frames.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  // It is safe to obtain the root frame tree node here, as it doesn't change.
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();

  EXPECT_EQ(
      " Site A ------------ proxies for B\n"
      "   |--Site B ------- proxies for A\n"
      "   |--Site A ------- proxies for B\n"
      "   +--Site A ------- proxies for B\n"
      "Where A = http://a.com/\n"
      "      B = http://b.com/",
      DepictFrameTree(root));
  SiteInstanceImpl* b_site_instance =
      root->child_at(0)->current_frame_host()->GetSiteInstance();

  // Kill the first subframe's renderer (B).
  RenderProcessHost* child_process =
      root->child_at(0)->current_frame_host()->GetProcess();
  RenderProcessHostWatcher crash_observer(
      child_process, RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
  child_process->Shutdown(0);
  crash_observer.Wait();

  // Add a new child frame to the third subframe.
  RenderFrameHostCreatedObserver frame_observer(shell()->web_contents(), 1);
  EXPECT_TRUE(
      ExecJs(root->child_at(2),
             "document.body.appendChild(document.createElement('iframe'));"));
  frame_observer.Wait();

  // The new frame should have a RenderFrameProxyHost for B, but it should not
  // be alive, and B should still not have a process (verified by last line of
  // expected DepictFrameTree output).
  EXPECT_EQ(
      " Site A ------------ proxies for B\n"
      "   |--Site B ------- proxies for A\n"
      "   |--Site A ------- proxies for B\n"
      "   +--Site A ------- proxies for B\n"
      "        +--Site A -- proxies for B\n"
      "Where A = http://a.com/\n"
      "      B = http://b.com/ (no process)",
      DepictFrameTree(root));
  FrameTreeNode* grandchild = root->child_at(2)->child_at(0);
  RenderFrameProxyHost* grandchild_rfph =
      grandchild->current_frame_host()
          ->browsing_context_state()
          ->GetRenderFrameProxyHost(b_site_instance->group());
  EXPECT_FALSE(grandchild_rfph->is_render_frame_proxy_live());

  // Navigate the second subframe to b.com to recreate process B.
  TestNavigationObserver observer(shell()->web_contents());
  GURL b_url = embedded_test_server()->GetURL("b.com", "/title1.html");
  EXPECT_TRUE(NavigateToURLFromRenderer(root->child_at(1), b_url));
  EXPECT_TRUE(observer.last_navigation_succeeded());
  EXPECT_EQ(b_url, observer.last_navigation_url());

  // Ensure that the grandchild `blink::RemoteFrame` in B was created when
  // process B was restored.
  EXPECT_TRUE(grandchild_rfph->is_render_frame_proxy_live());
}

// Verify that creating a child frame after killing and reloading an opener
// process doesn't crash. See https://crbug.com/501152.
//   1. Navigate to site A.
//   2. Open a popup with window.open and navigate it cross-process to site B.
//   3. Kill process A for the original tab.
//   4. Reload the original tab to resurrect process A.
//   5. Add a child frame to the top-level frame in the popup tab B.
// In step 5, we try to create proxies for the child frame in all SiteInstances
// for which its parent has proxies.  This includes A.  However, even though
// process A is live (step 4), the parent proxy in A is not live (which was
// incorrectly assumed previously).  This is because step 4 does not resurrect
// proxies for popups opened before the crash.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       CreateChildFrameAfterKillingOpener) {
  GURL main_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  // It is safe to obtain the root frame tree node here, as it doesn't change.
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  SiteInstanceImpl* site_instance_a =
      root->current_frame_host()->GetSiteInstance();

  // Open a popup and navigate it cross-process to b.com.
  ShellAddedObserver new_shell_observer;
  EXPECT_TRUE(ExecJs(root, "popup = window.open('about:blank');"));
  Shell* popup = new_shell_observer.GetShell();
  GURL popup_url(embedded_test_server()->GetURL("b.com", "/title2.html"));
  EXPECT_TRUE(NavigateToURLFromRenderer(popup, popup_url));

  // Verify that each top-level frame has proxies in the other's SiteInstance.
  FrameTreeNode* popup_root =
      static_cast<WebContentsImpl*>(popup->web_contents())
          ->GetPrimaryFrameTree()
          .root();
  EXPECT_EQ(
      " Site A ------------ proxies for B\n"
      "Where A = http://a.com/\n"
      "      B = http://b.com/",
      DepictFrameTree(root));
  EXPECT_EQ(
      " Site B ------------ proxies for A\n"
      "Where A = http://a.com/\n"
      "      B = http://b.com/",
      DepictFrameTree(popup_root));

  // Kill the first window's renderer (a.com).
  RenderProcessHost* child_process = root->current_frame_host()->GetProcess();
  RenderProcessHostWatcher crash_observer(
      child_process, RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
  child_process->Shutdown(0);
  crash_observer.Wait();
  EXPECT_FALSE(root->current_frame_host()->IsRenderFrameLive());

  // The proxy for the popup in a.com should've died.
  RenderFrameProxyHost* rfph =
      popup_root->current_frame_host()
          ->browsing_context_state()
          ->GetRenderFrameProxyHost(site_instance_a->group());
  EXPECT_FALSE(rfph->is_render_frame_proxy_live());

  // Recreate the a.com renderer.
  EXPECT_TRUE(NavigateToURL(shell(), main_url));
  EXPECT_TRUE(root->current_frame_host()->IsRenderFrameLive());

  // The popup's proxy in a.com should still not be live. Re-navigating the
  // main window to a.com doesn't reinitialize a.com proxies for popups
  // previously opened from the main window.
  EXPECT_FALSE(rfph->is_render_frame_proxy_live());

  // Add a new child frame on the popup.
  RenderFrameHostCreatedObserver frame_observer(popup->web_contents(), 1);
  EXPECT_TRUE(ExecJs(
      popup, "document.body.appendChild(document.createElement('iframe'));"));
  frame_observer.Wait();

  // Both the child frame's and its parent's proxies should still not be live.
  // The main page can't reach them since it lost reference to the popup after
  // it crashed, so there is no need to create them.
  EXPECT_FALSE(rfph->is_render_frame_proxy_live());
  RenderFrameProxyHost* child_rfph =
      popup_root->child_at(0)
          ->current_frame_host()
          ->browsing_context_state()
          ->GetRenderFrameProxyHost(site_instance_a->group());
  EXPECT_TRUE(child_rfph);
  EXPECT_FALSE(child_rfph->is_render_frame_proxy_live());
}

// In A-embed-B-embed-C scenario, verify that killing process B clears proxies
// of C from the tree.
//
//     1          A                  A
//    / \        / \                / \    .
//   2   3 ->   B   A -> Kill B -> B*  A
//  /          /
// 4          C
//
// node1 is the root.
// Initially, both node1.proxy_hosts_ and node3.proxy_hosts_ contain C.
// After we kill B, make sure proxies for C are cleared.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       KillingRendererClearsDescendantProxies) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/frame_tree/page_with_two_frames_nested.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  // It is safe to obtain the root frame tree node here, as it doesn't change.
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  ASSERT_EQ(2U, root->child_count());

  GURL site_b_url(embedded_test_server()->GetURL(
      "bar.com", "/frame_tree/page_with_one_frame.html"));
  // We can't use a TestNavigationObserver to verify the URL here,
  // since the frame has children that may have clobbered it in the observer.
  EXPECT_EQ(site_b_url, root->child_at(0)->current_url());

  // Ensure that a new process is created for node2.
  EXPECT_NE(shell()->web_contents()->GetSiteInstance(),
            root->child_at(0)->current_frame_host()->GetSiteInstance());
  // Ensure that a new process is *not* created for node3.
  EXPECT_EQ(shell()->web_contents()->GetSiteInstance(),
            root->child_at(1)->current_frame_host()->GetSiteInstance());

  ASSERT_EQ(1U, root->child_at(0)->child_count());

  // Make sure node4 points to the correct cross-site-page.
  FrameTreeNode* node4 = root->child_at(0)->child_at(0);
  GURL site_c_url(embedded_test_server()->GetURL("baz.com", "/title1.html"));
  EXPECT_EQ(site_c_url, node4->current_url());

  // |site_instance_c_group|'s frames and proxies are expected to go away once
  // we kill |child_process_b| below.
  scoped_refptr<SiteInstanceGroup> site_instance_c_group =
      node4->current_frame_host()->GetSiteInstance()->group();

  // Initially proxies for both B and C will be present in the root.
  EXPECT_EQ(
      " Site A ------------ proxies for B C\n"
      "   |--Site B ------- proxies for A C\n"
      "   |    +--Site C -- proxies for A B\n"
      "   +--Site A ------- proxies for B C\n"
      "Where A = http://a.com/\n"
      "      B = http://bar.com/\n"
      "      C = http://baz.com/",
      DepictFrameTree(root));

  EXPECT_GT(site_instance_c_group->active_frame_count(), 0U);

  // Kill process B.
  RenderProcessHost* child_process_b =
      root->child_at(0)->current_frame_host()->GetProcess();
  RenderProcessHostWatcher crash_observer(
      child_process_b, RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
  child_process_b->Shutdown(0);
  crash_observer.Wait();

  // Make sure proxy C has gone from root.
  // Make sure proxy C has gone from node3 as well.
  // Make sure proxy B stays around in root and node3.
  EXPECT_EQ(
      " Site A ------------ proxies for B\n"
      "   |--Site B ------- proxies for A\n"
      "   +--Site A ------- proxies for B\n"
      "Where A = http://a.com/\n"
      "      B = http://bar.com/ (no process)",
      DepictFrameTree(root));

  EXPECT_EQ(0U, site_instance_c_group->active_frame_count());
}

// Crash a subframe and ensures its children are cleared from the FrameTree.
// See http://crbug.com/338508.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest, CrashSubframe) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  // Check the subframe process.
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  EXPECT_EQ(
      " Site A ------------ proxies for B\n"
      "   +--Site B ------- proxies for A\n"
      "Where A = http://a.com/\n"
      "      B = http://b.com/",
      DepictFrameTree(root));
  FrameTreeNode* child = root->child_at(0);
  EXPECT_TRUE(
      child->current_frame_host()->render_view_host()->IsRenderViewLive());
  EXPECT_TRUE(child->current_frame_host()->IsRenderFrameLive());

  // Crash the subframe process.
  RenderProcessHost* root_process = root->current_frame_host()->GetProcess();
  RenderProcessHost* child_process = child->current_frame_host()->GetProcess();
  {
    RenderProcessHostWatcher crash_observer(
        child_process, RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
    child_process->Shutdown(0);
    crash_observer.Wait();
  }

  // Ensure that the child frame still exists but has been cleared.
  EXPECT_EQ(
      " Site A ------------ proxies for B\n"
      "   +--Site B ------- proxies for A\n"
      "Where A = http://a.com/\n"
      "      B = http://b.com/ (no process)",
      DepictFrameTree(root));
  EXPECT_EQ(1U, root->child_count());
  EXPECT_EQ(main_url, root->current_url());
  EXPECT_EQ(GURL(), child->current_url());

  EXPECT_FALSE(
      child->current_frame_host()->render_view_host()->IsRenderViewLive());
  EXPECT_FALSE(child->current_frame_host()->IsRenderFrameLive());

  // Now crash the top-level page to clear the child frame.
  {
    RenderProcessHostWatcher crash_observer(
        root_process, RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
    root_process->Shutdown(0);
    crash_observer.Wait();
  }
  EXPECT_EQ(0U, root->child_count());
  EXPECT_EQ(GURL(), root->current_url());
}

// When a new subframe is added, related SiteInstances that can reach the
// subframe should create proxies for it (https://crbug.com/423587).  This test
// checks that if A embeds B and later adds a new subframe A2, A2 gets a proxy
// in B's process.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest, CreateProxiesForNewFrames) {
  GURL main_url(embedded_test_server()->GetURL(
      "b.com", "/frame_tree/page_with_one_frame.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  // It is safe to obtain the root frame tree node here, as it doesn't change.
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  ASSERT_EQ(1U, root->child_count());

  // Make sure the frame starts out at the correct cross-site URL.
  EXPECT_EQ(embedded_test_server()->GetURL("baz.com", "/title1.html"),
            root->child_at(0)->current_url());

  EXPECT_EQ(
      " Site A ------------ proxies for B\n"
      "   +--Site B ------- proxies for A\n"
      "Where A = http://b.com/\n"
      "      B = http://baz.com/",
      DepictFrameTree(root));

  // Add a new child frame to the top-level frame.
  RenderFrameHostCreatedObserver frame_observer(shell()->web_contents(), 1);
  EXPECT_TRUE(ExecJs(shell(), "addFrame('about:blank');"));
  frame_observer.Wait();

  // The new frame should have a proxy in Site B, for use by the old frame.
  EXPECT_EQ(
      " Site A ------------ proxies for B\n"
      "   |--Site B ------- proxies for A\n"
      "   +--Site A ------- proxies for B\n"
      "Where A = http://b.com/\n"
      "      B = http://baz.com/",
      DepictFrameTree(root));
}

// TODO(nasko): Disable this test until out-of-process iframes is ready and the
// security checks are back in place.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       DISABLED_CrossSiteIframeRedirectOnce) {
  net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS);
  https_server.ServeFilesFromSourceDirectory(GetTestDataFilePath());
  ASSERT_TRUE(https_server.Start());

  GURL main_url(embedded_test_server()->GetURL("/site_per_process_main.html"));
  GURL http_url(embedded_test_server()->GetURL("/title1.html"));
  GURL https_url(https_server.GetURL("/title1.html"));

  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  TestNavigationObserver observer(shell()->web_contents());
  {
    // Load cross-site client-redirect page into Iframe.
    // Should be blocked.
    GURL client_redirect_https_url(
        https_server.GetURL("/client-redirect?/title1.html"));
    EXPECT_TRUE(NavigateIframeToURL(shell()->web_contents(), "test",
                                    client_redirect_https_url));
    // DidFailProvisionalLoad when navigating to client_redirect_https_url.
    EXPECT_EQ(observer.last_navigation_url(), client_redirect_https_url);
    EXPECT_FALSE(observer.last_navigation_succeeded());
  }

  {
    // Load cross-site server-redirect page into Iframe,
    // which redirects to same-site page.
    GURL server_redirect_http_url(
        https_server.GetURL("/server-redirect?" + http_url.spec()));
    EXPECT_TRUE(NavigateIframeToURL(shell()->web_contents(), "test",
                                    server_redirect_http_url));
    EXPECT_EQ(observer.last_navigation_url(), http_url);
    EXPECT_TRUE(observer.last_navigation_succeeded());
  }

  {
    // Load cross-site server-redirect page into Iframe,
    // which redirects to cross-site page.
    GURL server_redirect_http_url(
        https_server.GetURL("/server-redirect?/title1.html"));
    EXPECT_TRUE(NavigateIframeToURL(shell()->web_contents(), "test",
                                    server_redirect_http_url));
    // DidFailProvisionalLoad when navigating to https_url.
    EXPECT_EQ(observer.last_navigation_url(), https_url);
    EXPECT_FALSE(observer.last_navigation_succeeded());
  }

  {
    // Load same-site server-redirect page into Iframe,
    // which redirects to cross-site page.
    GURL server_redirect_http_url(
        embedded_test_server()->GetURL("/server-redirect?" + https_url.spec()));
    EXPECT_TRUE(NavigateIframeToURL(shell()->web_contents(), "test",
                                    server_redirect_http_url));

    EXPECT_EQ(observer.last_navigation_url(), https_url);
    EXPECT_FALSE(observer.last_navigation_succeeded());
  }

  {
    // Load same-site client-redirect page into Iframe,
    // which redirects to cross-site page.
    GURL client_redirect_http_url(
        embedded_test_server()->GetURL("/client-redirect?" + https_url.spec()));

    LoadStopObserver load_observer2(shell()->web_contents());

    EXPECT_TRUE(NavigateIframeToURL(shell()->web_contents(), "test",
                                    client_redirect_http_url));

    // Same-site Client-Redirect Page should be loaded successfully.
    EXPECT_EQ(observer.last_navigation_url(), client_redirect_http_url);
    EXPECT_TRUE(observer.last_navigation_succeeded());

    // Redirecting to Cross-site Page should be blocked.
    load_observer2.Wait();
    EXPECT_EQ(observer.last_navigation_url(), https_url);
    EXPECT_FALSE(observer.last_navigation_succeeded());
  }

  {
    // Load same-site server-redirect page into Iframe,
    // which redirects to same-site page.
    GURL server_redirect_http_url(
        embedded_test_server()->GetURL("/server-redirect?/title1.html"));
    EXPECT_TRUE(NavigateIframeToURL(shell()->web_contents(), "test",
                                    server_redirect_http_url));
    EXPECT_EQ(observer.last_navigation_url(), http_url);
    EXPECT_TRUE(observer.last_navigation_succeeded());
  }

  {
    // Load same-site client-redirect page into Iframe,
    // which redirects to same-site page.
    GURL client_redirect_http_url(
        embedded_test_server()->GetURL("/client-redirect?" + http_url.spec()));
    LoadStopObserver load_observer2(shell()->web_contents());

    EXPECT_TRUE(NavigateIframeToURL(shell()->web_contents(), "test",
                                    client_redirect_http_url));

    // Same-site Client-Redirect Page should be loaded successfully.
    EXPECT_EQ(observer.last_navigation_url(), client_redirect_http_url);
    EXPECT_TRUE(observer.last_navigation_succeeded());

    // Redirecting to Same-site Page should be loaded successfully.
    load_observer2.Wait();
    EXPECT_EQ(observer.last_navigation_url(), http_url);
    EXPECT_TRUE(observer.last_navigation_succeeded());
  }
}

// TODO(nasko): Disable this test until out-of-process iframes is ready and the
// security checks are back in place.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       DISABLED_CrossSiteIframeRedirectTwice) {
  net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS);
  https_server.ServeFilesFromSourceDirectory(GetTestDataFilePath());
  ASSERT_TRUE(https_server.Start());

  GURL main_url(embedded_test_server()->GetURL("/site_per_process_main.html"));
  GURL http_url(embedded_test_server()->GetURL("/title1.html"));
  GURL https_url(https_server.GetURL("/title1.html"));

  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  TestNavigationObserver observer(shell()->web_contents());
  {
    // Load client-redirect page pointing to a cross-site client-redirect page,
    // which eventually redirects back to same-site page.
    GURL client_redirect_https_url(
        https_server.GetURL("/client-redirect?" + http_url.spec()));
    GURL client_redirect_http_url(embedded_test_server()->GetURL(
        "/client-redirect?" + client_redirect_https_url.spec()));

    // We should wait until second client redirect get cancelled.
    LoadStopObserver load_observer2(shell()->web_contents());

    EXPECT_TRUE(NavigateIframeToURL(shell()->web_contents(), "test",
                                    client_redirect_http_url));

    // DidFailProvisionalLoad when navigating to client_redirect_https_url.
    load_observer2.Wait();
    EXPECT_EQ(observer.last_navigation_url(), client_redirect_https_url);
    EXPECT_FALSE(observer.last_navigation_succeeded());
  }

  {
    // Load server-redirect page pointing to a cross-site server-redirect page,
    // which eventually redirect back to same-site page.
    GURL server_redirect_https_url(
        https_server.GetURL("/server-redirect?" + http_url.spec()));
    GURL server_redirect_http_url(embedded_test_server()->GetURL(
        "/server-redirect?" + server_redirect_https_url.spec()));
    EXPECT_TRUE(NavigateIframeToURL(shell()->web_contents(), "test",
                                    server_redirect_http_url));
    EXPECT_EQ(observer.last_navigation_url(), http_url);
    EXPECT_TRUE(observer.last_navigation_succeeded());
  }

  {
    // Load server-redirect page pointing to a cross-site server-redirect page,
    // which eventually redirects back to cross-site page.
    GURL server_redirect_https_url(
        https_server.GetURL("/server-redirect?" + https_url.spec()));
    GURL server_redirect_http_url(embedded_test_server()->GetURL(
        "/server-redirect?" + server_redirect_https_url.spec()));
    EXPECT_TRUE(NavigateIframeToURL(shell()->web_contents(), "test",
                                    server_redirect_http_url));

    // DidFailProvisionalLoad when navigating to https_url.
    EXPECT_EQ(observer.last_navigation_url(), https_url);
    EXPECT_FALSE(observer.last_navigation_succeeded());
  }

  {
    // Load server-redirect page pointing to a cross-site client-redirect page,
    // which eventually redirects back to same-site page.
    GURL client_redirect_http_url(
        https_server.GetURL("/client-redirect?" + http_url.spec()));
    GURL server_redirect_http_url(embedded_test_server()->GetURL(
        "/server-redirect?" + client_redirect_http_url.spec()));
    EXPECT_TRUE(NavigateIframeToURL(shell()->web_contents(), "test",
                                    server_redirect_http_url));

    // DidFailProvisionalLoad when navigating to client_redirect_http_url.
    EXPECT_EQ(observer.last_navigation_url(), client_redirect_http_url);
    EXPECT_FALSE(observer.last_navigation_succeeded());
  }
}

// Ensure that when navigating a frame cross-process RenderFrameProxyHosts are
// created in the FrameTree skipping the subtree of the navigating frame (but
// not the navigating frame itself).
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest, ProxyCreationSkipsSubtree) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(a,a(a,a(a)))"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  // It is safe to obtain the root frame tree node here, as it doesn't change.
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();

  EXPECT_TRUE(root->child_at(1) != nullptr);
  EXPECT_EQ(2U, root->child_at(1)->child_count());

  {
    // Load same-site page into iframe.
    TestNavigationObserver observer(shell()->web_contents());
    GURL http_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
    EXPECT_TRUE(NavigateToURLFromRenderer(root->child_at(0), http_url));
    EXPECT_EQ(http_url, observer.last_navigation_url());
    EXPECT_TRUE(observer.last_navigation_succeeded());
    EXPECT_EQ(
        " Site A\n"
        "   |--Site A\n"
        "   +--Site A\n"
        "        |--Site A\n"
        "        +--Site A\n"
        "             +--Site A\n"
        "Where A = http://a.com/",
        DepictFrameTree(root));
  }

  // Create the cross-site URL to navigate to.
  GURL cross_site_url =
      embedded_test_server()->GetURL("foo.com", "/frame_tree/title2.html");

  // Load cross-site page into the second iframe without waiting for the
  // navigation to complete. Once LoadURLWithParams returns, we would expect
  // proxies to have been created in the frame tree, but children of the
  // navigating frame to still be present. The reason is that we don't run the
  // message loop, so no IPCs that alter the frame tree can be processed.
  FrameTreeNode* child = root->child_at(1);
  SiteInstance* site = nullptr;
  std::string cross_site_rfh_type = "speculative";
  {
    TestNavigationObserver observer(shell()->web_contents());
    TestNavigationManager navigation_manager(shell()->web_contents(),
                                             cross_site_url);
    NavigationController::LoadURLParams params(cross_site_url);
    params.transition_type = PageTransitionFromInt(ui::PAGE_TRANSITION_LINK);
    params.frame_tree_node_id = child->frame_tree_node_id();
    child->navigator().controller().LoadURLWithParams(params);
    navigation_manager.WaitForSpeculativeRenderFrameHostCreation();

    site = child->render_manager()->speculative_frame_host()->GetSiteInstance();
    EXPECT_NE(shell()->web_contents()->GetSiteInstance(), site);

    std::string tree = base::StringPrintf(
        " Site A ------------ proxies for B\n"
        "   |--Site A ------- proxies for B\n"
        "   +--Site A (B %s) -- proxies for B\n"
        "        |--Site A\n"
        "        +--Site A\n"
        "             +--Site A\n"
        "Where A = http://a.com/\n"
        "      B = http://foo.com/",
        cross_site_rfh_type.c_str());
    EXPECT_EQ(tree, DepictFrameTree(root));

    // Now that the verification is done, run the message loop and wait for the
    // navigation to complete.
    ASSERT_TRUE(navigation_manager.WaitForNavigationFinished());
    EXPECT_TRUE(observer.last_navigation_succeeded());
    EXPECT_EQ(cross_site_url, observer.last_navigation_url());

    EXPECT_EQ(
        " Site A ------------ proxies for B\n"
        "   |--Site A ------- proxies for B\n"
        "   +--Site B ------- proxies for A\n"
        "Where A = http://a.com/\n"
        "      B = http://foo.com/",
        DepictFrameTree(root));
  }

  // Load another cross-site page into the same iframe.
  cross_site_url = embedded_test_server()->GetURL("bar.com", "/title3.html");
  {
    // Perform the same checks as the first cross-site navigation, since
    // there have been issues in subsequent cross-site navigations. Also ensure
    // that the SiteInstance has properly changed.
    // TODO(nasko): Once we have proper cleanup of resources, add code to
    // verify that the intermediate SiteInstance/RenderFrameHost have been
    // properly cleaned up.
    TestNavigationObserver observer(shell()->web_contents());
    TestNavigationManager navigation_manager(shell()->web_contents(),
                                             cross_site_url);
    NavigationController::LoadURLParams params(cross_site_url);
    params.transition_type = PageTransitionFromInt(ui::PAGE_TRANSITION_LINK);
    params.frame_tree_node_id = child->frame_tree_node_id();
    child->navigator().controller().LoadURLWithParams(params);
    navigation_manager.WaitForSpeculativeRenderFrameHostCreation();

    SiteInstance* site2 =
        child->render_manager()->speculative_frame_host()->GetSiteInstance();
    EXPECT_NE(shell()->web_contents()->GetSiteInstance(), site2);
    EXPECT_NE(site, site2);

    std::string tree = base::StringPrintf(
        " Site A ------------ proxies for B C\n"
        "   |--Site A ------- proxies for B C\n"
        "   +--Site B (C %s) -- proxies for A C\n"
        "Where A = http://a.com/\n"
        "      B = http://foo.com/\n"
        "      C = http://bar.com/",
        cross_site_rfh_type.c_str());
    EXPECT_EQ(tree, DepictFrameTree(root));

    ASSERT_TRUE(navigation_manager.WaitForNavigationFinished());
    EXPECT_TRUE(observer.last_navigation_succeeded());
    EXPECT_EQ(cross_site_url, observer.last_navigation_url());
    EXPECT_EQ(0U, child->child_count());
  }
}

// Verify origin replication with an A-embed-B-embed-C-embed-A hierarchy.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest, OriginReplication) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b(c(a),b), a)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  // It is safe to obtain the root frame tree node here, as it doesn't change.
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();

  EXPECT_EQ(
      " Site A ------------ proxies for B C\n"
      "   |--Site B ------- proxies for A C\n"       // tiptop_child
      "   |    |--Site C -- proxies for A B\n"       // middle_child
      "   |    |    +--Site A -- proxies for B C\n"  // lowest_child
      "   |    +--Site B -- proxies for A C\n"
      "   +--Site A ------- proxies for B C\n"
      "Where A = http://a.com/\n"
      "      B = http://b.com/\n"
      "      C = http://c.com/",
      DepictFrameTree(root));

  url::Origin a_origin =
      url::Origin::Create(embedded_test_server()->GetURL("a.com", "/"));
  url::Origin b_origin =
      url::Origin::Create(embedded_test_server()->GetURL("b.com", "/"));
  url::Origin c_origin =
      url::Origin::Create(embedded_test_server()->GetURL("c.com", "/"));
  FrameTreeNode* tiptop_child = root->child_at(0);
  FrameTreeNode* middle_child = root->child_at(0)->child_at(0);
  FrameTreeNode* lowest_child = root->child_at(0)->child_at(0)->child_at(0);

  // Check that b.com frame's location.ancestorOrigins contains the correct
  // origin for the parent.  The origin should have been replicated as part of
  // the mojom::Renderer::CreateView message that created the parent's
  // `blink::RemoteFrame` in b.com's process.
  EXPECT_EQ(ListValueOf(a_origin),
            EvalJs(tiptop_child, "Array.from(location.ancestorOrigins);"));

  // Check that c.com frame's location.ancestorOrigins contains the correct
  // origin for its two ancestors. The topmost parent origin should be
  // replicated as part of mojom::Renderer::CreateView, and the middle frame
  // (b.com's) origin should be replicated as part of
  // blink::mojom::RemoteFrame::CreateRemoteChild sent for b.com's frame in
  // c.com's process.
  EXPECT_EQ(ListValueOf(b_origin, a_origin),
            EvalJs(middle_child, "Array.from(location.ancestorOrigins);"));

  // Check that the nested a.com frame's location.ancestorOrigins contains the
  // correct origin for its three ancestors.
  EXPECT_EQ(ListValueOf(c_origin, b_origin, a_origin),
            EvalJs(lowest_child, "Array.from(location.ancestorOrigins);"));
}

// Test that HasReceivedUserGesture and HasReceivedUserGestureBeforeNavigation
// are propagated correctly across origins.
// TODO(crbug.com/40653035): This test is flaky.
IN_PROC_BROWSER_TEST_P(SitePerProcessAutoplayBrowserTest,
                       DISABLED_PropagateUserGestureFlag) {
  GURL main_url(embedded_test_server()->GetURL(
      "example.com", "/media/autoplay/autoplay-enabled.html"));
  GURL foo_url(embedded_test_server()->GetURL(
      "foo.com", "/media/autoplay/autoplay-enabled.html"));
  GURL bar_url(embedded_test_server()->GetURL(
      "bar.com", "/media/autoplay/autoplay-enabled.html"));
  GURL secondary_url(embedded_test_server()->GetURL(
      "test.example.com", "/media/autoplay/autoplay-enabled.html"));
  GURL disabled_url(embedded_test_server()->GetURL(
      "test.example.com", "/media/autoplay/autoplay-disabled.html"));

  // Load a page with an iframe that has autoplay.
  EXPECT_TRUE(NavigateToURL(shell(), main_url));
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();

  // Navigate the subframes to cross-origin pages.
  EXPECT_TRUE(NavigateFrameToURL(root->child_at(0), foo_url));
  EXPECT_TRUE(NavigateFrameToURL(root->child_at(0)->child_at(0), bar_url));

  // Test that all frames can autoplay if there has been a gesture in the top
  // frame.
  EXPECT_TRUE(AutoplayAllowed(shell(), true));
  EXPECT_TRUE(AutoplayAllowed(root->child_at(0), false));
  EXPECT_TRUE(AutoplayAllowed(root->child_at(0)->child_at(0), false));

  // Navigate to a new page on the same origin.
  EXPECT_TRUE(NavigateToURLFromRenderer(shell(), secondary_url));
  root = web_contents()->GetPrimaryFrameTree().root();

  // Navigate the subframes to cross-origin pages.
  EXPECT_TRUE(NavigateFrameToURL(root->child_at(0), foo_url));
  EXPECT_TRUE(NavigateFrameToURL(root->child_at(0)->child_at(0), bar_url));

  // Test that all frames can autoplay because the gesture bit has been passed
  // through the navigation.
  EXPECT_TRUE(AutoplayAllowed(shell(), false));
  EXPECT_TRUE(AutoplayAllowed(root->child_at(0), false));
  EXPECT_TRUE(AutoplayAllowed(root->child_at(0)->child_at(0), false));

  // Navigate to a page with autoplay disabled.
  EXPECT_TRUE(NavigateToURLFromRenderer(shell(), disabled_url));
  EXPECT_TRUE(NavigateFrameToURL(root->child_at(0), foo_url));

  // Test that autoplay is no longer allowed.
  EXPECT_TRUE(AutoplayAllowed(shell(), false));
  EXPECT_FALSE(AutoplayAllowed(root->child_at(0), false));

  // Navigate to another origin and make sure autoplay is disabled.
  EXPECT_TRUE(NavigateToURLFromRenderer(shell(), foo_url));
  EXPECT_TRUE(NavigateFrameToURL(root->child_at(0), bar_url));
  EXPECT_FALSE(AutoplayAllowed(shell(), false));
  EXPECT_FALSE(AutoplayAllowed(shell(), false));
}

// Check that iframe sandbox flags are replicated correctly.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest, SandboxFlagsReplication) {
  GURL main_url(embedded_test_server()->GetURL("/sandboxed_frames.html"));
  const url::Origin main_origin = url::Origin::Create(main_url);
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  // It is safe to obtain the root frame tree node here, as it doesn't change.
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();

  TestNavigationObserver observer(shell()->web_contents());

  // Navigate the second (sandboxed) subframe to a cross-site page with a
  // subframe.
  GURL foo_url(
      embedded_test_server()->GetURL("foo.com", "/frame_tree/1-1.html"));
  EXPECT_TRUE(NavigateToURLFromRenderer(root->child_at(1), foo_url));
  EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));

  // We can't use a TestNavigationObserver to verify the URL here,
  // since the frame has children that may have clobbered it in the observer.
  EXPECT_EQ(foo_url, root->child_at(1)->current_url());

  // Load cross-site page into subframe's subframe.
  ASSERT_EQ(2U, root->child_at(1)->child_count());
  GURL bar_url(embedded_test_server()->GetURL("bar.com", "/title1.html"));
  EXPECT_TRUE(
      NavigateToURLFromRenderer(root->child_at(1)->child_at(0), bar_url));
  EXPECT_TRUE(observer.last_navigation_succeeded());
  EXPECT_EQ(bar_url, observer.last_navigation_url());

  // Opening a popup in the sandboxed foo.com iframe should fail.
  EXPECT_EQ(false, EvalJs(root->child_at(1),
                          "!!window.open('data:text/html,dataurl');"));
  EXPECT_EQ(1u, Shell::windows().size());

  // Opening a popup in a frame whose parent is sandboxed should also fail.
  // Here, bar.com frame's sandboxed parent frame is a remote frame in
  // bar.com's process.
  EXPECT_EQ(false, EvalJs(root->child_at(1)->child_at(0),
                          "!!window.open('data:text/html,dataurl');"));
  EXPECT_EQ(1u, Shell::windows().size());

  // Same, but now try the case where bar.com frame's sandboxed parent is a
  // local frame in bar.com's process.
  EXPECT_EQ(false, EvalJs(root->child_at(2)->child_at(0),
                          "!!window.open('data:text/html,dataurl');"));
  EXPECT_EQ(1u, Shell::windows().size());

  // Check that foo.com frame's location.ancestorOrigins contains the correct
  // origin for the parent, which should be unaffected by sandboxing.
  EXPECT_EQ(ListValueOf(main_origin),
            EvalJs(root->child_at(1), "Array.from(location.ancestorOrigins);"));

  // Now check location.ancestorOrigins for the bar.com frame. The middle frame
  // (foo.com's) origin should be unique, since that frame is sandboxed, and
  // the top frame should match |main_url|.
  EXPECT_EQ(ListValueOf("null", main_origin),
            EvalJs(root->child_at(1)->child_at(0),
                   "Array.from(location.ancestorOrigins);"));
}

// Check that dynamic updates to iframe sandbox flags are propagated correctly.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest, DynamicSandboxFlags) {
  bool sandboxed_iframes_are_isolated =
      SiteIsolationPolicy::AreIsolatedSandboxedIframesEnabled();
  GURL main_url(
      embedded_test_server()->GetURL("/frame_tree/page_with_two_frames.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  // It is safe to obtain the root frame tree node here, as it doesn't change.
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();

  TestNavigationObserver observer(shell()->web_contents());
  ASSERT_EQ(2U, root->child_count());

  // Make sure first frame starts out at the correct cross-site page.
  EXPECT_EQ(embedded_test_server()->GetURL("bar.com", "/title1.html"),
            root->child_at(0)->current_url());

  // Navigate second frame to another cross-site page.
  GURL baz_url(embedded_test_server()->GetURL("baz.com", "/title1.html"));
  EXPECT_TRUE(NavigateToURLFromRenderer(root->child_at(1), baz_url));
  EXPECT_TRUE(observer.last_navigation_succeeded());
  EXPECT_EQ(baz_url, observer.last_navigation_url());

  // Both frames should not be sandboxed to start with.
  EXPECT_EQ(network::mojom::WebSandboxFlags::kNone,
            root->child_at(0)->pending_frame_policy().sandbox_flags);
  EXPECT_EQ(network::mojom::WebSandboxFlags::kNone,
            root->child_at(0)->effective_frame_policy().sandbox_flags);
  EXPECT_EQ(network::mojom::WebSandboxFlags::kNone,
            root->child_at(1)->pending_frame_policy().sandbox_flags);
  EXPECT_EQ(network::mojom::WebSandboxFlags::kNone,
            root->child_at(1)->effective_frame_policy().sandbox_flags);

  // Dynamically update sandbox flags for the first frame.
  EXPECT_TRUE(ExecJs(
      shell(), "document.querySelector('iframe').sandbox='allow-scripts';"));

  // Check that updated sandbox flags are propagated to browser process.
  // The new flags should be reflected in pending_frame_policy().sandbox_flags,
  // while effective_frame_policy().sandbox_flags should still reflect the old
  // flags, because sandbox flag updates take place only after navigations.
  // "allow-scripts" resets both SandboxFlags::Scripts and
  // SandboxFlags::AutomaticFeatures bits per blink::parseSandboxPolicy().
  network::mojom::WebSandboxFlags expected_flags =
      network::mojom::WebSandboxFlags::kAll &
      ~network::mojom::WebSandboxFlags::kScripts &
      ~network::mojom::WebSandboxFlags::kAutomaticFeatures;
  EXPECT_EQ(expected_flags,
            root->child_at(0)->pending_frame_policy().sandbox_flags);
  EXPECT_EQ(network::mojom::WebSandboxFlags::kNone,
            root->child_at(0)->effective_frame_policy().sandbox_flags);

  // Navigate the first frame to a page on the same site.  The new sandbox
  // flags should take effect.
  GURL bar_url(
      embedded_test_server()->GetURL("bar.com", "/frame_tree/2-4.html"));
  {
    RenderFrameDeletedObserver deleted_observer(
        root->child_at(0)->current_frame_host());
    EXPECT_TRUE(NavigateToURLFromRenderer(root->child_at(0), bar_url));
    if (sandboxed_iframes_are_isolated) {
      deleted_observer.WaitUntilDeleted();
    }
  }
  // (The new page has a subframe; wait for it to load as well.)
  ASSERT_TRUE(WaitForLoadStop(shell()->web_contents()));
  EXPECT_EQ(bar_url, root->child_at(0)->current_url());
  ASSERT_EQ(1U, root->child_at(0)->child_count());

  EXPECT_EQ(
      base::StringPrintf(" Site A ------------ proxies for B C\n"
                         "   |--Site B ------- proxies for A C\n"
                         "   |    +--Site B -- proxies for A C\n"
                         "   +--Site C ------- proxies for A B\n"
                         "Where A = http://127.0.0.1/\n"
                         "      B = http://bar.com/%s\n"
                         "      C = http://baz.com/",
                         sandboxed_iframes_are_isolated ? " (sandboxed)" : ""),
      DepictFrameTree(root));

  // Confirm that the browser process has updated the frame's current sandbox
  // flags.
  EXPECT_EQ(expected_flags,
            root->child_at(0)->pending_frame_policy().sandbox_flags);
  EXPECT_EQ(expected_flags,
            root->child_at(0)->effective_frame_policy().sandbox_flags);

  // Opening a popup in the now-sandboxed frame should fail.
  EXPECT_EQ(false, EvalJs(root->child_at(0),
                          "!!window.open('data:text/html,dataurl');"));
  EXPECT_EQ(1u, Shell::windows().size());

  // Navigate the child of the now-sandboxed frame to a page on baz.com.  The
  // child should inherit the latest sandbox flags from its parent frame, which
  // is currently a proxy in baz.com's renderer process.  This checks that the
  // proxies of |root->child_at(0)| were also updated with the latest sandbox
  // flags.
  // TODO(crbug.com/40943240): When IsolateSandboxedIframes is enabled,
  // this test no longer uses the proxy inheritance mentioned above, because
  // sandboxed and unsandboxed baz.com pages will be in different SiteInstances.
  // Restructure the test so it still provides coverage for proxy inheritance
  // when IsolateSandboxedIframes is enabled.
  GURL baz_child_url(embedded_test_server()->GetURL("baz.com", "/title2.html"));
  {
    RenderFrameDeletedObserver deleted_observer(
        root->child_at(0)->child_at(0)->current_frame_host());
    EXPECT_TRUE(NavigateToURLFromRenderer(root->child_at(0)->child_at(0),
                                          baz_child_url));
    deleted_observer.WaitUntilDeleted();
  }
  EXPECT_TRUE(observer.last_navigation_succeeded());
  EXPECT_EQ(baz_child_url, observer.last_navigation_url());

  if (sandboxed_iframes_are_isolated) {
    switch (blink::features::kIsolateSandboxedIframesGroupingParam.Get()) {
      case blink::features::IsolateSandboxedIframesGrouping::kPerSite:
      case blink::features::IsolateSandboxedIframesGrouping::kPerOrigin:
        EXPECT_EQ(
            " Site A ------------ proxies for B C D\n"
            "   |--Site B ------- proxies for A C D\n"
            "   |    +--Site D -- proxies for A B C\n"
            "   +--Site C ------- proxies for A B D\n"
            "Where A = http://127.0.0.1/\n"
            "      B = http://bar.com/ (sandboxed)\n"
            "      C = http://baz.com/\n"
            "      D = http://baz.com/ (sandboxed)",
            DepictFrameTree(root));
        break;
      case blink::features::IsolateSandboxedIframesGrouping::kPerDocument:
        // TODO(crbug.com/40941714): Add output for the PerDocument
        // case, and parameterize this test to run all variants (none, per-site,
        // per-origin, per-document).
        break;
    }
  } else {
    EXPECT_EQ(
        " Site A ------------ proxies for B C\n"
        "   |--Site B ------- proxies for A C\n"
        "   |    +--Site C -- proxies for A B\n"
        "   +--Site C ------- proxies for A B\n"
        "Where A = http://127.0.0.1/\n"
        "      B = http://bar.com/\n"
        "      C = http://baz.com/",
        DepictFrameTree(root));
  }

  // Opening a popup in the child of a sandboxed frame should fail.
  EXPECT_EQ(false, EvalJs(root->child_at(0)->child_at(0),
                          "!!window.open('data:text/html,dataurl');"));
  EXPECT_EQ(1u, Shell::windows().size());

  // Child of a sandboxed frame should also be sandboxed on the browser side.
  EXPECT_EQ(
      expected_flags,
      root->child_at(0)->child_at(0)->effective_frame_policy().sandbox_flags);
}

// Check that dynamic updates to iframe sandbox flags are propagated correctly.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       DynamicSandboxFlagsRemoteToLocal) {
  GURL main_url(
      embedded_test_server()->GetURL("/frame_tree/page_with_two_frames.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  // It is safe to obtain the root frame tree node here, as it doesn't change.
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();

  TestNavigationObserver observer(shell()->web_contents());
  ASSERT_EQ(2U, root->child_count());

  // Make sure the two frames starts out at correct URLs.
  EXPECT_EQ(embedded_test_server()->GetURL("bar.com", "/title1.html"),
            root->child_at(0)->current_url());
  EXPECT_EQ(embedded_test_server()->GetURL("/title1.html"),
            root->child_at(1)->current_url());

  // Update the second frame's sandbox flags.
  EXPECT_TRUE(
      ExecJs(shell(),
             "document.querySelectorAll('iframe')[1].sandbox='allow-scripts'"));

  // Check that the current sandbox flags are updated but the effective
  // sandbox flags are not.
  network::mojom::WebSandboxFlags expected_flags =
      network::mojom::WebSandboxFlags::kAll &
      ~network::mojom::WebSandboxFlags::kScripts &
      ~network::mojom::WebSandboxFlags::kAutomaticFeatures;
  EXPECT_EQ(expected_flags,
            root->child_at(1)->pending_frame_policy().sandbox_flags);
  EXPECT_EQ(network::mojom::WebSandboxFlags::kNone,
            root->child_at(1)->effective_frame_policy().sandbox_flags);

  // Navigate the second subframe to a page on bar.com.  This will trigger a
  // remote-to-local frame swap in bar.com's process.
  GURL bar_url(embedded_test_server()->GetURL(
      "bar.com", "/frame_tree/page_with_one_frame.html"));
  EXPECT_TRUE(NavigateToURLFromRenderer(root->child_at(1), bar_url));
  EXPECT_EQ(bar_url, root->child_at(1)->current_url());
  ASSERT_EQ(1U, root->child_at(1)->child_count());

  // Confirm that the browser process has updated the current sandbox flags.
  EXPECT_EQ(expected_flags,
            root->child_at(1)->pending_frame_policy().sandbox_flags);
  EXPECT_EQ(expected_flags,
            root->child_at(1)->effective_frame_policy().sandbox_flags);

  // Opening a popup in the sandboxed second frame should fail.
  EXPECT_EQ(false, EvalJs(root->child_at(1),
                          "!!window.open('data:text/html,dataurl');"));
  EXPECT_EQ(1u, Shell::windows().size());

  // Make sure that the child frame inherits the sandbox flags of its
  // now-sandboxed parent frame.
  EXPECT_EQ(false, EvalJs(root->child_at(1)->child_at(0),
                          "!!window.open('data:text/html,dataurl');"));
  EXPECT_EQ(1u, Shell::windows().size());
}

// Check that dynamic updates to iframe sandbox flags are propagated correctly.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       DynamicSandboxFlagsRendererInitiatedNavigation) {
  GURL main_url(
      embedded_test_server()->GetURL("/frame_tree/page_with_one_frame.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  // It is safe to obtain the root frame tree node here, as it doesn't change.
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();

  TestNavigationObserver observer(shell()->web_contents());
  ASSERT_EQ(1U, root->child_count());

  // Make sure the frame starts out at the correct cross-site page.
  EXPECT_EQ(embedded_test_server()->GetURL("baz.com", "/title1.html"),
            root->child_at(0)->current_url());

  // The frame should not be sandboxed to start with.
  EXPECT_EQ(network::mojom::WebSandboxFlags::kNone,
            root->child_at(0)->pending_frame_policy().sandbox_flags);
  EXPECT_EQ(network::mojom::WebSandboxFlags::kNone,
            root->child_at(0)->effective_frame_policy().sandbox_flags);

  // Dynamically update the frame's sandbox flags.
  EXPECT_TRUE(ExecJs(
      shell(), "document.querySelector('iframe').sandbox='allow-scripts';"));

  // Check that updated sandbox flags are propagated to browser process.
  // The new flags should be set in pending_frame_policy().sandbox_flags, while
  // effective_frame_policy().sandbox_flags should still reflect the old flags,
  // because sandbox flag updates take place only after navigations.
  // "allow-scripts" resets both SandboxFlags::Scripts and
  // SandboxFlags::AutomaticFeatures bits per blink::parseSandboxPolicy().
  network::mojom::WebSandboxFlags expected_flags =
      network::mojom::WebSandboxFlags::kAll &
      ~network::mojom::WebSandboxFlags::kScripts &
      ~network::mojom::WebSandboxFlags::kAutomaticFeatures;
  EXPECT_EQ(expected_flags,
            root->child_at(0)->pending_frame_policy().sandbox_flags);
  EXPECT_EQ(network::mojom::WebSandboxFlags::kNone,
            root->child_at(0)->effective_frame_policy().sandbox_flags);

  // Perform a renderer-initiated same-site navigation in the first frame. The
  // new sandbox flags should take effect.
  TestFrameNavigationObserver frame_observer(root->child_at(0));
  ASSERT_TRUE(ExecJs(root->child_at(0), "window.location.href='/title2.html'"));
  frame_observer.Wait();
  EXPECT_EQ(embedded_test_server()->GetURL("baz.com", "/title2.html"),
            root->child_at(0)->current_url());

  // Confirm that the browser process has updated the frame's current sandbox
  // flags.
  EXPECT_EQ(expected_flags,
            root->child_at(0)->pending_frame_policy().sandbox_flags);
  EXPECT_EQ(expected_flags,
            root->child_at(0)->effective_frame_policy().sandbox_flags);

  // Opening a popup in the now-sandboxed frame should fail.
  EXPECT_EQ(false, EvalJs(root->child_at(0),
                          "!!window.open('data:text/html,dataurl');"));
  EXPECT_EQ(1u, Shell::windows().size());
}

// Verify that when a new child frame is added, the proxies created for it in
// other SiteInstances have correct sandbox flags and origin.
//
//     A         A           A
//    /         / \         / \    .
//   B    ->   B   A   ->  B   A
//                              \  .
//                               B
//
// The test checks sandbox flags and origin for the proxy added in step 2, by
// checking whether the grandchild frame added in step 3 sees proper sandbox
// flags and origin for its (remote) parent.  This wasn't addressed when
// https://crbug.com/423587 was fixed.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       ProxiesForNewChildFramesHaveCorrectReplicationState) {
  GURL main_url(
      embedded_test_server()->GetURL("/frame_tree/page_with_one_frame.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  // It is safe to obtain the root frame tree node here, as it doesn't change.
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();

  EXPECT_EQ(
      " Site A ------------ proxies for B\n"
      "   +--Site B ------- proxies for A\n"
      "Where A = http://127.0.0.1/\n"
      "      B = http://baz.com/",
      DepictFrameTree(root));

  // In the root frame, add a new sandboxed local frame, which itself has a
  // child frame on baz.com.  Wait for three RenderFrameHosts to be created:
  // the new sandboxed local frame, its child (while it's still local), and a
  // speculative RFH when starting the cross-site navigation to baz.com.
  RenderFrameHostCreatedObserver frame_observer(shell()->web_contents(), 3);
  EXPECT_TRUE(ExecJs(root,
                     "addFrame('/frame_tree/page_with_one_frame.html',"
                     "         'allow-scripts allow-same-origin')"));
  frame_observer.Wait();

  // Wait for the cross-site navigation to baz.com in the grandchild to finish.
  EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
  FrameTreeNode* bottom_child = root->child_at(1)->child_at(0);
  EXPECT_EQ(embedded_test_server()->GetURL("baz.com", "/title1.html"),
            bottom_child->current_url());

  EXPECT_EQ(
      " Site A ------------ proxies for B\n"
      "   |--Site B ------- proxies for A\n"
      "   +--Site A ------- proxies for B\n"
      "        +--Site B -- proxies for A\n"
      "Where A = http://127.0.0.1/\n"
      "      B = http://baz.com/",
      DepictFrameTree(root));

  // Use location.ancestorOrigins to check that the grandchild on baz.com sees
  // correct origin for its parent and grandparent, which are at the same URL
  // and origin (namely, page_with_one_frame.html on the server's default
  // origin).
  EXPECT_EQ(
      ListValueOf(url::Origin::Create(main_url), url::Origin::Create(main_url)),
      EvalJs(bottom_child, "Array.from(location.ancestorOrigins);"));

  // Check that the sandbox flags in the browser process are correct.
  // "allow-scripts" resets both network::mojom::WebSandboxFlags::Scripts and
  // network::mojom::WebSandboxFlags::AutomaticFeatures bits per
  // blink::parseSandboxPolicy().
  network::mojom::WebSandboxFlags expected_flags =
      network::mojom::WebSandboxFlags::kAll &
      ~network::mojom::WebSandboxFlags::kScripts &
      ~network::mojom::WebSandboxFlags::kAutomaticFeatures &
      ~network::mojom::WebSandboxFlags::kOrigin;
  EXPECT_EQ(expected_flags,
            root->child_at(1)->effective_frame_policy().sandbox_flags);

  // The child of the sandboxed frame should've inherited sandbox flags, so it
  // should not be able to create popups.
  EXPECT_EQ(expected_flags,
            bottom_child->effective_frame_policy().sandbox_flags);
  EXPECT_EQ(false,
            EvalJs(bottom_child, "!!window.open('data:text/html,dataurl')"));
  EXPECT_EQ(1u, Shell::windows().size());
}

// Verify that a child frame can retrieve the name property set by its parent.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest, WindowNameReplication) {
  GURL main_url(embedded_test_server()->GetURL("/frame_tree/2-4.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  // It is safe to obtain the root frame tree node here, as it doesn't change.
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();

  TestNavigationObserver observer(shell()->web_contents());

  // Load cross-site page into iframe.
  GURL frame_url =
      embedded_test_server()->GetURL("foo.com", "/frame_tree/3-1.html");
  EXPECT_TRUE(NavigateToURLFromRenderer(root->child_at(0), frame_url));
  EXPECT_TRUE(observer.last_navigation_succeeded());
  EXPECT_EQ(frame_url, observer.last_navigation_url());

  // Ensure that a new process is created for the subframe.
  EXPECT_NE(shell()->web_contents()->GetSiteInstance(),
            root->child_at(0)->current_frame_host()->GetSiteInstance());

  // Check that the window.name seen by the frame matches the name attribute
  // specified by its parent in the iframe tag.
  EXPECT_EQ("3-1-name", EvalJs(root->child_at(0), "window.name;"));
}

// Verify that dynamic updates to a frame's window.name propagate to the
// frame's proxies, so that the latest frame names can be used in navigations.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest, DynamicWindowName) {
  GURL main_url(embedded_test_server()->GetURL("/frame_tree/2-4.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  // It is safe to obtain the root frame tree node here, as it doesn't change.
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  TestNavigationObserver observer(shell()->web_contents());

  // Load cross-site page into iframe.
  GURL frame_url =
      embedded_test_server()->GetURL("foo.com", "/frame_tree/3-1.html");
  EXPECT_TRUE(NavigateToURLFromRenderer(root->child_at(0), frame_url));
  EXPECT_TRUE(observer.last_navigation_succeeded());
  EXPECT_EQ(frame_url, observer.last_navigation_url());

  // Browser process should know the child frame's original window.name
  // specified in the iframe element.
  EXPECT_EQ(root->child_at(0)->frame_name(), "3-1-name");

  // Update the child frame's window.name.
  EXPECT_TRUE(ExecJs(root->child_at(0), "window.name = 'updated-name';"));

  // The change should propagate to the browser process.
  EXPECT_EQ(root->child_at(0)->frame_name(), "updated-name");

  // The proxy in the parent process should also receive the updated name.
  // Now iframe's name and the content window's name differ, so it shouldn't
  // be possible to access to the content window with the updated name.
  EXPECT_EQ(true, EvalJs(shell(), "frames['updated-name'] === undefined;"));
  // Change iframe's name to match the content window's name so that it can
  // reference the child frame by its new name in case of cross origin.
  EXPECT_TRUE(ExecJs(root, "window['3-1-id'].name = 'updated-name';"));
  EXPECT_EQ(true, EvalJs(shell(), "frames['updated-name'] == frames[0];"));

  // Issue a renderer-initiated navigation from the root frame to the child
  // frame using the frame's name. Make sure correct frame is navigated.
  //
  // TODO(alexmos): When blink::createWindow is refactored to handle
  // RemoteFrames, this should also be tested via window.open(url, frame_name)
  // and a more complicated frame hierarchy (https://crbug.com/463742)
  TestFrameNavigationObserver frame_observer(root->child_at(0));
  GURL foo_url(embedded_test_server()->GetURL("foo.com", "/title1.html"));
  EXPECT_TRUE(
      ExecJs(shell(),
             JsReplace("frames['updated-name'].location.href = $1", foo_url)));
  frame_observer.Wait();
  EXPECT_EQ(foo_url, root->child_at(0)->current_url());
}

// Verify that when a frame is navigated to a new origin, the origin update
// propagates to the frame's proxies.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest, OriginUpdatesReachProxies) {
  GURL main_url(
      embedded_test_server()->GetURL("/frame_tree/page_with_two_frames.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  // It is safe to obtain the root frame tree node here, as it doesn't change.
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  TestNavigationObserver observer(shell()->web_contents());

  EXPECT_EQ(
      " Site A ------------ proxies for B\n"
      "   |--Site B ------- proxies for A\n"
      "   +--Site A ------- proxies for B\n"
      "Where A = http://127.0.0.1/\n"
      "      B = http://bar.com/",
      DepictFrameTree(root));

  // Navigate second subframe to a baz.com.  This should send an origin update
  // to the frame's proxy in the bar.com (first frame's) process.
  GURL frame_url = embedded_test_server()->GetURL("baz.com", "/title2.html");
  EXPECT_TRUE(NavigateToURLFromRenderer(root->child_at(1), frame_url));
  EXPECT_TRUE(observer.last_navigation_succeeded());
  EXPECT_EQ(frame_url, observer.last_navigation_url());

  // The first frame can't directly observe the second frame's origin with
  // JavaScript.  Instead, try to navigate the second frame from the first
  // frame.  This should fail with a console error message, which should
  // contain the second frame's updated origin (see blink::Frame::canNavigate).
  WebContentsConsoleObserver console_observer(shell()->web_contents());
  console_observer.SetPattern("Unsafe attempt to initiate navigation*");

  // frames[1] can't be used due to a bug where RemoteFrames are created out of
  // order (https://crbug.com/478792).  Instead, target second frame by name.
  EXPECT_TRUE(ExecJs(root->child_at(0),
                     "try { parent.frames['frame2'].location.href = "
                     "'data:text/html,foo'; } catch (e) {}"));
  ASSERT_TRUE(console_observer.Wait());

  std::string frame_origin = root->child_at(1)->current_origin().Serialize();
  EXPECT_EQ(frame_origin + "/", frame_url.DeprecatedGetOriginAsURL().spec());
  EXPECT_TRUE(base::MatchPattern(console_observer.GetMessageAt(0u),
                                 "*" + frame_origin + "*"))
      << "Error message does not contain the frame's latest origin ("
      << frame_origin << ")";
}

// Ensure that navigating subframes in --site-per-process mode properly fires
// the DidStopLoading event on WebContentsObserver.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest, CrossSiteDidStopLoading) {
  GURL main_url(embedded_test_server()->GetURL("/site_per_process_main.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  // It is safe to obtain the root frame tree node here, as it doesn't change.
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();

  TestNavigationObserver observer(shell()->web_contents());

  // Load same-site page into iframe.
  FrameTreeNode* child = root->child_at(0);
  GURL http_url(embedded_test_server()->GetURL("/title1.html"));
  EXPECT_TRUE(NavigateToURLFromRenderer(child, http_url));
  EXPECT_EQ(http_url, observer.last_navigation_url());
  EXPECT_TRUE(observer.last_navigation_succeeded());

  // Load cross-site page into iframe.
  TestNavigationObserver nav_observer(shell()->web_contents(), 1);
  GURL url = embedded_test_server()->GetURL("foo.com", "/title2.html");
  NavigationController::LoadURLParams params(url);
  params.transition_type = ui::PAGE_TRANSITION_LINK;
  params.frame_tree_node_id = child->frame_tree_node_id();
  child->navigator().controller().LoadURLWithParams(params);
  nav_observer.Wait();

  // Verify that the navigation succeeded and the expected URL was loaded.
  EXPECT_TRUE(observer.last_navigation_succeeded());
  EXPECT_EQ(url, observer.last_navigation_url());
}

// Ensure that the renderer does not crash when navigating a frame that has a
// sibling RemoteFrame.  See https://crbug.com/426953.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       NavigateWithSiblingRemoteFrame) {
  GURL main_url(
      embedded_test_server()->GetURL("/frame_tree/page_with_two_frames.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  // It is safe to obtain the root frame tree node here, as it doesn't change.
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  TestNavigationObserver observer(shell()->web_contents());

  // Make sure the first frame is out of process.
  ASSERT_EQ(2U, root->child_count());
  FrameTreeNode* node2 = root->child_at(0);
  EXPECT_NE(root->current_frame_host()->GetSiteInstance(),
            node2->current_frame_host()->GetSiteInstance());

  // Make sure the second frame is in the parent's process.
  FrameTreeNode* node3 = root->child_at(1);
  EXPECT_EQ(root->current_frame_host()->GetSiteInstance(),
            node3->current_frame_host()->GetSiteInstance());

  // Navigate the second iframe (node3) to a URL in its own process.
  GURL title_url = embedded_test_server()->GetURL("/title2.html");
  EXPECT_TRUE(NavigateToURLFromRenderer(node3, title_url));
  EXPECT_TRUE(observer.last_navigation_succeeded());
  EXPECT_EQ(title_url, observer.last_navigation_url());
  EXPECT_EQ(root->current_frame_host()->GetSiteInstance(),
            node3->current_frame_host()->GetSiteInstance());
  EXPECT_TRUE(node3->current_frame_host()->IsRenderFrameLive());
}

// Ensure that the renderer does not crash when a local frame with a remote
// parent frame is swapped from local to remote, then back to local again.
// See https://crbug.com/585654.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       NavigateSiblingsToSameProcess) {
  GURL main_url(
      embedded_test_server()->GetURL("/frame_tree/page_with_two_frames.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  // It is safe to obtain the root frame tree node here, as it doesn't change.
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();

  FrameTreeNode* node2 = root->child_at(0);
  FrameTreeNode* node3 = root->child_at(1);

  // Navigate the second iframe to the same process as the first.
  GURL frame_url = embedded_test_server()->GetURL("bar.com", "/title1.html");
  EXPECT_TRUE(NavigateToURLFromRenderer(node3, frame_url));

  // Verify that they are in the same process.
  EXPECT_EQ(node2->current_frame_host()->GetSiteInstance(),
            node3->current_frame_host()->GetSiteInstance());
  EXPECT_NE(root->current_frame_host()->GetSiteInstance(),
            node3->current_frame_host()->GetSiteInstance());

  // Navigate the first iframe into its parent's process.
  GURL title_url = embedded_test_server()->GetURL("/title2.html");
  EXPECT_TRUE(NavigateToURLFromRenderer(node2, title_url));
  EXPECT_NE(node2->current_frame_host()->GetSiteInstance(),
            node3->current_frame_host()->GetSiteInstance());

  // Return the first iframe to the same process as its sibling, and ensure
  // that it does not crash.
  EXPECT_TRUE(NavigateToURLFromRenderer(node2, frame_url));
  EXPECT_EQ(node2->current_frame_host()->GetSiteInstance(),
            node3->current_frame_host()->GetSiteInstance());
  EXPECT_TRUE(node2->current_frame_host()->IsRenderFrameLive());
}

// Verify that load events for iframe elements work when the child frame is
// out-of-process.  In such cases, the load event is forwarded from the child
// frame to the parent frame via the browser process.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest, LoadEventForwarding) {
  // Load a page with a cross-site frame.  The parent page has an onload
  // handler in the iframe element that appends "LOADED" to the document title.
  {
    GURL main_url(
        embedded_test_server()->GetURL("/frame_with_load_event.html"));
    std::u16string expected_title(u"LOADED");
    TitleWatcher title_watcher(shell()->web_contents(), expected_title);
    EXPECT_TRUE(NavigateToURL(shell(), main_url));
    EXPECT_EQ(title_watcher.WaitAndGetTitle(), expected_title);
  }

  // It is safe to obtain the root frame tree node here, as it doesn't change.
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();

  // Load another cross-site page into the iframe and check that the load event
  // is fired.
  {
    GURL foo_url(embedded_test_server()->GetURL("foo.com", "/title1.html"));
    std::u16string expected_title(u"LOADEDLOADED");
    TitleWatcher title_watcher(shell()->web_contents(), expected_title);
    TestNavigationObserver observer(shell()->web_contents());
    EXPECT_TRUE(NavigateToURLFromRenderer(root->child_at(0), foo_url));
    EXPECT_TRUE(observer.last_navigation_succeeded());
    EXPECT_EQ(foo_url, observer.last_navigation_url());
    EXPECT_EQ(title_watcher.WaitAndGetTitle(), expected_title);
  }
}

// Check that postMessage can be routed between cross-site iframes.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest, SubframePostMessage) {
  GURL main_url(embedded_test_server()->GetURL(
      "/frame_tree/page_with_post_message_frames.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  // It is safe to obtain the root frame tree node here, as it doesn't change.
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();

  ASSERT_EQ(2U, root->child_count());

  // Verify the frames start at correct URLs.  First frame should be
  // same-site; second frame should be cross-site.
  GURL same_site_url(embedded_test_server()->GetURL("/post_message.html"));
  EXPECT_EQ(same_site_url, root->child_at(0)->current_url());
  GURL foo_url(embedded_test_server()->GetURL("foo.com", "/post_message.html"));
  EXPECT_EQ(foo_url, root->child_at(1)->current_url());
  EXPECT_NE(root->child_at(0)->current_frame_host()->GetSiteInstance(),
            root->child_at(1)->current_frame_host()->GetSiteInstance());

  // Send a message from first, same-site frame to second, cross-site frame.
  // Expect the second frame to reply back to the first frame.
  PostMessageAndWaitForReply(root->child_at(0),
                             "postToSibling('subframe-msg','subframe2')",
                             "\"done-subframe1\"");

  // Send a postMessage from second, cross-site frame to its parent.  Expect
  // parent to send a reply to the frame.
  std::u16string expected_title(u"subframe-msg");
  TitleWatcher title_watcher(shell()->web_contents(), expected_title);
  PostMessageAndWaitForReply(root->child_at(1), "postToParent('subframe-msg')",
                             "\"done-subframe2\"");
  EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());

  // Verify the total number of received messages for each subframe.  First
  // frame should have one message (reply from second frame).  Second frame
  // should have two messages (message from first frame and reply from parent).
  // Parent should have one message (from second frame).
  EXPECT_EQ(1, GetReceivedMessages(root->child_at(0)));
  EXPECT_EQ(2, GetReceivedMessages(root->child_at(1)));
  EXPECT_EQ(1, GetReceivedMessages(root));
}

// Check that postMessage can be sent from a subframe on a cross-process opener
// tab, and that its event.source points to a valid proxy.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       PostMessageWithSubframeOnOpenerChain) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/frame_tree/page_with_post_message_frames.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  // It is safe to obtain the root frame tree node here, as it doesn't change.
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();

  ASSERT_EQ(2U, root->child_count());

  // Verify the initial state of the world.  First frame should be same-site;
  // second frame should be cross-site.
  EXPECT_EQ(
      " Site A ------------ proxies for B\n"
      "   |--Site A ------- proxies for B\n"
      "   +--Site B ------- proxies for A\n"
      "Where A = http://a.com/\n"
      "      B = http://foo.com/",
      DepictFrameTree(root));

  // Open a popup from the first subframe (so that popup's window.opener points
  // to the subframe) and navigate it to bar.com.
  ShellAddedObserver new_shell_observer;
  EXPECT_TRUE(ExecJs(root->child_at(0), "openPopup('about:blank');"));
  Shell* popup = new_shell_observer.GetShell();
  GURL popup_url(
      embedded_test_server()->GetURL("bar.com", "/post_message.html"));
  EXPECT_TRUE(NavigateToURLFromRenderer(popup, popup_url));

  // From the popup, open another popup for baz.com.  This will be used to
  // check that the whole opener chain is processed when creating proxies and
  // not just an immediate opener.
  ShellAddedObserver new_shell_observer2;
  EXPECT_TRUE(ExecJs(popup, "openPopup('about:blank');"));
  Shell* popup2 = new_shell_observer2.GetShell();
  GURL popup2_url(
      embedded_test_server()->GetURL("baz.com", "/post_message.html"));
  EXPECT_TRUE(NavigateToURLFromRenderer(popup2, popup2_url));

  // Ensure that we've created proxies for SiteInstances of both popups (C, D)
  // in the main window's frame tree.
  EXPECT_EQ(
      " Site A ------------ proxies for B C D\n"
      "   |--Site A ------- proxies for B C D\n"
      "   +--Site B ------- proxies for A C D\n"
      "Where A = http://a.com/\n"
      "      B = http://foo.com/\n"
      "      C = http://bar.com/\n"
      "      D = http://baz.com/",
      DepictFrameTree(root));

  // Check the first popup's frame tree as well.  Note that it doesn't have a
  // proxy for foo.com, since foo.com can't reach the popup.  It does have a
  // proxy for its opener a.com (which can reach it via the window.open
  // reference) and second popup (which can reach it via window.opener).
  FrameTreeNode* popup_root =
      static_cast<WebContentsImpl*>(popup->web_contents())
          ->GetPrimaryFrameTree()
          .root();
  EXPECT_EQ(
      " Site C ------------ proxies for A D\n"
      "Where A = http://a.com/\n"
      "      C = http://bar.com/\n"
      "      D = http://baz.com/",
      DepictFrameTree(popup_root));

  // Send a message from first subframe on main page to the first popup and
  // wait for a reply back. The reply verifies that the proxy for the opener
  // tab's subframe is targeted properly.
  PostMessageAndWaitForReply(root->child_at(0), "postToPopup('subframe-msg')",
                             "\"done-subframe1\"");

  // Send a postMessage from the popup to window.opener and ensure that it
  // reaches subframe1.  This verifies that the subframe opener information
  // propagated to the popup's RenderFrame.  Wait for subframe1 to send a reply
  // message to the popup.
  EXPECT_TRUE(ExecJs(popup, "window.name = 'popup';"));
  PostMessageAndWaitForReply(popup_root, "postToOpener('subframe-msg', '*')",
                             "\"done-popup\"");

  // Second a postMessage from popup2 to window.opener.opener, which should
  // resolve to subframe1.  This tests opener chains of length greater than 1.
  // As before, subframe1 will send a reply to popup2.
  FrameTreeNode* popup2_root =
      static_cast<WebContentsImpl*>(popup2->web_contents())
          ->GetPrimaryFrameTree()
          .root();
  EXPECT_TRUE(ExecJs(popup2, "window.name = 'popup2';"));
  PostMessageAndWaitForReply(popup2_root,
                             "postToOpenerOfOpener('subframe-msg', '*')",
                             "\"done-popup2\"");

  // Verify the total number of received messages for each subframe:
  //  - 3 for first subframe (two from first popup, one from second popup)
  //  - 2 for popup (both from first subframe)
  //  - 1 for popup2 (reply from first subframe)
  //  - 0 for other frames
  EXPECT_EQ(0, GetReceivedMessages(root));
  EXPECT_EQ(3, GetReceivedMessages(root->child_at(0)));
  EXPECT_EQ(0, GetReceivedMessages(root->child_at(1)));
  EXPECT_EQ(2, GetReceivedMessages(popup_root));
  EXPECT_EQ(1, GetReceivedMessages(popup2_root));
}

// Check that in certain situations, postMessage has to create proxies on demand
// so that event.source may be used to reply. In particular, this test starts on
// A(B) and opens C(D) from A. At this point, D can reach B (via
// parent.opener.frames[0], but B cannot see D. However, if D sends a
// postMessage to B, B now gains a reference to D through event.source, and
// therefore the message should create a proxy for D in B's process. See
// https://crbug.com/40261772.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       PostMessageCreatesProxyOnDemand) {
  // Start on A(B).
  GURL opener_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)"));
  EXPECT_TRUE(NavigateToURL(shell(), opener_url));
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();

  // From A, open a popup with a C(D) page.
  GURL popup_url(embedded_test_server()->GetURL(
      "c.com", "/cross_site_iframe_factory.html?c(d)"));
  Shell* new_shell = OpenPopup(root, popup_url, "");
  EXPECT_TRUE(new_shell);
  FrameTreeNode* popup_root =
      static_cast<WebContentsImpl*>(new_shell->web_contents())
          ->GetPrimaryFrameTree()
          .root();
  EXPECT_EQ(root, popup_root->opener());

  // Verify proxy setup. Both A and B should be visible to all four frames:
  // - C can reach A via opener
  // - C can reach B via opener.frames[0]
  // - D can reach A via parent.opener
  // - D can reach B via parent.opener.frames[0]
  EXPECT_EQ(
      " Site A ------------ proxies for B C D\n"
      "   +--Site B ------- proxies for A C D\n"
      "Where A = http://a.com/\n"
      "      B = http://b.com/\n"
      "      C = http://c.com/\n"
      "      D = http://d.com/",
      DepictFrameTree(root));
  // C and D are only visible to each other and to A, via A's window.open
  // reference. B doesn't have a way to reach them.
  EXPECT_EQ(
      " Site C ------------ proxies for A D\n"
      "   +--Site D ------- proxies for A C\n"
      "Where A = http://a.com/\n"
      "      C = http://c.com/\n"
      "      D = http://d.com/",
      DepictFrameTree(popup_root));

  // Install a postMessage handler in B that echoes back event.data with
  // "-reply" appended to it. This requires having a valid event.source.
  EXPECT_TRUE(ExecJs(root->child_at(0)->current_frame_host(),
                     "window.addEventListener('message', function(event) {\n"
                     "  event.source.postMessage(event.data + '-reply', '*');\n"
                     "});"));

  // Send a message from D to B and wait for a response. While processing the
  // message, the browser process should create a proxy for D in B, which B will
  // use when replying.
  EXPECT_TRUE(
      ExecJs(popup_root->child_at(0), WaitForMessageScript("event.data")));
  EXPECT_TRUE(ExecJs(popup_root->child_at(0),
                     "parent.opener.frames[0].postMessage('popup-ping', '*')"));
  EXPECT_EQ("popup-ping-reply",
            EvalJs(popup_root->child_at(0), "onMessagePromise"));

  // Verify the final proxies. The proxies for the opener window shouldn't have
  // changed (A and B are still visible to all other frames).
  EXPECT_EQ(
      " Site A ------------ proxies for B C D\n"
      "   +--Site B ------- proxies for A C D\n"
      "Where A = http://a.com/\n"
      "      B = http://b.com/\n"
      "      C = http://c.com/\n"
      "      D = http://d.com/",
      DepictFrameTree(root));
  // Frames C and D should now have proxies in site B, since frame B can now
  // reach both of them (D via event.source, and C via event.source.top).
  EXPECT_EQ(
      " Site C ------------ proxies for A B D\n"
      "   +--Site D ------- proxies for A B C\n"
      "Where A = http://a.com/\n"
      "      B = http://b.com/\n"
      "      C = http://c.com/\n"
      "      D = http://d.com/",
      DepictFrameTree(popup_root));
}

// Check that parent.frames[num] references correct sibling frames when the
// parent is remote.  See https://crbug.com/478792.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest, IndexedFrameAccess) {
  // Start on a page with three same-site subframes.
  GURL main_url(
      embedded_test_server()->GetURL("a.com", "/frame_tree/top.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  // It is safe to obtain the root frame tree node here, as it doesn't change.
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  ASSERT_EQ(3U, root->child_count());
  FrameTreeNode* child0 = root->child_at(0);
  FrameTreeNode* child1 = root->child_at(1);
  FrameTreeNode* child2 = root->child_at(2);

  // Send each of the frames to a different site.  Each new renderer will first
  // create proxies for the parent and two sibling subframes and then create
  // and insert the new RenderFrame into the frame tree.
  GURL b_url(embedded_test_server()->GetURL("b.com", "/post_message.html"));
  GURL c_url(embedded_test_server()->GetURL("c.com", "/post_message.html"));
  GURL d_url(embedded_test_server()->GetURL("d.com", "/post_message.html"));
  EXPECT_TRUE(NavigateToURLFromRenderer(child0, b_url));
  EXPECT_TRUE(NavigateToURLFromRenderer(child1, c_url));
  EXPECT_TRUE(NavigateToURLFromRenderer(child2, d_url));

  EXPECT_EQ(
      " Site A ------------ proxies for B C D\n"
      "   |--Site B ------- proxies for A C D\n"
      "   |--Site C ------- proxies for A B D\n"
      "   +--Site D ------- proxies for A B C\n"
      "Where A = http://a.com/\n"
      "      B = http://b.com/\n"
      "      C = http://c.com/\n"
      "      D = http://d.com/",
      DepictFrameTree(root));

  // Check that each subframe sees itself at correct index in parent.frames.
  EXPECT_EQ(true, EvalJs(child0, "window === parent.frames[0];"));
  EXPECT_EQ(true, EvalJs(child1, "window === parent.frames[1];"));
  EXPECT_EQ(true, EvalJs(child2, "window === parent.frames[2];"));

  // Send a postMessage from B to parent.frames[1], which should go to C, and
  // wait for reply.
  PostMessageAndWaitForReply(child0, "postToSibling('subframe-msg', 1)",
                             "\"done-1-1-name\"");

  // Send a postMessage from C to parent.frames[2], which should go to D, and
  // wait for reply.
  PostMessageAndWaitForReply(child1, "postToSibling('subframe-msg', 2)",
                             "\"done-1-2-name\"");

  // Verify the total number of received messages for each subframe.
  EXPECT_EQ(1, GetReceivedMessages(child0));
  EXPECT_EQ(2, GetReceivedMessages(child1));
  EXPECT_EQ(1, GetReceivedMessages(child2));
}

IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest, RFPHDestruction) {
  GURL main_url(embedded_test_server()->GetURL("/site_per_process_main.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  // It is safe to obtain the root frame tree node here, as it doesn't change.
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();

  TestNavigationObserver observer(shell()->web_contents());

  // Load cross-site page into iframe.
  FrameTreeNode* child = root->child_at(0);
  GURL url = embedded_test_server()->GetURL("foo.com", "/title2.html");
  {
    RenderFrameDeletedObserver deleted_observer(child->current_frame_host());
    EXPECT_TRUE(NavigateToURLFromRenderer(root->child_at(0), url));
    deleted_observer.WaitUntilDeleted();
  }
  EXPECT_TRUE(observer.last_navigation_succeeded());
  EXPECT_EQ(url, observer.last_navigation_url());
  EXPECT_EQ(
      " Site A ------------ proxies for B\n"
      "   |--Site B ------- proxies for A\n"
      "   +--Site A ------- proxies for B\n"
      "        |--Site A -- proxies for B\n"
      "        +--Site A -- proxies for B\n"
      "             +--Site A -- proxies for B\n"
      "Where A = http://127.0.0.1/\n"
      "      B = http://foo.com/",
      DepictFrameTree(root));

  // Load another cross-site page.
  url = embedded_test_server()->GetURL("bar.com", "/title3.html");
  {
    RenderFrameDeletedObserver deleted_observer(child->current_frame_host());
    NavigateIframeToURL(shell()->web_contents(), "test", url);
    deleted_observer.WaitUntilDeleted();
  }
  EXPECT_TRUE(observer.last_navigation_succeeded());
  EXPECT_EQ(url, observer.last_navigation_url());
  EXPECT_EQ(
      " Site A ------------ proxies for C\n"
      "   |--Site C ------- proxies for A\n"
      "   +--Site A ------- proxies for C\n"
      "        |--Site A -- proxies for C\n"
      "        +--Site A -- proxies for C\n"
      "             +--Site A -- proxies for C\n"
      "Where A = http://127.0.0.1/\n"
      "      C = http://bar.com/",
      DepictFrameTree(root));

  // Navigate back to the parent's origin.
  {
    RenderFrameDeletedObserver deleted_observer(child->current_frame_host());
    url = embedded_test_server()->GetURL("/title1.html");
    EXPECT_TRUE(NavigateToURLFromRenderer(child, url));
    // Wait for the old process to exit, to verify that the proxies go away.
    deleted_observer.WaitUntilDeleted();
  }
  EXPECT_EQ(url, observer.last_navigation_url());
  EXPECT_TRUE(observer.last_navigation_succeeded());

  EXPECT_EQ(
      " Site A\n"
      "   |--Site A\n"
      "   +--Site A\n"
      "        |--Site A\n"
      "        +--Site A\n"
      "             +--Site A\n"
      "Where A = http://127.0.0.1/",
      DepictFrameTree(root));
}

IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest, OpenPopupWithRemoteParent) {
  GURL main_url(
      embedded_test_server()->GetURL("a.com", "/site_per_process_main.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  // It is safe to obtain the root frame tree node here, as it doesn't change.
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();

  // Navigate first child cross-site.
  GURL frame_url(embedded_test_server()->GetURL("b.com", "/title1.html"));
  EXPECT_TRUE(NavigateToURLFromRenderer(root->child_at(0), frame_url));

  // Open a popup from the first child.
  Shell* new_shell =
      OpenPopup(root->child_at(0), GURL(url::kAboutBlankURL), "");
  EXPECT_TRUE(new_shell);

  // Check that the popup's opener is correct on both the browser and renderer
  // sides.
  FrameTreeNode* popup_root =
      static_cast<WebContentsImpl*>(new_shell->web_contents())
          ->GetPrimaryFrameTree()
          .root();
  EXPECT_EQ(root->child_at(0), popup_root->opener());

  EXPECT_EQ(frame_url.spec(),
            EvalJs(popup_root, "window.opener.location.href;"));

  // Now try the same with a cross-site popup and make sure it ends up in a new
  // process and with a correct opener.
  GURL popup_url(embedded_test_server()->GetURL("c.com", "/title2.html"));
  Shell* cross_site_popup = OpenPopup(root->child_at(0), popup_url, "");
  EXPECT_TRUE(cross_site_popup);

  FrameTreeNode* cross_site_popup_root =
      static_cast<WebContentsImpl*>(cross_site_popup->web_contents())
          ->GetPrimaryFrameTree()
          .root();
  EXPECT_EQ(cross_site_popup_root->current_url(), popup_url);

  EXPECT_NE(shell()->web_contents()->GetSiteInstance(),
            cross_site_popup->web_contents()->GetSiteInstance());
  EXPECT_NE(root->child_at(0)->current_frame_host()->GetSiteInstance(),
            cross_site_popup->web_contents()->GetSiteInstance());

  EXPECT_EQ(root->child_at(0), cross_site_popup_root->opener());

  // Ensure the popup's window.opener points to the right subframe.  Note that
  // we can't check the opener's location as above since it's cross-origin.
  EXPECT_EQ(true, EvalJs(cross_site_popup_root,
                         "window.opener === window.opener.top.frames[0];"));
}

// Test that cross-process popups can't be navigated to disallowed URLs by
// their opener.  This ensures that proper URL validation is performed when
// RenderFrameProxyHosts are navigated.  See https://crbug.com/595339.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest, NavigatePopupToIllegalURL) {
  GURL main_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  // Open a cross-site popup.
  GURL popup_url(embedded_test_server()->GetURL("b.com", "/title2.html"));
  Shell* popup = OpenPopup(shell(), popup_url, "foo");
  EXPECT_TRUE(popup);
  EXPECT_NE(popup->web_contents()->GetSiteInstance(),
            shell()->web_contents()->GetSiteInstance());

  WebContentsConsoleObserver console_observer(web_contents());
  console_observer.SetPattern("Not allowed to load local resource:*");

  // From the opener, navigate the popup to a file:/// URL.  This should result
  // in a console error and stay on the old page.
  GURL file_url("file:///");
  NavigateNamedFrame(shell(), file_url, "foo");
  EXPECT_TRUE(WaitForLoadStop(popup->web_contents()));
  EXPECT_EQ(popup_url, popup->web_contents()->GetLastCommittedURL());
  EXPECT_TRUE(base::MatchPattern(console_observer.GetMessageAt(0u),
                                 "Not allowed to load local resource: file:*"));

  // Now try the same test with a chrome:// URL.
  GURL chrome_url(std::string(kChromeUIScheme) + "://" +
                  std::string(kChromeUIGpuHost));
  NavigateNamedFrame(shell(), chrome_url, "foo");
  EXPECT_TRUE(WaitForLoadStop(popup->web_contents()));
  EXPECT_EQ(popup_url, popup->web_contents()->GetLastCommittedURL());
  EXPECT_TRUE(
      base::MatchPattern(console_observer.GetMessageAt(1u),
                         std::string("Not allowed to load local resource: ") +
                             kChromeUIScheme + ":*"));
}

// Verify that named frames are discoverable from their opener's ancestors.
// See https://crbug.com/511474.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       DiscoverNamedFrameFromAncestorOfOpener) {
  GURL main_url(
      embedded_test_server()->GetURL("a.com", "/site_per_process_main.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  // It is safe to obtain the root frame tree node here, as it doesn't change.
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();

  // Navigate first child cross-site.
  GURL frame_url(embedded_test_server()->GetURL("b.com", "/title1.html"));
  EXPECT_TRUE(NavigateToURLFromRenderer(root->child_at(0), frame_url));

  // Open a popup named "foo" from the first child.
  Shell* foo_shell =
      OpenPopup(root->child_at(0), GURL(url::kAboutBlankURL), "foo");
  EXPECT_TRUE(foo_shell);

  // Check that a proxy was created for the "foo" popup in a.com.
  FrameTreeNode* foo_root =
      static_cast<WebContentsImpl*>(foo_shell->web_contents())
          ->GetPrimaryFrameTree()
          .root();
  SiteInstanceImpl* site_instance_a =
      root->current_frame_host()->GetSiteInstance();
  RenderFrameProxyHost* popup_rfph_for_a =
      foo_root->current_frame_host()
          ->browsing_context_state()
          ->GetRenderFrameProxyHost(site_instance_a->group());
  EXPECT_TRUE(popup_rfph_for_a);

  // Verify that the main frame can find the "foo" popup by name.  If
  // window.open targets the correct frame, the "foo" popup's current URL
  // should be updated to |named_frame_url|.
  GURL named_frame_url(embedded_test_server()->GetURL("c.com", "/title2.html"));
  NavigateNamedFrame(shell(), named_frame_url, "foo");
  EXPECT_TRUE(WaitForLoadStop(foo_shell->web_contents()));
  EXPECT_EQ(named_frame_url, foo_root->current_url());

  // Navigate the popup cross-site and ensure it's still reachable via
  // window.open from the main frame.
  GURL d_url(embedded_test_server()->GetURL("d.com", "/title3.html"));
  EXPECT_TRUE(NavigateToURLFromRenderer(foo_shell, d_url));
  EXPECT_EQ(d_url, foo_root->current_url());
  NavigateNamedFrame(shell(), named_frame_url, "foo");
  EXPECT_TRUE(WaitForLoadStop(foo_shell->web_contents()));
  EXPECT_EQ(named_frame_url, foo_root->current_url());
}

class SitePerProcessFencedFrameTest : public SitePerProcessBrowserTestBase {
 public:
  SitePerProcessFencedFrameTest() {
    fenced_frame_helper_ =
        std::make_unique<content::test::FencedFrameTestHelper>();
  }

  void SetUpOnMainThread() override {
    SitePerProcessBrowserTestBase::SetUpOnMainThread();
    https_server_.ServeFilesFromSourceDirectory(GetTestDataFilePath());
    ASSERT_TRUE(https_server_.Start());
  }

 protected:
  net::EmbeddedTestServer& https_server() { return https_server_; }

  content::RenderFrameHost* CreateFencedFrame(content::RenderFrameHost* parent,
                                              const GURL& url) {
    if (fenced_frame_helper_) {
      return fenced_frame_helper_->CreateFencedFrame(parent, url);
    }

    // FencedFrameTestHelper only supports the MPArch version of fenced frames.
    // So need to maually create a fenced frame for the ShadowDOM version.
    content::TestNavigationManager navigation(web_contents(), url);

    constexpr char kAddFencedFrameScript[] = R"({
        const fenced_frame = document.createElement('fencedframe');
        fenced_frame.src = $1;
        document.body.appendChild(fenced_frame);
    })";
    EXPECT_TRUE(ExecJs(parent, content::JsReplace(kAddFencedFrameScript, url)));
    EXPECT_TRUE(navigation.WaitForNavigationFinished());

    return ChildFrameAt(parent, 0);
  }

 private:
  base::test::ScopedFeatureList feature_list_;
  std::unique_ptr<content::test::FencedFrameTestHelper> fenced_frame_helper_;
  net::EmbeddedTestServer https_server_{net::EmbeddedTestServer::TYPE_HTTPS};
};

IN_PROC_BROWSER_TEST_F(SitePerProcessFencedFrameTest,
                       PopupFromFencedFrameDoesNotCreateProxy) {
  GURL main_url(embedded_test_server()->GetURL("/title1.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  // It is safe to obtain the root frame tree node here, as it doesn't change.
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();

  // Create a fenced frame.
  GURL fenced_frame_url(https_server().GetURL("/fenced_frames/title1.html"));
  RenderFrameHost* fenced_frame_host = CreateFencedFrame(
      web_contents()->GetPrimaryMainFrame(), fenced_frame_url);
  EXPECT_NE(nullptr, fenced_frame_host);

  // Open a popup named "foo" from the fenced frame.
  Shell* popup_shell =
      OpenPopup(fenced_frame_host, GURL(url::kAboutBlankURL), "foo", "", false);
  EXPECT_TRUE(popup_shell);

  // Check that the popup from the fenced frame didn't create a proxy.
  // Opening popups from fenced frames forces noopener, which makes named
  // frames not discoverable.
  FrameTreeNode* popup_root =
      static_cast<WebContentsImpl*>(popup_shell->web_contents())
          ->GetPrimaryFrameTree()
          .root();
  EXPECT_EQ(nullptr, popup_root->opener());

  SiteInstanceImpl* site_instance =
      root->current_frame_host()->GetSiteInstance();
  EXPECT_FALSE(popup_root->current_frame_host()
                   ->browsing_context_state()
                   ->GetRenderFrameProxyHost(site_instance->group()));

  SiteInstanceImpl* embedder_site_instance =
      static_cast<RenderFrameHostImpl*>(fenced_frame_host)->GetSiteInstance();
  EXPECT_FALSE(popup_root->current_frame_host()
                   ->browsing_context_state()
                   ->GetRenderFrameProxyHost(embedder_site_instance->group()));
}

// Similar to DiscoverNamedFrameFromAncestorOfOpener, but check that if a
// window is created without a name and acquires window.name later, it will
// still be discoverable from its opener's ancestors.  Also, instead of using
// an opener's ancestor, this test uses a popup with same origin as that
// ancestor. See https://crbug.com/511474.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       DiscoverFrameAfterSettingWindowName) {
  GURL main_url(
      embedded_test_server()->GetURL("a.com", "/site_per_process_main.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  // It is safe to obtain the root frame tree node here, as it doesn't change.
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();

  // Open a same-site popup from the main frame.
  GURL a_com_url(embedded_test_server()->GetURL("a.com", "/title3.html"));
  Shell* a_com_shell = OpenPopup(root->child_at(0), a_com_url, "");
  EXPECT_TRUE(a_com_shell);

  // Navigate first child on main frame cross-site.
  GURL frame_url(embedded_test_server()->GetURL("b.com", "/title1.html"));
  EXPECT_TRUE(NavigateToURLFromRenderer(root->child_at(0), frame_url));

  // Open an unnamed popup from the first child frame.
  Shell* foo_shell =
      OpenPopup(root->child_at(0), GURL(url::kAboutBlankURL), "");
  EXPECT_TRUE(foo_shell);

  // There should be no proxy created for the "foo" popup in a.com, since
  // there's no way for the two a.com frames to access it yet.
  FrameTreeNode* foo_root =
      static_cast<WebContentsImpl*>(foo_shell->web_contents())
          ->GetPrimaryFrameTree()
          .root();
  SiteInstanceImpl* site_instance_a =
      root->current_frame_host()->GetSiteInstance();
  EXPECT_FALSE(foo_root->current_frame_host()
                   ->browsing_context_state()
                   ->GetRenderFrameProxyHost(site_instance_a->group()));

  // Set window.name in the popup's frame.
  EXPECT_TRUE(ExecJs(foo_shell, "window.name = 'foo'"));

  // A proxy for the popup should now exist in a.com.
  EXPECT_TRUE(foo_root->current_frame_host()
                  ->browsing_context_state()
                  ->GetRenderFrameProxyHost(site_instance_a->group()));

  // Verify that the a.com popup can now find the "foo" popup by name.
  GURL named_frame_url(embedded_test_server()->GetURL("c.com", "/title2.html"));
  NavigateNamedFrame(a_com_shell, named_frame_url, "foo");
  EXPECT_TRUE(WaitForLoadStop(foo_shell->web_contents()));
  EXPECT_EQ(named_frame_url, foo_root->current_url());
}

// Check that frame opener updates work with subframes.  Set up a window with a
// popup and update openers for the popup's main frame and subframe to
// subframes on first window, as follows:
//
//    foo      +---- bar
//    / \      |     / \      .
// bar   foo <-+  bar   foo
//  ^                    |
//  +--------------------+
//
// The sites are carefully set up so that both opener updates are cross-process
// but still allowed by Blink's navigation checks.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest, UpdateSubframeOpener) {
  GURL main_url = embedded_test_server()->GetURL(
      "foo.com", "/frame_tree/page_with_two_frames.html");
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  EXPECT_EQ(2U, root->child_count());

  // From the top frame, open a popup and navigate it to a cross-site page with
  // two subframes.
  Shell* popup_shell = OpenPopup(shell(), GURL(url::kAboutBlankURL), "popup");
  EXPECT_TRUE(popup_shell);
  GURL popup_url(embedded_test_server()->GetURL(
      "bar.com", "/frame_tree/page_with_post_message_frames.html"));
  EXPECT_TRUE(NavigateToURLFromRenderer(popup_shell, popup_url));

  FrameTreeNode* popup_root =
      static_cast<WebContentsImpl*>(popup_shell->web_contents())
          ->GetPrimaryFrameTree()
          .root();
  EXPECT_EQ(2U, popup_root->child_count());

  // Popup's opener should point to main frame to start with.
  EXPECT_EQ(root, popup_root->opener());

  // Update the popup's opener to the second subframe on the main page (which
  // is same-origin with the top frame, i.e., foo.com).
  EXPECT_EQ(true, EvalJs(root->child_at(1), "!!window.open('','popup');"));

  // Check that updated opener propagated to the browser process and the
  // popup's bar.com process.
  EXPECT_EQ(root->child_at(1), popup_root->opener());

  EXPECT_EQ(true,
            EvalJs(popup_shell,
                   "window.opener === window.opener.parent.frames['frame2'];"));

  // Now update opener on the popup's second subframe (foo.com) to the main
  // page's first subframe (bar.com).
  EXPECT_EQ(true, EvalJs(root->child_at(0), "!!window.open('','subframe2');"));

  // Check that updated opener propagated to the browser process and the
  // foo.com process.
  EXPECT_EQ(root->child_at(0), popup_root->child_at(1)->opener());

  EXPECT_EQ(true,
            EvalJs(popup_root->child_at(1),
                   "window.opener === window.opener.parent.frames['frame1'];"));
}

// Check that when a subframe navigates to a new SiteInstance, the new
// SiteInstance will get a proxy for the opener of subframe's parent.  I.e.,
// accessing parent.opener from the subframe should still work after a
// cross-process navigation.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       NavigatingSubframePreservesOpenerInParent) {
  GURL main_url = embedded_test_server()->GetURL("a.com", "/post_message.html");
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();

  // Open a popup with a cross-site page that has a subframe.
  GURL popup_url(embedded_test_server()->GetURL(
      "b.com", "/cross_site_iframe_factory.html?b(b)"));
  Shell* popup_shell = OpenPopup(shell(), popup_url, "popup");
  EXPECT_TRUE(popup_shell);
  FrameTreeNode* popup_root =
      static_cast<WebContentsImpl*>(popup_shell->web_contents())
          ->GetPrimaryFrameTree()
          .root();
  EXPECT_EQ(1U, popup_root->child_count());

  // Check that the popup's opener is correct in the browser process.
  EXPECT_EQ(root, popup_root->opener());

  // Navigate popup's subframe to another site.
  GURL frame_url(embedded_test_server()->GetURL("c.com", "/post_message.html"));
  EXPECT_TRUE(NavigateToURLFromRenderer(popup_root->child_at(0), frame_url));

  // Check that the new subframe process still sees correct opener for its
  // parent by sending a postMessage to subframe's parent.opener.
  EXPECT_EQ(true, EvalJs(popup_root->child_at(0), "!!parent.opener;"));

  std::u16string expected_title = u"msg";
  TitleWatcher title_watcher(shell()->web_contents(), expected_title);
  EXPECT_EQ(true, EvalJs(popup_root->child_at(0),
                         "postToOpenerOfParent('msg','*');"));
  EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
}

// Check that if a subframe has an opener, that opener is preserved when the
// subframe navigates cross-site.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest, NavigateSubframeWithOpener) {
  GURL main_url(embedded_test_server()->GetURL(
      "foo.com", "/frame_tree/page_with_two_frames.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  EXPECT_EQ(
      " Site A ------------ proxies for B\n"
      "   |--Site B ------- proxies for A\n"
      "   +--Site A ------- proxies for B\n"
      "Where A = http://foo.com/\n"
      "      B = http://bar.com/",
      DepictFrameTree(root));

  // Update the first (cross-site) subframe's opener to root frame.
  EXPECT_EQ(true, EvalJs(root, "!!window.open('','frame1');"));

  // Check that updated opener propagated to the browser process and subframe's
  // process.
  EXPECT_EQ(root, root->child_at(0)->opener());

  EXPECT_EQ(true,
            EvalJs(root->child_at(0), "window.opener === window.parent;"));

  // Navigate the subframe with opener to another site.
  GURL frame_url(embedded_test_server()->GetURL("baz.com", "/title1.html"));
  EXPECT_TRUE(NavigateToURLFromRenderer(root->child_at(0), frame_url));

  // Check that the subframe still sees correct opener in its new process.
  EXPECT_EQ(true,
            EvalJs(root->child_at(0), "window.opener === window.parent;"));

  // Navigate second subframe to a new site.  Check that the proxy that's
  // created for the first subframe in the new SiteInstance has correct opener.
  GURL frame2_url(embedded_test_server()->GetURL("qux.com", "/title1.html"));
  EXPECT_TRUE(NavigateToURLFromRenderer(root->child_at(1), frame2_url));

  EXPECT_EQ(true, EvalJs(root->child_at(1),
                         "parent.frames['frame1'].opener === parent;"));
}

// Check that if a subframe has an opener, that opener is preserved when a new
// `blink::RemoteFrame` is created for that subframe in another renderer
// process. Similar to NavigateSubframeWithOpener, but this test verifies the
// subframe opener plumbing for blink::mojom::RemoteFrame::CreateRemoteChild(),
// whereas NavigateSubframeWithOpener targets mojom::Renderer::CreateFrame().
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       NewRenderFrameProxyPreservesOpener) {
  GURL main_url(
      embedded_test_server()->GetURL("foo.com", "/post_message.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();

  // Open a popup with a cross-site page that has two subframes.
  GURL popup_url(embedded_test_server()->GetURL(
      "bar.com", "/frame_tree/page_with_post_message_frames.html"));
  Shell* popup_shell = OpenPopup(shell(), popup_url, "popup");
  EXPECT_TRUE(popup_shell);
  FrameTreeNode* popup_root =
      static_cast<WebContentsImpl*>(popup_shell->web_contents())
          ->GetPrimaryFrameTree()
          .root();
  EXPECT_EQ(
      " Site A ------------ proxies for B\n"
      "   |--Site A ------- proxies for B\n"
      "   +--Site B ------- proxies for A\n"
      "Where A = http://bar.com/\n"
      "      B = http://foo.com/",
      DepictFrameTree(popup_root));

  // Update the popup's second subframe's opener to root frame.  This is
  // allowed because that subframe is in the same foo.com SiteInstance as the
  // root frame.
  EXPECT_EQ(true, EvalJs(root, "!!window.open('','subframe2');"));

  // Check that the opener update propagated to the browser process and bar.com
  // process.
  EXPECT_EQ(root, popup_root->child_at(1)->opener());
  EXPECT_EQ(true,
            EvalJs(popup_root->child_at(0),
                   "parent.frames['subframe2'].opener && "
                   "    parent.frames['subframe2'].opener === parent.opener;"));

  // Navigate the popup's first subframe to another site.
  GURL frame_url(
      embedded_test_server()->GetURL("baz.com", "/post_message.html"));
  EXPECT_TRUE(NavigateToURLFromRenderer(popup_root->child_at(0), frame_url));

  // Check that the second subframe's opener is still correct in the first
  // subframe's new process.  Verify it both in JS and with a postMessage.
  EXPECT_EQ(true,
            EvalJs(popup_root->child_at(0),
                   "parent.frames['subframe2'].opener && "
                   "    parent.frames['subframe2'].opener === parent.opener;"));

  std::u16string expected_title = u"msg";
  TitleWatcher title_watcher(shell()->web_contents(), expected_title);
  EXPECT_EQ(true, EvalJs(popup_root->child_at(0),
                         "postToOpenerOfSibling('subframe2', 'msg', '*');"));
  EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
}

// Test for https://crbug.com/515302. Perform two navigations, A1 -> B2 -> A3,
// and drop the mojo::AgentSchedulingGroupHost::DidUnloadRenderFrame from the A1
// -> B2 navigation, so that the second B2 -> A3 navigation is initiated before
// the first page receives the
// mojo::AgentSchedulingGroupHost::DidUnloadRenderFrame. Ensure that this
// doesn't crash and that the RVH(A1) is not reused in that case.
#if BUILDFLAG(IS_MAC)
#define MAYBE_RenderViewHostIsNotReusedAfterDelayedUnloadACK \
  DISABLED_RenderViewHostIsNotReusedAfterDelayedUnloadACK
#else
#define MAYBE_RenderViewHostIsNotReusedAfterDelayedUnloadACK \
  RenderViewHostIsNotReusedAfterDelayedUnloadACK
#endif
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       MAYBE_RenderViewHostIsNotReusedAfterDelayedUnloadACK) {
  GURL a_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
  EXPECT_TRUE(NavigateToURL(shell(), a_url));

  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  RenderFrameHostImpl* rfh = root->current_frame_host();
  RenderViewHostImpl* rvh = rfh->render_view_host();
  int rvh_routing_id = rvh->GetRoutingID();
  int rvh_process_id = rvh->GetProcess()->GetDeprecatedID();
  SiteInstanceImpl* site_instance = rfh->GetSiteInstance();
  RenderFrameDeletedObserver deleted_observer(rfh);

  // Install a BrowserMessageFilter to drop
  // mojo::AgentSchedulingGroupHost::DidUnloadRenderFrame messages in A's
  // process.
  auto unload_ack_filter = base::BindRepeating([] { return true; });
  rfh->SetUnloadACKCallbackForTesting(unload_ack_filter);
  rfh->DisableUnloadTimerForTesting();

  // Navigate to B.  This must wait for DidCommitProvisionalLoad and not
  // DidStopLoading, so that the Unload timer doesn't call OnUnloaded and
  // destroy |rfh| and |rvh| before they are checked in the test.
  GURL b_url(embedded_test_server()->GetURL("b.com", "/title2.html"));
  TestFrameNavigationObserver commit_observer(root);
  EXPECT_TRUE(ExecJs(shell(), JsReplace("location = $1", b_url)));
  commit_observer.WaitForCommit();
  EXPECT_FALSE(deleted_observer.deleted());

  // The previous RFH should be either:
  // 1) In the BackForwardCache, if back-forward cache is enabled.
  // 2) Pending deletion otherwise, since the
  // mojo::AgentSchedulingGroupHost::DidUnloadRenderFrame for A->B is dropped.
  EXPECT_THAT(
      rfh->lifecycle_state(),
      testing::AnyOf(
          testing::Eq(
              RenderFrameHostImpl::LifecycleStateImpl::kRunningUnloadHandlers),
          testing::Eq(
              RenderFrameHostImpl::LifecycleStateImpl::kInBackForwardCache)));

  // Without the mojo::AgentSchedulingGroupHost::DidUnloadRenderFrame and timer,
  // the process A will never shutdown. Simulate the process being killed now.
  content::RenderProcessHostWatcher crash_observer(
      rvh->GetProcess(),
      content::RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
  EXPECT_TRUE(rvh->GetProcess()->Shutdown(0));
  crash_observer.Wait();

  // Verify that the RVH and RFH for A were cleaned up.
  EXPECT_FALSE(root->frame_tree().GetRenderViewHost(site_instance->group()));
  EXPECT_TRUE(deleted_observer.deleted());

  // Start a navigation back to A, being careful to stay in the same
  // BrowsingInstance, and check that the RenderViewHost wasn't reused.
  TestNavigationManager navigation_manager(shell()->web_contents(), a_url);
  shell()->LoadURLForFrame(a_url, std::string(),
                           ui::PageTransitionFromInt(ui::PAGE_TRANSITION_LINK));
  navigation_manager.WaitForSpeculativeRenderFrameHostCreation();
  RenderFrameHostImpl* pending_rfh =
      root->render_manager()->speculative_frame_host();
  RenderViewHostImpl* pending_rvh = pending_rfh->render_view_host();

  // When ProactivelySwapBrowsingInstance A1 and A3 aren't using the same
  // BrowsingInstance.
  if (CanCrossSiteNavigationsProactivelySwapBrowsingInstances())
    EXPECT_NE(site_instance, pending_rfh->GetSiteInstance());
  else
    EXPECT_EQ(site_instance, pending_rfh->GetSiteInstance());

  EXPECT_FALSE(rvh_routing_id == pending_rvh->GetRoutingID() &&
               rvh_process_id == pending_rvh->GetProcess()->GetDeprecatedID());

  // Make sure the last navigation finishes without crashing.
  ASSERT_TRUE(navigation_manager.WaitForNavigationFinished());
}

// Test for https://crbug.com/591478, where navigating to a cross-site page with
// a subframe on the old site caused a crash while trying to reuse the old
// RenderViewHost.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       ReusePendingDeleteRenderViewHostForSubframe) {
  GURL main_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  std::string script =
      "window.onunload = function() { "
      "  var start = Date.now();"
      "  while (Date.now() - start < 1000);"
      "}";
  EXPECT_TRUE(ExecJs(shell(), script));

  // Navigating cross-site with an iframe to the original site shouldn't crash.
  GURL second_url(embedded_test_server()->GetURL(
      "b.com", "/cross_site_iframe_factory.html?b(a)"));
  EXPECT_TRUE(NavigateToURL(shell(), second_url));

  // If the subframe is created while the main frame is pending deletion, then
  // the RVH will be reused.  The main frame should've been swapped with a
  // proxy despite being the last active frame in the progress (see
  // https://crbug.com/568836), and this proxy should also be reused by the new
  // page.
  //
  // TODO(creis, alexmos): Find a way to assert this that isn't flaky. For now,
  // the test is just likely (not certain) to catch regressions by crashing.
}

// Check that when a cross-process frame acquires focus, the old focused frame
// loses focus and fires blur events.  Starting on a page with a cross-site
// subframe, simulate mouse clicks to switch focus from root frame to subframe
// and then back to root frame.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       CrossProcessFocusChangeFiresBlurEvents) {
  GURL main_url(
      embedded_test_server()->GetURL("a.com", "/page_with_input_field.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  SimulateEndOfPaintHoldingOnPrimaryMainFrame(web_contents());

  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();

  EXPECT_EQ(
      " Site A ------------ proxies for B\n"
      "   +--Site B ------- proxies for A\n"
      "Where A = http://a.com/\n"
      "      B = http://b.com/",
      DepictFrameTree(root));

  // Focus the main frame's text field.  The return value "input-focus"
  // indicates that the focus event was fired correctly.
  EXPECT_EQ("input-focus", EvalJs(shell(), "focusInputField()"));

  // The main frame should be focused.
  EXPECT_EQ(root, root->frame_tree().GetFocusedFrame());

  DOMMessageQueue msg_queue(web_contents());

  // Click on the cross-process subframe.
  SimulateMouseClick(
      root->child_at(0)->current_frame_host()->GetRenderWidgetHost(), 1, 1);

  // Check that the main frame lost focus and fired blur event on the input
  // text field.
  EXPECT_EQ(true, EvalJs(shell(), "waitForBlur()"));

  // The subframe should now be focused.
  EXPECT_EQ(root->child_at(0), root->frame_tree().GetFocusedFrame());

  // Click on the root frame.
  SimulateMouseClick(shell()
                         ->web_contents()
                         ->GetPrimaryMainFrame()
                         ->GetRenderViewHost()
                         ->GetWidget(),
                     1, 1);

  // Check that the subframe lost focus and fired blur event on its
  // document's body.
  std::string status;
  while (msg_queue.WaitForMessage(&status)) {
    if (status == "\"document-blur\"")
      break;
  }

  // The root frame should be focused again.
  EXPECT_EQ(root, root->frame_tree().GetFocusedFrame());
}

// Check that when a cross-process subframe is focused, its parent's
// document.activeElement correctly returns the corresponding <iframe> element.
// The test sets up an A-embed-B-embed-C page and shifts focus A->B->A->C,
// checking document.activeElement after each change.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest, DocumentActiveElement) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b(c))"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  SimulateEndOfPaintHoldingOnPrimaryMainFrame(web_contents());

  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();

  EXPECT_EQ(
      " Site A ------------ proxies for B C\n"
      "   +--Site B ------- proxies for A C\n"
      "        +--Site C -- proxies for A B\n"
      "Where A = http://a.com/\n"
      "      B = http://b.com/\n"
      "      C = http://c.com/",
      DepictFrameTree(root));

  FrameTreeNode* child = root->child_at(0);
  FrameTreeNode* grandchild = root->child_at(0)->child_at(0);

  // The main frame should be focused to start with.
  EXPECT_EQ(root, root->frame_tree().GetFocusedFrame());

  // Focus the b.com frame.
  FocusFrame(child);
  EXPECT_EQ(child, root->frame_tree().GetFocusedFrame());

  // Helper function to check a property of document.activeElement in the
  // specified frame.
  auto verify_active_element_property = [](RenderFrameHost* rfh,
                                           const std::string& property,
                                           const std::string& expected_value) {
    std::string script = base::StringPrintf(
        "document.activeElement.%s.toLowerCase();", property.c_str());
    EXPECT_EQ(expected_value, EvalJs(rfh, script));
  };

  // Verify that document.activeElement on main frame points to the <iframe>
  // element for the b.com frame.
  RenderFrameHost* root_rfh = root->current_frame_host();
  verify_active_element_property(root_rfh, "tagName", "iframe");
  verify_active_element_property(root_rfh, "src", child->current_url().spec());

  // Focus the a.com main frame again.
  FocusFrame(root);
  EXPECT_EQ(root, root->frame_tree().GetFocusedFrame());

  // Main frame document's <body> should now be the active element.
  verify_active_element_property(root_rfh, "tagName", "body");

  // Now shift focus from main frame to c.com frame.
  FocusFrame(grandchild);

  // Check document.activeElement in main frame.  It should still point to
  // <iframe> for the b.com frame, since Blink computes the focused iframe
  // element by walking the parent chain of the focused frame until it hits the
  // current frame.  This logic should still work with remote frames.
  verify_active_element_property(root_rfh, "tagName", "iframe");
  verify_active_element_property(root_rfh, "src", child->current_url().spec());

  // Check document.activeElement in b.com subframe.  It should point to
  // <iframe> for the c.com frame.  This is a tricky case where B needs to find
  // out that focus changed from one remote frame to another (A to C).
  RenderFrameHost* child_rfh = child->current_frame_host();
  verify_active_element_property(child_rfh, "tagName", "iframe");
  verify_active_element_property(child_rfh, "src",
                                 grandchild->current_url().spec());
}

// Check that window.focus works for cross-process subframes.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest, SubframeWindowFocus) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b,c)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();

  EXPECT_EQ(
      " Site A ------------ proxies for B C\n"
      "   |--Site B ------- proxies for A C\n"
      "   +--Site C ------- proxies for A B\n"
      "Where A = http://a.com/\n"
      "      B = http://b.com/\n"
      "      C = http://c.com/",
      DepictFrameTree(root));

  FrameTreeNode* child1 = root->child_at(0);
  FrameTreeNode* child2 = root->child_at(1);

  // The main frame should be focused to start with.
  EXPECT_EQ(root, root->frame_tree().GetFocusedFrame());

  // Register focus and blur events that will send messages when each frame's
  // window gets or loses focus, and configure some utility functions useful for
  // waiting for these messages.
  const char kSetupFocusEvents[] = R"(
      window.addEventListener('focus', function() {
        window.top.postMessage('%s-got-focus', '*');
      });
      window.addEventListener('blur', function() {
        window.top.postMessage('%s-lost-focus', '*');
      });
      function onEvent(target, eventName, property, value) {
        return new Promise((resolve, reject) => {
          function listener(event) {
            if (event[property] == value) {
              resolve();
              target.removeEventListener(eventName, listener);
            }
          };
          target.addEventListener(eventName, listener);
        });
      }
      function expectMessages(messageList) {
        var promiseList = messageList.map(
            (dataValue) => onEvent(window, 'message', 'data', dataValue));
        return Promise.all(promiseList);
      }
  )";
  std::string script = base::StringPrintf(kSetupFocusEvents, "main", "main");
  ExecuteScriptAsync(shell(), script);
  script = base::StringPrintf(kSetupFocusEvents, "child1", "child1");
  ExecuteScriptAsync(child1, script);
  script = base::StringPrintf(kSetupFocusEvents, "child2", "child2");
  ExecuteScriptAsync(child2, script);

  // Execute window.focus on the B subframe from the A main frame.
  // Process A should fire a blur event, and process B should fire a focus
  // event.  Wait for both events.
  EXPECT_EQ(true, EvalJs(root, R"((async function() {
      allMessages = [];
      window.addEventListener('message', (event) => {
        allMessages.push(event.data);
      });

      var messages = expectMessages(['main-lost-focus', 'child1-got-focus']);
      frames[0].focus();
      await messages;

      return allMessages.length == 2 || allMessages;
  })())"));

  EXPECT_EQ(child1, root->frame_tree().GetFocusedFrame());

  // Now, execute window.focus on the C subframe from A main frame.  This
  // checks that we can shift focus from one remote frame to another.
  //
  // Wait for the two subframes (B and C) to fire blur and focus events.
  EXPECT_EQ(true, EvalJs(root, R"((async function() {
      var messages = expectMessages(['child1-lost-focus', 'child2-got-focus']);
      frames[1].focus();
      await messages;
      return allMessages.length == 4 || allMessages;
  })())"));

  // The C subframe should now be focused.
  EXPECT_EQ(child2, root->frame_tree().GetFocusedFrame());

  // Install event listeners in the A main frame, expecting the main frame to
  // obtain focus.
  EXPECT_TRUE(
      ExecJs(root,
             "var messages = "
             "    expectMessages(['child2-lost-focus', 'main-got-focus']);"));

  // window.focus the main frame from the C subframe.
  ExecuteScriptAsync(child2, "parent.focus()");

  // Wait for the messages to arrive in the A main frame.
  EXPECT_EQ(true, EvalJs(root, R"((async function() {
      await messages;
      return allMessages.length == 6 || allMessages;
  })())"));

  // The main frame should now be focused.
  EXPECT_EQ(root, root->frame_tree().GetFocusedFrame());
}

// Check that when a subframe has focus, and another subframe navigates
// cross-site to a new renderer process, this doesn't reset the focused frame
// to the main frame.  See https://crbug.com/802156.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       SubframeFocusNotLostWhenAnotherFrameNavigatesCrossSite) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(a,a)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  FrameTreeNode* child1 = root->child_at(0);
  FrameTreeNode* child2 = root->child_at(1);

  // The main frame should be focused to start with.
  EXPECT_EQ(root, root->frame_tree().GetFocusedFrame());

  // Add an <input> element to the first subframe.
  ExecuteScriptAsync(
      child1, "document.body.appendChild(document.createElement('input'))");

  // Focus the first subframe using window.focus().
  FrameFocusedObserver focus_observer(child1->current_frame_host());
  ExecuteScriptAsync(root, "frames[0].focus()");
  focus_observer.Wait();
  EXPECT_EQ(child1, root->frame_tree().GetFocusedFrame());

  // Give focus to the <input> element in the first subframe.
  ExecuteScriptAsync(child1, "document.querySelector('input').focus()");

  // Now, navigate second subframe cross-site.  Ensure that this won't change
  // the focused frame.
  GURL b_url(embedded_test_server()->GetURL("b.com", "/title1.html"));
  EXPECT_TRUE(NavigateToURLFromRenderer(child2, b_url));
  // This is needed because the incorrect focused frame change as in
  // https://crbug.com/802156 requires an additional post-commit IPC roundtrip.
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(child1, root->frame_tree().GetFocusedFrame());

  // The <input> in first subframe should still be the activeElement.
  EXPECT_EQ(
      "input",
      base::ToLowerASCII(
          EvalJs(child1, "document.activeElement.tagName").ExtractString()));
}

// Tests that we are using the correct `blink::RemoteFrame` when navigating an
// opener window.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest, OpenerSetLocation) {
  // Navigate the main window.
  GURL main_url(embedded_test_server()->GetURL("/title1.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));
  EXPECT_EQ(shell()->web_contents()->GetLastCommittedURL(), main_url);

  // Load cross-site page into a new window.
  GURL cross_url = embedded_test_server()->GetURL("foo.com", "/title1.html");
  Shell* popup = OpenPopup(shell(), cross_url, "");
  EXPECT_EQ(popup->web_contents()->GetLastCommittedURL(), cross_url);

  // Use new window to navigate main window.
  EXPECT_TRUE(
      ExecJs(popup, JsReplace("window.opener.location.href = $1", cross_url)));
  EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
  EXPECT_EQ(shell()->web_contents()->GetLastCommittedURL(), cross_url);
}

// crbug.com/1281755
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
#define MAYBE_NavigateProxyAndDetachBeforeProvisionalFrameCreation \
  DISABLED_NavigateProxyAndDetachBeforeProvisionalFrameCreation
#else
#define MAYBE_NavigateProxyAndDetachBeforeProvisionalFrameCreation \
  NavigateProxyAndDetachBeforeProvisionalFrameCreation
#endif
// Test for https://crbug.com/526304, where a parent frame executes a
// remote-to-local navigation on a child frame and immediately removes the same
// child frame.  This test exercises the path where the detach happens before
// the provisional local frame is created.
IN_PROC_BROWSER_TEST_P(
    SitePerProcessBrowserTest,
    MAYBE_NavigateProxyAndDetachBeforeProvisionalFrameCreation) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b,b)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  WebContents* contents = shell()->web_contents();
  FrameTreeNode* root =
      static_cast<WebContentsImpl*>(contents)->GetPrimaryFrameTree().root();
  EXPECT_EQ(2U, root->child_count());

  // Navigate the first child frame to 'about:blank' (which is a
  // remote-to-local transition), and then detach it.
  FrameDeletedObserver observer(root->child_at(0)->current_frame_host());
  std::string script =
      "var f = document.querySelector('iframe');"
      "f.contentWindow.location.href = 'about:blank';"
      "setTimeout(function() { document.body.removeChild(f); }, 0);";
  EXPECT_TRUE(ExecJs(root, script));
  observer.Wait();
  EXPECT_EQ(1U, root->child_count());

  // Make sure the main frame renderer does not crash and ignores the
  // navigation to the frame that's already been deleted.
  EXPECT_EQ(1, EvalJs(root, "frames.length"));
}

// Test for a variation of https://crbug.com/526304, where a child frame does a
// remote-to-local navigation, and the parent frame removes that child frame
// after the provisional local frame is created and starts to navigate, but
// before it commits.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       NavigateProxyAndDetachBeforeCommit) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b,b)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  WebContents* contents = shell()->web_contents();
  FrameTreeNode* root =
      static_cast<WebContentsImpl*>(contents)->GetPrimaryFrameTree().root();
  EXPECT_EQ(2U, root->child_count());
  FrameTreeNode* child = root->child_at(0);

  // Start a remote-to-local navigation for the child, but don't wait for
  // commit.
  GURL same_site_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
  NavigationController::LoadURLParams params(same_site_url);
  params.transition_type = ui::PAGE_TRANSITION_LINK;
  params.frame_tree_node_id = child->frame_tree_node_id();
  child->navigator().controller().LoadURLWithParams(params);

  // Tell parent to remove the first child.  This should happen after the
  // previous navigation starts but before it commits.
  FrameDeletedObserver observer(child->current_frame_host());
  EXPECT_TRUE(ExecJs(
      root, "document.body.removeChild(document.querySelector('iframe'));"));
  observer.Wait();
  EXPECT_EQ(1U, root->child_count());

  // Make sure the a.com renderer does not crash.
  EXPECT_EQ(1, EvalJs(root, "frames.length;"));
}

// Similar to NavigateProxyAndDetachBeforeCommit, but uses a synchronous
// navigation to about:blank and the parent removes the child frame in a load
// event handler for the subframe.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest, NavigateAboutBlankAndDetach) {
  GURL main_url(
      embedded_test_server()->GetURL("a.com", "/remove_frame_on_load.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  WebContents* contents = shell()->web_contents();
  FrameTreeNode* root =
      static_cast<WebContentsImpl*>(contents)->GetPrimaryFrameTree().root();
  EXPECT_EQ(1U, root->child_count());
  FrameTreeNode* child = root->child_at(0);
  EXPECT_NE(shell()->web_contents()->GetSiteInstance(),
            child->current_frame_host()->GetSiteInstance());

  // Navigate the child frame to "about:blank" from the parent document and
  // wait for it to be removed.
  FrameDeletedObserver observer(child->current_frame_host());
  EXPECT_TRUE(
      ExecJs(root, base::StringPrintf("f.src = '%s'", url::kAboutBlankURL)));
  observer.Wait();

  // Make sure the a.com renderer does not crash and the frame is removed.
  EXPECT_EQ(0, EvalJs(root, "frames.length;"));
}

// This test ensures that the RenderFrame isn't leaked in the renderer process
// if a pending cross-process navigation is cancelled. The test works by trying
// to create a new RenderFrame with the same routing id. If there is an
// entry with the same routing ID, a CHECK is hit and the process crashes.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       SubframePendingAndBackToSameSiteInstance) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  // Capture the FrameTreeNode this test will be navigating.
  FrameTreeNode* node =
      web_contents()->GetPrimaryFrameTree().root()->child_at(0);
  EXPECT_TRUE(node);
  EXPECT_NE(node->current_frame_host()->GetSiteInstance(),
            node->parent()->GetSiteInstance());

  // Navigate to the site of the parent, but to a page that will not commit.
  GURL same_site_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
  TestNavigationManager stalled_navigation(web_contents(), same_site_url);
  {
    NavigationController::LoadURLParams params(same_site_url);
    params.transition_type = ui::PAGE_TRANSITION_LINK;
    params.frame_tree_node_id = node->frame_tree_node_id();
    node->navigator().controller().LoadURLWithParams(params);
    EXPECT_TRUE(stalled_navigation.WaitForResponse());
  }

  // Grab the routing id of the pending RenderFrameHost and set up a process
  // observer to ensure there is no crash when a new RenderFrame creation is
  // attempted.
  RenderProcessHost* process =
      node->render_manager()->speculative_frame_host()->GetProcess();
  AgentSchedulingGroupHost* agent_scheduling_group =
      AgentSchedulingGroupHost::GetOrCreate(*node->render_manager()
                                                 ->speculative_frame_host()
                                                 ->GetSiteInstance()
                                                 ->group(),
                                            *process);
  RenderProcessHostWatcher watcher(
      process, RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
  int frame_routing_id =
      node->render_manager()->speculative_frame_host()->GetRoutingID();
  blink::LocalFrameToken frame_token =
      node->render_manager()->speculative_frame_host()->GetFrameToken();
  blink::RemoteFrameToken previous_frame_token =
      node->render_manager()->GetProxyToParent()->GetFrameToken();

  // Now go to c.com so the navigation to a.com is cancelled and send an IPC
  // to create a new RenderFrame with the routing id of the previously pending
  // one.
  EXPECT_TRUE(NavigateToURLFromRenderer(
      node, embedded_test_server()->GetURL("c.com", "/title2.html")));
  {
    mojo::PendingAssociatedRemote<mojom::Frame> pending_frame;

    mojom::CreateFrameParamsPtr params = mojom::CreateFrameParams::New();
    params->routing_id = frame_routing_id;
    params->frame = pending_frame.InitWithNewEndpointAndPassReceiver();
    std::ignore = params->interface_broker.InitWithNewPipeAndPassReceiver();
    std::ignore = params->associated_interface_provider_remote
                      .InitWithNewEndpointAndPassReceiver();
    params->previous_frame_token = previous_frame_token;
    params->opener_frame_token = std::nullopt;
    params->parent_frame_token =
        shell()->web_contents()->GetPrimaryMainFrame()->GetFrameToken();
    params->frame_owner_properties = blink::mojom::FrameOwnerProperties::New();
    params->frame_token = frame_token;
    params->devtools_frame_token = base::UnguessableToken::Create();
    params->document_token = blink::DocumentToken();
    params->policy_container = CreateStubPolicyContainer();
    params->replication_state = blink::mojom::FrameReplicationState::New();
    agent_scheduling_group->CreateFrame(std::move(params));
  }

  // Disable the BackForwardCache to ensure the old process is going to be
  // released.
  DisableBackForwardCacheForTesting(web_contents(),
                                    BackForwardCache::TEST_REQUIRES_NO_CACHING);

  // The test must wait for the process to exit, but if there is no leak, the
  // RenderFrame will be properly created and there will be no crash.
  // Therefore, navigate the main frame to completely different site, which
  // will cause the original process to exit cleanly.
  EXPECT_TRUE(NavigateToURL(
      shell(), embedded_test_server()->GetURL("d.com", "/title3.html")));
  watcher.Wait();
  EXPECT_TRUE(watcher.did_exit_normally());
}

// This test ensures that the RenderFrame isn't leaked in the renderer process
// when a remote parent detaches a child frame. The test works by trying
// to create a new RenderFrame with the same routing id. If there is an
// entry with the same routing ID, a CHECK is hit and the process crashes.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest, ParentDetachRemoteChild) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b,b)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  WebContentsImpl* contents = web_contents();
  EXPECT_EQ(2U, contents->GetPrimaryFrameTree().root()->child_count());

  // Capture the FrameTreeNode this test will be navigating.
  FrameTreeNode* node = contents->GetPrimaryFrameTree().root()->child_at(0);
  EXPECT_TRUE(node);
  EXPECT_NE(node->current_frame_host()->GetSiteInstance(),
            node->parent()->GetSiteInstance());

  // Grab the routing id of the first child RenderFrameHost and set up a process
  // observer to ensure there is no crash when a new RenderFrame creation is
  // attempted.
  RenderProcessHost* process = node->current_frame_host()->GetProcess();
  AgentSchedulingGroupHost* agent_scheduling_group =
      AgentSchedulingGroupHost::GetOrCreate(
          *node->current_frame_host()->GetSiteInstance()->group(), *process);
  RenderProcessHostWatcher watcher(
      process, RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
  int frame_routing_id = node->current_frame_host()->GetRoutingID();
  blink::LocalFrameToken frame_token =
      node->current_frame_host()->GetFrameToken();
  int widget_routing_id =
      node->current_frame_host()->GetRenderWidgetHost()->GetRoutingID();
  std::optional<blink::FrameToken> parent_frame_token =
      node->parent()
          ->frame_tree_node()
          ->render_manager()
          ->GetFrameTokenForSiteInstanceGroup(
              node->current_frame_host()->GetSiteInstance()->group());

  // Have the parent frame remove the child frame from its DOM. This should
  // result in the child RenderFrame being deleted in the remote process.
  EXPECT_TRUE(ExecJs(contents,
                     "document.body.removeChild("
                     "document.querySelectorAll('iframe')[0])"));
  EXPECT_EQ(1U, contents->GetPrimaryFrameTree().root()->child_count());

  {
    mojo::PendingAssociatedRemote<mojom::Frame> pending_frame;
    mojo::PendingAssociatedRemote<blink::mojom::FrameWidget> blink_frame_widget;
    mojo::PendingAssociatedRemote<blink::mojom::Widget> blink_widget;

    mojom::CreateFrameParamsPtr params = mojom::CreateFrameParams::New();
    params->routing_id = frame_routing_id;
    params->frame = pending_frame.InitWithNewEndpointAndPassReceiver();
    std::ignore = params->interface_broker.InitWithNewPipeAndPassReceiver();
    std::ignore = params->associated_interface_provider_remote
                      .InitWithNewEndpointAndPassReceiver();
    params->previous_frame_token = std::nullopt;
    params->opener_frame_token = std::nullopt;
    params->parent_frame_token = parent_frame_token;
    params->previous_sibling_frame_token = std::nullopt;
    params->frame_owner_properties = blink::mojom::FrameOwnerProperties::New();
    params->widget_params = mojom::CreateFrameWidgetParams::New();
    params->widget_params->routing_id = widget_routing_id;
    params->widget_params->frame_widget =
        blink_frame_widget.InitWithNewEndpointAndPassReceiver();
    params->widget_params->widget =
        blink_widget.InitWithNewEndpointAndPassReceiver();
    std::ignore = params->widget_params->frame_widget_host
                      .InitWithNewEndpointAndPassReceiver();
    std::ignore =
        params->widget_params->widget_host.InitWithNewEndpointAndPassReceiver();
    params->widget_params->visual_properties.screen_infos =
        display::ScreenInfos(display::ScreenInfo());
    params->replication_state = blink::mojom::FrameReplicationState::New();
    params->replication_state->name = "name";
    params->replication_state->unique_name = "name";
    params->frame_token = frame_token;
    params->devtools_frame_token = base::UnguessableToken::Create();
    params->document_token = blink::DocumentToken();
    params->policy_container = CreateStubPolicyContainer();
    agent_scheduling_group->CreateFrame(std::move(params));
  }

  // The test must wait for the process to exit, but if there is no leak, the
  // RenderFrame will be properly created and there will be no crash.
  // Therefore, navigate the remaining subframe to completely different site,
  // which will cause the original process to exit cleanly.
  EXPECT_TRUE(NavigateToURLFromRenderer(
      contents->GetPrimaryFrameTree().root()->child_at(0),
      embedded_test_server()->GetURL("d.com", "/title3.html")));
  watcher.Wait();
  EXPECT_TRUE(watcher.did_exit_normally());
}

// Verify that sandbox flags inheritance works across multiple levels of
// frames.  See https://crbug.com/576845.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest, SandboxFlagsInheritance) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(a)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  // It is safe to obtain the root frame tree node here, as it doesn't change.
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();

  // Set sandbox flags for child frame.
  EXPECT_TRUE(ExecJs(
      root, "document.querySelector('iframe').sandbox = 'allow-scripts';"));

  // Calculate expected flags.  Note that "allow-scripts" resets both
  // network::mojom::WebSandboxFlags::Scripts and
  // network::mojom::WebSandboxFlags::AutomaticFeatures bits per
  // blink::parseSandboxPolicy().
  network::mojom::WebSandboxFlags expected_flags =
      network::mojom::WebSandboxFlags::kAll &
      ~network::mojom::WebSandboxFlags::kScripts &
      ~network::mojom::WebSandboxFlags::kAutomaticFeatures;
  EXPECT_EQ(expected_flags,
            root->child_at(0)->pending_frame_policy().sandbox_flags);
  EXPECT_EQ(network::mojom::WebSandboxFlags::kNone,
            root->child_at(0)->effective_frame_policy().sandbox_flags);

  // Navigate child frame so that the sandbox flags take effect.  Use a page
  // with three levels of frames and make sure all frames properly inherit
  // sandbox flags.
  GURL frame_url(embedded_test_server()->GetURL(
      "b.com", "/cross_site_iframe_factory.html?b(c(d))"));
  EXPECT_TRUE(NavigateToURLFromRenderer(root->child_at(0), frame_url));

  // Wait for subframes to load as well.
  ASSERT_TRUE(WaitForLoadStop(shell()->web_contents()));

  // Check each new frame's sandbox flags on the browser process side.
  FrameTreeNode* b_child = root->child_at(0);
  FrameTreeNode* c_child = b_child->child_at(0);
  FrameTreeNode* d_child = c_child->child_at(0);
  EXPECT_EQ(expected_flags, b_child->effective_frame_policy().sandbox_flags);
  EXPECT_EQ(expected_flags, c_child->effective_frame_policy().sandbox_flags);
  EXPECT_EQ(expected_flags, d_child->effective_frame_policy().sandbox_flags);

  // Check whether each frame is sandboxed on the renderer side, by seeing if
  // each frame's origin is unique ("null").
  EXPECT_EQ("null", GetOriginFromRenderer(b_child));
  EXPECT_EQ("null", GetOriginFromRenderer(c_child));
  EXPECT_EQ("null", GetOriginFromRenderer(d_child));
}

// Check that sandbox flags are not inherited before they take effect.  Create
// a child frame, update its sandbox flags but don't navigate the frame, and
// ensure that a new cross-site grandchild frame doesn't inherit the new flags
// (which shouldn't have taken effect).
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       SandboxFlagsNotInheritedBeforeNavigation) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(a)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  // It is safe to obtain the root frame tree node here, as it doesn't change.
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();

  // Set sandbox flags for child frame.
  EXPECT_TRUE(ExecJs(
      root, "document.querySelector('iframe').sandbox = 'allow-scripts';"));

  // These flags should be pending but not take effect, since there's been no
  // navigation.
  network::mojom::WebSandboxFlags expected_flags =
      network::mojom::WebSandboxFlags::kAll &
      ~network::mojom::WebSandboxFlags::kScripts &
      ~network::mojom::WebSandboxFlags::kAutomaticFeatures;
  FrameTreeNode* child = root->child_at(0);
  EXPECT_EQ(expected_flags, child->pending_frame_policy().sandbox_flags);
  EXPECT_EQ(network::mojom::WebSandboxFlags::kNone,
            child->effective_frame_policy().sandbox_flags);

  // Add a new grandchild frame and navigate it cross-site.
  RenderFrameHostCreatedObserver frame_observer(shell()->web_contents(), 1);
  EXPECT_TRUE(ExecJs(
      child, "document.body.appendChild(document.createElement('iframe'));"));
  frame_observer.Wait();

  FrameTreeNode* grandchild = child->child_at(0);
  GURL frame_url(embedded_test_server()->GetURL("b.com", "/title1.html"));
  TestFrameNavigationObserver navigation_observer(grandchild);
  EXPECT_TRUE(NavigateToURLFromRenderer(grandchild, frame_url));
  navigation_observer.Wait();

  // Since the update flags haven't yet taken effect in its parent, this
  // grandchild frame should not be sandboxed.
  EXPECT_EQ(network::mojom::WebSandboxFlags::kNone,
            grandchild->pending_frame_policy().sandbox_flags);
  EXPECT_EQ(network::mojom::WebSandboxFlags::kNone,
            grandchild->effective_frame_policy().sandbox_flags);

  // Check that the grandchild frame isn't sandboxed on the renderer side.  If
  // sandboxed, its origin would be unique ("null").
  EXPECT_EQ(GetExpectedOrigin("b.com"), GetOriginFromRenderer(grandchild));
}

// Verify that popups opened from sandboxed frames inherit sandbox flags from
// their opener, and that they keep these inherited flags after being navigated
// cross-site.  See https://crbug.com/483584.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       NewPopupInheritsSandboxFlagsFromOpener) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(a)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  // It is safe to obtain the root frame tree node here, as it doesn't change.
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();

  // Set sandbox flags for child frame.
  EXPECT_TRUE(ExecJs(root,
                     "document.querySelector('iframe').sandbox = "
                     "    'allow-scripts allow-popups';"));

  // Calculate expected flags.  Note that "allow-scripts" resets both
  // network::mojom::WebSandboxFlags::Scripts and
  // network::mojom::WebSandboxFlags::AutomaticFeatures bits per
  // blink::parseSandboxPolicy().
  network::mojom::WebSandboxFlags expected_flags =
      network::mojom::WebSandboxFlags::kAll &
      ~network::mojom::WebSandboxFlags::kAutomaticFeatures &
      ~network::mojom::WebSandboxFlags::kPopups &
      ~network::mojom::WebSandboxFlags::kScripts &
      ~network::mojom::WebSandboxFlags::kTopNavigationToCustomProtocols;
  EXPECT_EQ(expected_flags,
            root->child_at(0)->pending_frame_policy().sandbox_flags);

  // Navigate child frame cross-site.  The sandbox flags should take effect.
  GURL frame_url(embedded_test_server()->GetURL("b.com", "/title1.html"));
  TestFrameNavigationObserver frame_observer(root->child_at(0));
  EXPECT_TRUE(NavigateToURLFromRenderer(root->child_at(0), frame_url));
  frame_observer.Wait();
  EXPECT_EQ(expected_flags,
            root->child_at(0)->effective_frame_policy().sandbox_flags);

  // Verify that they've also taken effect on the renderer side.  The sandboxed
  // frame's origin should be opaque.
  EXPECT_EQ("null", GetOriginFromRenderer(root->child_at(0)));
  const url::SchemeHostPort tuple_b(frame_url);
  const url::Origin sandbox_origin_b = root->child_at(0)->current_origin();
  EXPECT_TRUE(sandbox_origin_b.opaque());
  EXPECT_EQ(tuple_b, sandbox_origin_b.GetTupleOrPrecursorTupleIfOpaque());

  // Open a popup named "foo" from the sandboxed child frame.
  Shell* foo_shell =
      OpenPopup(root->child_at(0), GURL(url::kAboutBlankURL), "foo");
  EXPECT_TRUE(foo_shell);

  FrameTreeNode* foo_root =
      static_cast<WebContentsImpl*>(foo_shell->web_contents())
          ->GetPrimaryFrameTree()
          .root();

  // Check that the sandbox flags for new popup are correct in the browser
  // process.
  EXPECT_EQ(expected_flags, foo_root->effective_frame_policy().sandbox_flags);

  // The popup's origin should be opaque, since it's sandboxed, but cross-origin
  // from its opener.
  EXPECT_EQ("null", GetOriginFromRenderer(foo_root));
  url::Origin sandbox_origin_b2 = foo_root->current_origin();
  EXPECT_NE(sandbox_origin_b2, sandbox_origin_b);
  EXPECT_TRUE(sandbox_origin_b2.opaque());
  EXPECT_EQ(tuple_b, sandbox_origin_b2.GetTupleOrPrecursorTupleIfOpaque());

  // Navigate the popup cross-site.  This should be placed in an opaque origin
  // derived from c.com, and retain the inherited sandbox flags.
  GURL c_url(embedded_test_server()->GetURL("c.com", "/title1.html"));
  const url::SchemeHostPort tuple_c(c_url);
  {
    TestFrameNavigationObserver popup_observer(foo_root);
    EXPECT_TRUE(ExecJs(foo_root, JsReplace("location.href = $1", c_url)));
    popup_observer.Wait();
    EXPECT_EQ(c_url, foo_shell->web_contents()->GetLastCommittedURL());
  }

  // Confirm that the popup is still sandboxed, both on browser and renderer
  // sides.
  EXPECT_EQ(expected_flags, foo_root->effective_frame_policy().sandbox_flags);
  EXPECT_EQ("null", GetOriginFromRenderer(foo_root));
  const url::Origin sandbox_origin_c = foo_root->current_origin();
  EXPECT_NE(sandbox_origin_b, sandbox_origin_c);
  EXPECT_TRUE(sandbox_origin_c.opaque());
  EXPECT_EQ(tuple_c, sandbox_origin_c.GetTupleOrPrecursorTupleIfOpaque());

  // Navigate the popup back to b.com.  The popup should perform a
  // remote-to-local navigation in the b.com process, and keep an opaque
  // origin and the inherited sandbox flags.
  {
    TestFrameNavigationObserver popup_observer(foo_root);
    EXPECT_TRUE(ExecJs(foo_root, JsReplace("location.href = $1", frame_url)));
    popup_observer.Wait();
    EXPECT_EQ(frame_url, foo_shell->web_contents()->GetLastCommittedURL());
  }

  // Confirm that the popup is still sandboxed, both on browser and renderer
  // sides. This navigation should result in a new opaque origin derived
  // from b.com.
  EXPECT_EQ(expected_flags, foo_root->effective_frame_policy().sandbox_flags);
  EXPECT_EQ("null", GetOriginFromRenderer(foo_root));
  url::Origin sandbox_origin_b3 = foo_root->current_origin();
  EXPECT_TRUE(sandbox_origin_b3.opaque());
  EXPECT_EQ(tuple_b, sandbox_origin_b3.GetTupleOrPrecursorTupleIfOpaque());
  EXPECT_NE(sandbox_origin_b, sandbox_origin_b3);
  EXPECT_NE(sandbox_origin_b2, sandbox_origin_b3);
}

// Verify that popups opened from frames sandboxed with the
// "allow-popups-to-escape-sandbox" directive do *not* inherit sandbox flags
// from their opener.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       OpenUnsandboxedPopupFromSandboxedFrame) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(a)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  // It is safe to obtain the root frame tree node here, as it doesn't change.
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();

  // Set sandbox flags for child frame, specifying that popups opened from it
  // should not be sandboxed.
  EXPECT_TRUE(ExecJs(
      root,
      "document.querySelector('iframe').sandbox = "
      "    'allow-scripts allow-popups allow-popups-to-escape-sandbox';"));

  // Set expected flags for the child frame.  Note that "allow-scripts" resets
  // both network::mojom::WebSandboxFlags::Scripts and
  // network::mojom::WebSandboxFlags::AutomaticFeatures bits per
  // blink::parseSandboxPolicy().
  network::mojom::WebSandboxFlags expected_flags =
      network::mojom::WebSandboxFlags::kAll &
      ~network::mojom::WebSandboxFlags::kScripts &
      ~network::mojom::WebSandboxFlags::kAutomaticFeatures &
      ~network::mojom::WebSandboxFlags::kPopups &
      ~network::mojom::WebSandboxFlags::kTopNavigationToCustomProtocols &
      ~network::mojom::WebSandboxFlags::kPropagatesToAuxiliaryBrowsingContexts;
  EXPECT_EQ(expected_flags,
            root->child_at(0)->pending_frame_policy().sandbox_flags);

  // Navigate child frame cross-site.  The sandbox flags should take effect.
  GURL frame_url(embedded_test_server()->GetURL("b.com", "/title1.html"));
  TestFrameNavigationObserver frame_observer(root->child_at(0));
  EXPECT_TRUE(NavigateToURLFromRenderer(root->child_at(0), frame_url));
  frame_observer.Wait();
  EXPECT_EQ(expected_flags,
            root->child_at(0)->effective_frame_policy().sandbox_flags);

  // Open a cross-site popup named "foo" from the child frame.
  GURL b_url(embedded_test_server()->GetURL("c.com", "/title1.html"));
  Shell* foo_shell = OpenPopup(root->child_at(0), b_url, "foo");
  EXPECT_TRUE(foo_shell);

  FrameTreeNode* foo_root =
      static_cast<WebContentsImpl*>(foo_shell->web_contents())
          ->GetPrimaryFrameTree()
          .root();

  // Check that the sandbox flags for new popup are correct in the browser
  // process.  They should not have been inherited.
  EXPECT_EQ(network::mojom::WebSandboxFlags::kNone,
            foo_root->effective_frame_policy().sandbox_flags);
  // Check that the sandbox flags for the popup document are correct in the
  // browser process: None are set from the frame, none are set from the
  // navigation.
  EXPECT_EQ(network::mojom::WebSandboxFlags::kNone,
            foo_root->current_frame_host()->active_sandbox_flags());

  // The popup's origin should match |b_url|, since it's not sandboxed.
  EXPECT_EQ(url::Origin::Create(b_url).Serialize(),
            EvalJs(foo_root, "self.origin;"));
}

// Verify that popup frames opened from sandboxed documents with the
// "allow-popups-to-escape-sandbox" directive do *not* inherit sandbox flags AND
// that local scheme documents do *not* inherit flags from the opener/initiator.
IN_PROC_BROWSER_TEST_P(
    SitePerProcessBrowserTest,
    OpenSandboxedDocumentInUnsandboxedPopupFromSandboxedFrame) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(a)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  // It is safe to obtain the root frame tree node here, as it doesn't change.
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();

  // Set sandbox flags for child frame, specifying that popups opened from it
  // should not be sandboxed.
  EXPECT_TRUE(ExecJs(
      root,
      "document.querySelector('iframe').sandbox = "
      "    'allow-scripts allow-popups allow-popups-to-escape-sandbox';"));

  // Set expected flags for the child frame.  Note that "allow-scripts" resets
  // both network::mojom::WebSandboxFlags::Scripts and
  // network::mojom::WebSandboxFlags::AutomaticFeatures bits per
  // blink::parseSandboxPolicy().
  network::mojom::WebSandboxFlags expected_flags =
      network::mojom::WebSandboxFlags::kAll &
      ~network::mojom::WebSandboxFlags::kScripts &
      ~network::mojom::WebSandboxFlags::kAutomaticFeatures &
      ~network::mojom::WebSandboxFlags::kPopups &
      ~network::mojom::WebSandboxFlags::kTopNavigationToCustomProtocols &
      ~network::mojom::WebSandboxFlags::kPropagatesToAuxiliaryBrowsingContexts;
  EXPECT_EQ(expected_flags,
            root->child_at(0)->pending_frame_policy().sandbox_flags);

  // Navigate child frame cross-site.  The sandbox flags should take effect.
  GURL frame_url(embedded_test_server()->GetURL("b.com", "/title1.html"));
  TestFrameNavigationObserver frame_observer(root->child_at(0));
  EXPECT_TRUE(NavigateToURLFromRenderer(root->child_at(0), frame_url));
  frame_observer.Wait();
  EXPECT_EQ(expected_flags,
            root->child_at(0)->effective_frame_policy().sandbox_flags);

  // Open a popup named "foo" from the child frame on about:blank.
  GURL foo_url("about:blank");
  Shell* foo_shell = OpenPopup(root->child_at(0), foo_url, "foo");
  EXPECT_TRUE(foo_shell);

  FrameTreeNode* foo_root =
      static_cast<WebContentsImpl*>(foo_shell->web_contents())
          ->GetPrimaryFrameTree()
          .root();

  // Check that the sandbox flags for new popup frame are correct in the browser
  // process. They should not have been inherited.
  EXPECT_EQ(network::mojom::WebSandboxFlags::kNone,
            foo_root->effective_frame_policy().sandbox_flags);
  // Check that the sandbox flags for the popup document are correct in the
  // browser process. They should not have been inherited (for about:blank).
  EXPECT_EQ(network::mojom::WebSandboxFlags::kNone,
            foo_root->current_frame_host()->active_sandbox_flags());
}

// Verify that popup frames opened from sandboxed documents with the
// "allow-popups-to-escape-sandbox" directive do *not* inherit sandbox flags AND
// that local scheme documents do inherit CSP sandbox flags from the
// opener/initiator.
IN_PROC_BROWSER_TEST_P(
    SitePerProcessBrowserTest,
    OpenSandboxedDocumentInUnsandboxedPopupFromCSPSandboxedDocument) {
  GURL main_url = embedded_test_server()->GetURL(
      "a.test",
      "/set-header?"
      "Content-Security-Policy: sandbox "
      "allow-scripts allow-popups allow-popups-to-escape-sandbox");

  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  // It is safe to obtain the root frame tree node here, as it doesn't change.
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();

  // Set expected flags for the child frame.  Note that "allow-scripts" resets
  // both network::mojom::WebSandboxFlags::Scripts and
  // network::mojom::WebSandboxFlags::AutomaticFeatures bits per
  // blink::parseSandboxPolicy().
  network::mojom::WebSandboxFlags expected_flags =
      network::mojom::WebSandboxFlags::kAll &
      ~network::mojom::WebSandboxFlags::kScripts &
      ~network::mojom::WebSandboxFlags::kAutomaticFeatures &
      ~network::mojom::WebSandboxFlags::kPopups &
      ~network::mojom::WebSandboxFlags::kTopNavigationToCustomProtocols &
      ~network::mojom::WebSandboxFlags::kPropagatesToAuxiliaryBrowsingContexts;

  EXPECT_EQ(expected_flags, root->current_frame_host()->active_sandbox_flags());

  // Open a popup named "foo" from the child frame on about:blank.
  GURL foo_url("about:blank");
  Shell* foo_shell = OpenPopup(root, foo_url, "foo");
  EXPECT_TRUE(foo_shell);

  FrameTreeNode* foo_root =
      static_cast<WebContentsImpl*>(foo_shell->web_contents())
          ->GetPrimaryFrameTree()
          .root();

  // Check that the sandbox flags for new popup frame are correct in the browser
  // process. They should not have been inherited.
  EXPECT_EQ(network::mojom::WebSandboxFlags::kNone,
            foo_root->effective_frame_policy().sandbox_flags);
  // Check that the sandbox flags for the popup document are correct in the
  // browser process. They should have been inherited.
  EXPECT_EQ(expected_flags,
            foo_root->current_frame_host()->active_sandbox_flags());
}

// Test that subresources with certificate errors get reported to the
// browser. That is, if https://example.test frames https://a.com which
// loads an image with certificate errors, the browser should be
// notified about the subresource with certificate errors and downgrade
// the UI appropriately.
// TODO(crbug.com/40705650): Flaky.
IN_PROC_BROWSER_TEST_P(SitePerProcessIgnoreCertErrorsBrowserTest,
                       DISABLED_SubresourceWithCertificateErrors) {
  net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS);
  https_server.ServeFilesFromSourceDirectory(GetTestDataFilePath());
  SetupCrossSiteRedirector(&https_server);
  ASSERT_TRUE(https_server.Start());

  GURL url(https_server.GetURL(
      "example.test",
      "/mixed-content/non-redundant-cert-error-in-iframe.html"));

  // The update of the security state can happen asynchronously after the
  // navigation finished, see https://crbug.com/1105145.
  VisibleSecurityStateObserver displayed_content_with_cert_errors_observer(
      shell()->web_contents(),
      base::BindRepeating([](WebContents* web_contents) {
        NavigationEntry* entry =
            web_contents->GetController().GetLastCommittedEntry();
        // The image that the iframe loaded had certificate errors also, so
        // the page should be marked as having displayed subresources with
        // cert errors.
        return entry && (entry->GetSSL().content_status &
                         SSLStatus::DISPLAYED_CONTENT_WITH_CERT_ERRORS) != 0;
      }));
  EXPECT_TRUE(NavigateToURL(shell(), url));
  displayed_content_with_cert_errors_observer.Wait();

  NavigationEntry* entry =
      shell()->web_contents()->GetController().GetLastCommittedEntry();
  ASSERT_TRUE(entry);

  // The main page was loaded with certificate errors.
  EXPECT_TRUE(net::IsCertStatusError(entry->GetSSL().cert_status));
}

// Test setting a cross-origin iframe to display: none.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest, CrossSiteIframeDisplayNone) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  RenderWidgetHost* root_render_widget_host =
      root->current_frame_host()->GetRenderWidgetHost();

  // Set the iframe to display: none.
  EXPECT_TRUE(ExecJs(
      shell(), "document.querySelector('iframe').style.display = 'none'"));

  // Waits until pending frames are done.
  std::unique_ptr<MainThreadFrameObserver> observer(
      new MainThreadFrameObserver(root_render_widget_host));
  observer->Wait();

  // Force the renderer to generate a new frame.
  EXPECT_TRUE(ExecJs(shell(), "document.body.style.background = 'black'"));

  // Waits for the next frame.
  observer->Wait();
}

// Test that a cross-origin iframe can be blocked by X-Frame-Options and CSP
// frame-ancestors.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       CrossSiteIframeBlockedByXFrameOptionsOrCSP) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(a)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();

  // Add a load event handler for the iframe element.
  EXPECT_TRUE(ExecJs(shell(),
                     "document.querySelector('iframe').onload = "
                     "    function() { document.title = 'loaded'; };"));

  // The blocked url reported in the console message should only contain the
  // origin, in order to avoid sensitive data being leaked to the parent frame.
  //
  // TODO(crbug.com/40053800): We should not leak any information at all
  // to the parent frame. Instead, we should send a message directly to Devtools
  // (without passing through a renderer): that can also contain more
  // information (like the full blocked url).
  GURL reported_blocked_url = embedded_test_server()->GetURL("b.com", "/");
  const struct {
    const char* url;
    bool use_error_page;
    std::string expected_console_message;
  } kTestCases[] = {
      {"/frame-ancestors-none.html", false,
       "Framing '" + reported_blocked_url.spec() +
           "' violates the following Content Security "
           "Policy directive: \"frame-ancestors 'none'\". The request has "
           "been blocked.\n"},
      {"/x-frame-options-deny.html", true,
       "Refused to display '" + reported_blocked_url.spec() +
           "' in a frame because it set 'X-Frame-Options' to 'deny'."},
  };

  for (const auto& test : kTestCases) {
    GURL blocked_url = embedded_test_server()->GetURL("b.com", test.url);
    EXPECT_TRUE(ExecJs(shell(), "document.title = 'not loaded';"));
    std::u16string expected_title(u"loaded");
    TitleWatcher title_watcher(shell()->web_contents(), expected_title);

    WebContentsConsoleObserver console_observer(shell()->web_contents());
    console_observer.SetPattern("*'" + reported_blocked_url.spec() + "'*");

    // Navigate the subframe to a blocked URL.
    TestNavigationObserver load_observer(shell()->web_contents());
    EXPECT_TRUE(ExecJs(shell(),
                       JsReplace("frames[0].location.href = $1", blocked_url)));
    load_observer.Wait();

    // The blocked frame's origin should become unique.
    const url::Origin child_origin =
        root->child_at(0)->current_frame_host()->GetLastCommittedOrigin();
    EXPECT_TRUE(child_origin.opaque());
    EXPECT_EQ(url::Origin::Create(blocked_url.DeprecatedGetOriginAsURL())
                  .GetTupleOrPrecursorTupleIfOpaque(),
              child_origin.GetTupleOrPrecursorTupleIfOpaque());

    // X-Frame-Options and CSP frame-ancestors behave differently. XFO commits
    // an error page, while CSP commits a "data:," URL.
    // TODO(crbug.com/41405925): Use an error page for both.
    EXPECT_FALSE(load_observer.last_navigation_succeeded());
    EXPECT_EQ(net::ERR_BLOCKED_BY_RESPONSE,
              load_observer.last_net_error_code());
    EXPECT_EQ(root->child_at(0)->current_frame_host()->GetLastCommittedURL(),
              blocked_url);
    EXPECT_EQ("Error", EvalJs(root->child_at(0), "document.title"));

    // The blocked frame should still fire a load event in its parent's process.
    EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());

    EXPECT_EQ(console_observer.GetMessageAt(0u), test.expected_console_message);

    // Check that the current RenderFrameHost has stopped loading.
    EXPECT_FALSE(root->child_at(0)->current_frame_host()->is_loading());

    // Navigate the subframe to another cross-origin page and ensure that this
    // navigation succeeds.  Use a renderer-initiated navigation to test the
    // transfer logic, which used to have some issues with this.
    GURL c_url(embedded_test_server()->GetURL("c.com", "/title1.html"));
    EXPECT_TRUE(NavigateIframeToURL(shell()->web_contents(), "child-0", c_url));
    EXPECT_EQ(c_url, root->child_at(0)->current_url());

    // When a page gets blocked due to XFO or CSP, it is sandboxed with the
    // SandboxOrigin flag (i.e., its origin is set to be unique) to ensure that
    // the blocked page is seen as cross-origin. However, those flags shouldn't
    // affect future navigations for a frame. Verify this for the above
    // navigation.
    EXPECT_EQ(c_url.DeprecatedGetOriginAsURL().spec(),
              root->child_at(0)->current_origin().Serialize() + "/");
    EXPECT_EQ(network::mojom::WebSandboxFlags::kNone,
              root->child_at(0)->effective_frame_policy().sandbox_flags);
  }
}

// Test that a cross-origin frame's navigation can be blocked by CSP frame-src.
// In this version of a test, CSP comes from HTTP headers.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       CrossSiteIframeBlockedByParentCSPFromHeaders) {
  GURL main_url(
      embedded_test_server()->GetURL("a.com", "/frame-src-self-and-b.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();

  // Sanity-check that the test page has the expected shape for testing.
  GURL old_subframe_url(
      embedded_test_server()->GetURL("b.com", "/title2.html"));
  EXPECT_FALSE(root->child_at(0)->HasSameOrigin(*root));
  EXPECT_EQ(old_subframe_url, root->child_at(0)->current_url());
  const std::vector<network::mojom::ContentSecurityPolicyPtr>& root_csp =
      root->current_frame_host()
          ->policy_container_host()
          ->policies()
          .content_security_policies;
  EXPECT_EQ(1u, root_csp.size());
  EXPECT_EQ("frame-src 'self' http://b.com:*",
            root_csp[0]->header->header_value);

  // Monitor subframe's load events via main frame's title.
  EXPECT_TRUE(ExecJs(shell(),
                     "document.querySelector('iframe').onload = "
                     "    function() { document.title = 'loaded'; };"));
  EXPECT_TRUE(ExecJs(shell(), "document.title = 'not loaded';"));
  std::u16string expected_title(u"loaded");
  TitleWatcher title_watcher(shell()->web_contents(), expected_title);

  // Try to navigate the subframe to a blocked URL.
  TestNavigationObserver load_observer(shell()->web_contents());
  GURL blocked_url = embedded_test_server()->GetURL("c.com", "/title3.html");
  EXPECT_TRUE(ExecJs(root->child_at(0),
                     JsReplace("window.location.href = $1", blocked_url)));

  // The blocked frame should still fire a load event in its parent's process.
  EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());

  // Check that the current RenderFrameHost has stopped loading.
  if (root->child_at(0)->current_frame_host()->is_loading())
    load_observer.Wait();

  // The last successful url shouldn't be the blocked url.
  EXPECT_NE(blocked_url,
            root->child_at(0)->current_frame_host()->last_successful_url());

  // The blocked frame should go to an error page. Errors currently commit
  // with the URL of the blocked page.
  EXPECT_EQ(blocked_url, root->child_at(0)->current_url());

  // The page should get the title of an error page (i.e "Error") and not the
  // title of the blocked page.
  EXPECT_EQ("Error", EvalJs(root->child_at(0), "document.title"));

  // Navigate to a URL without CSP.
  EXPECT_TRUE(NavigateToURL(
      shell(), embedded_test_server()->GetURL("a.com", "/title1.html")));
}

// Test that a cross-origin frame's navigation can be blocked by CSP frame-src.
// In this version of a test, CSP comes from a <meta> element added after the
// page has already loaded.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       CrossSiteIframeBlockedByParentCSPFromMeta) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(a)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();

  // Navigate the subframe to a location we will disallow in the future.
  GURL old_subframe_url(
      embedded_test_server()->GetURL("b.com", "/title2.html"));
  EXPECT_TRUE(NavigateToURLFromRenderer(root->child_at(0), old_subframe_url));

  // Add frame-src CSP via a new <meta> element.
  EXPECT_TRUE(
      ExecJs(shell(),
             "var meta = document.createElement('meta');"
             "meta.httpEquiv = 'Content-Security-Policy';"
             "meta.content = 'frame-src https://a.com:*';"
             "document.getElementsByTagName('head')[0].appendChild(meta);"));

  // Sanity-check that the test page has the expected shape for testing.
  // (the CSP should not have an effect on the already loaded frames).
  EXPECT_FALSE(root->child_at(0)->HasSameOrigin(*root));
  EXPECT_EQ(old_subframe_url, root->child_at(0)->current_url());
  const std::vector<network::mojom::ContentSecurityPolicyPtr>& root_csp =
      root->current_frame_host()
          ->policy_container_host()
          ->policies()
          .content_security_policies;
  EXPECT_EQ(1u, root_csp.size());
  EXPECT_EQ("frame-src https://a.com:*", root_csp[0]->header->header_value);

  // Monitor subframe's load events via main frame's title.
  EXPECT_TRUE(ExecJs(shell(),
                     "document.querySelector('iframe').onload = "
                     "    function() { document.title = 'loaded'; };"));
  EXPECT_TRUE(ExecJs(shell(), "document.title = 'not loaded';"));
  std::u16string expected_title(u"loaded");
  TitleWatcher title_watcher(shell()->web_contents(), expected_title);

  // Try to navigate the subframe to a blocked URL.
  TestNavigationObserver load_observer2(shell()->web_contents());
  GURL blocked_url = embedded_test_server()->GetURL("c.com", "/title3.html");
  EXPECT_TRUE(ExecJs(root->child_at(0),
                     JsReplace("window.location.href = $1;", blocked_url)));

  // The blocked frame should still fire a load event in its parent's process.
  EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());

  // Check that the current RenderFrameHost has stopped loading.
  if (root->child_at(0)->current_frame_host()->is_loading())
    load_observer2.Wait();

  // The last successful url shouldn't be the blocked url.
  EXPECT_NE(blocked_url,
            root->child_at(0)->current_frame_host()->last_successful_url());

  // The blocked frame should go to an error page. Errors currently commit
  // with the URL of the blocked page.
  EXPECT_EQ(blocked_url, root->child_at(0)->current_url());

  // The page should get the title of an error page (i.e "Error") and not the
  // title of the blocked page.
  EXPECT_EQ("Error", EvalJs(root->child_at(0), "document.title"));
}

// Test that a cross-origin frame's navigation can be blocked by CSP frame-src.
// In this version of a test, CSP is inherited by srcdoc iframe from a parent
// that declared CSP via HTTP headers.  Cross-origin frame navigating to a
// blocked location is a child of the srcdoc iframe.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       CrossSiteIframeBlockedByCSPInheritedBySrcDocParent) {
  GURL main_url(
      embedded_test_server()->GetURL("a.com", "/frame-src-self-and-b.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  FrameTreeNode* srcdoc_frame = root->child_at(1);
  EXPECT_TRUE(srcdoc_frame != nullptr);
  FrameTreeNode* navigating_frame = srcdoc_frame->child_at(0);
  EXPECT_TRUE(navigating_frame != nullptr);

  // Sanity-check that the test page has the expected shape for testing.
  // (the CSP should not have an effect on the already loaded frames).
  GURL old_subframe_url(
      embedded_test_server()->GetURL("b.com", "/title2.html"));
  EXPECT_TRUE(srcdoc_frame->HasSameOrigin(*root));
  EXPECT_FALSE(srcdoc_frame->HasSameOrigin(*navigating_frame));
  EXPECT_EQ(old_subframe_url, navigating_frame->current_url());
  const std::vector<network::mojom::ContentSecurityPolicyPtr>& srcdoc_csp =
      srcdoc_frame->current_frame_host()
          ->policy_container_host()
          ->policies()
          .content_security_policies;
  EXPECT_EQ(1u, srcdoc_csp.size());
  EXPECT_EQ("frame-src 'self' http://b.com:*",
            srcdoc_csp[0]->header->header_value);

  // Monitor navigating_frame's load events via srcdoc_frame posting
  // a message to the parent frame.
  EXPECT_TRUE(ExecJs(root,
                     "window.addEventListener('message', function(event) {"
                     "  document.title = event.data;"
                     "});"));
  EXPECT_TRUE(
      ExecJs(srcdoc_frame,
             "document.querySelector('iframe').onload = "
             "    function() { window.top.postMessage('loaded', '*'); };"));
  EXPECT_TRUE(ExecJs(shell(), "document.title = 'not loaded';"));
  std::u16string expected_title(u"loaded");
  TitleWatcher title_watcher(shell()->web_contents(), expected_title);

  // Try to navigate the subframe to a blocked URL.
  TestNavigationObserver load_observer2(shell()->web_contents());
  GURL blocked_url = embedded_test_server()->GetURL("c.com", "/title3.html");
  EXPECT_TRUE(ExecJs(navigating_frame,
                     JsReplace("window.location.href = $1;", blocked_url)));

  // The blocked frame should still fire a load event in its parent's process.
  EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());

  // Check that the current RenderFrameHost has stopped loading.
  if (navigating_frame->current_frame_host()->is_loading())
    load_observer2.Wait();

  // The last successful url shouldn't be the blocked url.
  EXPECT_NE(blocked_url,
            navigating_frame->current_frame_host()->last_successful_url());

  // The blocked frame should go to an error page. Errors currently commit
  // with the URL of the blocked page.
  EXPECT_EQ(blocked_url, navigating_frame->current_url());

  // The page should get the title of an error page (i.e "Error") and not the
  // title of the blocked page.
  EXPECT_EQ("Error", EvalJs(navigating_frame, "document.title"));

  // Navigate the subframe to a URL without CSP.
  EXPECT_TRUE(NavigateToURLFromRenderer(
      srcdoc_frame, embedded_test_server()->GetURL("a.com", "/title1.html")));

  // Verify that the frame's CSP got correctly reset to an empty set.
  EXPECT_EQ(0u, srcdoc_frame->current_frame_host()
                    ->policy_container_host()
                    ->policies()
                    .content_security_policies.size());
}

// Tests that the state of the RenderViewHost is properly reset when the main
// frame is navigated to the same SiteInstance as one of its child frames.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       NavigateMainFrameToChildSite) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  SimulateEndOfPaintHoldingOnPrimaryMainFrame(web_contents());

  WebContentsImpl* contents = web_contents();
  FrameTreeNode* root = contents->GetPrimaryFrameTree().root();
  EXPECT_EQ(1U, root->child_count());

  // The test expect the BrowsingInstance to be kept across cross-site main
  // frame navigations. ProactivelySwapBrowsingInstance will provide a new one.
  // To prevent this, a popup is opened.
  if (CanCrossSiteNavigationsProactivelySwapBrowsingInstances()) {
    GURL popup_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
    EXPECT_TRUE(OpenPopup(root, popup_url, "foo"));
  }

  // Ensure the RenderViewHost for the SiteInstance of the child is considered
  // inactive.
  RenderViewHostImpl* rvh = contents->GetPrimaryFrameTree()
                                .GetRenderViewHost(root->child_at(0)
                                                       ->current_frame_host()
                                                       ->GetSiteInstance()
                                                       ->group())
                                .get();
  EXPECT_FALSE(rvh->is_active());

  // Have the child frame navigate its parent to its SiteInstance.
  GURL b_url(embedded_test_server()->GetURL("b.com", "/title1.html"));
  auto script = JsReplace("parent.location = $1", b_url);

  // Ensure the child has received a user gesture, so that it has permission
  // to framebust.
  SimulateMouseClick(
      root->child_at(0)->current_frame_host()->GetRenderWidgetHost(), 1, 1);
  TestFrameNavigationObserver frame_observer(root);
  EXPECT_TRUE(ExecJs(root->child_at(0), script));
  frame_observer.Wait();
  EXPECT_EQ(b_url, root->current_url());

  // Verify that the same RenderViewHost is preserved and that it is now active.
  EXPECT_EQ(rvh, contents->GetPrimaryFrameTree().GetRenderViewHost(
                     root->current_frame_host()->GetSiteInstance()->group()));
  EXPECT_TRUE(rvh->is_active());
}

// Test for https://crbug.com/568836.  From an A-embed-B page, navigate the
// subframe from B to A.  This cleans up the process for B, but the test delays
// the browser side from killing the B process right away.  This allows the
// B process to process the subframe's detached event and the disconnect
// of the blink::WebView's blink::mojom::PageBroadcast mojo channel. In the bug,
// the latter crashed while detaching the subframe's LocalFrame (triggered as
// part of closing the `blink::WebView`), because this tried to access the
// subframe's WebFrameWidget (from RenderFrameImpl::didChangeSelection), which
// had already been cleared by the former.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       CloseSubframeWidgetAndViewOnProcessExit) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
                            ->GetPrimaryFrameTree()
                            .root();

  // "Select all" in the subframe.  The bug only happens if there's a selection
  // change, which triggers the path through didChangeSelection.
  root->child_at(0)
      ->current_frame_host()
      ->GetRenderWidgetHost()
      ->GetFrameWidgetInputHandler()
      ->SelectAll();

  // Prevent b.com process from terminating right away once the subframe
  // navigates away from b.com below.  This is necessary so that the renderer
  // process has time to process the closings of RenderWidget and
  // `blink::WebView`, which is where the original bug was triggered.
  // Incrementing the worker ref count will cause
  // RenderProcessHostImpl::Cleanup to forego process termination.
  RenderProcessHostImpl* subframe_process = static_cast<RenderProcessHostImpl*>(
      root->child_at(0)->current_frame_host()->GetProcess());
  subframe_process->IncrementWorkerRefCount();

  // Navigate the subframe away from b.com.  Since this is the last active
  // frame in the b.com process, this causes the RenderWidget and
  // `blink::WebView` to be closed.
  EXPECT_TRUE(NavigateToURLFromRenderer(
      root->child_at(0),
      embedded_test_server()->GetURL("a.com", "/title1.html")));

  // Release the process.
  RenderProcessHostWatcher process_shutdown_observer(
      subframe_process, RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
  subframe_process->DecrementWorkerRefCount();
  process_shutdown_observer.Wait();
}

// Tests that an input event targeted to a out-of-process iframe correctly
// triggers a user interaction notification for WebContentsObservers.
// This is used for browser features such as download request limiting and
// launching multiple external protocol handlers, which can block repeated
// actions from a page when a user is not interacting with the page.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       UserInteractionForChildFrameTest) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  SimulateEndOfPaintHoldingOnPrimaryMainFrame(web_contents());

  UserInteractionObserver observer(web_contents());

  // Target an event to the child frame's RenderWidgetHostView.
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  SimulateMouseClick(
      root->child_at(0)->current_frame_host()->GetRenderWidgetHost(), 5, 5);

  EXPECT_TRUE(observer.WasUserInteractionReceived());

  // Target an event to the main frame.
  observer.Reset();
  SimulateMouseClick(root->current_frame_host()->GetRenderWidgetHost(), 1, 1);

  EXPECT_TRUE(observer.WasUserInteractionReceived());
}

// Ensures that navigating to data: URLs present in session history will
// correctly commit the navigation in the same process as the one used for the
// original navigation. See https://crbug.com/606996.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       NavigateSubframeToDataUrlInSessionHistory) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b,b)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  EXPECT_EQ(2U, root->child_count());
  EXPECT_EQ(
      " Site A ------------ proxies for B\n"
      "   |--Site B ------- proxies for A\n"
      "   +--Site B ------- proxies for A\n"
      "Where A = http://a.com/\n"
      "      B = http://b.com/",
      DepictFrameTree(root));

  TestNavigationObserver observer(shell()->web_contents());
  FrameTreeNode* child = root->child_at(0);

  // Navigate iframe to a data URL, which will commit in a new SiteInstance.
  GURL data_url("data:text/html,dataurl");
  EXPECT_TRUE(NavigateToURLFromRenderer(child, data_url));
  EXPECT_TRUE(observer.last_navigation_succeeded());
  EXPECT_EQ(data_url, observer.last_navigation_url());
  scoped_refptr<SiteInstanceImpl> orig_site_instance =
      child->current_frame_host()->GetSiteInstance();
  EXPECT_NE(root->current_frame_host()->GetSiteInstance(), orig_site_instance);

  // Navigate it to another cross-site url.
  GURL cross_site_url(embedded_test_server()->GetURL("c.com", "/title1.html"));
  EXPECT_TRUE(NavigateToURLFromRenderer(child, cross_site_url));
  EXPECT_TRUE(observer.last_navigation_succeeded());
  EXPECT_EQ(cross_site_url, observer.last_navigation_url());
  EXPECT_EQ(3, web_contents()->GetController().GetEntryCount());
  EXPECT_NE(orig_site_instance, child->current_frame_host()->GetSiteInstance());

  // Go back and ensure the data: URL committed in the same SiteInstance as the
  // original navigation.
  EXPECT_TRUE(web_contents()->GetController().CanGoBack());
  TestFrameNavigationObserver frame_observer(child);
  web_contents()->GetController().GoBack();
  frame_observer.WaitForCommit();
  EXPECT_EQ(orig_site_instance, child->current_frame_host()->GetSiteInstance());
}

// The site URL for a data: URL is the scheme + the serialized nonce from the
// origin. This means that two data: URLs with the same body will have different
// site URLs.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest, DataUrlsHaveUniqueSiteURLs) {
  // Force process reuse for same-site URLs, to test whether identical data:
  // URLs share a process with each other.
  RenderProcessHost::SetMaxRendererProcessCount(1);

  // Load a main frame data: URL.
  GURL data_url("data:text/html,dataurl");
  EXPECT_TRUE(NavigateToURL(shell(), data_url));

  // Open another tab, then load the same data: URL in that tab. We need to
  // first navigate the new tab to a different page, a_url.
  // Shell::CreateNewWindow opens a new tab to about:blank, then loads the URL
  // passed in. Since the about:blank is in a new tab, it gets a new process,
  // and the passed-in URL keeps using that about:blank process. By navigating
  // from a_url to the data: URL, we exercise the flow that will reuse the
  // existing data: URL process, if possible.
  GURL a_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
  ShellAddedObserver new_shell_observer;
  Shell* new_shell =
      Shell::CreateNewWindow(static_cast<NavigationControllerImpl&>(
                                 shell()->web_contents()->GetController())
                                 .GetBrowserContext(),
                             a_url, nullptr, gfx::Size());
  auto* new_contents = static_cast<WebContentsImpl*>(new_shell->web_contents());
  EXPECT_TRUE(WaitForLoadStop(new_contents));
  EXPECT_TRUE(NavigateToURL(new_shell, data_url));

  auto* main_frame = shell()->web_contents()->GetPrimaryMainFrame();
  auto* new_frame = new_shell->web_contents()->GetPrimaryMainFrame();
  GURL main_url = main_frame->GetSiteInstance()->GetSiteURL();
  GURL new_url = new_frame->GetSiteInstance()->GetSiteURL();
  EXPECT_NE(new_frame->GetSiteInstance(), main_frame->GetSiteInstance());

  // The site URL is the data scheme followed by a serialized nonce, which is
  // unique for every data: URL instance.
  EXPECT_NE(main_url, new_url);
  EXPECT_TRUE(main_url.SchemeIs(url::kDataScheme));
  EXPECT_EQ(new_url.GetContent().length(),
            base::UnguessableToken::Create().ToString().length());
  EXPECT_NE(new_frame->GetProcess(), main_frame->GetProcess());
}

// Ensures that subframes navigated to data: URLs start in a process based on
// their creator, but end up in unique processes after a restore (since
// SiteInstance relationships are not preserved on restore, until
// https://crbug.com/14987 is fixed).  This is better than restoring into the
// parent process, per https://crbug.com/863069.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       SubframeDataUrlsAfterRestore) {
  // We must use a page that has iframes in the HTML here, unlike
  // cross_site_iframe_factory.html which loads them dynamically.  In the latter
  // case, Chrome will not restore subframe URLs from history, which is needed
  // for this test.
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/frame_tree/page_with_two_iframes.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  EXPECT_EQ(2U, root->child_count());
  EXPECT_EQ(
      " Site A ------------ proxies for B C\n"
      "   |--Site B ------- proxies for A C\n"
      "   +--Site C ------- proxies for A B\n"
      "Where A = http://a.com/\n"
      "      B = http://bar.com/\n"
      "      C = http://baz.com/",
      DepictFrameTree(root));

  FrameTreeNode* child_0 = root->child_at(0);
  FrameTreeNode* child_1 = root->child_at(1);
  scoped_refptr<SiteInstanceImpl> child_site_instance_0 =
      child_0->current_frame_host()->GetSiteInstance();
  scoped_refptr<SiteInstanceImpl> child_site_instance_1 =
      child_1->current_frame_host()->GetSiteInstance();

  // Navigate the iframes to data URLs via renderer initiated navigations, which
  // will commit in the existing SiteInstanceGroups.
  TestNavigationObserver observer(shell()->web_contents());
  GURL data_url_0("data:text/html,dataurl_0");
  {
    TestFrameNavigationObserver commit_observer(child_0);
    EXPECT_TRUE(ExecJs(child_0, JsReplace("location.href = $1", data_url_0)));
    commit_observer.WaitForCommit();
  }
  EXPECT_TRUE(observer.last_navigation_succeeded());
  EXPECT_EQ(data_url_0, observer.last_navigation_url());

  if (ShouldCreateSiteInstanceForDataUrls()) {
    EXPECT_NE(child_site_instance_0,
              child_0->current_frame_host()->GetSiteInstance());
    EXPECT_EQ(child_site_instance_0->group(),
              child_0->current_frame_host()->GetSiteInstance()->group());
  } else {
    EXPECT_EQ(child_site_instance_0,
              child_0->current_frame_host()->GetSiteInstance());
  }

  GURL data_url_1("data:text/html,dataurl_1");
  {
    TestFrameNavigationObserver commit_observer(child_1);
    EXPECT_TRUE(ExecJs(child_1, JsReplace("location.href = $1", data_url_1)));
    commit_observer.WaitForCommit();
  }
  EXPECT_TRUE(observer.last_navigation_succeeded());
  EXPECT_EQ(data_url_1, observer.last_navigation_url());

  if (ShouldCreateSiteInstanceForDataUrls()) {
    EXPECT_NE(child_site_instance_1,
              child_1->current_frame_host()->GetSiteInstance());
    EXPECT_EQ(child_site_instance_1->group(),
              child_1->current_frame_host()->GetSiteInstance()->group());
  } else {
    EXPECT_EQ(child_site_instance_1,
              child_1->current_frame_host()->GetSiteInstance());
  }

  // Grab the NavigationEntry and clone its PageState into a new entry for
  // restoring into a new tab.
  NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>(
      shell()->web_contents()->GetController());
  NavigationEntryImpl* entry = controller.GetLastCommittedEntry();
  std::unique_ptr<NavigationEntryImpl> restored_entry =
      NavigationEntryImpl::FromNavigationEntry(
          NavigationController::CreateNavigationEntry(
              main_url, Referrer(), /* initiator_origin= */ std::nullopt,
              /* initiator_base_url= */ std::nullopt,
              ui::PAGE_TRANSITION_RELOAD, false, std::string(),
              controller.GetBrowserContext(),
              nullptr /* blob_url_loader_factory */));
  EXPECT_EQ(0U, restored_entry->root_node()->children.size());
  NavigationEntryRestoreContextImpl context;
  restored_entry->SetPageState(entry->GetPageState(), &context);
  ASSERT_EQ(2U, restored_entry->root_node()->children.size());

  // Restore the NavigationEntry into a new tab and check that the data URLs are
  // not loaded into the parent's SiteInstance.
  std::vector<std::unique_ptr<NavigationEntry>> entries;
  entries.push_back(std::move(restored_entry));
  Shell* new_shell = Shell::CreateNewWindow(controller.GetBrowserContext(),
                                            GURL(), nullptr, gfx::Size());
  FrameTreeNode* new_root =
      static_cast<WebContentsImpl*>(new_shell->web_contents())
          ->GetPrimaryFrameTree()
          .root();
  NavigationControllerImpl& new_controller =
      static_cast<NavigationControllerImpl&>(
          new_shell->web_contents()->GetController());
  new_controller.Restore(entries.size() - 1, RestoreType::kRestored, &entries);
  ASSERT_EQ(0u, entries.size());
  {
    TestNavigationObserver restore_observer(new_shell->web_contents());
    new_controller.LoadIfNecessary();
    restore_observer.Wait();
  }
  ASSERT_EQ(2U, new_root->child_count());
  EXPECT_EQ(main_url, new_root->current_url());
  EXPECT_EQ("data", new_root->child_at(0)->current_url().scheme());
  EXPECT_EQ("data", new_root->child_at(1)->current_url().scheme());

  EXPECT_NE(new_root->current_frame_host()->GetSiteInstance(),
            new_root->child_at(0)->current_frame_host()->GetSiteInstance());
  EXPECT_NE(new_root->current_frame_host()->GetSiteInstance(),
            new_root->child_at(1)->current_frame_host()->GetSiteInstance());
  EXPECT_NE(new_root->child_at(0)->current_frame_host()->GetSiteInstance(),
            new_root->child_at(1)->current_frame_host()->GetSiteInstance());
}

// Similar to SubframeDataUrlsAfterRestore. Ensures that about:blank frames
// are not put into their parent process after restore if their initiator origin
// is different from the parent.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       SubframeBlankUrlsAfterRestore) {
  // We must use a page that has iframes in the HTML here, unlike
  // cross_site_iframe_factory.html which loads them dynamically.  In the latter
  // case, Chrome will not restore subframe URLs from history, which is needed
  // for this test.
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/frame_tree/page_with_two_iframes.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  EXPECT_EQ(2U, root->child_count());
  EXPECT_EQ(
      " Site A ------------ proxies for B C\n"
      "   |--Site B ------- proxies for A C\n"
      "   +--Site C ------- proxies for A B\n"
      "Where A = http://a.com/\n"
      "      B = http://bar.com/\n"
      "      C = http://baz.com/",
      DepictFrameTree(root));

  FrameTreeNode* child_0 = root->child_at(0);
  FrameTreeNode* child_1 = root->child_at(1);
  scoped_refptr<SiteInstanceImpl> child_site_instance_0 =
      child_0->current_frame_host()->GetSiteInstance();
  scoped_refptr<SiteInstanceImpl> child_site_instance_1 =
      child_1->current_frame_host()->GetSiteInstance();

  // Navigate the iframes to about:blank URLs via renderer initiated
  // navigations, which will commit in the existing SiteInstances.
  TestNavigationObserver observer(shell()->web_contents());
  GURL blank_url("about:blank");
  {
    TestFrameNavigationObserver commit_observer(child_0);
    EXPECT_TRUE(ExecJs(child_0, JsReplace("location.href = $1", blank_url)));
    commit_observer.WaitForCommit();
  }
  EXPECT_TRUE(observer.last_navigation_succeeded());
  EXPECT_EQ(blank_url, observer.last_navigation_url());
  EXPECT_EQ(child_site_instance_0,
            child_0->current_frame_host()->GetSiteInstance());

  GURL blank_url_ref("about:blank#1");
  {
    TestFrameNavigationObserver commit_observer(child_1);
    EXPECT_TRUE(
        ExecJs(child_1, JsReplace("location.href = $1", blank_url_ref)));
    commit_observer.WaitForCommit();
  }
  EXPECT_TRUE(observer.last_navigation_succeeded());
  EXPECT_EQ(blank_url_ref, observer.last_navigation_url());
  EXPECT_EQ(child_site_instance_1,
            child_1->current_frame_host()->GetSiteInstance());

  // Grab the NavigationEntry and clone its PageState into a new entry for
  // restoring into a new tab.
  NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>(
      shell()->web_contents()->GetController());
  NavigationEntryImpl* entry = controller.GetLastCommittedEntry();
  std::unique_ptr<NavigationEntryImpl> restored_entry =
      NavigationEntryImpl::FromNavigationEntry(
          NavigationController::CreateNavigationEntry(
              main_url, Referrer(), /* initiator_origin= */ std::nullopt,
              /* initiator_base_url= */ std::nullopt,
              ui::PAGE_TRANSITION_RELOAD, false, std::string(),
              controller.GetBrowserContext(),
              nullptr /* blob_url_loader_factory */));
  EXPECT_EQ(0U, restored_entry->root_node()->children.size());
  NavigationEntryRestoreContextImpl context;
  restored_entry->SetPageState(entry->GetPageState(), &context);
  ASSERT_EQ(2U, restored_entry->root_node()->children.size());

  // Restore the NavigationEntry into a new tab and check that the about:blank
  // URLs are not loaded into the parent's SiteInstance.
  std::vector<std::unique_ptr<NavigationEntry>> entries;
  entries.push_back(std::move(restored_entry));
  Shell* new_shell = Shell::CreateNewWindow(controller.GetBrowserContext(),
                                            GURL(), nullptr, gfx::Size());
  FrameTreeNode* new_root =
      static_cast<WebContentsImpl*>(new_shell->web_contents())
          ->GetPrimaryFrameTree()
          .root();
  NavigationControllerImpl& new_controller =
      static_cast<NavigationControllerImpl&>(
          new_shell->web_contents()->GetController());
  new_controller.Restore(entries.size() - 1, RestoreType::kRestored, &entries);
  ASSERT_EQ(0u, entries.size());
  {
    TestNavigationObserver restore_observer(new_shell->web_contents());
    new_controller.LoadIfNecessary();
    restore_observer.Wait();
  }
  ASSERT_EQ(2U, new_root->child_count());
  EXPECT_EQ(main_url, new_root->current_url());
  auto* new_child_0 = new_root->child_at(0);
  auto* new_child_1 = new_root->child_at(1);
  EXPECT_TRUE(new_child_0->current_url().IsAboutBlank());
  EXPECT_TRUE(new_child_1->current_url().IsAboutBlank());

  // Restored frames should retain the origin from before restoring.
  EXPECT_EQ(new_root->current_frame_host()->GetLastCommittedOrigin(),
            root->current_frame_host()->GetLastCommittedOrigin());
  EXPECT_EQ(new_child_0->current_frame_host()
                ->GetLastCommittedOrigin()
                .GetTupleOrPrecursorTupleIfOpaque(),
            child_0->current_frame_host()
                ->GetLastCommittedOrigin()
                .GetTupleOrPrecursorTupleIfOpaque());
  EXPECT_EQ(new_child_1->current_frame_host()
                ->GetLastCommittedOrigin()
                .GetTupleOrPrecursorTupleIfOpaque(),
            child_1->current_frame_host()
                ->GetLastCommittedOrigin()
                .GetTupleOrPrecursorTupleIfOpaque());
  EXPECT_NE(child_0->current_frame_host()
                ->GetLastCommittedOrigin()
                .GetTupleOrPrecursorTupleIfOpaque(),
            child_1->current_frame_host()
                ->GetLastCommittedOrigin()
                .GetTupleOrPrecursorTupleIfOpaque());

  // Origin for child frames should match the navigation initiators.
  EXPECT_EQ(
      new_root->current_frame_host()->GetLastCommittedOrigin().Serialize(),
      GetOriginFromRenderer(new_root));
  EXPECT_EQ(GetExpectedOrigin("bar.com"), GetOriginFromRenderer(new_child_0));
  EXPECT_EQ(GetExpectedOrigin("baz.com"), GetOriginFromRenderer(new_child_1));

  // Since the origin for the frames are different, they all end up in different
  // SiteInstances.
  EXPECT_NE(new_root->current_frame_host()->GetSiteInstance(),
            new_child_0->current_frame_host()->GetSiteInstance());
  EXPECT_NE(new_root->current_frame_host()->GetSiteInstance(),
            new_child_1->current_frame_host()->GetSiteInstance());
  EXPECT_NE(new_child_0->current_frame_host()->GetSiteInstance(),
            new_child_1->current_frame_host()->GetSiteInstance());
}

// Similar to SubframeBlankUrlsAfterRestore, but ensures that about:srcdoc ends
// up in its parent's process after restore, since that's where its content
// comes from.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       SubframeSrcdocUrlAfterRestore) {
  // Load a page that uses iframe srcdoc.
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/frame_tree/page_with_srcdoc_frame.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  EXPECT_EQ(1U, root->child_count());
  FrameTreeNode* child = root->child_at(0);
  scoped_refptr<SiteInstanceImpl> child_site_instance =
      child->current_frame_host()->GetSiteInstance();
  EXPECT_EQ(child_site_instance, root->current_frame_host()->GetSiteInstance());

  // Grab the NavigationEntry and clone its PageState into a new entry for
  // restoring into a new tab.
  NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>(
      shell()->web_contents()->GetController());
  NavigationEntryImpl* entry = controller.GetLastCommittedEntry();
  std::unique_ptr<NavigationEntryImpl> restored_entry =
      NavigationEntryImpl::FromNavigationEntry(
          NavigationController::CreateNavigationEntry(
              main_url, Referrer(), /* initiator_origin= */ std::nullopt,
              /* initiator_base_url= */ std::nullopt,
              ui::PAGE_TRANSITION_RELOAD, false, std::string(),
              controller.GetBrowserContext(),
              nullptr /* blob_url_loader_factory */));
  EXPECT_EQ(0U, restored_entry->root_node()->children.size());
  NavigationEntryRestoreContextImpl context;
  restored_entry->SetPageState(entry->GetPageState(), &context);
  ASSERT_EQ(1U, restored_entry->root_node()->children.size());

  // Restore the NavigationEntry into a new tab and check that the srcdoc URLs
  // are still loaded into the parent's SiteInstance.
  std::vector<std::unique_ptr<NavigationEntry>> entries;
  entries.push_back(std::move(restored_entry));
  Shell* new_shell = Shell::CreateNewWindow(controller.GetBrowserContext(),
                                            GURL(), nullptr, gfx::Size());
  FrameTreeNode* new_root =
      static_cast<WebContentsImpl*>(new_shell->web_contents())
          ->GetPrimaryFrameTree()
          .root();
  NavigationControllerImpl& new_controller =
      static_cast<NavigationControllerImpl&>(
          new_shell->web_contents()->GetController());
  new_controller.Restore(entries.size() - 1, RestoreType::kRestored, &entries);
  ASSERT_EQ(0u, entries.size());
  {
    TestNavigationObserver restore_observer(new_shell->web_contents());
    new_controller.LoadIfNecessary();
    restore_observer.Wait();
  }
  ASSERT_EQ(1U, new_root->child_count());
  EXPECT_EQ(main_url, new_root->current_url());
  EXPECT_TRUE(new_root->child_at(0)->current_url().IsAboutSrcdoc());
  // Not only should the srcdoc inherit its base url from its initiator, but it
  // should also be properly restored from the session history.
  EXPECT_EQ(
      main_url,
      GURL(EvalJs(new_root->child_at(0), "document.baseURI").ExtractString()));

  EXPECT_EQ(new_root->current_frame_host()->GetSiteInstance(),
            new_root->child_at(0)->current_frame_host()->GetSiteInstance());
}

// Ensures that navigating to about:blank URLs present in session history will
// correctly commit the navigation in the same process as the one used for
// the original navigation.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       NavigateSubframeToAboutBlankInSessionHistory) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b,b)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  EXPECT_EQ(2U, root->child_count());
  EXPECT_EQ(
      " Site A ------------ proxies for B\n"
      "   |--Site B ------- proxies for A\n"
      "   +--Site B ------- proxies for A\n"
      "Where A = http://a.com/\n"
      "      B = http://b.com/",
      DepictFrameTree(root));

  TestNavigationObserver observer(shell()->web_contents());
  FrameTreeNode* child = root->child_at(0);

  // Navigate iframe to about:blank, which will commit in a new SiteInstance.
  GURL about_blank_url("about:blank");
  EXPECT_TRUE(NavigateToURLFromRenderer(child, about_blank_url));
  EXPECT_TRUE(observer.last_navigation_succeeded());
  EXPECT_EQ(about_blank_url, observer.last_navigation_url());
  scoped_refptr<SiteInstanceImpl> orig_site_instance =
    child->current_frame_host()->GetSiteInstance();
  EXPECT_NE(root->current_frame_host()->GetSiteInstance(), orig_site_instance);

  // Navigate it to another cross-site url.
  GURL cross_site_url(embedded_test_server()->GetURL("c.com", "/title1.html"));
  EXPECT_TRUE(NavigateToURLFromRenderer(child, cross_site_url));
  EXPECT_TRUE(observer.last_navigation_succeeded());
  EXPECT_EQ(cross_site_url, observer.last_navigation_url());
  EXPECT_EQ(3, web_contents()->GetController().GetEntryCount());
  EXPECT_NE(orig_site_instance, child->current_frame_host()->GetSiteInstance());

  // Go back and ensure the about:blank URL committed in the same SiteInstance
  // as the original navigation.
  EXPECT_TRUE(web_contents()->GetController().CanGoBack());
  TestFrameNavigationObserver frame_observer(child);
  web_contents()->GetController().GoBack();
  frame_observer.WaitForCommit();
  EXPECT_EQ(orig_site_instance, child->current_frame_host()->GetSiteInstance());
}

// Intercepts calls to LocalMainFrame's ShowCreatedWindow mojo method, and
// invokes the provided callback.
class ShowCreatedWindowInterceptor
    : public blink::mojom::LocalMainFrameHostInterceptorForTesting {
 public:
  // The caller has to guarantee that `render_frame_host` lives at least as long
  // as ShowCreatedWindowInterceptor.
  ShowCreatedWindowInterceptor(
      RenderFrameHostImpl* render_frame_host,
      base::OnceCallback<void(int32_t pending_widget_routing_id)> test_callback)
      : render_frame_host_(render_frame_host),
        test_callback_(std::move(test_callback)),
        swapped_impl_(
            render_frame_host_->local_main_frame_host_receiver_for_testing(),
            this) {}

  ~ShowCreatedWindowInterceptor() override = default;

  blink::mojom::LocalMainFrameHost* GetForwardingInterface() override {
    return swapped_impl_.old_impl();
  }

  void ShowCreatedWindow(const blink::LocalFrameToken& opener_frame_token,
                         WindowOpenDisposition disposition,
                         blink::mojom::WindowFeaturesPtr window_features,
                         bool user_gesture,
                         ShowCreatedWindowCallback callback) override {
    show_callback_ = std::move(callback);
    opener_frame_token_ = opener_frame_token;
    user_gesture_ = user_gesture;
    window_features_ = std::move(window_features);
    disposition_ = disposition;
    std::move(test_callback_)
        .Run(render_frame_host_->GetRenderWidgetHost()->GetRoutingID());
  }

  void ResumeShowCreatedWindow() {
    GetForwardingInterface()->ShowCreatedWindow(
        opener_frame_token_, disposition_, std::move(window_features_),
        user_gesture_, std::move(show_callback_));
  }

 private:
  raw_ptr<RenderFrameHostImpl> render_frame_host_;
  base::OnceCallback<void(int32_t pending_widget_routing_id)> test_callback_;
  ShowCreatedWindowCallback show_callback_;
  blink::LocalFrameToken opener_frame_token_;
  blink::mojom::WindowFeaturesPtr window_features_;
  bool user_gesture_ = false;
  WindowOpenDisposition disposition_;
  mojo::test::ScopedSwapImplForTesting<blink::mojom::LocalMainFrameHost>
      swapped_impl_;
};

// Listens for the source WebContents opening the new WebContents then attaches
// a show listener to the widget.
class NewWindowCreatedObserver : public WebContentsObserver {
 public:
  NewWindowCreatedObserver(
      WebContents* web_contents,
      base::OnceCallback<void(int32_t pending_widget_routing_id)> test_callback)
      : WebContentsObserver(web_contents),
        test_callback_(std::move(test_callback)) {}

  // WebContentsObserver overrides.
  void DidOpenRequestedURL(WebContents* new_contents,
                           RenderFrameHost* source_render_frame_host,
                           const GURL& url,
                           const Referrer& referrer,
                           WindowOpenDisposition disposition,
                           ui::PageTransition transition,
                           bool started_from_context_menu,
                           bool renderer_initiated) override {
    show_interceptor_ = std::make_unique<ShowCreatedWindowInterceptor>(
        static_cast<RenderFrameHostImpl*>(new_contents->GetPrimaryMainFrame()),
        std::move(test_callback_));

    // Stop observing now.
    Observe(nullptr);
  }

  void ResumeShowCreatedWindow() {
    show_interceptor_->ResumeShowCreatedWindow();
  }

 private:
  std::unique_ptr<ShowCreatedWindowInterceptor> show_interceptor_;
  base::OnceCallback<void(int32_t pending_widget_routing_id)> test_callback_;
};

// Test for https://crbug.com/612276.  Simultaneously open two new windows from
// two subframes in different processes, where each subframe process's next
// routing ID is the same.  Make sure that both windows are created properly.
//
// Each new window requires two IPCs to first create it (handled by
// CreateNewWindow) and then show it (ShowCreatedWindow).  In the bug, both
// CreateNewWindow calls arrived before the ShowCreatedWindow calls, resulting
// in the two pending windows colliding in the pending WebContents map, which
// used to be keyed only by routing_id.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       TwoSubframesCreatePopupsSimultaneously) {
  // This test covers a scenario which can only happen when creating and showing
  // a new window is split between to IPC's and some conflicting update happens
  // between them. kCombineNewWindowIPCs eliminates this possibility by
  // combining the function of the two IPC's into one.
  if (base::FeatureList::IsEnabled(blink::features::kCombineNewWindowIPCs)) {
    return;
  }
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b,c)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  FrameTreeNode* child1 = root->child_at(0);
  FrameTreeNode* child2 = root->child_at(1);
  RenderFrameHostImpl* frame1 = child1->current_frame_host();
  RenderFrameHostImpl* frame2 = child2->current_frame_host();
  RenderProcessHost* process1 = frame1->GetProcess();
  RenderProcessHost* process2 = frame2->GetProcess();

  // Call window.open simultaneously in both subframes to create two popups.
  // Wait for and then drop both ShowCreatedWindow messages.  This will ensure
  // that both CreateNewWindow calls happen before either ShowCreatedWindow
  // call.
  base::RunLoop run_loop1;
  int32_t routing_id1;
  NewWindowCreatedObserver interceptor1(
      web_contents(),
      base::BindLambdaForTesting([&](int32_t pending_widget_routing_id) {
        routing_id1 = pending_widget_routing_id;
        run_loop1.Quit();
      }));
  EXPECT_TRUE(ExecJs(child1, "window.open();"));
  run_loop1.Run();

  base::RunLoop run_loop2;
  int32_t routing_id2;
  NewWindowCreatedObserver interceptor2(
      web_contents(),
      base::BindLambdaForTesting([&](int32_t pending_widget_routing_id) {
        routing_id2 = pending_widget_routing_id;
        run_loop2.Quit();
      }));

  EXPECT_TRUE(ExecJs(child2, "window.open();"));
  run_loop2.Run();

  // At this point, we should have two pending WebContents.
  EXPECT_TRUE(base::Contains(
      web_contents()->pending_contents_,
      GlobalRoutingID(process1->GetDeprecatedID(), routing_id1)));
  EXPECT_TRUE(base::Contains(
      web_contents()->pending_contents_,
      GlobalRoutingID(process2->GetDeprecatedID(), routing_id2)));

  // Both subframes were set up in the same way, so the next routing ID for the
  // new popup windows should match up (this led to the collision in the
  // pending contents map in the original bug).
  EXPECT_EQ(routing_id1, routing_id2);

  // Now, resuming processing the show messages.
  interceptor1.ResumeShowCreatedWindow();
  interceptor2.ResumeShowCreatedWindow();

  // Verify that both shells were properly created.
  EXPECT_EQ(3u, Shell::windows().size());
}

// Intercepts calls to PopupWidgetHost's ShowPopup mojo method, and
// invokes the provided callback. The caller has to guarantee that
// `render_widget_host` lives at least as long as
// ShowCreatedPopupWidgetInterceptor.
class ShowCreatedPopupWidgetInterceptor
    : public blink::mojom::PopupWidgetHostInterceptorForTesting {
 public:
  ShowCreatedPopupWidgetInterceptor(
      RenderWidgetHostImpl* render_widget_host,
      base::OnceCallback<void(int32_t pending_widget_routing_id)> test_callback)
      : render_widget_host_(render_widget_host),
        test_callback_(std::move(test_callback)),
        swapped_impl_(
            render_widget_host_->popup_widget_host_receiver_for_testing(),
            this) {}

  ~ShowCreatedPopupWidgetInterceptor() override = default;

  blink::mojom::PopupWidgetHost* GetForwardingInterface() override {
    return swapped_impl_.old_impl();
  }

  void ShowPopup(const gfx::Rect& initial_rect,
                 const gfx::Rect& initial_anchor_rect,
                 ShowPopupCallback callback) override {
    show_callback_ = std::move(callback);
    initial_rect_ = initial_rect;
    std::move(test_callback_).Run(render_widget_host_->GetRoutingID());
  }

  void ResumeShowPopupWidget() {
    // Let anchor have same origin as bounds, but its width and height should be
    // 1,1 as RenderWidgetHostViewAura sets OwnedWindowAnchorPosition as
    // kBottomLeft. Otherwise, the bottom left point of the |initial_rect|'s
    // size is going to be used as the origin of a popup.
    gfx::Rect anchor = initial_rect_;
    anchor.set_size({1, 1});
    GetForwardingInterface()->ShowPopup(initial_rect_, anchor,
                                        std::move(show_callback_));
  }

 private:
  raw_ptr<RenderWidgetHostImpl> render_widget_host_;
  base::OnceCallback<void(int32_t pending_widget_routing_id)> test_callback_;
  ShowPopupCallback show_callback_;
  gfx::Rect initial_rect_;
  mojo::test::ScopedSwapImplForTesting<blink::mojom::PopupWidgetHost>
      swapped_impl_;
};

// Listens for the source RenderFrameHost opening the new popup widget then
// attaches a show listener to the widget.
class NewPopupWidgetCreatedObserver {
 public:
  NewPopupWidgetCreatedObserver(
      RenderFrameHostImpl* frame_host,
      base::OnceCallback<void(int32_t pending_widget_routing_id)> test_callback)
      : create_new_popup_widget_interceptor_(
            frame_host,
            base::BindOnce(&NewPopupWidgetCreatedObserver::DidCreatePopupWidget,
                           base::Unretained(this))),
        test_callback_(std::move(test_callback)) {}

  void ResumeShowPopupWidget() { show_interceptor_->ResumeShowPopupWidget(); }

 private:
  void DidCreatePopupWidget(RenderWidgetHost* widget) {
    show_interceptor_ = std::make_unique<ShowCreatedPopupWidgetInterceptor>(
        static_cast<RenderWidgetHostImpl*>(widget), std::move(test_callback_));
  }

  CreateNewPopupWidgetInterceptor create_new_popup_widget_interceptor_;
  std::unique_ptr<ShowCreatedPopupWidgetInterceptor> show_interceptor_;
  base::OnceCallback<void(int32_t pending_widget_routing_id)> test_callback_;
};

// Test for https://crbug.com/612276.  Similar to
// TwoSubframesOpenWindowsSimultaneously, but use popup menu widgets instead of
// windows.
//
// The plumbing that this test is verifying is not utilized on Mac/Android,
// where popup menus don't create a popup RenderWidget, but rather they trigger
// a FrameHostMsg_ShowPopup to ask the browser to build and display the actual
// popup using native controls.
#if !BUILDFLAG(IS_MAC) && !BUILDFLAG(IS_ANDROID)
// Disable the test due to flaky: https://crbug.com/1126165
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
#define MAYBE_TwoSubframesCreatePopupMenuWidgetsSimultaneously \
  DISABLED_TwoSubframesCreatePopupMenuWidgetsSimultaneously
#else
#define MAYBE_TwoSubframesCreatePopupMenuWidgetsSimultaneously \
  TwoSubframesCreatePopupMenuWidgetsSimultaneously
#endif
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       MAYBE_TwoSubframesCreatePopupMenuWidgetsSimultaneously) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b,c)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  FrameTreeNode* child1 = root->child_at(0);
  FrameTreeNode* child2 = root->child_at(1);
  RenderProcessHost* process1 = child1->current_frame_host()->GetProcess();
  RenderProcessHost* process2 = child2->current_frame_host()->GetProcess();

  // Navigate both subframes to a page with a <select> element.
  EXPECT_TRUE(NavigateToURLFromRenderer(
      child1, embedded_test_server()->GetURL(
                  "b.com", "/site_isolation/page-with-select.html")));
  EXPECT_TRUE(NavigateToURLFromRenderer(
      child2, embedded_test_server()->GetURL(
                  "c.com", "/site_isolation/page-with-select.html")));

  // Open both <select> menus by focusing each item and sending a space key
  // at the focused node. This creates a popup widget in both processes.
  // Wait for and then drop the ViewHostMsg_ShowWidget messages, so that both
  // widgets are left in pending-but-not-shown state.
  input::NativeWebKeyboardEvent event(
      blink::WebKeyboardEvent::Type::kChar, blink::WebInputEvent::kNoModifiers,
      blink::WebInputEvent::GetStaticTimeStampForTests());
  event.text[0] = ' ';

  base::RunLoop run_loop1;
  int32_t routing_id1;
  NewPopupWidgetCreatedObserver interceptor1(
      child1->current_frame_host(),
      base::BindLambdaForTesting([&](int32_t pending_widget_routing_id) {
        routing_id1 = pending_widget_routing_id;
        run_loop1.Quit();
      }));
  EXPECT_TRUE(ExecJs(child1, "focusSelectMenu();"));
  child1->current_frame_host()->GetRenderWidgetHost()->ForwardKeyboardEvent(
      event);
  run_loop1.Run();

  auto first_popup_global_id =
      GlobalRoutingID(process1->GetDeprecatedID(), routing_id1);
  // Add an interceptor for first popup widget so it doesn't get closed
  // immediately while the other one is being opened.
  EXPECT_TRUE(
      base::Contains(web_contents()->pending_widgets_, first_popup_global_id));

  RequestCloseWidgetInterceptor child1_popup_widget_interceptor(
      static_cast<RenderWidgetHostImpl*>(
          web_contents()->pending_widgets_[first_popup_global_id]));

  base::RunLoop run_loop2;
  int32_t routing_id2;
  NewPopupWidgetCreatedObserver interceptor2(
      child2->current_frame_host(),
      base::BindLambdaForTesting([&](int32_t pending_widget_routing_id) {
        routing_id2 = pending_widget_routing_id;
        run_loop2.Quit();
      }));
  EXPECT_TRUE(ExecJs(child2, "focusSelectMenu();"));
  child2->current_frame_host()->GetRenderWidgetHost()->ForwardKeyboardEvent(
      event);
  run_loop2.Run();

  // At this point, we should have two pending widgets.
  EXPECT_TRUE(
      base::Contains(web_contents()->pending_widgets_, first_popup_global_id));
  EXPECT_TRUE(base::Contains(
      web_contents()->pending_widgets_,
      GlobalRoutingID(process2->GetDeprecatedID(), routing_id2)));

  // Both subframes were set up in the same way, so the next routing ID for the
  // new popup widgets should match up (this led to the collision in the
  // pending widgets map in the original bug).
  EXPECT_EQ(routing_id1, routing_id2);

  // Now simulate both widgets being shown.
  interceptor1.ResumeShowPopupWidget();
  interceptor2.ResumeShowPopupWidget();
  EXPECT_FALSE(base::Contains(
      web_contents()->pending_widgets_,
      GlobalRoutingID(process1->GetDeprecatedID(), routing_id1)));
  EXPECT_FALSE(base::Contains(
      web_contents()->pending_widgets_,
      GlobalRoutingID(process2->GetDeprecatedID(), routing_id2)));

  // There are posted tasks that must be run before the test shuts down, lest
  // they access deleted state.
  RunPostedTasks();
}
#endif

// Test for https://crbug.com/615575. It ensures that file chooser triggered
// by a document in an out-of-process subframe works properly.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest, FileChooserInSubframe) {
  EXPECT_TRUE(NavigateToURL(shell(), embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)")));
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();

  GURL url(embedded_test_server()->GetURL("b.com", "/file_input.html"));
  EXPECT_TRUE(NavigateToURLFromRenderer(root->child_at(0), url));

  // Use FileChooserDelegate to avoid showing the actual dialog and to respond
  // back to the renderer process with predefined file.
  base::RunLoop run_loop;
  base::FilePath file;
  EXPECT_TRUE(base::PathService::Get(base::DIR_TEMP, &file));
  file = file.AppendASCII("bar");
  std::unique_ptr<FileChooserDelegate> delegate(
      new FileChooserDelegate(file, run_loop.QuitClosure()));
  shell()->web_contents()->SetDelegate(delegate.get());
  EXPECT_TRUE(ExecJs(root->child_at(0),
                     "document.getElementById('fileinput').click();"));
  run_loop.Run();

  // Also, extract the file from the renderer process to ensure that the
  // response made it over successfully and the proper filename is set.
  EXPECT_EQ("bar",
            EvalJs(root->child_at(0),
                   "document.getElementById('fileinput').files[0].name;"));
}

// Test that the pending RenderFrameHost is canceled and destroyed when its
// process dies. Previously, reusing a top-level pending RFH which
// is not live was hitting a CHECK in CreateRenderView due to having neither a
// main frame routing ID nor a proxy routing ID.  See https://crbug.com/627400
// for more details.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       PendingRFHIsCanceledWhenItsProcessDies) {
  GURL main_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();

  // Open a popup at b.com.
  GURL popup_url(embedded_test_server()->GetURL("b.com", "/title1.html"));
  Shell* popup_shell = OpenPopup(root, popup_url, "foo");
  EXPECT_TRUE(popup_shell);

  // The RenderViewHost for b.com in the main tab should not be active.
  SiteInstanceGroup* b_group =
      static_cast<SiteInstanceImpl*>(
          popup_shell->web_contents()->GetSiteInstance())
          ->group();
  RenderViewHostImpl* rvh =
      web_contents()->GetPrimaryFrameTree().GetRenderViewHost(b_group).get();
  EXPECT_FALSE(rvh->is_active());

  // Navigate main tab to a b.com URL that will not commit.
  GURL stall_url(embedded_test_server()->GetURL("b.com", "/title2.html"));
  TestNavigationManager delayer(shell()->web_contents(), stall_url);
  EXPECT_TRUE(ExecJs(shell(), JsReplace("location = $1", stall_url)));
  delayer.WaitForSpeculativeRenderFrameHostCreation();

  // The pending RFH should be in the same process as the popup.
  RenderFrameHostImpl* pending_rfh =
      root->render_manager()->speculative_frame_host();
  RenderProcessHost* pending_process = pending_rfh->GetProcess();
  EXPECT_EQ(pending_process,
            popup_shell->web_contents()->GetPrimaryMainFrame()->GetProcess());

  // Kill the b.com process, currently in use by the pending RenderFrameHost
  // and the popup.
  RenderProcessHostWatcher crash_observer(
      pending_process, RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
  EXPECT_TRUE(pending_process->Shutdown(0));
  crash_observer.Wait();

  // The pending RFH should have been canceled and destroyed, so that it won't
  // be reused while it's not live in the next navigation.
  EXPECT_FALSE(root->render_manager()->speculative_frame_host());

  // Navigate main tab to b.com again.  This should not crash.
  GURL b_url(embedded_test_server()->GetURL("b.com", "/title3.html"));
  EXPECT_TRUE(NavigateToURLFromRenderer(shell(), b_url));

  // The b.com RVH in the main tab should become active.
  EXPECT_TRUE(rvh->is_active());
}

// Test that killing a pending RenderFrameHost's process doesn't leave its
// RenderViewHost confused whether it's active or not for future navigations
// that try to reuse it.  See https://crbug.com/627893 for more details.
// Similar to the test above for https://crbug.com/627400, except the popup is
// navigated after pending RFH's process is killed, rather than the main tab.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       RenderViewHostKeepsSwappedOutStateIfPendingRFHDies) {
  GURL main_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();

  // Open a popup at b.com.
  GURL popup_url(embedded_test_server()->GetURL("b.com", "/title1.html"));
  Shell* popup_shell = OpenPopup(root, popup_url, "foo");
  EXPECT_TRUE(popup_shell);

  // The RenderViewHost for b.com in the main tab should not be active.
  SiteInstanceGroup* b_group =
      static_cast<SiteInstanceImpl*>(
          popup_shell->web_contents()->GetSiteInstance())
          ->group();
  RenderViewHostImpl* rvh =
      web_contents()->GetPrimaryFrameTree().GetRenderViewHost(b_group).get();
  EXPECT_FALSE(rvh->is_active());

  // Navigate main tab to a b.com URL that will not commit.
  GURL stall_url(embedded_test_server()->GetURL("b.com", "/title2.html"));
  NavigationHandleObserver handle_observer(shell()->web_contents(), stall_url);
  TestNavigationManager delayer(shell()->web_contents(), stall_url);
  EXPECT_TRUE(ExecJs(shell(), JsReplace("location = $1", stall_url)));
  delayer.WaitForSpeculativeRenderFrameHostCreation();

  // Kill the b.com process, currently in use by the pending RenderFrameHost
  // and the popup.
  RenderProcessHost* pending_process =
      popup_shell->web_contents()->GetPrimaryMainFrame()->GetProcess();
  RenderProcessHostWatcher crash_observer(
      pending_process, RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
  EXPECT_TRUE(pending_process->Shutdown(0));
  crash_observer.Wait();

  // Since the navigation above didn't commit, the b.com RenderViewHost in the
  // main tab should still not be active.
  EXPECT_FALSE(rvh->is_active());
  EXPECT_EQ(net::ERR_ABORTED, handle_observer.net_error_code());

  // Navigate popup to b.com to recreate the b.com process.  When creating
  // opener proxies, |rvh| should be reused as a swapped out RVH.  In
  // https://crbug.com/627893, recreating the opener `blink::WebView` was
  // hitting a CHECK(params.swapped_out) in the renderer process, since its
  // RenderViewHost was brought into an active state by the navigation to
  // |stall_url| above, even though it never committed.
  GURL b_url(embedded_test_server()->GetURL("b.com", "/title3.html"));
  EXPECT_TRUE(NavigateToURLInSameBrowsingInstance(popup_shell, b_url));
  EXPECT_FALSE(rvh->is_active());
}

// Test that a crashed subframe can be successfully navigated to the site it
// was on before crashing.  See https://crbug.com/634368.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       NavigateCrashedSubframeToSameSite) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  FrameTreeNode* child = root->child_at(0);

  // Set up a postMessage handler in the main frame for later use.
  EXPECT_TRUE(ExecJs(
      root->current_frame_host(),
      "window.addEventListener('message',"
      "                        function(e) { document.title = e.data; });"));

  // Crash the subframe process.
  RenderProcessHost* child_process = child->current_frame_host()->GetProcess();
  RenderProcessHostWatcher crash_observer(
      child_process, RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
  child_process->Shutdown(0);
  crash_observer.Wait();
  EXPECT_FALSE(child->current_frame_host()->IsRenderFrameLive());

  // When the subframe dies, its RenderWidgetHostView should be cleared and
  // reset in the CrossProcessFrameConnector.
  EXPECT_FALSE(child->current_frame_host()->GetView());
  RenderFrameProxyHost* proxy_to_parent =
      child->render_manager()->GetProxyToParent();
  EXPECT_FALSE(
      proxy_to_parent->cross_process_frame_connector()->get_view_for_testing());

  // Navigate the subframe to the same site it was on before crashing.  This
  // should reuse the subframe's current RenderFrameHost and reinitialize the
  // RenderFrame in a new process.
  NavigateFrameToURL(child,
                     embedded_test_server()->GetURL("b.com", "/title1.html"));
  EXPECT_TRUE(child->current_frame_host()->IsRenderFrameLive());

  // The RenderWidgetHostView for the child should be recreated and set to be
  // used in the CrossProcessFrameConnector.  Without this, the frame won't be
  // rendered properly.
  EXPECT_TRUE(child->current_frame_host()->GetView());
  EXPECT_EQ(
      child->current_frame_host()->GetView(),
      proxy_to_parent->cross_process_frame_connector()->get_view_for_testing());

  // Make sure that the child frame has submitted a compositor frame
  RenderFrameSubmissionObserver frame_observer(child);
  frame_observer.WaitForMetadataChange();

  // Send a postMessage from the child to its parent.  This verifies that the
  // parent's proxy in the child's SiteInstance was also restored.
  std::u16string expected_title(u"I am alive!");
  TitleWatcher title_watcher(shell()->web_contents(), expected_title);
  EXPECT_TRUE(ExecJs(child->current_frame_host(),
                     "parent.postMessage('I am alive!', '*');"));
  EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
}

// Test that session history length and offset are replicated to all renderer
// processes in a FrameTree.  This allows each renderer to see correct values
// for history.length, and to check the offset validity properly for
// navigations initiated via history.go(). See https:/crbug.com/501116.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest, SessionHistoryReplication) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(a,a)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  FrameTreeNode* child1 = root->child_at(0);
  FrameTreeNode* child2 = root->child_at(1);
  GURL child_first_url(child1->current_url());
  EXPECT_EQ(child1->current_url(), child2->current_url());

  // Helper to retrieve the history length from a given frame.
  auto history_length = [](FrameTreeNode* ftn) {
    return EvalJs(ftn->current_frame_host(), "history.length;");
  };

  // All frames should see a history length of 1 to start with.
  EXPECT_EQ(1, history_length(root));
  EXPECT_EQ(1, history_length(child1));
  EXPECT_EQ(1, history_length(child2));

  // Navigate first child cross-site.  This increases history length to 2.
  EXPECT_TRUE(NavigateToURLFromRenderer(
      child1, embedded_test_server()->GetURL("b.com", "/title1.html")));
  EXPECT_EQ(2, history_length(root));
  EXPECT_EQ(2, history_length(child1));
  EXPECT_EQ(2, history_length(child2));

  // Navigate second child same-site.
  GURL child2_last_url(embedded_test_server()->GetURL("a.com", "/title2.html"));
  EXPECT_TRUE(NavigateToURLFromRenderer(child2, child2_last_url));
  EXPECT_EQ(3, history_length(root));
  EXPECT_EQ(3, history_length(child1));
  EXPECT_EQ(3, history_length(child2));

  // Navigate first child same-site to another b.com URL.
  GURL child1_last_url(embedded_test_server()->GetURL("b.com", "/title3.html"));
  EXPECT_TRUE(NavigateToURLFromRenderer(child1, child1_last_url));
  EXPECT_EQ(4, history_length(root));
  EXPECT_EQ(4, history_length(child1));
  EXPECT_EQ(4, history_length(child2));

  // Go back three entries using the history API from the main frame. This
  // checks that both history length and offset are not stale in a.com, as
  // otherwise this navigation might be dropped by Blink.
  EXPECT_TRUE(ExecJs(root, "history.go(-3);"));
  EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
  EXPECT_EQ(main_url, root->current_url());
  EXPECT_EQ(child_first_url, child1->current_url());
  EXPECT_EQ(child_first_url, child2->current_url());

  // Now go forward three entries from the child1 frame and check that the
  // history length and offset are not stale in b.com.
  EXPECT_TRUE(ExecJs(child1, "history.go(3);"));
  EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
  EXPECT_EQ(main_url, root->current_url());
  EXPECT_EQ(child1_last_url, child1->current_url());
  EXPECT_EQ(child2_last_url, child2->current_url());
}

// Intercepts calls to LocalFrameHost::DispatchLoad method(), and discards them.
class DispatchLoadInterceptor
    : public blink::mojom::LocalFrameHostInterceptorForTesting {
 public:
  explicit DispatchLoadInterceptor(RenderFrameHostImpl* render_frame_host)
      : swapped_impl_(
            render_frame_host->local_frame_host_receiver_for_testing(),
            this) {}

  ~DispatchLoadInterceptor() override = default;

  LocalFrameHost* GetForwardingInterface() override {
    return swapped_impl_.old_impl();
  }

  // Discard incoming calls to LocalFrameHost::DispatchLoad().
  void DispatchLoad() override {}

 private:
  mojo::test::ScopedSwapImplForTesting<blink::mojom::LocalFrameHost>
      swapped_impl_;
};

// Test that the renderer isn't killed when a frame generates a load event just
// after becoming pending deletion.  See https://crbug.com/636513.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       LoadEventForwardingWhilePendingDeletion) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(a)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  FrameTreeNode* child = root->child_at(0);

  // Open a popup in the b.com process for later use.
  GURL popup_url(embedded_test_server()->GetURL("b.com", "/title1.html"));
  Shell* popup_shell = OpenPopup(root, popup_url, "foo");
  EXPECT_TRUE(popup_shell);

  // Navigate subframe to b.com.  Wait for commit but not full load.
  GURL b_url(embedded_test_server()->GetURL("b.com", "/title2.html"));
  {
    TestFrameNavigationObserver commit_observer(child);
    EXPECT_TRUE(ExecJs(child, JsReplace("location.href = $1", b_url)));
    commit_observer.WaitForCommit();
  }
  RenderFrameHostImpl* child_rfh = child->current_frame_host();
  child_rfh->DisableUnloadTimerForTesting();

  // At this point, the subframe should have a proxy in its parent's
  // SiteInstance, a.com.
  EXPECT_TRUE(child->render_manager()->GetProxyToParent());

  {
    // Intercept calls to the LocalFrameHost::DispatchLoad() method.
    DispatchLoadInterceptor interceptor(child_rfh);

    // Now, go back to a.com in the subframe and wait for commit.
    {
      TestFrameNavigationObserver commit_observer(child);
      web_contents()->GetController().GoBack();
      commit_observer.WaitForCommit();
    }

    // At this point, the subframe's old RFH for b.com should be pending
    // deletion, and the subframe's proxy in a.com should've been cleared.
    EXPECT_TRUE(child_rfh->IsPendingDeletion());
    EXPECT_FALSE(child->render_manager()->GetProxyToParent());

    // Simulate that the load event is dispatched from |child_rfh| just after
    // it's become pending deletion.
    child_rfh->DispatchLoad();
  }

  // In the bug, DispatchLoad killed the b.com renderer.  Ensure that this is
  // not the case. Note that the process kill doesn't happen immediately, so
  // IsRenderFrameLive() can't be checked here (yet).  Instead, check that
  // JavaScript can still execute in b.com using the popup.
  EXPECT_TRUE(ExecJs(popup_shell->web_contents(), "true"));
}

IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       RFHTransfersWhilePendingDeletion) {
  GURL main_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
                            ->GetPrimaryFrameTree()
                            .root();

  // Start a cross-process navigation and wait until the response is received.
  GURL cross_site_url_1 =
      embedded_test_server()->GetURL("b.com", "/title1.html");
  TestNavigationManager cross_site_manager(shell()->web_contents(),
                                           cross_site_url_1);
  shell()->web_contents()->GetController().LoadURL(
      cross_site_url_1, Referrer(), ui::PAGE_TRANSITION_LINK, std::string());
  EXPECT_TRUE(cross_site_manager.WaitForResponse());

  // Start a renderer-initiated navigation to a cross-process url and make sure
  // the navigation will be blocked before being transferred.
  GURL cross_site_url_2 =
      embedded_test_server()->GetURL("c.com", "/title1.html");
  TestNavigationManager transfer_manager(shell()->web_contents(),
                                         cross_site_url_2);
  EXPECT_TRUE(ExecJs(root, JsReplace("location.href = $1", cross_site_url_2)));
  EXPECT_TRUE(transfer_manager.WaitForResponse());

  // Now have the cross-process navigation commit and mark the current RFH as
  // pending deletion.
  ASSERT_TRUE(cross_site_manager.WaitForNavigationFinished());

  // Resume the navigation in the previous RFH that has just been marked as
  // pending deletion. We should not crash.
  ASSERT_TRUE(transfer_manager.WaitForNavigationFinished());
}

class NavigationHandleWatcher : public WebContentsObserver {
 public:
  explicit NavigationHandleWatcher(WebContents* web_contents)
      : WebContentsObserver(web_contents) {}
  void DidStartNavigation(NavigationHandle* navigation_handle) override {
    DCHECK_EQ(GURL("http://b.com/"),
              navigation_handle->GetStartingSiteInstance()->GetSiteURL());
  }
};

// Verifies that the SiteInstance of a NavigationHandle correctly identifies the
// RenderFrameHost that started the navigation (and not the destination RFH).
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       NavigationHandleSiteInstance) {
  // Navigate to a page with a cross-site iframe.
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  // Navigate the iframe cross-site.
  NavigationHandleWatcher watcher(shell()->web_contents());
  TestNavigationObserver load_observer(shell()->web_contents());
  GURL frame_url = embedded_test_server()->GetURL("c.com", "/title1.html");
  EXPECT_TRUE(ExecJs(shell()->web_contents(),
                     JsReplace("window.frames[0].location = $1", frame_url)));
  load_observer.Wait();
}

// Test that when canceling a pending RenderFrameHost in the middle of a
// redirect, and then killing the corresponding `blink::WebView`'s renderer
// process, the RenderViewHost isn't reused in an improper state later.
// Previously this led to a crash in CreateRenderView when recreating the
// `blink::WebView` due to a stale main frame routing ID.  See
// https://crbug.com/627400.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       ReuseNonLiveRenderViewHostAfterCancelPending) {
  GURL a_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
  GURL b_url(embedded_test_server()->GetURL("b.com", "/title2.html"));
  GURL c_url(embedded_test_server()->GetURL("c.com", "/title3.html"));

  EXPECT_TRUE(NavigateToURL(shell(), a_url));

  // Open a popup and navigate it to b.com.
  Shell* popup = OpenPopup(shell(), a_url, "popup");
  EXPECT_TRUE(NavigateToURLFromRenderer(popup, b_url));

  // Open a second popup and navigate it to b.com, which redirects to c.com.
  // The navigation to b.com will create a pending RenderFrameHost, which will
  // be canceled during the redirect to c.com.  Note that
  // NavigateToURLFromRenderer will return false because the committed URL
  // won't match the requested URL due to the redirect.
  Shell* popup2 = OpenPopup(shell(), a_url, "popup2");
  TestNavigationObserver observer(popup2->web_contents());
  GURL redirect_url(embedded_test_server()->GetURL(
      "b.com", "/server-redirect?" + c_url.spec()));
  EXPECT_FALSE(NavigateToURLFromRenderer(popup2, redirect_url));
  EXPECT_EQ(c_url, observer.last_navigation_url());
  EXPECT_TRUE(observer.last_navigation_succeeded());

  // Kill the b.com process (which currently hosts a `blink::RemoteFrame` that
  // replaced the pending RenderFrame in |popup2|, as well as the RenderFrame
  // for |popup|).
  RenderProcessHost* b_process =
      popup->web_contents()->GetPrimaryMainFrame()->GetProcess();
  RenderProcessHostWatcher crash_observer(
      b_process, RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
  b_process->Shutdown(0);
  crash_observer.Wait();

  // Navigate the second popup to b.com.  This used to crash when creating the
  // `blink::WebView`, because it reused the RenderViewHost created by the
  // canceled navigation to b.com, and that RenderViewHost had a stale main
  // frame routing ID and active state.
  EXPECT_TRUE(NavigateToURLInSameBrowsingInstance(popup2, b_url));
}

// Check that after a pending RFH is canceled and replaced with a proxy (which
// reuses the canceled RFH's RenderViewHost), navigating to a main frame in the
// same site as the canceled RFH doesn't lead to a renderer crash.  The steps
// here are similar to ReuseNonLiveRenderViewHostAfterCancelPending, but don't
// involve crashing the renderer. See https://crbug.com/651980.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       RecreateMainFrameAfterCancelPending) {
  GURL a_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
  GURL b_url(embedded_test_server()->GetURL("b.com", "/title2.html"));
  GURL c_url(embedded_test_server()->GetURL("c.com", "/title3.html"));

  EXPECT_TRUE(NavigateToURL(shell(), a_url));

  // Open a popup and navigate it to b.com.
  Shell* popup = OpenPopup(shell(), a_url, "popup");
  EXPECT_TRUE(NavigateToURLFromRenderer(popup, b_url));

  // Open a second popup and navigate it to b.com, which redirects to c.com.
  // The navigation to b.com will create a pending RenderFrameHost, which will
  // be canceled during the redirect to c.com.  Note that NavigateToURL will
  // return false because the committed URL won't match the requested URL due
  // to the redirect.
  Shell* popup2 = OpenPopup(shell(), a_url, "popup2");
  TestNavigationObserver observer(popup2->web_contents());
  GURL redirect_url(embedded_test_server()->GetURL(
      "b.com", "/server-redirect?" + c_url.spec()));
  EXPECT_FALSE(NavigateToURLFromRenderer(popup2, redirect_url));
  EXPECT_EQ(c_url, observer.last_navigation_url());
  EXPECT_TRUE(observer.last_navigation_succeeded());

  // Navigate the second popup to b.com.  This used to crash the b.com renderer
  // because it failed to delete the canceled RFH's RenderFrame, so this caused
  // it to try to create a frame widget which already existed.
  EXPECT_TRUE(NavigateToURLFromRenderer(popup2, b_url));
}

// Check that when a pending RFH is canceled and a proxy needs to be created in
// its place, the proxy is properly initialized on the renderer side.  See
// https://crbug.com/653746.
// The test disables the delay of creating the speculative RFH since it requires
// the created RFH to be cancelld because of the cross-origin redirect.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTestWithoutSpeculativeRFHDelay,
                       CommunicateWithProxyAfterCancelPending) {
  GURL a_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
  GURL b_url(embedded_test_server()->GetURL("b.com", "/title2.html"));
  GURL c_url(embedded_test_server()->GetURL("c.com", "/title3.html"));

  EXPECT_TRUE(NavigateToURL(shell(), a_url));

  // Open a popup and navigate it to b.com.
  Shell* popup = OpenPopup(shell(), a_url, "popup");
  EXPECT_TRUE(NavigateToURLFromRenderer(popup, b_url));

  // Open a second popup and navigate it to b.com, which redirects to c.com.
  // The navigation to b.com will create a pending RenderFrameHost, which will
  // be canceled during the redirect to c.com.  Note that NavigateToURL will
  // return false because the committed URL won't match the requested URL due
  // to the redirect.
  Shell* popup2 = OpenPopup(shell(), a_url, "popup2");
  TestNavigationObserver observer(popup2->web_contents());
  GURL redirect_url(embedded_test_server()->GetURL(
      "b.com", "/server-redirect?" + c_url.spec()));
  EXPECT_FALSE(NavigateToURLFromRenderer(popup2, redirect_url));
  EXPECT_EQ(c_url, observer.last_navigation_url());
  EXPECT_TRUE(observer.last_navigation_succeeded());

  // Because b.com has other active frames (namely, the frame in |popup|),
  // there should be a proxy created for the canceled RFH, and it should be
  // live.
  SiteInstance* b_instance = popup->web_contents()->GetSiteInstance();
  FrameTreeNode* popup2_root =
      static_cast<WebContentsImpl*>(popup2->web_contents())
          ->GetPrimaryFrameTree()
          .root();
  RenderFrameProxyHost* proxy =
      popup2_root->current_frame_host()
          ->browsing_context_state()
          ->GetRenderFrameProxyHost(
              static_cast<SiteInstanceImpl*>(b_instance)->group());
  EXPECT_TRUE(proxy);
  EXPECT_TRUE(proxy->is_render_frame_proxy_live());

  // Add a postMessage listener in |popup2| (currently at a c.com URL).
  EXPECT_TRUE(ExecJs(popup2,
                     "window.addEventListener('message', function(event) {\n"
                     "  document.title=event.data;\n"
                     "});"));

  // Check that a postMessage can be sent via |proxy| above.  This needs to be
  // done from the b.com process.  |popup| is currently in b.com, but it can't
  // reach the window reference for |popup2| due to a security restriction in
  // Blink. So, navigate the main tab to b.com and then send a postMessage to
  // |popup2|. This is allowed since the main tab is |popup2|'s opener.
  EXPECT_TRUE(NavigateToURLFromRenderer(shell(), b_url));

  std::u16string expected_title(u"foo");
  TitleWatcher title_watcher(popup2->web_contents(), expected_title);
  EXPECT_TRUE(
      ExecJs(shell(), "window.open('','popup2').postMessage('foo', '*');"));
  EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
}

IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       HeaderPolicyOnXSLTNavigation) {
  GURL url(embedded_test_server()->GetURL("a.com", "/permissions-policy.xml"));

  EXPECT_TRUE(NavigateToURL(shell(), url));

  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  EXPECT_EQ(CreateParsedPermissionsPolicyMatchesSelf(
                {network::mojom::PermissionsPolicyFeature::kGeolocation},
                url.DeprecatedGetOriginAsURL()),
            root->current_replication_state().permissions_policy_header);
}

IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       TestPolicyReplicationOnSameOriginNavigation) {
  GURL start_url(
      embedded_test_server()->GetURL("a.com", "/permissions-policy1.html"));
  GURL first_nav_url(
      embedded_test_server()->GetURL("a.com", "/permissions-policy2.html"));
  GURL second_nav_url(embedded_test_server()->GetURL("a.com", "/title2.html"));

  EXPECT_TRUE(NavigateToURL(shell(), start_url));

  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  EXPECT_EQ(CreateParsedPermissionsPolicyMatchesSelf(
                {network::mojom::PermissionsPolicyFeature::kGeolocation,
                 network::mojom::PermissionsPolicyFeature::kPayment},
                start_url.DeprecatedGetOriginAsURL()),
            root->current_replication_state().permissions_policy_header);

  // When the main frame navigates to a page with a new policy, it should
  // overwrite the old one.
  EXPECT_TRUE(NavigateToURL(shell(), first_nav_url));
  EXPECT_EQ(CreateParsedPermissionsPolicyMatchesAll(
                {network::mojom::PermissionsPolicyFeature::kGeolocation,
                 network::mojom::PermissionsPolicyFeature::kPayment}),
            root->current_replication_state().permissions_policy_header);

  // When the main frame navigates to a page without a policy, the replicated
  // policy header should be cleared.
  EXPECT_TRUE(NavigateToURL(shell(), second_nav_url));
  EXPECT_TRUE(
      root->current_replication_state().permissions_policy_header.empty());
}

IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       TestPolicyReplicationOnCrossOriginNavigation) {
  GURL start_url(
      embedded_test_server()->GetURL("a.com", "/permissions-policy1.html"));
  GURL first_nav_url(
      embedded_test_server()->GetURL("b.com", "/permissions-policy2.html"));
  GURL second_nav_url(embedded_test_server()->GetURL("c.com", "/title2.html"));

  EXPECT_TRUE(NavigateToURL(shell(), start_url));

  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  EXPECT_EQ(CreateParsedPermissionsPolicyMatchesSelf(
                {network::mojom::PermissionsPolicyFeature::kGeolocation,
                 network::mojom::PermissionsPolicyFeature::kPayment},
                start_url.DeprecatedGetOriginAsURL()),
            root->current_replication_state().permissions_policy_header);

  // When the main frame navigates to a page with a new policy, it should
  // overwrite the old one.
  EXPECT_TRUE(NavigateToURL(shell(), first_nav_url));
  EXPECT_EQ(CreateParsedPermissionsPolicyMatchesAll(
                {network::mojom::PermissionsPolicyFeature::kGeolocation,
                 network::mojom::PermissionsPolicyFeature::kPayment}),
            root->current_replication_state().permissions_policy_header);

  // When the main frame navigates to a page without a policy, the replicated
  // policy header should be cleared.
  EXPECT_TRUE(NavigateToURL(shell(), second_nav_url));
  EXPECT_TRUE(
      root->current_replication_state().permissions_policy_header.empty());
}

// Test that the replicated permissions policy header is correct in subframes as
// they navigate.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       TestPolicyReplicationFromRemoteFrames) {
  GURL main_url(
      embedded_test_server()->GetURL("a.com", "/permissions-policy-main.html"));
  GURL first_nav_url(
      embedded_test_server()->GetURL("b.com", "/permissions-policy2.html"));
  GURL second_nav_url(embedded_test_server()->GetURL("c.com", "/title2.html"));

  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  EXPECT_EQ(CreateParsedPermissionsPolicy(
                {network::mojom::PermissionsPolicyFeature::kGeolocation,
                 network::mojom::PermissionsPolicyFeature::kPayment},
                {GURL("http://example.com/")}, /*match_all_origins=*/false,
                main_url.DeprecatedGetOriginAsURL()),
            root->current_replication_state().permissions_policy_header);
  EXPECT_EQ(1UL, root->child_count());
  EXPECT_EQ(
      CreateParsedPermissionsPolicyMatchesSelf(
          {network::mojom::PermissionsPolicyFeature::kGeolocation,
           network::mojom::PermissionsPolicyFeature::kPayment},
          main_url.DeprecatedGetOriginAsURL()),
      root->child_at(0)->current_replication_state().permissions_policy_header);

  // Navigate the iframe cross-site.
  EXPECT_TRUE(NavigateToURLFromRenderer(root->child_at(0), first_nav_url));
  EXPECT_EQ(
      CreateParsedPermissionsPolicyMatchesAll(
          {network::mojom::PermissionsPolicyFeature::kGeolocation,
           network::mojom::PermissionsPolicyFeature::kPayment}),
      root->child_at(0)->current_replication_state().permissions_policy_header);

  // Navigate the iframe to another location, this one with no policy header
  EXPECT_TRUE(NavigateToURLFromRenderer(root->child_at(0), second_nav_url));
  EXPECT_TRUE(root->child_at(0)
                  ->current_replication_state()
                  .permissions_policy_header.empty());

  // Navigate the iframe back to a page with a policy
  EXPECT_TRUE(NavigateToURLFromRenderer(root->child_at(0), first_nav_url));
  EXPECT_EQ(
      CreateParsedPermissionsPolicyMatchesAll(
          {network::mojom::PermissionsPolicyFeature::kGeolocation,
           network::mojom::PermissionsPolicyFeature::kPayment}),
      root->child_at(0)->current_replication_state().permissions_policy_header);
}

// Test that the replicated permissions policy header is correct in remote
// proxies after the local frame has navigated.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       TestPermissionsPolicyReplicationToProxyOnNavigation) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/frame_tree/page_with_two_frames.html"));
  GURL first_nav_url(
      embedded_test_server()->GetURL("a.com", "/permissions-policy3.html"));
  GURL second_nav_url(
      embedded_test_server()->GetURL("a.com", "/permissions-policy4.html"));

  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  EXPECT_TRUE(
      root->current_replication_state().permissions_policy_header.empty());
  EXPECT_EQ(2UL, root->child_count());
  EXPECT_TRUE(root->child_at(1)
                  ->current_replication_state()
                  .permissions_policy_header.empty());

  // Navigate the iframe to a page with a policy, and a nested cross-site iframe
  // (to the same site as a root->child_at(1) so that the render process already
  // exists.)
  EXPECT_TRUE(NavigateToURLFromRenderer(root->child_at(1), first_nav_url));
  EXPECT_EQ(
      CreateParsedPermissionsPolicyMatchesNone(
          {network::mojom::PermissionsPolicyFeature::kGeolocation,
           network::mojom::PermissionsPolicyFeature::kPayment}),
      root->child_at(1)->current_replication_state().permissions_policy_header);

  EXPECT_EQ(1UL, root->child_at(1)->child_count());

  // Ask the deepest iframe to report the enabled state of the geolocation
  // feature. If its parent frame's policy was replicated correctly to the
  // proxy, then this will be disabled. Otherwise, it will be enabled by the
  // "allow" attribute on the parent frame.
  EXPECT_EQ(false,
            EvalJs(root->child_at(1)->child_at(0),
                   "document.featurePolicy.allowsFeature('geolocation')"));

  // Now navigate the iframe to a page with no header policy, and the same
  // nested cross-site iframe. The header policy should be cleared in the proxy.
  // In this case, the frame policy from the parent will allow geolocation to be
  // delegated.
  EXPECT_TRUE(NavigateToURLFromRenderer(root->child_at(1), second_nav_url));
  EXPECT_TRUE(root->child_at(1)
                  ->current_replication_state()
                  .permissions_policy_header.empty());
  EXPECT_EQ(1UL, root->child_at(1)->child_count());

  // Ask the deepest iframe to report the enabled state of the geolocation
  // feature. If its parent frame's policy was replicated correctly to the
  // proxy, then this will now be allowed.
  EXPECT_EQ(true,
            EvalJs(root->child_at(1)->child_at(0),
                   "document.featurePolicy.allowsFeature('geolocation')"));
}

// Test that the constructed permissions policy is correct in sandboxed
// frames. Sandboxed frames have an opaque origin, and if the frame policy,
// which is constructed in the parent frame, cannot send that origin through
// the browser process to the sandboxed frame, then the sandboxed frame's
// policy will be incorrect.
//
// This is a regression test for https://crbug.com/690520
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       TestAllowAttributeInSandboxedFrame) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com",
      "/cross_site_iframe_factory.html?"
      "a(b{allow-geolocation,sandbox-allow-scripts})"));
  GURL nav_url(embedded_test_server()->GetURL("c.com", "/title1.html"));

  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  EXPECT_TRUE(
      root->current_replication_state().permissions_policy_header.empty());
  EXPECT_EQ(1UL, root->child_count());
  // Verify that the child frame is sandboxed with an opaque origin.
  EXPECT_TRUE(root->child_at(0)
                  ->current_frame_host()
                  ->GetLastCommittedOrigin()
                  .opaque());
  // And verify that the origin in the replication state is also opaque.
  EXPECT_TRUE(root->child_at(0)->current_origin().opaque());

  // Ask the sandboxed iframe to report the enabled state of the geolocation
  // feature. If the declared policy was correctly flagged as referring to the
  // opaque origin, then the policy in the sandboxed renderer will be
  // constructed correctly, and geolocation will be enabled in the sandbox.
  // Otherwise, it will be disabled, as geolocation is disabled by default in
  // cross-origin frames.
  EXPECT_EQ(true,
            EvalJs(root->child_at(0),
                   "document.featurePolicy.allowsFeature('geolocation');"));

  TestNavigationObserver load_observer(shell()->web_contents());
  EXPECT_TRUE(ExecJs(root->child_at(0),
                     JsReplace("document.location.href=$1", nav_url)));
  load_observer.Wait();

  // Verify that the child frame is sandboxed with an opaque origin.
  EXPECT_TRUE(root->child_at(0)
                  ->current_frame_host()
                  ->GetLastCommittedOrigin()
                  .opaque());
  // And verify that the origin in the replication state is also opaque.
  EXPECT_TRUE(root->child_at(0)->current_origin().opaque());

  EXPECT_EQ(true,
            EvalJs(root->child_at(0),
                   "document.featurePolicy.allowsFeature('geolocation');"));
}

// Test that the constructed permissions policy is correct in sandboxed
// frames. Sandboxed frames have an opaque origin, and if the frame policy,
// which is constructed in the parent frame, cannot send that origin through
// the browser process to the sandboxed frame, then the sandboxed frame's
// policy will be incorrect.
//
// This is a regression test for https://crbug.com/690520
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       TestAllowAttributeInOpaqueOriginAfterNavigation) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/page_with_data_iframe_and_allow.html"));
  GURL nav_url(embedded_test_server()->GetURL("c.com", "/title1.html"));

  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  EXPECT_TRUE(
      root->current_replication_state().permissions_policy_header.empty());
  EXPECT_EQ(1UL, root->child_count());
  // Verify that the child frame has an opaque origin.
  EXPECT_TRUE(root->child_at(0)
                  ->current_frame_host()
                  ->GetLastCommittedOrigin()
                  .opaque());
  // And verify that the origin in the replication state is also opaque.
  EXPECT_TRUE(root->child_at(0)->current_origin().opaque());

  // Verify that geolocation is enabled in the document.
  EXPECT_EQ(true,
            EvalJs(root->child_at(0),
                   "document.featurePolicy.allowsFeature('geolocation');"));

  TestNavigationObserver load_observer(shell()->web_contents());
  EXPECT_TRUE(ExecJs(root->child_at(0),
                     JsReplace("document.location.href=$1", nav_url)));
  load_observer.Wait();

  // Verify that the child frame no longer has an opaque origin.
  EXPECT_FALSE(root->child_at(0)
                   ->current_frame_host()
                   ->GetLastCommittedOrigin()
                   .opaque());
  // Verify that the origin in the replication state is also no longer opaque.
  EXPECT_FALSE(root->child_at(0)->current_origin().opaque());

  // Verify that the new document does not have geolocation enabled.
  EXPECT_EQ(false,
            EvalJs(root->child_at(0),
                   "document.featurePolicy.allowsFeature('geolocation');"));
}

// Ensure that an iframe that navigates cross-site doesn't use the same process
// as its parent. Then when its parent navigates it via the "srcdoc" attribute,
// it must reuse its parent's process.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       IframeSrcdocAfterCrossSiteNavigation) {
  GURL parent_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)"));
  GURL child_url(embedded_test_server()->GetURL(
      "b.com", "/cross_site_iframe_factory.html?b()"));

  // #1 Navigate to a page with a cross-site iframe.
  EXPECT_TRUE(NavigateToURL(shell(), parent_url));

  // Ensure that the iframe uses its own process.
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  ASSERT_EQ(1u, root->child_count());
  FrameTreeNode* child = root->child_at(0);
  EXPECT_EQ(parent_url, root->current_url());
  EXPECT_EQ(child_url, child->current_url());
  EXPECT_NE(root->current_frame_host()->GetSiteInstance(),
            child->current_frame_host()->GetSiteInstance());
  EXPECT_NE(root->current_frame_host()->GetProcess(),
            child->current_frame_host()->GetProcess());

  // #2 Navigate the iframe to its srcdoc attribute.
  TestNavigationObserver load_observer(shell()->web_contents());
  EXPECT_TRUE(ExecJs(
      root, "document.getElementById('child-0').srcdoc = 'srcdoc content';"));
  load_observer.Wait();

  // Ensure that the iframe reuses its parent's process.
  EXPECT_TRUE(child->current_url().IsAboutSrcdoc());
  EXPECT_EQ(root->current_frame_host()->GetSiteInstance(),
            child->current_frame_host()->GetSiteInstance());
  EXPECT_EQ(root->current_frame_host()->GetProcess(),
            child->current_frame_host()->GetProcess());
}

// Verify that a remote-to-local navigation in a crashed subframe works.  See
// https://crbug.com/487872.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       RemoteToLocalNavigationInCrashedSubframe) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  FrameTreeNode* child = root->child_at(0);

  // Crash the subframe process.
  RenderProcessHost* child_process = child->current_frame_host()->GetProcess();
  {
    RenderProcessHostWatcher crash_observer(
        child_process, RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
    child_process->Shutdown(0);
    crash_observer.Wait();
  }
  EXPECT_FALSE(child->current_frame_host()->IsRenderFrameLive());

  // Do a remote-to-local navigation of the child frame from the parent frame.
  TestFrameNavigationObserver frame_observer(child);
  GURL frame_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
  EXPECT_TRUE(ExecJs(
      root, JsReplace("document.querySelector('iframe').src = $1", frame_url)));
  frame_observer.Wait();

  EXPECT_TRUE(child->current_frame_host()->IsRenderFrameLive());
  EXPECT_FALSE(child->IsLoading());
  EXPECT_EQ(child->current_frame_host()->GetSiteInstance(),
            root->current_frame_host()->GetSiteInstance());

  // Ensure the subframe is correctly attached in the frame tree, and that it
  // has correct content.
  EXPECT_EQ(1, EvalJs(root, "frames.length;"));

  EXPECT_EQ("This page has no title.",
            EvalJs(root, "frames[0].document.body.innerText;"));
}

// Tests that trying to open a context menu in the old RFH after commiting a
// navigation doesn't crash the browser. https://crbug.com/677266.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       ContextMenuAfterCrossProcessNavigation) {
  // Navigate to a.com.
  EXPECT_TRUE(NavigateToURL(
      shell(), embedded_test_server()->GetURL("a.com", "/title1.html")));

  // Disable the unload ACK and the unload timer.
  RenderFrameHostImpl* rfh = static_cast<RenderFrameHostImpl*>(
      shell()->web_contents()->GetPrimaryMainFrame());
  auto unload_ack_filter = base::BindRepeating([] { return true; });
  rfh->SetUnloadACKCallbackForTesting(unload_ack_filter);
  rfh->DisableUnloadTimerForTesting();

  // Open a popup on a.com to keep the process alive.
  OpenPopup(shell(), embedded_test_server()->GetURL("a.com", "/title2.html"),
            "foo");

  // Cross-process navigation to b.com.
  EXPECT_TRUE(NavigateToURL(
      shell(), embedded_test_server()->GetURL("b.com", "/title3.html")));

  // Pretend that a.com just requested a context menu. This used to cause a
  // because the RenderWidgetHostView is destroyed when the frame is unloaded
  // and added to pending delete list.
  rfh->ShowContextMenu(mojo::NullAssociatedRemote(), ContextMenuParams());
}

// Test iframe container policy is replicated properly to the browser.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest, ContainerPolicy) {
  GURL url(embedded_test_server()->GetURL("/allowed_frames.html"));
  EXPECT_TRUE(NavigateToURL(shell(), url));

  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();

  EXPECT_EQ(0UL, root->effective_frame_policy().container_policy.size());
  EXPECT_EQ(
      0UL, root->child_at(0)->effective_frame_policy().container_policy.size());
  EXPECT_EQ(
      0UL, root->child_at(1)->effective_frame_policy().container_policy.size());
  EXPECT_EQ(
      2UL, root->child_at(2)->effective_frame_policy().container_policy.size());
  EXPECT_EQ(
      2UL, root->child_at(3)->effective_frame_policy().container_policy.size());
}

// Test dynamic updates to iframe "allow" attribute are propagated correctly.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest, ContainerPolicyDynamic) {
  GURL main_url(embedded_test_server()->GetURL("/allowed_frames.html"));
  GURL nav_url(
      embedded_test_server()->GetURL("b.com", "/permissions-policy2.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();

  EXPECT_EQ(
      2UL, root->child_at(2)->effective_frame_policy().container_policy.size());

  // Removing the "allow" attribute; pending policy should update, but effective
  // policy remains unchanged.
  EXPECT_TRUE(ExecJs(
      root, "document.getElementById('child-2').setAttribute('allow','')"));
  EXPECT_EQ(
      2UL, root->child_at(2)->effective_frame_policy().container_policy.size());
  EXPECT_EQ(0UL,
            root->child_at(2)->pending_frame_policy().container_policy.size());

  // Navigate the frame; pending policy should be committed.
  EXPECT_TRUE(NavigateToURLFromRenderer(root->child_at(2), nav_url));
  EXPECT_EQ(
      0UL, root->child_at(2)->effective_frame_policy().container_policy.size());
}

// Check that out-of-process frames correctly calculate the container policy in
// the renderer when navigating cross-origin. The policy should be unchanged
// when modified dynamically in the parent frame. When the frame is navigated,
// the new renderer should have the correct container policy.
//
// TODO(iclelland): Once there is a proper JS inspection API from the renderer,
// use that to check the policy. Until then, we test webkitFullscreenEnabled,
// which conveniently just returns the result of calling isFeatureEnabled on
// the fullscreen feature. Since there are no HTTP header policies involved,
// this verifies the presence of the container policy in the iframe.
// https://crbug.com/703703
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       ContainerPolicyCrossOriginNavigation) {
  WebContentsImpl* contents = web_contents();
  FrameTreeNode* root = contents->GetPrimaryFrameTree().root();

  // Helper to check if a frame is allowed to go fullscreen on the renderer
  // side.
  auto is_fullscreen_allowed = [](FrameTreeNode* ftn) {
    return EvalJs(ftn, "document.webkitFullscreenEnabled;");
  };

  // Load a page with an <iframe> without allowFullscreen.
  EXPECT_TRUE(NavigateToURL(
      shell(), embedded_test_server()->GetURL(
                   "a.com", "/cross_site_iframe_factory.html?a(b)")));

  // Dynamically enable fullscreen for the subframe and check that the
  // fullscreen property was updated on the FrameTreeNode.
  EXPECT_TRUE(ExecJs(
      root, "document.getElementById('child-0').allowFullscreen='true'"));

  // No change is expected to the container policy for dynamic modification of
  // a loaded frame.
  EXPECT_EQ(false, is_fullscreen_allowed(root->child_at(0)));

  // Cross-site navigation should update the container policy in the new render
  // frame.
  EXPECT_TRUE(NavigateToURLFromRenderer(
      root->child_at(0),
      embedded_test_server()->GetURL("c.com", "/title1.html")));
  EXPECT_EQ(true, is_fullscreen_allowed(root->child_at(0)));
}

// Test that dynamic updates to iframe sandbox attribute correctly set the
// replicated container policy.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       ContainerPolicySandboxDynamic) {
  GURL main_url(embedded_test_server()->GetURL("/allowed_frames.html"));
  GURL nav_url(
      embedded_test_server()->GetURL("b.com", "/permissions-policy2.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();

  // Validate that the effective container policy contains a single non-unique
  // origin.
  const network::ParsedPermissionsPolicy initial_effective_policy =
      root->child_at(2)->effective_frame_policy().container_policy;
  EXPECT_EQ(1UL, initial_effective_policy[0].allowed_origins.size());

  // Set the "sandbox" attribute; pending policy should update, and should now
  // be flagged as matching the opaque origin of the frame (without containing
  // an actual opaque origin, since the parent frame doesn't actually have that
  // origin yet) but the effective policy should remain unchanged.
  EXPECT_TRUE(ExecJs(
      root, "document.getElementById('child-2').setAttribute('sandbox','')"));
  const network::ParsedPermissionsPolicy updated_effective_policy =
      root->child_at(2)->effective_frame_policy().container_policy;
  const network::ParsedPermissionsPolicy updated_pending_policy =
      root->child_at(2)->pending_frame_policy().container_policy;
  EXPECT_EQ(1UL, updated_effective_policy[0].allowed_origins.size());
  EXPECT_TRUE(updated_pending_policy[0].matches_opaque_src);
  EXPECT_EQ(0UL, updated_pending_policy[0].allowed_origins.size());

  // Navigate the frame; pending policy should now be committed.
  EXPECT_TRUE(NavigateToURLFromRenderer(root->child_at(2), nav_url));
  const network::ParsedPermissionsPolicy final_effective_policy =
      root->child_at(2)->effective_frame_policy().container_policy;
  EXPECT_TRUE(final_effective_policy[0].matches_opaque_src);
  EXPECT_EQ(0UL, final_effective_policy[0].allowed_origins.size());
}

// Test that creating a new remote frame at the same origin as its parent
// results in the correct permissions policy in the RemoteSecurityContext.
// https://crbug.com/852102
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       PermissionsPolicyConstructionInExistingProxy) {
  WebContentsImpl* contents = web_contents();
  FrameTreeNode* root = contents->GetPrimaryFrameTree().root();

  // Navigate to a page (1) with a cross-origin iframe (2). After load, the
  // frame tree should look like:
  //
  //    a.com(1)
  //   /
  // b.com(2)
  EXPECT_TRUE(NavigateToURL(
      shell(), embedded_test_server()->GetURL(
                   "a.com", "/cross_site_iframe_factory.html?a(b)")));

  // Programmatically create a new same-origin frame (3) under the root, with a
  // cross-origin child (4). Since two SiteInstances already exist at this
  // point, a proxy for frame 3 will be created in the renderer for frames 2 and
  // 4. The frame tree should look like:
  //
  //    a.com(1)
  //   /      \
  // b.com(2) a.com(3)
  //                \
  //                b.com(4)
  auto create_subframe_script = JsReplace(
      "var f = document.createElement('iframe'); f.src=$1; "
      "document.body.appendChild(f);",
      embedded_test_server()->GetURL(
          "a.com", "/cross_site_iframe_factory.html?a(b{allow-autoplay})"));
  EXPECT_TRUE(ExecJs(root, create_subframe_script));
  EXPECT_TRUE(WaitForLoadStop(contents));

  // Verify the shape of the frame tree
  EXPECT_EQ(2UL, root->child_count());
  EXPECT_EQ(1UL, root->child_at(1)->child_count());

  // Ask frame 4 to report the enabled state of the autoplay feature. Frame 3's
  // policy should allow autoplay if created correctly, as it is same-origin
  // with the root, where the feature is enabled by default, and therefore
  // should be able to delegate it to frame 4.
  // This indirectly tests the replicated policy in frame 3: Because frame 4 is
  // cross-origin to frame 3, it will use the proxy's replicated policy as the
  // parent policy; otherwise we would just ask frame 3 to report its own state.
  EXPECT_EQ(true, EvalJs(root->child_at(1)->child_at(0),
                         "document.featurePolicy.allowsFeature('autoplay');"));
}

// Test harness that allows for "barrier" style delaying of requests matching
// certain paths. Call SetDelayedRequestsForPath to delay requests, then
// SetUpEmbeddedTestServer to register handlers and start the server.
class RequestDelayingSitePerProcessBrowserTest
    : public SitePerProcessBrowserTest {
 public:
  RequestDelayingSitePerProcessBrowserTest()
      : test_server_(std::make_unique<net::EmbeddedTestServer>()) {}

  // Must be called after any calls to SetDelayedRequestsForPath.
  void SetUpEmbeddedTestServer() {
    SetupCrossSiteRedirector(test_server_.get());
    test_server_->RegisterRequestHandler(base::BindRepeating(
        &RequestDelayingSitePerProcessBrowserTest::HandleMockResource,
        base::Unretained(this)));
    ASSERT_TRUE(test_server_->Start());
  }

  // Delays |num_delayed| requests with URLs whose path parts match |path|. When
  // the |num_delayed| + 1 request matching the path comes in, the rest are
  // unblocked.
  // Note: must be called on the UI thread before |test_server_| is started.
  void SetDelayedRequestsForPath(const std::string& path, int num_delayed) {
    DCHECK_CURRENTLY_ON(BrowserThread::UI);
    DCHECK(!test_server_->Started());
    num_remaining_requests_to_delay_for_path_[path] = num_delayed;
  }

 private:
  // Called on the test server's thread.
  void AddDelayedResponse(
      base::WeakPtr<net::test_server::HttpResponseDelegate> delegate) {
    response_closures_.push_back(base::BindOnce(
        &net::test_server::HttpResponseDelegate::SendHeadersContentAndFinish,
        delegate, net::HTTP_OK, "OK", base::StringPairs(), ""));
  }

  // Custom embedded test server handler. Looks for requests matching
  // num_remaining_requests_to_delay_for_path_, and delays them if necessary. As
  // soon as a single request comes in and:
  // 1) It matches a delayed path
  // 2) No path has any more requests to delay
  // Then we release the barrier and finish all delayed requests.
  std::unique_ptr<net::test_server::HttpResponse> HandleMockResource(
      const net::test_server::HttpRequest& request) {
    auto it =
        num_remaining_requests_to_delay_for_path_.find(request.GetURL().path());
    if (it == num_remaining_requests_to_delay_for_path_.end())
      return nullptr;

    // If there are requests to delay for this path, make a delayed request
    // which will be finished later. Otherwise fall through to the bottom and
    // send an empty response.
    if (it->second > 0) {
      --it->second;
      return std::make_unique<DelayedResponse>(this);
    }
    MaybeStartRequests();
    return nullptr;
  }

  // If there are no more requests to delay, post a series of tasks finishing
  // all the delayed tasks. This will be called on the test server's thread.
  void MaybeStartRequests() {
    for (auto it : num_remaining_requests_to_delay_for_path_) {
      if (it.second > 0)
        return;
    }
    for (auto& it : response_closures_)
      std::move(it).Run();
  }

  // This class passes the delegates needed to respond to a request to the
  // underlying test fixture.
  class DelayedResponse : public net::test_server::BasicHttpResponse {
   public:
    explicit DelayedResponse(
        RequestDelayingSitePerProcessBrowserTest* test_harness)
        : test_harness_(test_harness) {}

    DelayedResponse(const DelayedResponse&) = delete;
    DelayedResponse& operator=(const DelayedResponse&) = delete;

    void SendResponse(base::WeakPtr<net::test_server::HttpResponseDelegate>
                          delegate) override {
      test_harness_->AddDelayedResponse(delegate);
    }

   private:
    raw_ptr<RequestDelayingSitePerProcessBrowserTest> test_harness_;
  };

  // Set of delegates to call which will complete delayed requests. May only be
  // modified on the test_server_'s thread.
  std::vector<base::OnceClosure> response_closures_;

  // Map from URL paths to the number of requests to delay for that particular
  // path. Initialized on the UI thread but modified and read on the test
  // server's thread after the |test_server_| is started.
  std::map<std::string, int> num_remaining_requests_to_delay_for_path_;

  // Don't use embedded_test_server() because this one requires custom
  // initialization.
  std::unique_ptr<net::EmbeddedTestServer> test_server_;
};

// Regression tests for https://crbug.com/678206, where the request throttling
// in ResourceScheduler was not updated for OOPIFs. This resulted in a single
// hung delayable request (e.g. video) starving all other delayable requests.
// The tests work by delaying n requests in a cross-domain iframe. Once the n +
// 1st request goes through to the network stack (ensuring it was not starved),
// the delayed request completed.
//
// If the logic is not correct, these tests will time out, as the n + 1st
// request will never start.
IN_PROC_BROWSER_TEST_P(RequestDelayingSitePerProcessBrowserTest,
                       DelayableSubframeRequestsOneFrame) {
  std::string path = "/mock-video.mp4";
  SetDelayedRequestsForPath(path, 2);
  SetUpEmbeddedTestServer();
  GURL url(embedded_test_server()->GetURL(
      "a.com", base::StringPrintf("/site_isolation/"
                                  "subframes_with_resources.html?urls=%s&"
                                  "numSubresources=3",
                                  path.c_str())));
  EXPECT_TRUE(NavigateToURL(shell(), url));
  EXPECT_EQ(true, EvalJs(shell(), "createFrames()"));
}

IN_PROC_BROWSER_TEST_P(RequestDelayingSitePerProcessBrowserTest,
                       DelayableSubframeRequestsTwoFrames) {
  std::string path0 = "/mock-video0.mp4";
  std::string path1 = "/mock-video1.mp4";
  SetDelayedRequestsForPath(path0, 2);
  SetDelayedRequestsForPath(path1, 2);
  SetUpEmbeddedTestServer();
  GURL url(embedded_test_server()->GetURL(
      "a.com", base::StringPrintf("/site_isolation/"
                                  "subframes_with_resources.html?urls=%s,%s&"
                                  "numSubresources=3",
                                  path0.c_str(), path1.c_str())));
  EXPECT_TRUE(NavigateToURL(shell(), url));
  EXPECT_EQ(true, EvalJs(shell(), "createFrames()"));
}

#if BUILDFLAG(IS_ANDROID)
class TextSelectionObserver : public TextInputManager::Observer {
 public:
  explicit TextSelectionObserver(TextInputManager* text_input_manager)
      : text_input_manager_(text_input_manager) {
    text_input_manager->AddObserver(this);
  }

  TextSelectionObserver(const TextSelectionObserver&) = delete;
  TextSelectionObserver& operator=(const TextSelectionObserver&) = delete;

  ~TextSelectionObserver() { text_input_manager_->RemoveObserver(this); }

  void WaitForSelectedText(const std::string& expected_text) {
    if (last_selected_text_ == expected_text)
      return;
    expected_text_ = expected_text;
    loop_runner_ = new MessageLoopRunner();
    loop_runner_->Run();
  }

 private:
  void OnTextSelectionChanged(TextInputManager* text_input_manager,
                              RenderWidgetHostViewBase* updated_view) override {
    last_selected_text_ = base::UTF16ToUTF8(
        text_input_manager->GetTextSelection(updated_view)->selected_text());
    if (last_selected_text_ == expected_text_ && loop_runner_)
      loop_runner_->Quit();
  }

  const raw_ptr<TextInputManager> text_input_manager_;
  std::string last_selected_text_;
  std::string expected_text_;
  scoped_refptr<MessageLoopRunner> loop_runner_;
};

class SitePerProcessAndroidImeTest : public SitePerProcessBrowserTest {
 public:
  SitePerProcessAndroidImeTest() : SitePerProcessBrowserTest() {}

  SitePerProcessAndroidImeTest(const SitePerProcessAndroidImeTest&) = delete;
  SitePerProcessAndroidImeTest& operator=(const SitePerProcessAndroidImeTest&) =
      delete;

  ~SitePerProcessAndroidImeTest() override {}

 protected:
  ImeAdapterAndroid* ime_adapter() {
    return static_cast<RenderWidgetHostViewAndroid*>(
               web_contents()->GetRenderWidgetHostView())
        ->ime_adapter_for_testing();
  }

  void FocusInputInFrame(RenderFrameHostImpl* frame) {
    ASSERT_TRUE(ExecJs(frame, "window.focus(); input.focus();"));
  }

  // Creates a page with multiple (nested) OOPIFs and populates all of them
  // with an <input> element along with the required handlers for the test.
  void LoadPage() {
    ASSERT_TRUE(NavigateToURL(
        shell(),
        GURL(embedded_test_server()->GetURL(
            "a.com", "/cross_site_iframe_factory.html?a(b,c(a(b)))"))));
    FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
    frames_.push_back(root->current_frame_host());
    frames_.push_back(root->child_at(0)->current_frame_host());
    frames_.push_back(root->child_at(1)->current_frame_host());
    frames_.push_back(root->child_at(1)->child_at(0)->current_frame_host());
    frames_.push_back(
        root->child_at(1)->child_at(0)->child_at(0)->current_frame_host());

    // Adds an <input> to frame and sets up a handler for |window.oninput|. When
    // the input event is fired (by changing the value of <input> element), the
    // handler will select all the text so that the corresponding text selection
    // update on the browser side notifies the test about input insertion.
    std::string add_input_script =
        "var input = document.createElement('input');"
        "document.body.appendChild(input);"
        "window.oninput = function() {"
        "  input.select();"
        "};";

    for (content::RenderFrameHostImpl* frame : frames_) {
      ASSERT_TRUE(ExecJs(frame, add_input_script));
    }
  }

  // This methods tries to commit |text| by simulating a native call from Java.
  void CommitText(const char* text) {
    JNIEnv* env = base::android::AttachCurrentThread();

    // A valid caller is needed for ImeAdapterAndroid::GetUnderlinesFromSpans.
    base::android::ScopedJavaLocalRef<jobject> caller =
        ime_adapter()->java_ime_adapter_for_testing(env);

    // Input string from Java side.
    base::android::ScopedJavaLocalRef<jstring> jtext =
        base::android::ConvertUTF8ToJavaString(env, text);

    // Simulating a native call from Java side.
    ime_adapter()->CommitText(env, caller, jtext, jtext, 0);
  }

  std::vector<raw_ptr<RenderFrameHostImpl, VectorExperimental>> frames_;
};

// This test verifies that committing text will be applied on the focused
// RenderWidgetHost.
IN_PROC_BROWSER_TEST_P(SitePerProcessAndroidImeTest,
                       CommitTextForFocusedWidget) {
  LoadPage();
  TextSelectionObserver selection_observer(
      web_contents()->GetTextInputManager());
  for (size_t index = 0; index < frames_.size(); ++index) {
    std::string text = base::StringPrintf("text%zu", index);
    FocusInputInFrame(frames_[index]);
    CommitText(text.c_str());
    selection_observer.WaitForSelectedText(text);
  }
}
#endif  // BUILDFLAG(IS_ANDROID)

// Test that an OOPIF at b.com can navigate to a cross-site a.com URL that
// transfers back to b.com.  See https://crbug.com/681077#c10 and
// https://crbug.com/660407.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       SubframeTransfersToCurrentRFH) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)"));
  ASSERT_TRUE(NavigateToURL(shell(), main_url));

  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
                            ->GetPrimaryFrameTree()
                            .root();
  scoped_refptr<SiteInstanceImpl> b_site_instance =
      root->child_at(0)->current_frame_host()->GetSiteInstance();

  // Navigate subframe to a URL that will redirect from a.com back to b.com.
  // This navigation shouldn't time out.  Also ensure that the pending RFH
  // that was created for a.com is destroyed.
  GURL frame_url(
      embedded_test_server()->GetURL("a.com", "/cross-site/b.com/title2.html"));
  NavigateIframeToURL(shell()->web_contents(), "child-0", frame_url);
  EXPECT_FALSE(root->child_at(0)->render_manager()->speculative_frame_host());
  GURL redirected_url(embedded_test_server()->GetURL("b.com", "/title2.html"));
  EXPECT_EQ(root->child_at(0)->current_url(), redirected_url);
  EXPECT_EQ(b_site_instance,
            root->child_at(0)->current_frame_host()->GetSiteInstance());

  // Try the same navigation, but use the browser-initiated path.
  NavigateFrameToURL(root->child_at(0), frame_url);
  EXPECT_FALSE(root->child_at(0)->render_manager()->speculative_frame_host());
  EXPECT_EQ(root->child_at(0)->current_url(), redirected_url);
  EXPECT_EQ(b_site_instance,
            root->child_at(0)->current_frame_host()->GetSiteInstance());
}

IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       FrameSwapPreservesUniqueName) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(a)"));
  ASSERT_TRUE(NavigateToURL(shell(), main_url));

  // Navigate the subframe cross-site…
  {
    GURL url(embedded_test_server()->GetURL("b.com", "/title1.html"));
    EXPECT_TRUE(NavigateIframeToURL(shell()->web_contents(), "child-0", url));
  }
  // and then same-site…
  {
    GURL url(embedded_test_server()->GetURL("a.com", "/title1.html"));
    EXPECT_TRUE(NavigateIframeToURL(shell()->web_contents(), "child-0", url));
  }
  // and cross-site once more.
  {
    GURL url(embedded_test_server()->GetURL("b.com", "/title1.html"));
    EXPECT_TRUE(NavigateIframeToURL(shell()->web_contents(), "child-0", url));
  }

  // Inspect the navigation entries and make sure that the navigation target
  // remained constant across frame swaps.
  auto& controller = static_cast<NavigationControllerImpl&>(
      shell()->web_contents()->GetController());
  EXPECT_EQ(4, controller.GetEntryCount());

  std::set<std::string> names;
  for (int i = 0; i < controller.GetEntryCount(); ++i) {
    NavigationEntryImpl::TreeNode* root =
        controller.GetEntryAtIndex(i)->root_node();
    ASSERT_EQ(1U, root->children.size());
    names.insert(root->children[0]->frame_entry->frame_unique_name());
  }

  // More than one entry in the set means that the subframe frame navigation
  // entries didn't have a consistent unique name. This will break history
  // navigations =(
  EXPECT_THAT(names, SizeIs(1)) << "Mismatched names for subframe!";
}

// Tests that POST body is not lost when it targets a OOPIF.
// See https://crbug.com/710937.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest, PostTargetSubFrame) {
  // Navigate to a page with an OOPIF.
  GURL main_url(
      embedded_test_server()->GetURL("/frame_tree/page_with_one_frame.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));
  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
                            ->GetPrimaryFrameTree()
                            .root();

  // The main frame and the subframe live on different processes.
  EXPECT_EQ(1u, root->child_count());
  EXPECT_NE(root->current_frame_host()->GetSiteInstance(),
            root->child_at(0)->current_frame_host()->GetSiteInstance());

  // Make a form submission from the main frame and target the OOPIF.
  GURL form_url(embedded_test_server()->GetURL("/echoall"));
  TestNavigationObserver form_post_observer(shell()->web_contents(), 1);
  EXPECT_TRUE(ExecJs(shell()->web_contents(), JsReplace(R"(
    var form = document.createElement('form');

    // POST form submission to /echoall.
    form.setAttribute("method", "POST");
    form.setAttribute("action", $1);

    // Target the OOPIF.
    form.setAttribute("target", "child-name-0");

    // Add some POST data: "my_token=my_value";
    var input = document.createElement("input");
    input.setAttribute("type", "hidden");
    input.setAttribute("name", "my_token");
    input.setAttribute("value", "my_value");
    form.appendChild(input);

    // Submit the form.
    document.body.appendChild(form);
    form.submit();
  )",
                                                        form_url)));
  form_post_observer.Wait();

  NavigationEntryImpl* entry = static_cast<NavigationEntryImpl*>(
      shell()->web_contents()->GetController().GetLastCommittedEntry());
  // TODO(arthursonzogni): This is wrong. The last committed entry was
  // renderer-initiated. See https://crbug.com/722251.
  EXPECT_FALSE(entry->is_renderer_initiated());

  // Verify that POST body was correctly passed to the server and ended up in
  // the body of the page.
  EXPECT_EQ("my_token=my_value\n",
            EvalJs(root->child_at(0),
                   "document.getElementsByTagName('pre')[0].innerText;"));
}

// Tests that POST method and body is not lost when an OOPIF submits a form
// that targets the main frame.  See https://crbug.com/806215.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       PostTargetsMainFrameFromOOPIF) {
  // Navigate to a page with an OOPIF.
  GURL main_url(
      embedded_test_server()->GetURL("/frame_tree/page_with_one_frame.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();

  // The main frame and the subframe live on different processes.
  EXPECT_EQ(1u, root->child_count());
  EXPECT_NE(root->current_frame_host()->GetSiteInstance(),
            root->child_at(0)->current_frame_host()->GetSiteInstance());

  // Make a form submission from the subframe and target its parent frame.
  GURL form_url(embedded_test_server()->GetURL("/echoall"));
  TestNavigationObserver form_post_observer(web_contents());
  EXPECT_TRUE(
      ExecJs(root->child_at(0)->current_frame_host(), JsReplace(R"(
    var form = document.createElement('form');

    // POST form submission to /echoall.
    form.setAttribute("method", "POST");
    form.setAttribute("action", $1);

    // Target the parent.
    form.setAttribute("target", "_parent");

    // Add some POST data: "my_token=my_value";
    var input = document.createElement("input");
    input.setAttribute("type", "hidden");
    input.setAttribute("name", "my_token");
    input.setAttribute("value", "my_value");
    form.appendChild(input);

    // Submit the form.
    document.body.appendChild(form);
    form.submit();
  )",
                                                                form_url)));
  form_post_observer.Wait();

  // Verify that the FrameNavigationEntry's method is POST.
  NavigationEntryImpl* entry = static_cast<NavigationEntryImpl*>(
      web_contents()->GetController().GetLastCommittedEntry());
  EXPECT_EQ("POST", entry->root_node()->frame_entry->method());

  // Verify that POST body was correctly passed to the server and ended up in
  // the body of the page.
  EXPECT_EQ("my_token=my_value\n",
            EvalJs(root, "document.getElementsByTagName('pre')[0].innerText"));

  // Reload the main frame and ensure the POST body is preserved.  This checks
  // that the POST body was saved in the FrameNavigationEntry.
  web_contents()->GetController().Reload(ReloadType::NORMAL,
                                         false /* check_for_repost */);
  EXPECT_TRUE(WaitForLoadStop(web_contents()));
  EXPECT_EQ("my_token=my_value\n",
            EvalJs(root, "document.getElementsByTagName('pre')[0].innerText"));
}

// Verify that a remote-to-local main frame navigation doesn't overwrite
// the previous history entry.  See https://crbug.com/725716.
IN_PROC_BROWSER_TEST_P(
    SitePerProcessBrowserTest,
    DISABLED_CrossProcessMainFrameNavigationDoesNotOverwriteHistory) {
  GURL foo_url(embedded_test_server()->GetURL("foo.com", "/title1.html"));
  GURL bar_url(embedded_test_server()->GetURL("bar.com", "/title2.html"));

  EXPECT_TRUE(NavigateToURL(shell(), foo_url));

  // Open a same-site popup to keep the www.foo.com process alive.
  OpenPopup(shell(), GURL(url::kAboutBlankURL), "foo");

  // Navigate foo -> bar -> foo.
  EXPECT_TRUE(NavigateToURLFromRenderer(shell(), bar_url));
  EXPECT_TRUE(NavigateToURLFromRenderer(shell(), foo_url));

  // There should be three history entries.
  EXPECT_EQ(3, web_contents()->GetController().GetEntryCount());

  // Go back: this should go to bar.com.
  {
    TestNavigationObserver back_observer(web_contents());
    web_contents()->GetController().GoBack();
    back_observer.Wait();
  }
  EXPECT_EQ(bar_url,
            web_contents()->GetPrimaryMainFrame()->GetLastCommittedURL());

  // Go back again.  This should go to foo.com.
  {
    TestNavigationObserver back_observer(web_contents());
    web_contents()->GetController().GoBack();
    back_observer.Wait();
  }
  EXPECT_EQ(foo_url,
            web_contents()->GetPrimaryMainFrame()->GetLastCommittedURL());
}

// The test is flaky on Linux, Chrome OS, etc; cf https://crbug.com/1170583.
#if BUILDFLAG(IS_POSIX)
#define MAYBE_CrossProcessInertSubframe DISABLED_CrossProcessInertSubframe
#else
#define MAYBE_CrossProcessInertSubframe CrossProcessInertSubframe
#endif
// Tests that when an out-of-process iframe becomes inert due to a modal
// <dialog> element, the contents of the iframe can still take focus.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       MAYBE_CrossProcessInertSubframe) {
  // This uses a(b,b) instead of a(b) to preserve the b.com process even when
  // the first subframe is navigated away from it.
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b,b)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
                            ->GetPrimaryFrameTree()
                            .root();
  ASSERT_EQ(2U, root->child_count());

  FrameTreeNode* iframe_node = root->child_at(0);

  EXPECT_TRUE(ExecJs(
      iframe_node,
      "document.head.innerHTML = '';"
      "document.body.innerHTML = '<input id=\"text1\"> <input id=\"text2\">';"
      "text1.focus();"));

  // Add a <dialog> to the root frame and call showModal on it.
  EXPECT_TRUE(ExecJs(root,
                     "let dialog = "
                     "document.body.appendChild(document.createElement('"
                     "dialog'));"
                     "dialog.innerHTML = 'Modal dialog <input>';"
                     "dialog.showModal();"));

  // Yield the UI thread to ensure that the real SetIsInert message
  // handler runs, in order to guarantee that the update arrives at the
  // renderer process before the script below.
  base::RunLoop().RunUntilIdle();

  RenderFrameProxyHost* root_proxy =
      iframe_node->render_manager()->GetProxyToParent();
  EXPECT_TRUE(root_proxy->IsInertForTesting());

  std::string focused_element;

  // Attempt to change focus in the inert subframe. This should work.
  // The setTimeout ensures that the inert bit can propagate before the
  // test JS code runs.
  EXPECT_EQ("text2", EvalJs(iframe_node,
                            "new Promise(resolve => {"
                            "  window.setTimeout(() => {"
                            "    text2.focus();"
                            "    resolve(document.activeElement.id);"
                            "  }, 0);"
                            "});"));

  // Navigate the child frame to another site, so that it moves into a new
  // process.
  GURL site_url(embedded_test_server()->GetURL("c.com", "/title1.html"));
  EXPECT_TRUE(NavigateToURLFromRenderer(iframe_node, site_url));

  // NavigateToURLFromRenderer returns when the navigation commits, at which
  // point frame state has to be re-sent to the new frame. Yield the thread to
  // prevent races with the inertness update.
  base::RunLoop().RunUntilIdle();

  EXPECT_TRUE(ExecJs(
      iframe_node,
      "document.head.innerHTML = '';"
      "document.body.innerHTML = '<input id=\"text1\"> <input id=\"text2\">';"
      "text1.focus();"));

  // Verify we can still set focus after the navigation.
  EXPECT_EQ("text2", EvalJs(iframe_node,
                            "text2.focus();"
                            "document.activeElement.id;"));

  // Navigate the subframe back into its parent process to verify that the
  // new local frame remains non-inert.
  GURL same_site_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
  EXPECT_TRUE(NavigateToURLFromRenderer(iframe_node, same_site_url));

  EXPECT_TRUE(ExecJs(
      iframe_node,
      "document.head.innerHTML = '';"
      "document.body.innerHTML = '<input id=\"text1\"> <input id=\"text2\">';"
      "text1.focus();"));

  // Verify we can still set focus after the navigation.
  EXPECT_EQ("text2", EvalJs(iframe_node,
                            "text2.focus();"
                            "document.activeElement.id;"));
}

// Tests that IsInert frame flag is correctly updated and propagated.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       CrossProcessIsInertPropagation) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b(c))"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  FrameTreeNode* frame_a =
      static_cast<WebContentsImpl*>(shell()->web_contents())
          ->GetPrimaryFrameTree()
          .root();
  ASSERT_EQ(1U, frame_a->child_count());
  FrameTreeNode* frame_b = frame_a->child_at(0);
  ASSERT_EQ(1U, frame_b->child_count());
  FrameTreeNode* frame_c = frame_b->child_at(0);
  RenderFrameProxyHost* proxy_b = frame_b->render_manager()->GetProxyToParent();
  RenderFrameProxyHost* proxy_c = frame_c->render_manager()->GetProxyToParent();

  auto waitForInertPropagated = [&]() {
    // Force layout. This recomputes the element styles so that the <iframe>
    // gets the updated ComputedStyle::IsInert() flag. This triggers an update
    // of the associated RenderFrameProxyHost::IsInertForTesting().
    for (FrameTreeNode* frame : {frame_a, frame_b, frame_c})
      ExecuteScriptAsync(frame, "document.body.offsetLeft");

    // Propagating the inert flag requires sending messages in between the
    // browser and the renderers. Since they are using the same mojo interfaces
    // as ExecJs, waiting for an browser<->renderer roundtrip using ExecJs
    // should be enough to guarantee it has been propagate.
    for (FrameTreeNode* frame : {frame_a, frame_b, frame_c})
      EXPECT_TRUE(ExecJs(frame, "'Done'"));
  };

  waitForInertPropagated();
  EXPECT_FALSE(proxy_b->IsInertForTesting());
  EXPECT_FALSE(proxy_c->IsInertForTesting());

  // Make b inert, this should also make c inert.
  EXPECT_TRUE(ExecJs(frame_a, "document.body.inert = true;"));
  waitForInertPropagated();
  EXPECT_TRUE(proxy_b->IsInertForTesting());
  EXPECT_TRUE(proxy_c->IsInertForTesting());

  // Make b non-inert, this should also make c non-inert.
  EXPECT_TRUE(ExecJs(frame_a, "document.body.inert = false;"));
  waitForInertPropagated();
  EXPECT_FALSE(proxy_b->IsInertForTesting());
  EXPECT_FALSE(proxy_c->IsInertForTesting());

  // Make c inert.
  EXPECT_TRUE(ExecJs(frame_b, "document.body.inert = true;"));
  waitForInertPropagated();
  EXPECT_FALSE(proxy_b->IsInertForTesting());
  EXPECT_TRUE(proxy_c->IsInertForTesting());

  // Make b inert, c should continue being inert.
  EXPECT_TRUE(ExecJs(frame_a, "document.body.inert = true;"));
  waitForInertPropagated();
  EXPECT_TRUE(proxy_b->IsInertForTesting());
  EXPECT_TRUE(proxy_c->IsInertForTesting());

  // Try to make c non-inert, it should still be inert due to b.
  EXPECT_TRUE(ExecJs(frame_b, "document.body.inert = false;"));
  waitForInertPropagated();
  EXPECT_TRUE(proxy_b->IsInertForTesting());
  EXPECT_TRUE(proxy_c->IsInertForTesting());

  // Make b non-inert, this should also make c non-inert.
  EXPECT_TRUE(ExecJs(frame_a, "document.body.inert = false;"));
  waitForInertPropagated();
  EXPECT_FALSE(proxy_b->IsInertForTesting());
  EXPECT_FALSE(proxy_c->IsInertForTesting());

  // Make b anc inert.
  EXPECT_TRUE(ExecJs(frame_a, "document.body.inert = true;"));
  EXPECT_TRUE(ExecJs(frame_b, "document.body.inert = true;"));
  waitForInertPropagated();
  EXPECT_TRUE(proxy_b->IsInertForTesting());
  EXPECT_TRUE(proxy_c->IsInertForTesting());

  // Make b non-inert, c should continue being inert.
  EXPECT_TRUE(ExecJs(frame_a, "document.body.inert = false;"));
  waitForInertPropagated();
  EXPECT_FALSE(proxy_b->IsInertForTesting());
  EXPECT_TRUE(proxy_c->IsInertForTesting());
}

// Check that main frames for the same site rendering in unrelated tabs start
// sharing processes that are already dedicated to that site when over process
// limit. See https://crbug.com/513036.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       MainFrameProcessReuseWhenOverLimit) {
  // Set the process limit to 1.
  RenderProcessHost::SetMaxRendererProcessCount(1);

  GURL url_a(embedded_test_server()->GetURL("a.com", "/title1.html"));
  ASSERT_TRUE(NavigateToURL(shell(), url_a));

  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();

  // Create an unrelated shell window.
  GURL url_b(embedded_test_server()->GetURL("b.com", "/title2.html"));
  Shell* new_shell = CreateBrowser();
  EXPECT_TRUE(NavigateToURL(new_shell, url_b));

  FrameTreeNode* new_shell_root =
      static_cast<WebContentsImpl*>(new_shell->web_contents())
          ->GetPrimaryFrameTree()
          .root();

  // The new window's b.com root should not reuse the a.com process.
  EXPECT_NE(root->current_frame_host()->GetProcess(),
            new_shell_root->current_frame_host()->GetProcess());

  // Navigating the new window to a.com should reuse the first window's
  // process.
  EXPECT_TRUE(NavigateToURL(new_shell, url_a));
  EXPECT_EQ(root->current_frame_host()->GetProcess(),
            new_shell_root->current_frame_host()->GetProcess());
}

// Check that subframes for the same site rendering in unrelated tabs start
// sharing processes that are already dedicated to that site when over process
// limit. See https://crbug.com/513036.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       SubframeProcessReuseWhenOverLimit) {
  // Set the process limit to 1.
  RenderProcessHost::SetMaxRendererProcessCount(1);

  GURL first_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b,b(c))"));
  ASSERT_TRUE(NavigateToURL(shell(), first_url));

  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();

  // Processes for dedicated sites should never be reused.
  EXPECT_NE(root->current_frame_host()->GetProcess(),
            root->child_at(0)->current_frame_host()->GetProcess());
  EXPECT_NE(root->current_frame_host()->GetProcess(),
            root->child_at(1)->current_frame_host()->GetProcess());
  EXPECT_NE(root->current_frame_host()->GetProcess(),
            root->child_at(1)->child_at(0)->current_frame_host()->GetProcess());
  EXPECT_NE(root->child_at(1)->current_frame_host()->GetProcess(),
            root->child_at(1)->child_at(0)->current_frame_host()->GetProcess());
  EXPECT_EQ(root->child_at(0)->current_frame_host()->GetProcess(),
            root->child_at(1)->current_frame_host()->GetProcess());

  // Create an unrelated shell window.
  Shell* new_shell = CreateBrowser();

  GURL new_shell_url(embedded_test_server()->GetURL(
      "d.com", "/cross_site_iframe_factory.html?d(a(b))"));
  ASSERT_TRUE(NavigateToURL(new_shell, new_shell_url));

  FrameTreeNode* new_shell_root =
      static_cast<WebContentsImpl*>(new_shell->web_contents())
          ->GetPrimaryFrameTree()
          .root();

  // New tab's root (d.com) should go into a separate process.
  EXPECT_NE(root->current_frame_host()->GetProcess(),
            new_shell_root->current_frame_host()->GetProcess());
  EXPECT_NE(root->child_at(0)->current_frame_host()->GetProcess(),
            new_shell_root->current_frame_host()->GetProcess());
  EXPECT_NE(root->child_at(1)->child_at(0)->current_frame_host()->GetProcess(),
            new_shell_root->current_frame_host()->GetProcess());

  // The new tab's subframe should reuse the a.com process.
  EXPECT_EQ(root->current_frame_host()->GetProcess(),
            new_shell_root->child_at(0)->current_frame_host()->GetProcess());

  // The new tab's grandchild frame should reuse the b.com process.
  EXPECT_EQ(root->child_at(0)->current_frame_host()->GetProcess(),
            new_shell_root->child_at(0)
                ->child_at(0)
                ->current_frame_host()
                ->GetProcess());
}

// Check that when a main frame and a subframe start navigating to the same
// cross-site URL at the same time, the new RenderFrame for the subframe is
// created successfully without crashing, and the navigations complete
// successfully.  This test checks the scenario where the main frame ends up
// committing before the subframe, and the test below checks the case where the
// subframe commits first.
//
// This used to be problematic in that the main frame navigation created an
// active RenderViewHost with a RenderFrame already swapped into the tree, and
// then while that navigation was still pending, the subframe navigation
// created its RenderFrame, which crashed when referencing its parent by a
// proxy which didn't exist.
//
// All cross-process navigations now require creating a `blink::RemoteFrame`
// before creating a RenderFrame, which makes such navigations follow the
// provisional frame (remote-to-local navigation) paths, where such a scenario
// is no longer possible.  See https://crbug.com/756790.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       TwoCrossSitePendingNavigationsAndMainFrameWins) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(a)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  FrameTreeNode* child = root->child_at(0);

  // Navigate both frames cross-site to b.com simultaneously.
  GURL new_url_1(embedded_test_server()->GetURL("b.com", "/title1.html"));
  GURL new_url_2(embedded_test_server()->GetURL("b.com", "/title2.html"));
  TestNavigationManager manager1(web_contents(), new_url_1);
  TestNavigationManager manager2(web_contents(), new_url_2);
  auto script = JsReplace("location = $1; frames[0].location = $2;", new_url_1,
                          new_url_2);
  EXPECT_TRUE(ExecJs(web_contents(), script));

  // Wait for main frame request, but don't commit it yet.  This should create
  // a speculative RenderFrameHost.
  manager1.WaitForSpeculativeRenderFrameHostCreation();
  RenderFrameHostImpl* root_speculative_rfh =
      root->render_manager()->speculative_frame_host();
  EXPECT_TRUE(root_speculative_rfh);
  scoped_refptr<SiteInstanceImpl> b_root_site_instance(
      root_speculative_rfh->GetSiteInstance());

  // There should now be a live b.com proxy for the root, since it is doing a
  // cross-process navigation.
  RenderFrameProxyHost* root_proxy =
      root->current_frame_host()
          ->browsing_context_state()
          ->GetRenderFrameProxyHost(b_root_site_instance->group());
  EXPECT_TRUE(root_proxy);
  EXPECT_TRUE(root_proxy->is_render_frame_proxy_live());

  // Wait for subframe request, but don't commit it yet.
  manager2.WaitForSpeculativeRenderFrameHostCreation();
  RenderFrameHostImpl* subframe_speculative_rfh =
      child->render_manager()->speculative_frame_host();
  EXPECT_TRUE(child->render_manager()->speculative_frame_host());
  scoped_refptr<SiteInstanceImpl> b_subframe_site_instance(
      subframe_speculative_rfh->GetSiteInstance());

  // Similarly, the subframe should also have a b.com proxy (unused in this
  // test), since it is also doing a cross-process navigation.
  RenderFrameProxyHost* child_proxy =
      child->current_frame_host()
          ->browsing_context_state()
          ->GetRenderFrameProxyHost(b_subframe_site_instance->group());
  EXPECT_TRUE(child_proxy);
  EXPECT_TRUE(child_proxy->is_render_frame_proxy_live());

  // Now let the main frame commit.
  ASSERT_TRUE(manager1.WaitForNavigationFinished());

  // Make sure the process is live and at the new URL.
  EXPECT_TRUE(b_root_site_instance->GetProcess()->IsInitializedAndNotDead());
  EXPECT_TRUE(root->current_frame_host()->IsRenderFrameLive());
  EXPECT_EQ(root_speculative_rfh, root->current_frame_host());
  EXPECT_EQ(new_url_1, root->current_frame_host()->GetLastCommittedURL());

  // The subframe should be gone, so the second navigation should have no
  // effect.
  ASSERT_TRUE(manager2.WaitForNavigationFinished());

  // The new commit should have detached the old child frame.
  EXPECT_EQ(0U, root->child_count());
  EXPECT_EQ(0, EvalJs(web_contents(), "frames.length;"));

  // The root proxy should be gone.
  if (b_subframe_site_instance->group()) {
    EXPECT_FALSE(
        root->current_frame_host()
            ->browsing_context_state()
            ->GetRenderFrameProxyHost(b_subframe_site_instance->group()));
  }
}

// Similar to TwoCrossSitePendingNavigationsAndMainFrameWins, but checks the
// case where the subframe navigation commits before the main frame.  See
// https://crbug.com/756790.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       TwoCrossSitePendingNavigationsAndSubframeWins) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(a,a)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  FrameTreeNode* child = root->child_at(0);
  FrameTreeNode* child2 = root->child_at(1);

  // Install postMessage handlers in main frame and second subframe for later
  // use.
  EXPECT_TRUE(ExecJs(root->current_frame_host(),
                     "window.addEventListener('message', function(event) {\n"
                     "  event.source.postMessage(event.data + '-reply', '*');\n"
                     "});"));
  EXPECT_TRUE(ExecJs(
      child2->current_frame_host(),
      "window.addEventListener('message', function(event) {\n"
      "  event.source.postMessage(event.data + '-subframe-reply', '*');\n"
      "});"));

  // Start a main frame navigation to b.com.
  GURL new_url_1(embedded_test_server()->GetURL("b.com", "/title1.html"));
  TestNavigationManager manager1(web_contents(), new_url_1);
  EXPECT_TRUE(ExecJs(web_contents(), JsReplace("location = $1", new_url_1)));

  // Wait for main frame request and check the frame tree.  There should be a
  // proxy for b.com at the root, but nowhere else at this point.
  manager1.WaitForSpeculativeRenderFrameHostCreation();
  EXPECT_EQ(
      " Site A (B speculative) -- proxies for B\n"
      "   |--Site A\n"
      "   +--Site A\n"
      "Where A = http://a.com/\n"
      "      B = http://b.com/",
      DepictFrameTree(root));

  // Now start navigating the first subframe to b.com.
  GURL new_url_2(embedded_test_server()->GetURL("b.com", "/title2.html"));
  TestNavigationManager manager2(web_contents(), new_url_2);
  EXPECT_TRUE(
      ExecJs(web_contents(), JsReplace("frames[0].location = $1", new_url_2)));

  // Wait for subframe request.
  manager2.WaitForSpeculativeRenderFrameHostCreation();
  RenderFrameHostImpl* child_speculative_rfh =
      child->render_manager()->speculative_frame_host();
  EXPECT_TRUE(child_speculative_rfh);
  scoped_refptr<SiteInstanceImpl> b_site_instance(
      child_speculative_rfh->GetSiteInstance());

  // Check that all frames have proxies for b.com at this point. The proxy for
  // |child2| is important to create since |child| has to use it to communicate
  // with |child2| if |child| commits first.
  if (CanCrossSiteNavigationsProactivelySwapBrowsingInstances()) {
    // With ProactivelySwapBrowsingInstance, the new main document and the new
    // iframe don't have the same SiteInstance, because they belong to two
    // unrelated pages. The two page use different BrowsingInstances.
    EXPECT_EQ(
        " Site A (B speculative) -- proxies for B C\n"
        "   |--Site A (C speculative) -- proxies for C\n"
        "   +--Site A ------- proxies for C\n"
        "Where A = http://a.com/\n"
        "      B = http://b.com/\n"
        "      C = http://b.com/",
        DepictFrameTree(root));
  } else {
    EXPECT_EQ(
        " Site A (B speculative) -- proxies for B\n"
        "   |--Site A (B speculative) -- proxies for B\n"
        "   +--Site A ------- proxies for B\n"
        "Where A = http://a.com/\n"
        "      B = http://b.com/",
        DepictFrameTree(root));
  }

  // Now let the subframe commit.
  ASSERT_TRUE(manager2.WaitForNavigationFinished());

  // Make sure the process is live and at the new URL.
  EXPECT_TRUE(b_site_instance->GetProcess()->IsInitializedAndNotDead());
  ASSERT_EQ(2U, root->child_count());
  EXPECT_TRUE(child->current_frame_host()->IsRenderFrameLive());
  EXPECT_EQ(child_speculative_rfh, child->current_frame_host());
  EXPECT_EQ(new_url_2, child->current_frame_host()->GetLastCommittedURL());

  // Recheck the proxies.  Main frame should still be pending.
  if (CanCrossSiteNavigationsProactivelySwapBrowsingInstances()) {
    EXPECT_EQ(
        " Site A (B speculative) -- proxies for B C\n"
        "   |--Site C ------- proxies for A\n"
        "   +--Site A ------- proxies for C\n"
        "Where A = http://a.com/\n"
        "      B = http://b.com/\n"
        "      C = http://b.com/",
        DepictFrameTree(root));
  } else {
    EXPECT_EQ(
        " Site A (B speculative) -- proxies for B\n"
        "   |--Site B ------- proxies for A\n"
        "   +--Site A ------- proxies for B\n"
        "Where A = http://a.com/\n"
        "      B = http://b.com/",
        DepictFrameTree(root));
  }

  // Make sure the subframe can communicate to both the root remote frame
  // (where the postMessage should go to the current RenderFrameHost rather
  // than the pending one) and its sibling remote frame in the a.com process.
  EXPECT_TRUE(
      ExecJs(child->current_frame_host(), WaitForMessageScript("event.data")));
  EXPECT_TRUE(ExecJs(child, "parent.postMessage('root-ping', '*')"));
  EXPECT_EQ("root-ping-reply",
            EvalJs(child->current_frame_host(), "onMessagePromise"));

  EXPECT_TRUE(
      ExecJs(child->current_frame_host(), WaitForMessageScript("event.data")));
  EXPECT_TRUE(
      ExecJs(child, "parent.frames[1].postMessage('sibling-ping', '*')"));
  EXPECT_EQ("sibling-ping-subframe-reply",
            EvalJs(child->current_frame_host(), "onMessagePromise"));

  // Cancel the pending main frame navigation, and verify that the subframe can
  // still communicate with the (old) main frame.
  root->navigator().CancelNavigation(
      root, NavigationDiscardReason::kExplicitCancellation);
  EXPECT_FALSE(root->render_manager()->speculative_frame_host());

  EXPECT_TRUE(
      ExecJs(child->current_frame_host(), WaitForMessageScript("event.data")));
  EXPECT_TRUE(ExecJs(child, "parent.postMessage('root-ping', '*')"));
  EXPECT_EQ("root-ping-reply",
            EvalJs(child->current_frame_host(), "onMessagePromise"));
}

// Similar to TwoCrossSitePendingNavigations* tests above, but checks the case
// where the current window and its opener navigate simultaneously.
// See https://crbug.com/756790.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       TwoCrossSitePendingNavigationsWithOpener) {
  GURL main_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();

  // Install a postMessage handler in main frame for later use.
  EXPECT_TRUE(ExecJs(web_contents(),
                     "window.addEventListener('message', function(event) {\n"
                     "  event.source.postMessage(event.data + '-reply', '*');\n"
                     "});"));

  Shell* popup_shell =
      OpenPopup(shell()->web_contents(), GURL(url::kAboutBlankURL), "popup");

  // Start a navigation to b.com in the first (opener) tab.
  GURL new_url_1(embedded_test_server()->GetURL("b.com", "/title1.html"));
  TestNavigationManager manager(web_contents(), new_url_1);
  EXPECT_TRUE(ExecJs(web_contents(), JsReplace("location = $1", new_url_1)));
  manager.WaitForSpeculativeRenderFrameHostCreation();

  // Before it commits, start and commit a navigation to b.com in the second
  // tab.
  GURL new_url_2(embedded_test_server()->GetURL("b.com", "/title2.html"));
  EXPECT_TRUE(NavigateToURLFromRenderer(popup_shell, new_url_2));

  // Check that the opener still has a speculative RenderFrameHost and a
  // corresponding proxy for b.com.
  RenderFrameHostImpl* speculative_rfh =
      root->render_manager()->speculative_frame_host();
  EXPECT_TRUE(speculative_rfh);
  scoped_refptr<SiteInstanceImpl> b_site_instance(
      speculative_rfh->GetSiteInstance());
  RenderFrameProxyHost* proxy =
      root->current_frame_host()
          ->browsing_context_state()
          ->GetRenderFrameProxyHost(b_site_instance->group());
  EXPECT_TRUE(proxy);
  EXPECT_TRUE(proxy->is_render_frame_proxy_live());

  // Make sure the second tab can communicate to its (old) opener remote frame.
  // The postMessage should go to the current RenderFrameHost rather than the
  // pending one in the first tab's main frame.
  EXPECT_TRUE(
      ExecJs(popup_shell->web_contents(), WaitForMessageScript("event.data")));

  EXPECT_TRUE(ExecJs(popup_shell->web_contents(),
                     "opener.postMessage('opener-ping', '*');"));
  EXPECT_EQ("opener-ping-reply",
            EvalJs(popup_shell->web_contents(), "onMessagePromise"));

  // Cancel the pending main frame navigation, and verify that the subframe can
  // still communicate with the (old) main frame.
  root->navigator().CancelNavigation(
      root, NavigationDiscardReason::kExplicitCancellation);
  EXPECT_FALSE(root->render_manager()->speculative_frame_host());

  EXPECT_TRUE(
      ExecJs(popup_shell->web_contents(), WaitForMessageScript("event.data")));
  EXPECT_TRUE(ExecJs(popup_shell->web_contents(),
                     "opener.postMessage('opener-ping', '*')"));
  EXPECT_EQ("opener-ping-reply",
            EvalJs(popup_shell->web_contents(), "onMessagePromise"));
}

IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       DetachSpeculativeRenderFrameHost) {
  // Commit a page with one iframe.
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(a)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  // Start a cross-site navigation.
  GURL cross_site_url(embedded_test_server()->GetURL("b.com", "/title2.html"));
  TestNavigationManager nav_manager(shell()->web_contents(), cross_site_url);
  BeginNavigateIframeToURL(web_contents(), "child-0", cross_site_url);

  // Wait for the request, but don't commit it yet. This should create a
  // speculative RenderFrameHost.
  nav_manager.WaitForSpeculativeRenderFrameHostCreation();
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  RenderFrameHostImpl* speculative_rfh = root->current_frame_host()
                                             ->child_at(0)
                                             ->render_manager()
                                             ->speculative_frame_host();
  EXPECT_TRUE(speculative_rfh);

  // Currently, the browser process never handles an explicit Detach() for a
  // speculative RFH, since the speculative RFH or the entire FTN is always
  // destroyed before the renderer sends this IPC.
  speculative_rfh->Detach();

  // Passes if there is no crash.
}

// Tests what happens if the renderer attempts to cancel a navigation after the
// NavigationRequest has already reached READY_TO_COMMIT.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       CancelNavigationAfterReadyToCommit) {
  class NavigationCanceller : public WebContentsObserver {
   public:
    NavigationCanceller(WebContents* web_contents,
                        RenderFrameHost& requesting_rfh)
        : WebContentsObserver(web_contents), requesting_rfh_(requesting_rfh) {}

    // WebContentsObserver overrides:
    void ReadyToCommitNavigation(NavigationHandle* navigation_handle) override {
      // Cancel the navigation in the renderer, but don't wait for the
      // reply. This is to ensure the browser process does not process any
      // incoming messages and learn about the renderer's cancellation
      // before the browser process dispatches a CommitNavigation() to the
      // renderer.
      ExecuteScriptAsync(&*requesting_rfh_, "window.stop()");
    }

   private:
    const raw_ref<RenderFrameHost, AcrossTasksDanglingUntriaged>
        requesting_rfh_;
  };

  // Set up a test page with a same-site child frame.
  // TODO(dcheng): In the future, it might be useful to also have a test where
  // the child frame is same-site but cross-origin, and have the parent
  // initiate the navigation in the child frame.
  GURL url1(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(a)"));
  EXPECT_TRUE(NavigateToURL(web_contents(), url1));

  // Now navigate the first child to another same-site page. Note that with
  // subframe RenderDocument, this will create a speculative RFH.
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  GURL url2(embedded_test_server()->GetURL("a.com", "/title1.html"));
  TestNavigationManager nav_manager(web_contents(), url2);
  FrameTreeNode* first_child = root->child_at(0);
  EXPECT_TRUE(BeginNavigateToURLFromRenderer(
      first_child->render_manager()->current_frame_host(), url2));

  EXPECT_TRUE(nav_manager.WaitForResponse());

  bool using_speculative_rfh =
      !!first_child->render_manager()->speculative_frame_host();

  NavigationCanceller canceller(
      web_contents(), *first_child->render_manager()->current_frame_host());

  ASSERT_TRUE(nav_manager.WaitForNavigationFinished());
  // The navigation should be committed if and only if it committed in a new
  // RFH (i.e. if the navigation used a speculative RFH).
  EXPECT_EQ(using_speculative_rfh, nav_manager.was_committed());
}

namespace {

// Helper for various <object> navigation test cases that trigger fallback
// handling. Fallback handling should never reach ready-to-commit navigation, so
// this helper forces test failure if a ReadyToCommitNavigation() is received.
class AssertNoReadyToCommitNavigationCalls : public WebContentsObserver {
 public:
  explicit AssertNoReadyToCommitNavigationCalls(WebContents* contents)
      : WebContentsObserver(contents) {}

 private:
  // WebContentsObserver overrides:
  void ReadyToCommitNavigation(NavigationHandle* handle) override {
    ASSERT_TRUE(false);
  }
};

}  // namespace

// Test that a same-site navigation in <object> that fails with an HTTP error
// directly triggers fallback handling, rather than triggering fallback handling
// in the renderer after it receives a `CommitNavigation()` IPC.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       ObjectTagSameSiteNavigationWithHTTPError) {
  // Set up a test page with a same-site child frame hosted in an <object> tag.
  // TODO(dcheng): In the future, it might be useful to also have a test where
  // the child frame is same-site but cross-origin, and have the parent
  // initiate the navigation in the child frame.
  GURL url1(embedded_test_server()->GetURL("a.com", "/object-frame.html"));
  EXPECT_TRUE(NavigateToURL(web_contents(), url1));

  // There should be one nested browsing context.
  EXPECT_EQ(1, EvalJs(web_contents(), "window.length"));
  // And there should be no fallback content displayed.
  EXPECT_EQ("", EvalJs(web_contents(), "document.body.innerText"));

  // <object> fallback handling should never reach ReadyToCommitNavigation.
  AssertNoReadyToCommitNavigationCalls asserter(web_contents());

  // Now navigate the first child to a same-site page that will result in a 404.
  // Note that with subframe RenderDocument, this will create a speculative RFH.
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  GURL url2(embedded_test_server()->GetURL("a.com", "/page404.html"));
  TestNavigationManager nav_manager(web_contents(), url2);
  FrameTreeNode* first_child = root->child_at(0);
  EXPECT_TRUE(BeginNavigateToURLFromRenderer(
      first_child->render_manager()->current_frame_host(), url2));

  const bool using_speculative_rfh =
      !!first_child->render_manager()->speculative_frame_host();
  // Speculative RFH will not be created at this point if we enable deferring.
  EXPECT_EQ(using_speculative_rfh,
            GetRenderDocumentLevel() >= RenderDocumentLevel::kSubframe &&
                !base::FeatureList::IsEnabled(
                    features::kDeferSpeculativeRFHCreation));

  ASSERT_TRUE(nav_manager.WaitForNavigationFinished());
  // There should be no commit...
  EXPECT_FALSE(nav_manager.was_committed());
  // .. and the navigation should have been aborted.
  EXPECT_FALSE(nav_manager.was_successful());
  // Fallback handling should discard the child browsing context and render the
  // fallback contents.
  EXPECT_EQ(0, EvalJs(web_contents(), "window.length"));
  EXPECT_EQ("fallback", EvalJs(web_contents(), "document.body.innerText"));
}

// Test that a cross-site navigation in <object> that fails with an HTTP error
// directly triggers fallback handling, rather than triggering fallback handling
// in the renderer after it receives a `CommitNavigation()` IPC.
// The test disables the delay of creating the speculative RFH since it
// will check the created speculative RFH for a failing request. The speculative
// RFH will not be created after receiving the 404 response.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTestWithoutSpeculativeRFHDelay,
                       ObjectTagCrossSiteNavigationWithHTTPError) {
  // Set up a test page with a same-site child frame hosted in an <object> tag.
  // TODO(dcheng): In the future, it might be useful to also have a test where
  // the child frame is same-site but cross-origin, and have the parent
  // initiate the navigation in the child frame.
  GURL url1(embedded_test_server()->GetURL("a.com", "/object-frame.html"));
  EXPECT_TRUE(NavigateToURL(web_contents(), url1));

  // There should be one nested browsing context.
  EXPECT_EQ(1, EvalJs(web_contents(), "window.length"));
  // And there should be no fallback content displayed.
  EXPECT_EQ("", EvalJs(web_contents(), "document.body.innerText"));

  // <object> fallback handling should never reach ReadyToCommitNavigation.
  AssertNoReadyToCommitNavigationCalls asserter(web_contents());

  // Now navigate the first child to a cross-site page that will result in a
  // 404.
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  GURL url2(embedded_test_server()->GetURL("b.com", "/page404.html"));
  TestNavigationManager nav_manager(web_contents(), url2);
  FrameTreeNode* first_child = root->child_at(0);
  EXPECT_TRUE(BeginNavigateToURLFromRenderer(
      first_child->render_manager()->current_frame_host(), url2));
  nav_manager.WaitForSpeculativeRenderFrameHostCreation();
  // Cross-site navigations always force a speculative RFH to be created.
  EXPECT_TRUE(first_child->render_manager()->speculative_frame_host());

  ASSERT_TRUE(nav_manager.WaitForNavigationFinished());
  // There should be no commit...
  EXPECT_FALSE(nav_manager.was_committed());
  // .. and the navigation should have been aborted.
  EXPECT_FALSE(nav_manager.was_successful());
  // Fallback handling should discard the child browsing context and render the
  // fallback contents.
  EXPECT_EQ(0, EvalJs(web_contents(), "window.length"));
  EXPECT_EQ("fallback", EvalJs(web_contents(), "document.body.innerText"));
}

// Test that a same-site navigation in <object> that fails with an HTTP error
// and also subsequently fails to load the body still directly triggers fallback
// handling, rather than triggering fallback handling in the renderer after it
// receives a `CommitNavigation()` IPC.
IN_PROC_BROWSER_TEST_P(
    SitePerProcessBrowserTest,
    ObjectTagSameSiteNavigationWithHTTPErrorAndFailedBodyLoad) {
  // Set up a test page with a same-site child frame hosted in an <object> tag.
  // TODO(dcheng): In the future, it might be useful to also have a test where
  // the child frame is same-site but cross-origin, and have the parent
  // initiate the navigation in the child frame.
  GURL url1(embedded_test_server()->GetURL("a.com", "/object-frame.html"));
  EXPECT_TRUE(NavigateToURL(web_contents(), url1));

  // There should be one nested browsing context.
  EXPECT_EQ(1, EvalJs(web_contents(), "window.length"));
  // And there should be no fallback content displayed.
  EXPECT_EQ("", EvalJs(web_contents(), "document.body.innerText"));

  // This test differs from CommitNavigationWithHTTPErrorInObjectTag by
  // triggering a body load failure. `ObjectNavigationFallbackBodyLoader`
  // detects this by setting a disconnect handler on the `mojo::Receiver` for
  // `network:;mojom::URLLoaderClient`. Exercise this code path by:
  // 1. inserting a test `NavigationThrottle`
  // 2. replacing the `network::mojom::URLLoaderClient` endpoint with one where
  //    the corresponding `mojo::Remote` is simply closed at
  //    `WILL_PROCESS_RESPONSE` time.
  TestNavigationThrottleInserter navigation_throttle_inserter(
      web_contents(),
      base::BindRepeating(
          [](NavigationThrottleRegistry& registry) -> void {
            auto throttle = std::make_unique<TestNavigationThrottle>(registry);
            auto* handle = &registry.GetNavigationHandle();
            throttle->SetCallback(
                TestNavigationThrottle::WILL_PROCESS_RESPONSE,
                base::BindLambdaForTesting([handle]() {
                  // Swap out the URL loader client endpoint and just drop the
                  // mojo::Remote. This will trigger the mojo::Receiver to be
                  // disconnected, which should still trigger fallback handling
                  // despite body loading failing.
                  mojo::Remote<network::mojom::URLLoaderClient>
                      remote_to_be_dropped;
                  auto* request = static_cast<NavigationRequest*>(handle);
                  request->mutable_url_loader_client_endpoints_for_testing()
                      ->url_loader_client =
                      remote_to_be_dropped.BindNewPipeAndPassReceiver();
                }));
            registry.AddThrottle(std::move(throttle));
          }));

  // <object> fallback handling should never reach ReadyToCommitNavigation.
  AssertNoReadyToCommitNavigationCalls asserter(web_contents());

  // Now navigate the first child to a same-site page that will result in a 404,
  // though the body loading will fail. Note that with subframe RenderDocument,
  // this will create a speculative RFH.
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  GURL url2(embedded_test_server()->GetURL("a.com", "/page404.html"));
  TestNavigationManager nav_manager(web_contents(), url2);
  FrameTreeNode* first_child = root->child_at(0);
  EXPECT_TRUE(BeginNavigateToURLFromRenderer(
      first_child->render_manager()->current_frame_host(), url2));

  const bool using_speculative_rfh =
      !!first_child->render_manager()->speculative_frame_host();
  // Speculative RFH will not be created at this point if we enable deferring.
  EXPECT_EQ(using_speculative_rfh,
            GetRenderDocumentLevel() >= RenderDocumentLevel::kSubframe &&
                !base::FeatureList::IsEnabled(
                    features::kDeferSpeculativeRFHCreation));

  ASSERT_TRUE(nav_manager.WaitForNavigationFinished());
  // There should be no commit...
  EXPECT_FALSE(nav_manager.was_committed());
  // .. and the navigation should have been aborted.
  EXPECT_FALSE(nav_manager.was_successful());
  // Fallback handling should discard the child browsing context and render the
  // fallback contents.
  EXPECT_EQ(0, EvalJs(web_contents(), "window.length"));
  EXPECT_EQ("fallback", EvalJs(web_contents(), "document.body.innerText"));
}

// Test that a cross-site navigation in <object> that fails with an HTTP error
// and also subsequently fails to load the body still directly triggers fallback
// handling, rather than triggering fallback handling in the renderer after it
// receives a `CommitNavigation()` IPC.
// The test disables the delay of creating the speculative RFH since it
// will check the created speculative RFH for a failing request. The speculative
// RFH will not be created after receiving the 404 response.
IN_PROC_BROWSER_TEST_P(
    SitePerProcessBrowserTestWithoutSpeculativeRFHDelay,
    ObjectTagCrossSiteNavigationWithHTTPErrorAndFailedBodyLoad) {
  // Set up a test page with a same-site child frame hosted in an <object> tag.
  // TODO(dcheng): In the future, it might be useful to also have a test where
  // the child frame is same-site but cross-origin, and have the parent
  // initiate the navigation in the child frame.
  GURL url1(embedded_test_server()->GetURL("a.com", "/object-frame.html"));
  EXPECT_TRUE(NavigateToURL(web_contents(), url1));

  // There should be one nested browsing context.
  EXPECT_EQ(1, EvalJs(web_contents(), "window.length"));
  // And there should be no fallback content displayed.
  EXPECT_EQ("", EvalJs(web_contents(), "document.body.innerText"));

  // This test differs from CommitNavigationWithHTTPErrorInObjectTag by
  // triggering a body load failure. `ObjectNavigationFallbackBodyLoader`
  // detects this by setting a disconnect handler on the `mojo::Receiver` for
  // `network:;mojom::URLLoaderClient`. Exercise this code path by:
  // 1. inserting a test `NavigationThrottle`
  // 2. replacing the `network::mojom::URLLoaderClient` endpoint with one where
  //    the corresponding `mojo::Remote` is simply closed at
  //    `WILL_PROCESS_RESPONSE` time.
  TestNavigationThrottleInserter navigation_throttle_inserter(
      web_contents(),
      base::BindRepeating(
          [](NavigationThrottleRegistry& registry) -> void {
            auto throttle = std::make_unique<TestNavigationThrottle>(registry);
            auto* handle = &registry.GetNavigationHandle();
            throttle->SetCallback(
                TestNavigationThrottle::WILL_PROCESS_RESPONSE,
                base::BindLambdaForTesting([handle]() {
                  // Swap out the URL loader client endpoint and just drop the
                  // mojo::Remote. This will trigger the mojo::Receiver to be
                  // disconnected, which should still trigger fallback handling
                  // despite body loading failing.
                  mojo::Remote<network::mojom::URLLoaderClient>
                      remote_to_be_dropped;
                  auto* request = static_cast<NavigationRequest*>(handle);
                  request->mutable_url_loader_client_endpoints_for_testing()
                      ->url_loader_client =
                      remote_to_be_dropped.BindNewPipeAndPassReceiver();
                }));
            registry.AddThrottle(std::move(throttle));
          }));

  // <object> fallback handling should never reach ReadyToCommitNavigation.
  AssertNoReadyToCommitNavigationCalls asserter(web_contents());

  // Now navigate the first child to a cross-site page that will result in a
  // 404, though the body loading will fail.
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  GURL url2(embedded_test_server()->GetURL("b.com", "/page404.html"));
  TestNavigationManager nav_manager(web_contents(), url2);
  FrameTreeNode* first_child = root->child_at(0);
  EXPECT_TRUE(BeginNavigateToURLFromRenderer(
      first_child->render_manager()->current_frame_host(), url2));
  nav_manager.WaitForSpeculativeRenderFrameHostCreation();
  // Cross-site navigations always force a speculative RFH to be created.
  EXPECT_TRUE(first_child->render_manager()->speculative_frame_host());

  ASSERT_TRUE(nav_manager.WaitForNavigationFinished());
  // There should be no commit...
  EXPECT_FALSE(nav_manager.was_committed());
  // .. and the navigation should have been aborted.
  EXPECT_FALSE(nav_manager.was_successful());
  // Fallback handling should discard the child browsing context and render the
  // fallback contents.
  EXPECT_EQ(0, EvalJs(web_contents(), "window.length"));
  EXPECT_EQ("fallback", EvalJs(web_contents(), "document.body.innerText"));
}

// Test that a same-site navigation in <object> that fails with a network error
// directly triggers fallback handling, rather than triggering fallback handling
// in the renderer after it receives a `CommitFailedNavigation()` IPC.
// The test disables the delay of creating the speculative RFH since it
// will check the created speculative RFH for a failing request. The speculative
// RFH will not be created after the network error.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTestWithoutSpeculativeRFHDelay,
                       ObjectTagSameSiteNavigationWithNetworkError) {
  // Set up a test page with a same-site child frame hosted in an <object> tag.
  GURL url1(embedded_test_server()->GetURL("a.com", "/object-frame.html"));
  EXPECT_TRUE(NavigateToURL(web_contents(), url1));

  // <object> fallback handling should never reach ReadyToCommitNavigation.
  AssertNoReadyToCommitNavigationCalls asserter(web_contents());

  // Now navigate the first child to a same-site page that will result in a
  // network error. Note that with subframe RenderDocument, this will create a
  // speculative RFH.
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  GURL error_url(embedded_test_server()->GetURL("a.com", "/empty.html"));
  std::unique_ptr<URLLoaderInterceptor> interceptor =
      URLLoaderInterceptor::SetupRequestFailForURL(error_url,
                                                   net::ERR_CONNECTION_REFUSED);
  TestNavigationManager nav_manager(web_contents(), error_url);
  FrameTreeNode* first_child = root->child_at(0);
  EXPECT_TRUE(BeginNavigateToURLFromRenderer(
      first_child->render_manager()->current_frame_host(), error_url));
  if (GetRenderDocumentLevel() >= RenderDocumentLevel::kSubframe) {
    nav_manager.WaitForSpeculativeRenderFrameHostCreation();
  }

  const bool using_speculative_rfh =
      !!first_child->render_manager()->speculative_frame_host();
  EXPECT_EQ(using_speculative_rfh,
            GetRenderDocumentLevel() >= RenderDocumentLevel::kSubframe);

  // `WaitForResponse()` should signal failure by returning `false` false since
  // the URLLoaderInterceptor forces a network error.
  EXPECT_FALSE(nav_manager.WaitForResponse());

  ASSERT_TRUE(nav_manager.WaitForNavigationFinished());
  EXPECT_FALSE(nav_manager.was_committed());

  // Make sure that the speculative RFH has been cleaned up, if needed.
  EXPECT_EQ(nullptr, first_child->render_manager()->speculative_frame_host());
}

// Test that a cross-site navigation in <object> that fails with a network error
// directly triggers fallback handling, rather than triggering fallback handling
// in the renderer after it receives a `CommitFailedNavigation()` IPC.
// The test disables the delay of creating the speculative RFH since it
// will check the created speculative RFH for a failing request. The speculative
// RFH will not be created after the network error.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTestWithoutSpeculativeRFHDelay,
                       ObjectTagCrossSiteNavigationWithNetworkError) {
  // Set up a test page with a same-site child frame hosted in an <object> tag.
  GURL url1(embedded_test_server()->GetURL("a.com", "/object-frame.html"));
  EXPECT_TRUE(NavigateToURL(web_contents(), url1));

  // <object> fallback handling should never reach ReadyToCommitNavigation.
  AssertNoReadyToCommitNavigationCalls asserter(web_contents());

  // Now navigate the first child to a cross-site page that will result in a
  // network error.
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  GURL error_url(embedded_test_server()->GetURL("b.com", "/empty.html"));
  std::unique_ptr<URLLoaderInterceptor> interceptor =
      URLLoaderInterceptor::SetupRequestFailForURL(error_url,
                                                   net::ERR_CONNECTION_REFUSED);
  TestNavigationManager nav_manager(web_contents(), error_url);
  FrameTreeNode* first_child = root->child_at(0);
  EXPECT_TRUE(BeginNavigateToURLFromRenderer(
      first_child->render_manager()->current_frame_host(), error_url));
  nav_manager.WaitForSpeculativeRenderFrameHostCreation();
  // Cross-site navigations always force a speculative RFH to be created.
  EXPECT_TRUE(first_child->render_manager()->speculative_frame_host());

  // `WaitForResponse()` should signal failure by returning `false` false since
  // the URLLoaderInterceptor forces a network error.
  EXPECT_FALSE(nav_manager.WaitForResponse());

  ASSERT_TRUE(nav_manager.WaitForNavigationFinished());
  EXPECT_FALSE(nav_manager.was_committed());

  // Make sure that the speculative RFH has been cleaned up, if needed.
  EXPECT_EQ(nullptr, first_child->render_manager()->speculative_frame_host());
}

class SitePerProcessBrowserTestWithLeakDetector
    : public SitePerProcessBrowserTest {
 public:
  void SetUpCommandLine(base::CommandLine* command_line) override {
    SitePerProcessBrowserTest::SetUpCommandLine(command_line);
    // Using the LeakDetector requires exposing GC.
    command_line->AppendSwitchASCII(blink::switches::kJavaScriptFlags,
                                    "--expose-gc");
  }
};

IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTestWithLeakDetector,
                       CloseWebContentsWithSpeculativeRenderFrameHost) {
  const GURL url1(embedded_test_server()->GetURL("a.com", "/title1.html"));
  ASSERT_TRUE(NavigateToURL(web_contents(), url1));

  // Open a popup in B. This is to prevent any fast shutdown shenanigans that
  // might otherwise happen when the speculative RFH is discarded later.
  Shell* new_shell =
      OpenPopup(web_contents(),
                embedded_test_server()->GetURL("b.com", "/title1.html"), "");
  ASSERT_TRUE(new_shell);

  mojo::Remote<blink::mojom::LeakDetector> leak_detector_remote;
  new_shell->web_contents()->GetPrimaryMainFrame()->GetProcess()->BindReceiver(
      leak_detector_remote.BindNewPipeAndPassReceiver());

  // One live document is expected from the newly opened popup.
  {
    base::test::TestFuture<blink::mojom::LeakDetectionResultPtr> result_future;
    leak_detector_remote->PerformLeakDetection(result_future.GetCallback());
    auto result = result_future.Take();
    EXPECT_EQ(1u, result->number_of_live_documents);
    // Note: the number of live frames includes remote frames.
    EXPECT_EQ(2u, result->number_of_live_frames);
  }

  // Start a navigation to B, but don't let it commit. This should associate a
  // speculative RFH with the main frame.
  const GURL url2(embedded_test_server()->GetURL("b.com", "/title1.html"));
  TestNavigationManager nav_manager(web_contents(), url2);
  ASSERT_TRUE(BeginNavigateToURLFromRenderer(web_contents(), url2));
  ASSERT_TRUE(nav_manager.WaitForResponse());

  // Speculative RFH should be created in B, increasing the number of live
  // documents and frames.
  {
    base::test::TestFuture<blink::mojom::LeakDetectionResultPtr> result_future;
    leak_detector_remote->PerformLeakDetection(result_future.GetCallback());
    auto result = result_future.Take();
    EXPECT_EQ(2u, result->number_of_live_documents);
    // Note: the number of live frames includes remote frames.
    EXPECT_EQ(3u, result->number_of_live_frames);
  }

  // Close the WebContents associated with the speculative RFH.
  shell()->Close();
  // Synchronize with the renderer.
  EXPECT_TRUE(ExecJs(new_shell, ""));

  // The resources associated with the speculative RFH should be freed now, as
  // well as the original frame from the now closed shell.
  {
    base::test::TestFuture<blink::mojom::LeakDetectionResultPtr> result_future;
    leak_detector_remote->PerformLeakDetection(result_future.GetCallback());
    auto result = result_future.Take();
    EXPECT_EQ(1u, result->number_of_live_documents);
    // Note: the number of live frames includes remote frames.
    EXPECT_EQ(1u, result->number_of_live_frames);
  }
}

IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTestWithLeakDetector,
                       DetachFrameWithSpeculativeRenderFrameHost) {
  const GURL url1(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(a)"));
  ASSERT_TRUE(NavigateToURL(web_contents(), url1));

  // Open a popup in B. This is to prevent any fast shutdown shenanigans that
  // might otherwise happen when the speculative RFH is discarded later.
  Shell* new_shell =
      OpenPopup(web_contents(),
                embedded_test_server()->GetURL("b.com", "/title1.html"), "");
  ASSERT_TRUE(new_shell);

  mojo::Remote<blink::mojom::LeakDetector> leak_detector_remote;
  new_shell->web_contents()->GetPrimaryMainFrame()->GetProcess()->BindReceiver(
      leak_detector_remote.BindNewPipeAndPassReceiver());

  // One live document is expected from the newly opened popup.
  {
    base::test::TestFuture<blink::mojom::LeakDetectionResultPtr> result_future;
    leak_detector_remote->PerformLeakDetection(result_future.GetCallback());
    auto result = result_future.Take();
    EXPECT_EQ(1u, result->number_of_live_documents);
    // Note: the number of live frames includes remote frames.
    EXPECT_EQ(3u, result->number_of_live_frames);
  }

  // Start a navigation to B in the iframe, but don't let it commit. This should
  // associate a speculative RFH with the child frame.
  const GURL url2(embedded_test_server()->GetURL("b.com", "/title1.html"));
  TestNavigationManager nav_manager(web_contents(), url2);
  ASSERT_TRUE(BeginNavigateToURLFromRenderer(web_contents()
                                                 ->GetPrimaryFrameTree()
                                                 .root()
                                                 ->current_frame_host()
                                                 ->child_at(0),
                                             url2));
  ASSERT_TRUE(nav_manager.WaitForResponse());

  // Speculative RFH should be created in B, increasing the number of live
  // documents and frames.
  {
    base::test::TestFuture<blink::mojom::LeakDetectionResultPtr> result_future;
    leak_detector_remote->PerformLeakDetection(result_future.GetCallback());
    auto result = result_future.Take();
    EXPECT_EQ(2u, result->number_of_live_documents);
    // Note: the number of live frames includes remote frames.
    EXPECT_EQ(4u, result->number_of_live_frames);
  }

  // Detach the <iframe> associated with the speculative RFH.
  EXPECT_TRUE(
      ExecJs(web_contents(), "document.querySelector('iframe').remove()"));
  // Synchronize with the renderer.
  EXPECT_TRUE(ExecJs(new_shell, ""));

  // The resources associated with the speculative RFH should be freed now.
  {
    base::test::TestFuture<blink::mojom::LeakDetectionResultPtr> result_future;
    leak_detector_remote->PerformLeakDetection(result_future.GetCallback());
    auto result = result_future.Take();
    EXPECT_EQ(1u, result->number_of_live_documents);
    // Note: the number of live frames includes remote frames.
    EXPECT_EQ(2u, result->number_of_live_frames);
  }
}

#if BUILDFLAG(IS_ANDROID)

namespace {

class MockEventHandlerAndroid : public ui::EventHandlerAndroid {
 public:
  bool OnTouchEvent(const ui::MotionEventAndroid& event) override {
    did_receive_event_ = true;
    return true;
  }

  bool did_receive_event() { return did_receive_event_; }

 private:
  bool did_receive_event_ = false;
};

}  // namespace

IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       SpeculativeRenderFrameHostDoesNotReceiveInput) {
  GURL url1(embedded_test_server()->GetURL("a.com", "/title1.html"));
  EXPECT_TRUE(NavigateToURL(shell(), url1));

  RenderWidgetHostViewAndroid* rwhva =
      static_cast<RenderWidgetHostViewAndroid*>(
          shell()->web_contents()->GetRenderWidgetHostView());
  ui::ViewAndroid* rwhva_native_view = rwhva->GetNativeView();
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();

  // Start a cross-site navigation.
  GURL url2(embedded_test_server()->GetURL("b.com", "/title2.html"));
  TestNavigationManager nav_manager(web_contents(), url2);
  shell()->LoadURL(url2);

  // Wait for the request, but don't commit it yet. This should create a
  // speculative RenderFrameHost.
  nav_manager.WaitForSpeculativeRenderFrameHostCreation();
  RenderFrameHostImpl* root_speculative_rfh =
      root->render_manager()->speculative_frame_host();
  EXPECT_TRUE(root_speculative_rfh);
  RenderWidgetHostViewAndroid* rwhv_speculative =
      static_cast<RenderWidgetHostViewAndroid*>(
          root_speculative_rfh->GetView());
  ui::ViewAndroid* rwhv_speculative_native_view =
      rwhv_speculative->GetNativeView();

  ui::ViewAndroid* root_view = web_contents()->GetView()->GetNativeView();
  EXPECT_TRUE(root_view);

  MockEventHandlerAndroid mock_handler;
  rwhva_native_view->set_event_handler(&mock_handler);
  MockEventHandlerAndroid mock_handler_speculative;
  rwhv_speculative_native_view->set_event_handler(&mock_handler_speculative);
  // Avoid having the root try to handle the following event.
  root_view->set_event_handler(nullptr);

  auto size = root_view->GetSizeDIPs();
  float x = size.width() / 2;
  float y = size.height() / 2;
  ui::MotionEventAndroid::Pointer pointer0(0, x, y, 0, 0, 0, 0, 0, 0);

  JNIEnv* env = base::android::AttachCurrentThread();
  base::android::ScopedJavaLocalRef<jobject> obj =
      JNI_MotionEvent::Java_MotionEvent_obtain(
          env, /*downTime=*/0, /*eventTime=*/0, /*action=*/0, /*x=*/0, /*y=*/0,
          /*metaState=*/0);
  auto event = ui::MotionEventAndroidFactory::CreateFromJava(
      env, obj,
      /*pix_to_dip=*/1.f / root_view->GetDipScale(),
      /*ticks_x=*/0.f,
      /*ticks_y=*/0.f,
      /*tick_multiplier=*/0.f,
      /*oldest_event_time=*/base::TimeTicks(),
      /*android_action=*/0,
      /*pointer_count=*/1,
      /*history_size=*/0,
      /*action_index=*/0,
      /*android_action_button=*/0,
      /*android_gesture_classification=*/0,
      /*android_button_state=*/0,
      /*raw_offset_x_pixels=*/0,
      /*raw_offset_y_pixels=*/0,
      /*for_touch_handle=*/false,
      /*pointer0=*/&pointer0,
      /*pointer1=*/nullptr);
  root_view->OnTouchEventForTesting(*event);

  EXPECT_TRUE(mock_handler.did_receive_event());
  EXPECT_FALSE(mock_handler_speculative.did_receive_event());
}

class SitePerProcessBrowserTestWithSubframePriority
    : public SitePerProcessBrowserTest {
 public:
  SitePerProcessBrowserTestWithSubframePriority() {
    scoped_feature_list_.InitWithFeatures(
        /* enabled_features= */ {features::kSubframePriorityContribution,
                                 features::kSubframeImportance},
        /* disabled_features= */ {});
  }

 private:
  base::test::ScopedFeatureList scoped_feature_list_;
};

IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTestWithSubframePriority,
                       TestChildProcessImportance) {
  web_contents()->SetPrimaryPageImportance(ChildProcessImportance::IMPORTANT,
                                           ChildProcessImportance::MODERATE);

  // Construct root page with one child in different domain.
  EXPECT_TRUE(NavigateToURL(
      shell(), embedded_test_server()->GetURL(
                   "a.com", "/cross_site_iframe_factory.html?a(b)")));
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  ASSERT_EQ(1u, root->child_count());
  FrameTreeNode* child = root->child_at(0);

  // Importance should survive initial navigation.
  EXPECT_EQ(ChildProcessImportance::IMPORTANT,
            root->current_frame_host()->GetProcess()->GetEffectiveImportance());
  EXPECT_EQ(
      ChildProcessImportance::MODERATE,
      child->current_frame_host()->GetProcess()->GetEffectiveImportance());

  // Setting NORMAL importance for child frame.
  web_contents()->SetPrimaryPageImportance(ChildProcessImportance::MODERATE,
                                           ChildProcessImportance::NORMAL);
  EXPECT_EQ(ChildProcessImportance::MODERATE,
            root->current_frame_host()->GetProcess()->GetEffectiveImportance());
  EXPECT_EQ(
      ChildProcessImportance::NORMAL,
      child->current_frame_host()->GetProcess()->GetEffectiveImportance());

  // Check setting the same importance for main frame and subframe.
  web_contents()->SetPrimaryPageImportance(ChildProcessImportance::MODERATE,
                                           ChildProcessImportance::MODERATE);
  EXPECT_EQ(ChildProcessImportance::MODERATE,
            root->current_frame_host()->GetProcess()->GetEffectiveImportance());
  EXPECT_EQ(
      ChildProcessImportance::MODERATE,
      child->current_frame_host()->GetProcess()->GetEffectiveImportance());

  // Check setting importance.
  web_contents()->SetPrimaryPageImportance(ChildProcessImportance::NORMAL,
                                           ChildProcessImportance::NORMAL);
  EXPECT_EQ(ChildProcessImportance::NORMAL,
            root->current_frame_host()->GetProcess()->GetEffectiveImportance());
  EXPECT_EQ(
      ChildProcessImportance::NORMAL,
      child->current_frame_host()->GetProcess()->GetEffectiveImportance());
  web_contents()->SetPrimaryPageImportance(ChildProcessImportance::IMPORTANT,
                                           ChildProcessImportance::MODERATE);
  EXPECT_EQ(ChildProcessImportance::IMPORTANT,
            root->current_frame_host()->GetProcess()->GetEffectiveImportance());
  EXPECT_EQ(
      ChildProcessImportance::MODERATE,
      child->current_frame_host()->GetProcess()->GetEffectiveImportance());

  // Check importance is maintained if child navigates to new domain.
  int old_child_process_id =
      child->current_frame_host()->GetProcess()->GetDeprecatedID();
  EXPECT_TRUE(NavigateToURLFromRenderer(
      root->child_at(0),
      embedded_test_server()->GetURL("foo.com", "/title2.html")));
  int new_child_process_id =
      child->current_frame_host()->GetProcess()->GetDeprecatedID();
  EXPECT_NE(old_child_process_id, new_child_process_id);
  EXPECT_EQ(
      ChildProcessImportance::MODERATE,
      child->current_frame_host()->GetProcess()->GetEffectiveImportance());
  EXPECT_EQ(ChildProcessImportance::IMPORTANT,
            root->current_frame_host()->GetProcess()->GetEffectiveImportance());

  // Check importance is maintained if root navigates to new domain.
  int old_root_process_id =
      root->current_frame_host()->GetProcess()->GetDeprecatedID();
  EXPECT_TRUE(NavigateToURLFromRenderer(
      root, embedded_test_server()->GetURL(
                "b.com", "/cross_site_iframe_factory.html?b(a)")));
  int new_root_process_id =
      root->current_frame_host()->GetProcess()->GetDeprecatedID();
  EXPECT_NE(old_root_process_id, new_root_process_id);
  EXPECT_EQ(ChildProcessImportance::IMPORTANT,
            root->current_frame_host()->GetProcess()->GetEffectiveImportance());

  ASSERT_EQ(1u, root->child_count());
  child = root->child_at(0);
  int new_child_process_id_2 =
      child->current_frame_host()->GetProcess()->GetDeprecatedID();
  EXPECT_NE(new_child_process_id, new_child_process_id_2);
  EXPECT_EQ(
      ChildProcessImportance::MODERATE,
      child->current_frame_host()->GetProcess()->GetEffectiveImportance());
}

IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       TestChildProcessImportanceWithNormalSubframes) {
  // In this test case, subframe importance is always NORMAL. With that
  // WebContents never updates subframe importance.
  web_contents()->SetPrimaryPageImportance(ChildProcessImportance::MODERATE,
                                           ChildProcessImportance::NORMAL);

  // Construct root page with one child in different domain.
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  ASSERT_EQ(1u, root->child_count());
  FrameTreeNode* child = root->child_at(0);

  // Importance should survive initial navigation.
  EXPECT_EQ(ChildProcessImportance::MODERATE,
            root->current_frame_host()->GetProcess()->GetEffectiveImportance());
  EXPECT_EQ(
      ChildProcessImportance::NORMAL,
      child->current_frame_host()->GetProcess()->GetEffectiveImportance());

  // Check setting importance.
  web_contents()->SetPrimaryPageImportance(ChildProcessImportance::NORMAL,
                                           ChildProcessImportance::NORMAL);
  EXPECT_EQ(ChildProcessImportance::NORMAL,
            root->current_frame_host()->GetProcess()->GetEffectiveImportance());
  EXPECT_EQ(
      ChildProcessImportance::NORMAL,
      child->current_frame_host()->GetProcess()->GetEffectiveImportance());
  web_contents()->SetPrimaryPageImportance(ChildProcessImportance::IMPORTANT,
                                           ChildProcessImportance::NORMAL);
  EXPECT_EQ(ChildProcessImportance::IMPORTANT,
            root->current_frame_host()->GetProcess()->GetEffectiveImportance());
  EXPECT_EQ(
      ChildProcessImportance::NORMAL,
      child->current_frame_host()->GetProcess()->GetEffectiveImportance());

  // Check importance is maintained if child navigates to new domain.
  int old_child_process_id =
      child->current_frame_host()->GetProcess()->GetDeprecatedID();
  GURL url = embedded_test_server()->GetURL("foo.com", "/title2.html");
  EXPECT_TRUE(NavigateToURLFromRenderer(root->child_at(0), url));
  int new_child_process_id =
      child->current_frame_host()->GetProcess()->GetDeprecatedID();
  EXPECT_NE(old_child_process_id, new_child_process_id);
  EXPECT_EQ(
      ChildProcessImportance::NORMAL,
      child->current_frame_host()->GetProcess()->GetEffectiveImportance());
  EXPECT_EQ(ChildProcessImportance::IMPORTANT,
            root->current_frame_host()->GetProcess()->GetEffectiveImportance());

  // Check importance is maintained if root navigates to new domain.
  int old_root_process_id =
      root->current_frame_host()->GetProcess()->GetDeprecatedID();
  child = nullptr;  // Going to navigate root to page without any child.
  EXPECT_TRUE(NavigateToURLFromRenderer(root, url));
  EXPECT_EQ(0u, root->child_count());
  int new_root_process_id =
      root->current_frame_host()->GetProcess()->GetDeprecatedID();
  EXPECT_NE(old_root_process_id, new_root_process_id);
  EXPECT_EQ(ChildProcessImportance::IMPORTANT,
            root->current_frame_host()->GetProcess()->GetEffectiveImportance());
}

class TouchSelectionControllerClientTestWrapper
    : public ui::TouchSelectionControllerClient {
 public:
  explicit TouchSelectionControllerClientTestWrapper(
      ui::TouchSelectionControllerClient* client)
      : expected_event_(ui::SELECTION_HANDLES_SHOWN), client_(client) {}

  TouchSelectionControllerClientTestWrapper(
      const TouchSelectionControllerClientTestWrapper&) = delete;
  TouchSelectionControllerClientTestWrapper& operator=(
      const TouchSelectionControllerClientTestWrapper&) = delete;

  ~TouchSelectionControllerClientTestWrapper() override {}

  void InitWaitForSelectionEvent(ui::SelectionEventType expected_event) {
    DCHECK(!run_loop_);
    expected_event_ = expected_event;
    run_loop_ = std::make_unique<base::RunLoop>();
  }

  void Wait() {
    DCHECK(run_loop_);
    run_loop_->Run();
    run_loop_.reset();
  }

 private:
  // TouchSelectionControllerClient:
  void OnSelectionEvent(ui::SelectionEventType event) override {
    client_->OnSelectionEvent(event);
    if (run_loop_ && event == expected_event_)
      run_loop_->Quit();
  }

  bool SupportsAnimation() const override {
    return client_->SupportsAnimation();
  }

  void SetNeedsAnimate() override { client_->SetNeedsAnimate(); }

  void MoveCaret(const gfx::PointF& position) override {
    client_->MoveCaret(position);
  }

  void MoveRangeSelectionExtent(const gfx::PointF& extent) override {
    client_->MoveRangeSelectionExtent(extent);
  }

  void SelectBetweenCoordinates(const gfx::PointF& base,
                                const gfx::PointF& extent) override {
    client_->SelectBetweenCoordinates(base, extent);
  }

  std::unique_ptr<ui::TouchHandleDrawable> CreateDrawable() override {
    return client_->CreateDrawable();
  }

  void DidScroll() override {}

  void OnDragUpdate(const ui::TouchSelectionDraggable::Type type,
                    const gfx::PointF& position) override {}

  ui::SelectionEventType expected_event_;
  std::unique_ptr<base::RunLoop> run_loop_;
  // Not owned.
  raw_ptr<ui::TouchSelectionControllerClient, DanglingUntriaged> client_;
};

class TouchSelectionControllerClientAndroidSiteIsolationTest
    : public SitePerProcessBrowserTest {
 public:
  TouchSelectionControllerClientAndroidSiteIsolationTest()
      : root_rwhv_(nullptr),
        child_rwhv_(nullptr),
        child_frame_tree_node_(nullptr),
        selection_controller_client_(nullptr) {}

  void SetUpCommandLine(base::CommandLine* command_line) override {
    SitePerProcessBrowserTestBase::SetUpCommandLine(command_line);
    IsolateAllSitesForTesting(command_line);
  }

  RenderWidgetHostViewAndroid* GetRenderWidgetHostViewAndroid() {
    return static_cast<RenderWidgetHostViewAndroid*>(
        shell()->web_contents()->GetRenderWidgetHostView());
  }

  void SelectWithLongPress(gfx::Point point) {
    // Get main frame view for event insertion.
    RenderWidgetHostViewAndroid* main_view = GetRenderWidgetHostViewAndroid();

    SendTouch(main_view, ui::MotionEvent::Action::DOWN, point);
    // action_timeout() is far longer than needed for a LongPress, so we use
    // a custom timeout here.
    DelayBy(base::Milliseconds(2000));
    SendTouch(main_view, ui::MotionEvent::Action::UP, point);
  }

  void SimpleTap(gfx::Point point) {
    // Get main frame view for event insertion.
    RenderWidgetHostViewAndroid* main_view = GetRenderWidgetHostViewAndroid();

    SendTouch(main_view, ui::MotionEvent::Action::DOWN, point);
    // tiny_timeout() is way shorter than a reasonable user-created tap gesture,
    // so we use a custom timeout here.
    DelayBy(base::Milliseconds(300));
    SendTouch(main_view, ui::MotionEvent::Action::UP, point);
  }

  void SetupTest() {
    GURL test_url(embedded_test_server()->GetURL(
        "a.com", "/cross_site_iframe_factory.html?a(a)"));
    EXPECT_TRUE(NavigateToURL(shell(), test_url));
    frame_observer_ = std::make_unique<RenderFrameSubmissionObserver>(
        shell()->web_contents());
    FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
                              ->GetPrimaryFrameTree()
                              .root();
    EXPECT_EQ(
        " Site A\n"
        "   +--Site A\n"
        "Where A = http://a.com/",
        FrameTreeVisualizer().DepictFrameTree(root));
    TestNavigationObserver observer(shell()->web_contents());
    EXPECT_EQ(1u, root->child_count());
    child_frame_tree_node_ = root->child_at(0);

    root_rwhv_ = static_cast<RenderWidgetHostViewAndroid*>(
        root->current_frame_host()->GetRenderWidgetHost()->GetView());
    selection_controller_client_ =
        new TouchSelectionControllerClientTestWrapper(
            static_cast<TouchSelectionControllerClientManagerAndroid*>(
                root_rwhv_->GetTouchSelectionControllerClientManager()));
    root_rwhv_->SetSelectionControllerClientForTesting(
        base::WrapUnique(selection_controller_client_.get()));

    // We need to load the desired subframe and then wait until it's stable,
    // i.e. generates no new compositor frames for some reasonable time period:
    // a stray frame between touch selection's pre-handling of GestureLongPress
    // and the expected frame containing the selected region can confuse the
    // TouchSelectionController, causing it to fail to show selection handles.
    // Note this is an issue with the TouchSelectionController in general, and
    // not a property of this test.
    GURL child_url(
        embedded_test_server()->GetURL("b.com", "/touch_selection.html"));
    EXPECT_TRUE(
        NavigateToURLFromRenderer(child_frame_tree_node_.get(), child_url));
    EXPECT_EQ(
        " Site A ------------ proxies for B\n"
        "   +--Site B ------- proxies for A\n"
        "Where A = http://a.com/\n"
        "      B = http://b.com/",
        FrameTreeVisualizer().DepictFrameTree(root));
    // The child will change with the cross-site navigation. It shouldn't change
    // after this.
    child_frame_tree_node_ = root->child_at(0);
    WaitForHitTestData(child_frame_tree_node_->current_frame_host());

    child_rwhv_ = static_cast<RenderWidgetHostViewChildFrame*>(
        child_frame_tree_node_->current_frame_host()
            ->GetRenderWidgetHost()
            ->GetView());

    EXPECT_EQ(child_url, observer.last_navigation_url());
    EXPECT_TRUE(observer.last_navigation_succeeded());
  }

  // This must be called before the main-frame's RenderWidgetHostView is freed,
  // else we'll have a nullptr dereference on shutdown.
  void ShutdownTest() {
    ASSERT_TRUE(frame_observer_);
    frame_observer_.reset();
  }

  gfx::PointF GetPointInChild() {
    gfx::PointF point_f;
    std::string str = EvalJs(child_frame_tree_node_->current_frame_host(),
                             "get_top_left_of_text()")
                          .ExtractString();
    ConvertJSONToPoint(str, &point_f);
    // Offset the point so that it is within the text. Character dimensions are
    // based on the font size in `touch_selection.html`.
    constexpr int kCharacterWidth = 15;
    constexpr int kCharacterHeight = 15;
    point_f.Offset(2 * kCharacterWidth, 0.5f * kCharacterHeight);
    point_f = child_rwhv()->TransformPointToRootCoordSpaceF(point_f);
    return point_f;
  }

  void VerifyHandlePosition() {
    // Check that selection handles are close to the selection range.
    // The test will timeout if this never happens.
    ui::TouchSelectionController* touch_selection_controller =
        root_rwhv()->touch_selection_controller();

    bool handles_in_place = false;
    while (!handles_in_place) {
      gfx::PointF selection_start =
          touch_selection_controller->GetStartPosition();
      gfx::PointF selection_end = touch_selection_controller->GetEndPosition();
      gfx::RectF handle_start =
          touch_selection_controller->GetStartHandleRect();
      gfx::RectF handle_end = touch_selection_controller->GetEndHandleRect();

      // Not all Android bots seem to actually show the handle, so check first.
      if (handle_start.IsEmpty()) {
        handles_in_place = true;
      } else {
        bool has_end_handle =
            !touch_selection_controller->GetEndHandleRect().IsEmpty();
        // handle_start.y() defined the top of the handle's rect, and x() is
        // left.
        bool start_near_y =
            std::abs(selection_start.y() - handle_start.y()) <= 3.f;
        bool start_in_x_range = selection_start.x() >= handle_start.x() &&
                                selection_start.x() <= handle_start.right();
        bool end_near_y = std::abs(selection_end.y() - handle_end.y()) <= 3.f;
        bool end_in_x_range = selection_end.x() >= handle_end.x() &&
                              selection_end.x() <= handle_end.right();
        handles_in_place = start_near_y && start_in_x_range && end_near_y &&
                           end_in_x_range && has_end_handle;
      }
      if (!handles_in_place)
        DelayBy(base::Milliseconds(100));
    }
  }

  RenderWidgetHostViewAndroid* root_rwhv() { return root_rwhv_; }

  RenderWidgetHostViewChildFrame* child_rwhv() { return child_rwhv_; }

  float PageScaleFactor() {
    return frame_observer_->LastRenderFrameMetadata().page_scale_factor;
  }

  TouchSelectionControllerClientTestWrapper* selection_controller_client() {
    return selection_controller_client_;
  }

  void OnSyntheticGestureSent() {
    gesture_run_loop_ = std::make_unique<base::RunLoop>();
    gesture_run_loop_->Run();
  }

  void OnSyntheticGestureCompleted(SyntheticGesture::Result result) {
    EXPECT_EQ(SyntheticGesture::GESTURE_FINISHED, result);
    gesture_run_loop_->Quit();
  }

 protected:
  void DelayBy(base::TimeDelta delta) {
    base::RunLoop run_loop;
    base::SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
        FROM_HERE, run_loop.QuitClosure(), delta);
    run_loop.Run();
  }

 private:
  void SendTouch(RenderWidgetHostViewAndroid* view,
                 ui::MotionEvent::Action action,
                 gfx::Point point) {
    DCHECK(action >= ui::MotionEvent::Action::DOWN &&
           action < ui::MotionEvent::Action::CANCEL);

    ui::MotionEventAndroid::Pointer p(0, point.x(), point.y(), 10, 0, 0, 0, 0,
                                      0);
    JNIEnv* env = base::android::AttachCurrentThread();
    auto event_time = ui::EventTimeForNow();
    auto down_time_ms =
        base::TimeTicks::FromUptimeMillis(event_time.ToUptimeMillis());

    base::android::ScopedJavaLocalRef<jobject> obj =
        JNI_MotionEvent::Java_MotionEvent_obtain(
            env, /*downTime=*/0, /*eventTime=*/0, /*action=*/0, /*x=*/0,
            /*y=*/0, /*metaState=*/0);
    auto touch = ui::MotionEventAndroidFactory::CreateFromJava(
        env, obj,
        /*pix_to_dip=*/1.f,
        /*ticks_x=*/0,
        /*ticks_y=*/0,
        /*tick_multiplier=*/0,
        /*oldest_event_time=*/event_time,
        /*latest_event_time=*/event_time,
        /*down_time_ms=*/down_time_ms,
        /*android_action=*/ui::MotionEventAndroid::GetAndroidAction(action),
        /*pointer_count=*/1,
        /*history_size=*/0,
        /*action_index=*/0,
        /*android_action_button=*/0,
        /*android_gesture_classification=*/0,
        /*android_button_state=*/0,
        /*raw_offset_x_pixels=*/0,
        /*raw_offset_y_pixels=*/0,
        /*for_touch_handle=*/false,
        /*pointer0=*/&p,
        /*pointer1=*/nullptr,
        /*is_latest_event_time_resampled=*/false);
    view->OnTouchEvent(*touch);
  }

  raw_ptr<RenderWidgetHostViewAndroid, DanglingUntriaged> root_rwhv_;
  raw_ptr<RenderWidgetHostViewChildFrame, DanglingUntriaged> child_rwhv_;
  raw_ptr<FrameTreeNode, DanglingUntriaged> child_frame_tree_node_;
  std::unique_ptr<RenderFrameSubmissionObserver> frame_observer_;
  raw_ptr<TouchSelectionControllerClientTestWrapper, DanglingUntriaged>
      selection_controller_client_;

  std::unique_ptr<base::RunLoop> gesture_run_loop_;
};

IN_PROC_BROWSER_TEST_P(TouchSelectionControllerClientAndroidSiteIsolationTest,
                       BasicSelectionIsolatedIframe) {
  // Load test URL with cross-process child.
  SetupTest();

  EXPECT_EQ(ui::TouchSelectionController::INACTIVE,
            root_rwhv()->touch_selection_controller()->active_status());
  // Find the location of some text to select.
  gfx::PointF point_f = GetPointInChild();

  // Initiate selection with a sequence of events that go through the targeting
  // system.
  selection_controller_client()->InitWaitForSelectionEvent(
      ui::SELECTION_HANDLES_SHOWN);

  SelectWithLongPress(gfx::Point(point_f.x(), point_f.y()));

  selection_controller_client()->Wait();

  // Check that selection is active and the quick menu is showing.
  EXPECT_EQ(ui::TouchSelectionController::SELECTION_ACTIVE,
            root_rwhv()->touch_selection_controller()->active_status());

  // Make sure handles are correctly positioned.
  VerifyHandlePosition();

  // Tap inside/outside the iframe and make sure the selection handles go away.
  selection_controller_client()->InitWaitForSelectionEvent(
      ui::SELECTION_HANDLES_CLEARED);
  // Since Android tests may run with page_scale_factor < 1, use an offset a
  // bigger than +/-1 for doing the inside/outside taps to cancel the selection
  // handles.
  gfx::PointF point_inside_iframe =
      child_rwhv()->TransformPointToRootCoordSpaceF(gfx::PointF(+5.f, +5.f));
  SimpleTap(gfx::Point(point_inside_iframe.x(), point_inside_iframe.y()));
  selection_controller_client()->Wait();

  EXPECT_EQ(ui::TouchSelectionController::INACTIVE,
            root_rwhv()->touch_selection_controller()->active_status());

  // Let's wait for the previous events to clear the round-trip to the renders
  // and back.
  DelayBy(base::Milliseconds(2000));

  // Initiate selection with a sequence of events that go through the targeting
  // system. Repeat of above but this time we'l cancel the selection by
  // tapping outside of the OOPIF.
  selection_controller_client()->InitWaitForSelectionEvent(
      ui::SELECTION_HANDLES_SHOWN);

  SelectWithLongPress(gfx::Point(point_f.x(), point_f.y()));

  selection_controller_client()->Wait();

  // Check that selection is active and the quick menu is showing.
  EXPECT_EQ(ui::TouchSelectionController::SELECTION_ACTIVE,
            root_rwhv()->touch_selection_controller()->active_status());

  // Tap inside/outside the iframe and make sure the selection handles go away.
  selection_controller_client()->InitWaitForSelectionEvent(
      ui::SELECTION_HANDLES_CLEARED);
  // Since Android tests may run with page_scale_factor < 1, use an offset a
  // bigger than +/-1 for doing the inside/outside taps to cancel the selection
  // handles.
  gfx::PointF point_outside_iframe =
      child_rwhv()->TransformPointToRootCoordSpaceF(gfx::PointF(-5.f, -5.f));
  SimpleTap(gfx::Point(point_outside_iframe.x(), point_outside_iframe.y()));
  selection_controller_client()->Wait();

  EXPECT_EQ(ui::TouchSelectionController::INACTIVE,
            root_rwhv()->touch_selection_controller()->active_status());

  // Cleanup before shutting down.
  ShutdownTest();
}

// This test verifies that the handles associated with an active touch selection
// are still correctly positioned after a pinch-zoom operation.
#if BUILDFLAG(IS_ANDROID)  // Flaky on Android.  See https://crbug.com/906204.
#define MAYBE_SelectionThenPinchInOOPIF DISABLED_SelectionThenPinchInOOPIF
#else
#define MAYBE_SelectionThenPinchInOOPIF SelectionThenPinchInOOPIF
#endif
IN_PROC_BROWSER_TEST_P(TouchSelectionControllerClientAndroidSiteIsolationTest,
                       MAYBE_SelectionThenPinchInOOPIF) {
  // Load test URL with cross-process child.
  SetupTest();

  EXPECT_EQ(ui::TouchSelectionController::INACTIVE,
            root_rwhv()->touch_selection_controller()->active_status());
  // Find the location of some text to select.
  gfx::PointF point_f = GetPointInChild();

  // Initiate selection with a sequence of events that go through the targeting
  // system.
  selection_controller_client()->InitWaitForSelectionEvent(
      ui::SELECTION_HANDLES_SHOWN);

  SelectWithLongPress(gfx::Point(point_f.x(), point_f.y()));

  selection_controller_client()->Wait();

  // Check that selection is active and the quick menu is showing.
  EXPECT_EQ(ui::TouchSelectionController::SELECTION_ACTIVE,
            root_rwhv()->touch_selection_controller()->active_status());

  // Make sure handles are correctly positioned.
  VerifyHandlePosition();

  // Generate a pinch sequence, then re-verify handles are in the correct
  // location.
  float page_scale_delta = 2.f;
  float current_page_scale = PageScaleFactor();
  float target_page_scale = current_page_scale * page_scale_delta;

  SyntheticPinchGestureParams params;
  // We'll use the selection point for the pinch center to minimize the
  // likelihood of the selection getting zoomed offscreen.
  params.anchor = point_f;
  // Note: the |scale_factor| in |params| is actually treated as a delta, not
  // absolute, page scale.
  params.scale_factor = page_scale_delta;
  auto synthetic_pinch_gesture =
      std::make_unique<SyntheticTouchscreenPinchGesture>(params);

  auto* host =
      static_cast<RenderWidgetHostImpl*>(root_rwhv()->GetRenderWidgetHost());
  InputEventAckWaiter gesture_pinch_end_waiter(
      host, blink::WebInputEvent::Type::kGesturePinchEnd);
  host->QueueSyntheticGesture(
      std::move(synthetic_pinch_gesture),
      base::BindOnce(&TouchSelectionControllerClientAndroidSiteIsolationTest::
                         OnSyntheticGestureCompleted,
                     base::Unretained(this)));
  OnSyntheticGestureSent();
  // Make sure the gesture is complete from the renderer's point of view.
  gesture_pinch_end_waiter.Wait();

  VerifyHandlePosition();
  // TODO(wjmaclean): Investigate why SyntheticTouchscreenPinchGesture final
  // scales are so imprecise.
  // https://crbug.com/897173
  const float kScaleFactorTolerance = 0.05f;
  EXPECT_NEAR(target_page_scale, PageScaleFactor(), kScaleFactorTolerance);

  // Cleanup before shutting down.
  ShutdownTest();
}
#endif  // BUILDFLAG(IS_ANDROID)

class TouchEventObserver : public RenderWidgetHost::InputEventObserver {
 public:
  TouchEventObserver(std::vector<uint32_t>* outgoing_touch_event_ids,
                     std::vector<uint32_t>* acked_touch_event_ids)
      : outgoing_touch_event_ids_(outgoing_touch_event_ids),
        acked_touch_event_ids_(acked_touch_event_ids) {}

  TouchEventObserver(const TouchEventObserver&) = delete;
  TouchEventObserver& operator=(const TouchEventObserver&) = delete;

  void OnInputEvent(const RenderWidgetHost& widget,
                    const blink::WebInputEvent& event) override {
    if (!blink::WebInputEvent::IsTouchEventType(event.GetType()))
      return;

    const auto& touch_event = static_cast<const blink::WebTouchEvent&>(event);
    outgoing_touch_event_ids_->push_back(touch_event.unique_touch_event_id);
  }

  void OnInputEventAck(const RenderWidgetHost& widget,
                       blink::mojom::InputEventResultSource source,
                       blink::mojom::InputEventResultState state,
                       const blink::WebInputEvent& event) override {
    if (!blink::WebInputEvent::IsTouchEventType(event.GetType()))
      return;

    const auto& touch_event = static_cast<const blink::WebTouchEvent&>(event);
    acked_touch_event_ids_->push_back(touch_event.unique_touch_event_id);
  }

 private:
  raw_ptr<std::vector<uint32_t>> outgoing_touch_event_ids_;
  raw_ptr<std::vector<uint32_t>> acked_touch_event_ids_;
};

// This test verifies the ability of the TouchEventAckQueue to send TouchEvent
// acks to the root view in the correct order in the event of a slow renderer.
// This test uses a main-frame which acks instantly (no touch handler), and a
// child frame which acks very slowly. A synthetic gesture tap is sent to the
// child first, then the main frame. In this scenario, we expect the touch
// events sent to the main-frame to ack first, which will be problematic if
// the events are acked to the GestureRecognizer out of order.
//
// This test is disabled due to flakiness on all platforms, but especially on
// Android.  See https://crbug.com/945025.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       DISABLED_TouchEventAckQueueOrdering) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  ASSERT_EQ(1u, root->child_count());
  FrameTreeNode* child_node = root->child_at(0);

  // Add a *slow* & non-passive touch event handler in the child. It needs to
  // be non-passive to ensure TouchStart doesn't get acked until after the
  // touch handler completes.
  EXPECT_TRUE(ExecJs(child_node,
                     "touch_event_count = 0;\
       function touch_handler(ev) {\
         var start = Date.now();\
         while (Date.now() < start + 1000) {}\
         touch_event_count++;\
       }\
       document.body.addEventListener('touchstart', touch_handler,\
                                      { passive : false });\
       document.body.addEventListener('touchend', touch_handler,\
                                      { passive : false });"));

  WaitForHitTestData(child_node->current_frame_host());

  auto* root_host = static_cast<RenderWidgetHostImpl*>(
      root->current_frame_host()->GetRenderWidgetHost());
  auto* child_host = static_cast<RenderWidgetHostImpl*>(
      child_node->current_frame_host()->GetRenderWidgetHost());

  // Create InputEventObserver for both, with access to common queue for
  // logging.
  std::vector<uint32_t> outgoing_touch_event_ids;
  std::vector<uint32_t> acked_touch_event_ids;

  TouchEventObserver parent_touch_event_observer(&outgoing_touch_event_ids,
                                                 &acked_touch_event_ids);
  TouchEventObserver child_touch_event_observer(&outgoing_touch_event_ids,
                                                &acked_touch_event_ids);

  root_host->AddInputEventObserver(&parent_touch_event_observer);
  child_host->AddInputEventObserver(&child_touch_event_observer);

  InputEventAckWaiter root_ack_waiter(root_host,
                                      blink::WebInputEvent::Type::kTouchEnd);
  InputEventAckWaiter child_ack_waiter(child_host,
                                       blink::WebInputEvent::Type::kTouchEnd);
  InputEventAckWaiter child_gesture_tap_ack_waiter(
      child_host, blink::WebInputEvent::Type::kGestureTap);

  // Create GestureTap for child.
  gfx::PointF child_tap_point;
  {
    // We need to know the center of the child's body, but in root view
    // coordinates.
    std::string str = EvalJs(child_node,
                             "var rect = document.body.getBoundingClientRect();\
         var point = {\
           x: rect.left + rect.width / 2,\
           y: rect.top + rect.height / 2\
         };\
         JSON.stringify(point);")
                          .ExtractString();
    ConvertJSONToPoint(str, &child_tap_point);
    child_tap_point = child_node->current_frame_host()
                          ->GetView()
                          ->TransformPointToRootCoordSpaceF(child_tap_point);
  }
  SyntheticTapGestureParams child_tap_params;
  child_tap_params.position = child_tap_point;
  child_tap_params.gesture_source_type =
      content::mojom::GestureSourceType::kTouchInput;
  child_tap_params.duration_ms = 300.f;
  auto child_tap_gesture =
      std::make_unique<SyntheticTapGesture>(child_tap_params);

  // Create GestureTap for root.
  SyntheticTapGestureParams root_tap_params;
  root_tap_params.position = gfx::PointF(5.f, 5.f);
  root_tap_params.duration_ms = 300.f;
  root_tap_params.gesture_source_type =
      content::mojom::GestureSourceType::kTouchInput;
  auto root_tap_gesture =
      std::make_unique<SyntheticTapGesture>(root_tap_params);

  // Queue both GestureTaps, child first.
  // Note that we want the SyntheticGestureController to start sending the
  // root tap gesture as soon as it's finished sending the events for the
  // child tap gesture, otherwise it would wait for the acks from the child
  // before starting the root gesture which defeats the purpose of this test.
  root_host->QueueSyntheticGestureCompleteImmediately(
      std::move(child_tap_gesture));
  root_host->QueueSyntheticGesture(
      std::move(root_tap_gesture),
      base::BindOnce([](SyntheticGesture::Result result) {
        EXPECT_EQ(SyntheticGesture::GESTURE_FINISHED, result);
      }));

  root_ack_waiter.Wait();
  child_ack_waiter.Wait();

  // Verify the child did receive two touch events.
  EXPECT_EQ(2, EvalJs(child_node, "touch_event_count;"));

  // Verify Acks from parent arrive first.
  EXPECT_EQ(4u, outgoing_touch_event_ids.size());
  EXPECT_EQ(4u, acked_touch_event_ids.size());
  EXPECT_EQ(outgoing_touch_event_ids[2], acked_touch_event_ids[0]);
  EXPECT_EQ(outgoing_touch_event_ids[3], acked_touch_event_ids[1]);

  // Verify no DCHECKs from GestureRecognizer, indicating acks happened in
  // order.
  child_gesture_tap_ack_waiter.Wait();
}

// Verify that sandbox flags specified by a CSP header are properly inherited by
// child frames, but are removed when the frame navigates.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       ActiveSandboxFlagsMaintainedAcrossNavigation) {
  bool sandboxed_iframes_are_isolated =
      SiteIsolationPolicy::AreIsolatedSandboxedIframesEnabled();
  GURL main_url(
      embedded_test_server()->GetURL("a.com", "/sandbox_main_frame_csp.html"));
  RenderFrameDeletedObserver deleted_observer(
      web_contents()->GetPrimaryFrameTree().root()->current_frame_host());
  EXPECT_TRUE(NavigateToURL(shell(), main_url));
  if (sandboxed_iframes_are_isolated) {
    // The initial navigation is away from an initial un-sandboxed mainframe to
    // a sandboxed mainframe, so before we call DepictFrameTree below we need to
    // wait for the RenderFrameHost from the initial mainframe to be deleted and
    // its proxies removed.
    // TODO(crbug.com/40282613): See if we can reuse the initial RFH for
    // a navigation to a sandboxed frame instead?
    deleted_observer.WaitUntilDeleted();
  }

  // It is safe to obtain the root frame tree node here, as it doesn't change.
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  ASSERT_EQ(1u, root->child_count());

  EXPECT_EQ(
      base::StringPrintf(" Site A\n"
                         "   +--Site A\n"
                         "Where A = http://a.com/%s",
                         sandboxed_iframes_are_isolated ? " (sandboxed)" : ""),
      DepictFrameTree(root));
  if (sandboxed_iframes_are_isolated &&
      blink::features::kIsolateSandboxedIframesGroupingParam.Get() ==
          blink::features::IsolateSandboxedIframesGrouping::kPerOrigin) {
    // In per-origin IsolatedSandboxedIframes mode, the server port is retained
    // in the site URL.
    GURL main_site(embedded_test_server()->GetURL("a.com", "/"));
    EXPECT_EQ(main_site,
              root->current_frame_host()->GetSiteInstance()->GetSiteURL());
  }

  FrameTreeNode* child_node = root->child_at(0);

  EXPECT_EQ(shell()->web_contents()->GetSiteInstance(),
            child_node->current_frame_host()->GetSiteInstance());

  // Main page is served with a CSP header applying sandbox flags allow-popups,
  // allow-pointer-lock and allow-scripts.
  EXPECT_EQ(network::mojom::WebSandboxFlags::kNone,
            root->pending_frame_policy().sandbox_flags);
  EXPECT_EQ(network::mojom::WebSandboxFlags::kNone,
            root->effective_frame_policy().sandbox_flags);
  EXPECT_EQ(
      network::mojom::WebSandboxFlags::kAll &
          ~network::mojom::WebSandboxFlags::kAutomaticFeatures &
          ~network::mojom::WebSandboxFlags::kPointerLock &
          ~network::mojom::WebSandboxFlags::kPopups &
          ~network::mojom::WebSandboxFlags::kScripts &
          ~network::mojom::WebSandboxFlags::kTopNavigationToCustomProtocols,
      root->active_sandbox_flags());

  // Child frame has iframe sandbox flags allow-popups, allow-scripts, and
  // allow-orientation-lock. It should receive the intersection of those with
  // the parent sandbox flags: allow-popups and allow-scripts.
  EXPECT_EQ(
      network::mojom::WebSandboxFlags::kAll &
          ~network::mojom::WebSandboxFlags::kAutomaticFeatures &
          ~network::mojom::WebSandboxFlags::kPopups &
          ~network::mojom::WebSandboxFlags::kScripts &
          ~network::mojom::WebSandboxFlags::kTopNavigationToCustomProtocols,
      root->child_at(0)->pending_frame_policy().sandbox_flags);
  EXPECT_EQ(
      network::mojom::WebSandboxFlags::kAll &
          ~network::mojom::WebSandboxFlags::kAutomaticFeatures &
          ~network::mojom::WebSandboxFlags::kPopups &
          ~network::mojom::WebSandboxFlags::kScripts &
          ~network::mojom::WebSandboxFlags::kTopNavigationToCustomProtocols,
      root->child_at(0)->effective_frame_policy().sandbox_flags);

  // Document in child frame is served with a CSP header giving sandbox flags
  // allow-scripts, allow-popups and allow-pointer-lock. The final effective
  // flags should only include allow-scripts and allow-popups.
  EXPECT_EQ(
      network::mojom::WebSandboxFlags::kAll &
          ~network::mojom::WebSandboxFlags::kAutomaticFeatures &
          ~network::mojom::WebSandboxFlags::kPopups &
          ~network::mojom::WebSandboxFlags::kScripts &
          ~network::mojom::WebSandboxFlags::kTopNavigationToCustomProtocols,
      root->child_at(0)->active_sandbox_flags());

  // Navigate the child frame to a new page. This should clear any CSP-applied
  // sandbox flags.
  GURL frame_url(embedded_test_server()->GetURL("b.com", "/title1.html"));
  EXPECT_TRUE(NavigateToURLFromRenderer(root->child_at(0), frame_url));

  EXPECT_NE(shell()->web_contents()->GetSiteInstance(),
            child_node->current_frame_host()->GetSiteInstance());

  // Navigating should reset the sandbox flags to the frame owner flags:
  // allow-popups and allow-scripts.
  EXPECT_EQ(
      network::mojom::WebSandboxFlags::kAll &
          ~network::mojom::WebSandboxFlags::kAutomaticFeatures &
          ~network::mojom::WebSandboxFlags::kPopups &
          ~network::mojom::WebSandboxFlags::kScripts &
          ~network::mojom::WebSandboxFlags::kTopNavigationToCustomProtocols,
      root->child_at(0)->active_sandbox_flags());
  EXPECT_EQ(
      network::mojom::WebSandboxFlags::kAll &
          ~network::mojom::WebSandboxFlags::kAutomaticFeatures &
          ~network::mojom::WebSandboxFlags::kPopups &
          ~network::mojom::WebSandboxFlags::kScripts &
          ~network::mojom::WebSandboxFlags::kTopNavigationToCustomProtocols,
      root->child_at(0)->pending_frame_policy().sandbox_flags);
  EXPECT_EQ(
      network::mojom::WebSandboxFlags::kAll &
          ~network::mojom::WebSandboxFlags::kAutomaticFeatures &
          ~network::mojom::WebSandboxFlags::kPopups &
          ~network::mojom::WebSandboxFlags::kScripts &
          ~network::mojom::WebSandboxFlags::kTopNavigationToCustomProtocols,
      root->child_at(0)->effective_frame_policy().sandbox_flags);
}

// Test that after an RFH is unloaded, its old sandbox flags remain active.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       ActiveSandboxFlagsRetainedAfterUnload) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/sandboxed_main_frame_script.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  // It is safe to obtain the root frame tree node here, as it doesn't change.
  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
                            ->GetPrimaryFrameTree()
                            .root();

  RenderFrameHostImpl* rfh =
      static_cast<WebContentsImpl*>(shell()->web_contents())
          ->GetPrimaryMainFrame();

  // Check sandbox flags on RFH before navigating away.
  EXPECT_EQ(
      network::mojom::WebSandboxFlags::kAll &
          ~network::mojom::WebSandboxFlags::kAutomaticFeatures &
          ~network::mojom::WebSandboxFlags::kPointerLock &
          ~network::mojom::WebSandboxFlags::kPopups &
          ~network::mojom::WebSandboxFlags::kScripts &
          ~network::mojom::WebSandboxFlags::kTopNavigationToCustomProtocols,
      rfh->active_sandbox_flags());

  // Set up a slow unload handler to force the RFH to linger in the unloaded but
  // not-yet-deleted state.
  EXPECT_TRUE(ExecJs(rfh, "window.onunload=function(e){ while(1); };\n"));

  rfh->DisableUnloadTimerForTesting();
  RenderFrameDeletedObserver rfh_observer(rfh);

  // Navigate to a page with no sandbox, but wait for commit, not for the actual
  // load to finish.
  TestFrameNavigationObserver commit_observer(root);
  shell()->LoadURL(
      GURL(embedded_test_server()->GetURL("b.com", "/title1.html")));
  commit_observer.WaitForCommit();

  // The previous RFH should be either:
  // 1) In the BackForwardCache, or
  // 2) Pending deletion, waiting for the
  // mojo::AgentSchedulingGroupHost::DidUnloadRenderFrame. As a result, it must
  // still be alive.
  ASSERT_TRUE(rfh->IsRenderFrameLive());
  EXPECT_THAT(
      rfh->lifecycle_state(),
      testing::AnyOf(
          testing::Eq(
              RenderFrameHostImpl::LifecycleStateImpl::kRunningUnloadHandlers),
          testing::Eq(
              RenderFrameHostImpl::LifecycleStateImpl::kInBackForwardCache)));

  ASSERT_FALSE(rfh_observer.deleted());

  // Check sandbox flags on old RFH -- they should be unchanged.
  EXPECT_EQ(
      network::mojom::WebSandboxFlags::kAll &
          ~network::mojom::WebSandboxFlags::kAutomaticFeatures &
          ~network::mojom::WebSandboxFlags::kPointerLock &
          ~network::mojom::WebSandboxFlags::kPopups &
          ~network::mojom::WebSandboxFlags::kScripts &
          ~network::mojom::WebSandboxFlags::kTopNavigationToCustomProtocols,
      rfh->active_sandbox_flags());

  // The FrameTreeNode should have flags which represent the new state.
  EXPECT_EQ(network::mojom::WebSandboxFlags::kNone,
            root->effective_frame_policy().sandbox_flags);
}

// Verify that when CSP-set sandbox flags on a page change due to navigation,
// the new flags are propagated to proxies in other SiteInstances.
//
//   A        A         A         A
//    \        \         \         \     .
//     B  ->    B*   ->   B*   ->   B*
//             /  \      /  \      /  \  .
//            B    B    A    B    C    B
//
// (B* has CSP-set sandbox flags)
// The test checks sandbox flags for the proxy added in step 2, by checking
// whether the grandchild frames navigated to in step 3 and 4 see the correct
// sandbox flags.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       ActiveSandboxFlagsCorrectInProxies) {
  bool sandboxed_iframes_are_isolated =
      SiteIsolationPolicy::AreIsolatedSandboxedIframesEnabled();
  GURL main_url(embedded_test_server()->GetURL(
      "foo.com", "/cross_site_iframe_factory.html?foo(bar)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  // It is safe to obtain the root frame tree node here, as it doesn't change.
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  TestNavigationObserver observer(shell()->web_contents());

  EXPECT_EQ(
      " Site A ------------ proxies for B\n"
      "   +--Site B ------- proxies for A\n"
      "Where A = http://foo.com/\n"
      "      B = http://bar.com/",
      DepictFrameTree(root));

  // Navigate the child to a CSP-sandboxed page on the same origin as it is
  // currently. This should update the flags in its proxies as well.
  auto* child = root->child_at(0);
  RenderFrameDeletedObserver deleted_observer_child(
      child->current_frame_host());
  EXPECT_TRUE(NavigateToURLFromRenderer(
      root->child_at(0),
      embedded_test_server()->GetURL("bar.com", "/csp_sandboxed_frame.html")));
  // DepictFrameTree remembers all the sites it has seen in the test, so the
  // expected output changes depending on whether we have additional sites from
  // process-isolated sandboxed frames. How many additional sites we have
  // depends on the grouping mode.
  if (sandboxed_iframes_are_isolated) {
    // Sandboxed iframes force the RFH to change; wait for the old one to go
    // away so that proxies in its SiteInstance don't affect DepictFrameTree
    // output.
    deleted_observer_child.WaitUntilDeleted();
    switch (blink::features::kIsolateSandboxedIframesGroupingParam.Get()) {
      case blink::features::IsolateSandboxedIframesGrouping::kPerSite:
      case blink::features::IsolateSandboxedIframesGrouping::kPerOrigin:
        EXPECT_EQ(
            " Site A ------------ proxies for C\n"
            "   +--Site C ------- proxies for A\n"
            "        |--Site C -- proxies for A\n"
            "        +--Site C -- proxies for A\n"
            "Where A = http://foo.com/\n"
            "      C = http://bar.com/ (sandboxed)",
            DepictFrameTree(root));
        break;
      case blink::features::IsolateSandboxedIframesGrouping::kPerDocument:
        // TODO(crbug.com/40941714): Add output for the PerDocument
        // case, and parameterize this test to run all variants (none, per-site,
        // per-origin, per-document).
        break;
    }
  } else {
    EXPECT_EQ(
        " Site A ------------ proxies for B\n"
        "   +--Site B ------- proxies for A\n"
        "        |--Site B -- proxies for A\n"
        "        +--Site B -- proxies for A\n"
        "Where A = http://foo.com/\n"
        "      B = http://bar.com/",
        DepictFrameTree(root));
  }

  // Now navigate the first grandchild to a page on the same origin as the main
  // frame. It should still be sandboxed, as it should get its flags from its
  // (remote) parent.
  // TODO(crbug.com/40943240): When IsolateSandboxedIframes is enabled,
  // this test no longer uses proxy inheritance; the grandchild and the main
  // frame won't be in the same SiteInstance anymore, so this test will no
  // longer exercise sandbox flags inheritance from an existing remote frame.
  // Restructure the test so it still provides coverage for proxy inheritance
  // when IsolateSandboxedIframes is enabled.
  EXPECT_TRUE(NavigateToURLFromRenderer(
      root->child_at(0)->child_at(0),
      embedded_test_server()->GetURL("foo.com", "/title1.html")));

  if (sandboxed_iframes_are_isolated) {
    switch (blink::features::kIsolateSandboxedIframesGroupingParam.Get()) {
      case blink::features::IsolateSandboxedIframesGrouping::kPerSite:
      case blink::features::IsolateSandboxedIframesGrouping::kPerOrigin:
        EXPECT_EQ(
            " Site A ------------ proxies for C D\n"
            "   +--Site C ------- proxies for A D\n"
            "        |--Site D -- proxies for A C\n"
            "        +--Site C -- proxies for A D\n"
            "Where A = http://foo.com/\n"
            "      C = http://bar.com/ (sandboxed)\n"
            "      D = http://foo.com/ (sandboxed)",
            DepictFrameTree(root));
        break;
      case blink::features::IsolateSandboxedIframesGrouping::kPerDocument:
        // TODO(crbug.com/40941714): Add output for the PerDocument
        // case, and parameterize this test to run all variants (none, per-site,
        // per-origin, per-document).
        break;
    }
  } else {
    EXPECT_EQ(
        " Site A ------------ proxies for B\n"
        "   +--Site B ------- proxies for A\n"
        "        |--Site A -- proxies for B\n"
        "        +--Site B -- proxies for A\n"
        "Where A = http://foo.com/\n"
        "      B = http://bar.com/",
        DepictFrameTree(root));
  }

  // The child of the sandboxed frame should've inherited sandbox flags, so it
  // should not be able to create popups.
  EXPECT_EQ(
      network::mojom::WebSandboxFlags::kAll &
          ~network::mojom::WebSandboxFlags::kScripts &
          ~network::mojom::WebSandboxFlags::kAutomaticFeatures,
      root->child_at(0)->child_at(0)->effective_frame_policy().sandbox_flags);
  EXPECT_EQ(
      root->child_at(0)->child_at(0)->active_sandbox_flags(),
      root->child_at(0)->child_at(0)->effective_frame_policy().sandbox_flags);
  EXPECT_EQ(true, EvalJs(root->child_at(0)->child_at(0),
                         "!window.open('data:text/html,dataurl');"));
  EXPECT_EQ(1u, Shell::windows().size());

  // Finally, navigate the grandchild frame to a new origin, creating a new site
  // instance. Again, the new document should be sandboxed, as it should get its
  // flags from its (remote) parent in B.
  RenderFrameDeletedObserver deleted_observer_grandchild(
      root->child_at(0)->child_at(0)->current_frame_host());
  EXPECT_TRUE(NavigateToURLFromRenderer(
      root->child_at(0)->child_at(0),
      embedded_test_server()->GetURL("baz.com", "/title1.html")));

  deleted_observer_grandchild.WaitUntilDeleted();
  if (sandboxed_iframes_are_isolated) {
    switch (blink::features::kIsolateSandboxedIframesGroupingParam.Get()) {
      case blink::features::IsolateSandboxedIframesGrouping::kPerSite:
      case blink::features::IsolateSandboxedIframesGrouping::kPerOrigin:
        EXPECT_EQ(
            " Site A ------------ proxies for C E\n"
            "   +--Site C ------- proxies for A E\n"
            "        |--Site E -- proxies for A C\n"
            "        +--Site C -- proxies for A E\n"
            "Where A = http://foo.com/\n"
            "      C = http://bar.com/ (sandboxed)\n"
            "      E = http://baz.com/ (sandboxed)",
            DepictFrameTree(root));
        break;
      case blink::features::IsolateSandboxedIframesGrouping::kPerDocument:
        // TODO(crbug.com/40941714): Add output for the PerDocument
        // case, and parameterize this test to run all variants (none, per-site,
        // per-origin, per-document).
        break;
    }
  } else {
    EXPECT_EQ(
        " Site A ------------ proxies for B C\n"
        "   +--Site B ------- proxies for A C\n"
        "        |--Site C -- proxies for A B\n"
        "        +--Site B -- proxies for A C\n"
        "Where A = http://foo.com/\n"
        "      B = http://bar.com/\n"
        "      C = http://baz.com/",
        DepictFrameTree(root));
  }

  // The child of the sandboxed frame should've inherited sandbox flags, so it
  // should not be able to create popups.
  EXPECT_EQ(
      network::mojom::WebSandboxFlags::kAll &
          ~network::mojom::WebSandboxFlags::kScripts &
          ~network::mojom::WebSandboxFlags::kAutomaticFeatures,
      root->child_at(0)->child_at(0)->effective_frame_policy().sandbox_flags);
  EXPECT_EQ(
      root->child_at(0)->child_at(0)->active_sandbox_flags(),
      root->child_at(0)->child_at(0)->effective_frame_policy().sandbox_flags);
  EXPECT_EQ(true, EvalJs(root->child_at(0)->child_at(0),
                         "!window.open('data:text/html,dataurl');"));
  EXPECT_EQ(1u, Shell::windows().size());
}

// Verify that when the sandbox iframe attribute changes on a page which also
// has CSP-set sandbox flags, that the correct combination of flags is set in
// the sandboxed page after navigation.
//
//   A        A         A                                  A
//    \        \         \                                  \     .
//     B  ->    B*   ->   B*   -> (change sandbox attr) ->   B*
//             /  \      /  \                               /  \  .
//            B    B    A    B                             A'   B
//
// (B* has CSP-set sandbox flags)
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       ActiveSandboxFlagsCorrectAfterUpdate) {
  GURL main_url(embedded_test_server()->GetURL(
      "foo.com", "/cross_site_iframe_factory.html?foo(bar)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  // It is safe to obtain the root frame tree node here, as it doesn't change.
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  TestNavigationObserver observer(shell()->web_contents());

  // Navigate the child to a CSP-sandboxed page on the same origin as it is
  // currently. This should update the flags in its proxies as well.
  EXPECT_TRUE(NavigateToURLFromRenderer(
      root->child_at(0),
      embedded_test_server()->GetURL("bar.com", "/csp_sandboxed_frame.html")));

  // Now navigate the first grandchild to a page on the same origin as the main
  // frame. It should still be sandboxed, as it should get its flags from its
  // (remote) parent.
  EXPECT_TRUE(NavigateToURLFromRenderer(
      root->child_at(0)->child_at(0),
      embedded_test_server()->GetURL("foo.com", "/title1.html")));

  // The child of the sandboxed frame should've inherited sandbox flags, so it
  // should not be able to create popups.
  EXPECT_EQ(
      network::mojom::WebSandboxFlags::kAll &
          ~network::mojom::WebSandboxFlags::kScripts &
          ~network::mojom::WebSandboxFlags::kAutomaticFeatures,
      root->child_at(0)->child_at(0)->effective_frame_policy().sandbox_flags);
  EXPECT_EQ(
      root->child_at(0)->child_at(0)->active_sandbox_flags(),
      root->child_at(0)->child_at(0)->effective_frame_policy().sandbox_flags);
  EXPECT_EQ(true, EvalJs(root->child_at(0)->child_at(0),
                         "!window.open('data:text/html,dataurl');"));
  EXPECT_EQ(1u, Shell::windows().size());

  // Update the sandbox attribute in the child frame. This should be overridden
  // by the CSP-set sandbox on this frame: The grandchild should *not* receive
  // an allowance for popups after it is navigated.
  EXPECT_TRUE(ExecJs(root->child_at(0),
                     "document.querySelector('iframe').sandbox = "
                     "    'allow-scripts allow-popups';"));
  // Finally, navigate the grandchild frame to another page on the top-level
  // origin; the active sandbox flags should still come from the it's parent's
  // CSP and the frame owner attributes.
  EXPECT_TRUE(NavigateToURLFromRenderer(
      root->child_at(0)->child_at(0),
      embedded_test_server()->GetURL("foo.com", "/title2.html")));
  EXPECT_EQ(
      network::mojom::WebSandboxFlags::kAll &
          ~network::mojom::WebSandboxFlags::kScripts &
          ~network::mojom::WebSandboxFlags::kAutomaticFeatures,
      root->child_at(0)->child_at(0)->effective_frame_policy().sandbox_flags);
  EXPECT_EQ(
      root->child_at(0)->child_at(0)->active_sandbox_flags(),
      root->child_at(0)->child_at(0)->effective_frame_policy().sandbox_flags);
  EXPECT_EQ(true, EvalJs(root->child_at(0)->child_at(0),
                         "!window.open('data:text/html,dataurl');"));
  EXPECT_EQ(1u, Shell::windows().size());
}

// Verify that when the sandbox iframe attribute is removed from a page which
// also has CSP-set sandbox flags, that the flags are cleared in the browser
// and renderers (including proxies) after navigation to a page without CSP-set
// flags.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       ActiveSandboxFlagsCorrectWhenCleared) {
  GURL main_url(
      embedded_test_server()->GetURL("foo.com", "/sandboxed_frames_csp.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  // It is safe to obtain the root frame tree node here, as it doesn't change.
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  TestNavigationObserver observer(shell()->web_contents());

  // The second child has both iframe-attribute sandbox flags and CSP-set flags.
  // Verify that it the flags are combined correctly in the frame tree.
  EXPECT_EQ(network::mojom::WebSandboxFlags::kAll &
                ~network::mojom::WebSandboxFlags::kPointerLock &
                ~network::mojom::WebSandboxFlags::kOrientationLock &
                ~network::mojom::WebSandboxFlags::kScripts &
                ~network::mojom::WebSandboxFlags::kAutomaticFeatures,
            root->child_at(1)->effective_frame_policy().sandbox_flags);
  EXPECT_EQ(network::mojom::WebSandboxFlags::kAll &
                ~network::mojom::WebSandboxFlags::kPointerLock &
                ~network::mojom::WebSandboxFlags::kScripts &
                ~network::mojom::WebSandboxFlags::kAutomaticFeatures,
            root->child_at(1)->active_sandbox_flags());

  EXPECT_TRUE(NavigateToURLFromRenderer(
      root->child_at(1), embedded_test_server()->GetURL(
                             "bar.com", "/sandboxed_child_frame.html")));
  EXPECT_EQ(network::mojom::WebSandboxFlags::kAll &
                ~network::mojom::WebSandboxFlags::kPointerLock &
                ~network::mojom::WebSandboxFlags::kOrientationLock &
                ~network::mojom::WebSandboxFlags::kScripts &
                ~network::mojom::WebSandboxFlags::kAutomaticFeatures,
            root->child_at(1)->effective_frame_policy().sandbox_flags);
  EXPECT_EQ(network::mojom::WebSandboxFlags::kAll &
                ~network::mojom::WebSandboxFlags::kPointerLock &
                ~network::mojom::WebSandboxFlags::kScripts &
                ~network::mojom::WebSandboxFlags::kAutomaticFeatures,
            root->child_at(1)->active_sandbox_flags());

  // Remove the sandbox attribute from the child frame.
  EXPECT_TRUE(ExecJs(root,
                     "document.querySelectorAll('iframe')[1]"
                     ".removeAttribute('sandbox');"));
  // Finally, navigate that child frame to another page on the same origin with
  // no CSP-set sandbox. Its sandbox flags should be completely cleared, and
  // should be cleared in the proxy in the main frame's renderer as well.
  // We can check that the flags were properly cleared by nesting another frame
  // under the child, and ensuring that *it* saw no sandbox flags in the
  // browser, or in the RemoteSecurityContext in the main frame's renderer.
  EXPECT_TRUE(NavigateToURLFromRenderer(
      root->child_at(1),
      embedded_test_server()->GetURL(
          "bar.com", "/cross_site_iframe_factory.html?bar(foo)")));

  // Check the sandbox flags on the child frame in the browser process.
  EXPECT_EQ(network::mojom::WebSandboxFlags::kNone,
            root->child_at(1)->effective_frame_policy().sandbox_flags);
  EXPECT_EQ(network::mojom::WebSandboxFlags::kNone,
            root->child_at(1)->active_sandbox_flags());

  // Check the sandbox flags on the grandchid frame in the browser process.
  EXPECT_EQ(
      network::mojom::WebSandboxFlags::kNone,
      root->child_at(1)->child_at(0)->effective_frame_policy().sandbox_flags);
  EXPECT_EQ(
      root->child_at(1)->child_at(0)->active_sandbox_flags(),
      root->child_at(1)->child_at(0)->effective_frame_policy().sandbox_flags);

  // Check the sandbox flags in the grandchild frame's renderer by attempting
  // to open a popup. This should succeed.
  EXPECT_EQ(true, EvalJs(root->child_at(1)->child_at(0),
                         "!!window.open('data:text/html,dataurl');"));
  EXPECT_EQ(2u, Shell::windows().size());
}

// Check that a subframe that requires a dedicated process will attempt to
// reuse an existing process for the same site, even across BrowsingInstances.
// This helps consolidate processes when running under --site-per-process.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       SubframeReusesExistingProcess) {
  GURL foo_url(
      embedded_test_server()->GetURL("foo.com", "/page_with_iframe.html"));
  EXPECT_TRUE(NavigateToURL(shell(), foo_url));
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  FrameTreeNode* child = root->child_at(0);

  // Open an unrelated tab in a separate BrowsingInstance, and navigate it to
  // to bar.com.  This SiteInstance should have a default process reuse
  // policy - only subframes attempt process reuse.
  GURL bar_url(
      embedded_test_server()->GetURL("bar.com", "/page_with_iframe.html"));
  Shell* second_shell = CreateBrowser();
  EXPECT_TRUE(NavigateToURL(second_shell, bar_url));
  scoped_refptr<SiteInstanceImpl> second_shell_instance =
      static_cast<SiteInstanceImpl*>(second_shell->web_contents()
                                         ->GetPrimaryMainFrame()
                                         ->GetSiteInstance());
  EXPECT_FALSE(second_shell_instance->IsRelatedSiteInstance(
      root->current_frame_host()->GetSiteInstance()));
  RenderProcessHost* bar_process = second_shell_instance->GetProcess();
  EXPECT_EQ(ProcessReusePolicy::kDefault,
            second_shell_instance->process_reuse_policy());

  // Now navigate the first tab's subframe to bar.com.  Confirm that it reuses
  // |bar_process|.
  NavigateIframeToURL(web_contents(), "test_iframe", bar_url);
  EXPECT_EQ(bar_url, child->current_url());
  EXPECT_EQ(bar_process, child->current_frame_host()->GetProcess());
  EXPECT_EQ(
      ProcessReusePolicy::kReusePendingOrCommittedSiteSubframe,
      child->current_frame_host()->GetSiteInstance()->process_reuse_policy());

  EXPECT_TRUE(child->current_frame_host()->IsCrossProcessSubframe());
  EXPECT_EQ(
      bar_url.host(),
      child->current_frame_host()->GetSiteInstance()->GetSiteURL().host());

  // The subframe's SiteInstance should still be different from second_shell's
  // SiteInstance, and they should be in separate BrowsingInstances.
  EXPECT_NE(second_shell_instance,
            child->current_frame_host()->GetSiteInstance());
  EXPECT_FALSE(second_shell_instance->IsRelatedSiteInstance(
      child->current_frame_host()->GetSiteInstance()));

  // Navigate the second tab to a foo.com URL with a same-site subframe.  This
  // leaves only the first tab's subframe in the bar.com process.
  EXPECT_TRUE(NavigateToURL(second_shell, foo_url));
  EXPECT_NE(bar_process,
            second_shell->web_contents()->GetPrimaryMainFrame()->GetProcess());

  // Navigate the second tab's subframe to bar.com, and check that this
  // new subframe reuses the process of the subframe in the first tab, even
  // though the two are in separate BrowsingInstances.
  NavigateIframeToURL(second_shell->web_contents(), "test_iframe", bar_url);
  FrameTreeNode* second_subframe =
      static_cast<WebContentsImpl*>(second_shell->web_contents())
          ->GetPrimaryFrameTree()
          .root()
          ->child_at(0);
  EXPECT_EQ(bar_process, second_subframe->current_frame_host()->GetProcess());
  EXPECT_NE(child->current_frame_host()->GetSiteInstance(),
            second_subframe->current_frame_host()->GetSiteInstance());

  // Open a third, unrelated tab, navigate it to bar.com, and check that
  // its main frame doesn't share a process with the existing bar.com
  // subframes.
  Shell* third_shell = CreateBrowser();
  EXPECT_TRUE(NavigateToURL(third_shell, bar_url));
  SiteInstanceImpl* third_shell_instance = static_cast<SiteInstanceImpl*>(
      third_shell->web_contents()->GetPrimaryMainFrame()->GetSiteInstance());
  EXPECT_NE(third_shell_instance,
            second_subframe->current_frame_host()->GetSiteInstance());
  EXPECT_NE(third_shell_instance,
            child->current_frame_host()->GetSiteInstance());
  EXPECT_NE(third_shell_instance->GetProcess(), bar_process);
}

class SitePerProcessNoSharingBrowserTest : public SitePerProcessBrowserTest {
 public:
  SitePerProcessNoSharingBrowserTest() {
    scoped_feature_list_.InitAndDisableFeature(
        features::kProcessPerSiteUpToMainFrameThreshold);
  }

 private:
  base::test::ScopedFeatureList scoped_feature_list_;
};

// Check that when a subframe reuses an existing process for the same site
// across BrowsingInstances, a browser-initiated navigation in that subframe's
// tab doesn't unnecessarily share the reused process.  See
// https://crbug.com/803367.
IN_PROC_BROWSER_TEST_P(SitePerProcessNoSharingBrowserTest,
                       NoProcessSharingAfterSubframeReusesExistingProcess) {
  GURL foo_url(embedded_test_server()->GetURL("foo.com", "/title1.html"));
  EXPECT_TRUE(NavigateToURL(shell(), foo_url));
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  SiteInstanceImpl* foo_instance =
      root->current_frame_host()->GetSiteInstance();

  // Open an unrelated tab in a separate BrowsingInstance, and navigate it to
  // to bar.com.
  GURL bar_url(
      embedded_test_server()->GetURL("bar.com", "/page_with_iframe.html"));
  Shell* second_shell = CreateBrowser();
  EXPECT_TRUE(NavigateToURL(second_shell, bar_url));
  FrameTreeNode* second_root =
      static_cast<WebContentsImpl*>(second_shell->web_contents())
          ->GetPrimaryFrameTree()
          .root();
  FrameTreeNode* second_child = second_root->child_at(0);
  scoped_refptr<SiteInstanceImpl> bar_instance =
      second_root->current_frame_host()->GetSiteInstance();
  EXPECT_FALSE(bar_instance->IsRelatedSiteInstance(foo_instance));

  // Navigate the second tab's subframe to foo.com.  Confirm that it reuses
  // first tab's process.
  NavigateIframeToURL(second_shell->web_contents(), "test_iframe", foo_url);
  EXPECT_EQ(foo_url, second_child->current_url());
  scoped_refptr<SiteInstanceImpl> second_child_foo_instance =
      second_child->current_frame_host()->GetSiteInstance();
  EXPECT_EQ(ProcessReusePolicy::kReusePendingOrCommittedSiteSubframe,
            second_child_foo_instance->process_reuse_policy());
  EXPECT_NE(foo_instance, second_child_foo_instance);
  EXPECT_EQ(foo_instance->GetProcess(),
            second_child_foo_instance->GetProcess());

  // Perform a browser-initiated address bar navigation in the second tab to
  // foo.com.  This should swap BrowsingInstances and end up in a separate
  // process from the first tab.
  EXPECT_TRUE(NavigateToURL(second_shell, foo_url));
  SiteInstanceImpl* new_instance =
      second_root->current_frame_host()->GetSiteInstance();
  EXPECT_NE(second_child_foo_instance, new_instance);
  EXPECT_FALSE(second_child_foo_instance->IsRelatedSiteInstance(new_instance));
  EXPECT_FALSE(bar_instance->IsRelatedSiteInstance(new_instance));
  EXPECT_FALSE(foo_instance->IsRelatedSiteInstance(new_instance));
  EXPECT_NE(new_instance->GetProcess(), foo_instance->GetProcess());
  EXPECT_NE(new_instance->GetProcess(),
            bar_instance->GetOrCreateProcessForTesting());
}

namespace {

// Intercepts the next DidCommitProvisionalLoad message for |deferred_url| in
// any frame of the |web_contents|, and holds off on dispatching it until
// *after* the DidCommitProvisionalLoad message for the next navigation in the
// |web_contents| has been dispatched.
//
// Reversing the order in which the commit messages are dispatched simulates a
// busy renderer that takes a very long time to actually commit the navigation
// to |deferred_url| after receiving DidCommitNavigation; whereas there is a
// fast cross-site navigation taking place in the same frame which starts second
// but finishes first.
class CommitMessageOrderReverser : public DidCommitNavigationInterceptor {
 public:
  using DidStartDeferringCommitCallback =
      base::OnceCallback<void(RenderFrameHost*)>;

  CommitMessageOrderReverser(
      WebContents* web_contents,
      const GURL& deferred_url,
      DidStartDeferringCommitCallback deferred_url_triggered_action)
      : DidCommitNavigationInterceptor(web_contents),
        deferred_url_(deferred_url),
        deferred_url_triggered_action_(
            std::move(deferred_url_triggered_action)) {}

  CommitMessageOrderReverser(const CommitMessageOrderReverser&) = delete;
  CommitMessageOrderReverser& operator=(const CommitMessageOrderReverser&) =
      delete;

  ~CommitMessageOrderReverser() override = default;

  void WaitForBothCommits() { outer_run_loop.Run(); }

 protected:
  bool WillProcessDidCommitNavigation(
      RenderFrameHost* render_frame_host,
      NavigationRequest* navigation_request,
      mojom::DidCommitProvisionalLoadParamsPtr* params,
      mojom::DidCommitProvisionalLoadInterfaceParamsPtr* interface_params)
      override {
    // The DidCommitProvisionalLoad message is dispatched once this method
    // returns, so to defer committing the the navigation to |deferred_url_|,
    // run a nested message loop until the subsequent other commit message is
    // dispatched.
    if ((**params).url == deferred_url_) {
      std::move(deferred_url_triggered_action_).Run(render_frame_host);

      base::RunLoop nested_run_loop(base::RunLoop::Type::kNestableTasksAllowed);
      nested_loop_quit_ = nested_run_loop.QuitClosure();
      nested_run_loop.Run();
      outer_run_loop.Quit();
    } else if (nested_loop_quit_) {
      std::move(nested_loop_quit_).Run();
    }
    return true;
  }

 private:
  base::RunLoop outer_run_loop;
  base::OnceClosure nested_loop_quit_;

  const GURL deferred_url_;
  DidStartDeferringCommitCallback deferred_url_triggered_action_;
};

}  // namespace

// Create an out-of-process iframe that causes itself to be detached during
// its layout/animate phase. See https://crbug.com/802932.
//
// TODO(crbug.com/40561636): Disabled on Android, Mac, and ChromeOS due to
// flakiness.
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_CHROMEOS)
#define MAYBE_OOPIFDetachDuringAnimation DISABLED_OOPIFDetachDuringAnimation
#else
#define MAYBE_OOPIFDetachDuringAnimation OOPIFDetachDuringAnimation
#endif
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       MAYBE_OOPIFDetachDuringAnimation) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/frame_tree/frame-detached-in-animationstart-event.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();

  EXPECT_EQ(
      " Site A ------------ proxies for B\n"
      "   +--Site B ------- proxies for A\n"
      "        +--Site A -- proxies for B\n"
      "Where A = http://a.com/\n"
      "      B = http://b.com/",
      DepictFrameTree(root));

  FrameTreeNode* nested_child = root->child_at(0)->child_at(0);
  WaitForHitTestData(nested_child->current_frame_host());

  EXPECT_TRUE(ExecJs(nested_child->current_frame_host(), "startTest();"));

  // Test passes if the main renderer doesn't crash. Ping to verify.
  EXPECT_EQ(true, EvalJs(root->current_frame_host(), "true;"));
}

// Tests that a cross-process iframe asked to navigate to the same URL will
// successfully commit the navigation.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       IFrameSameDocumentNavigation) {
  GURL main_url(embedded_test_server()->GetURL(
      "foo.com", "/cross_site_iframe_factory.html?foo(bar)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  FrameTreeNode* iframe = root->child_at(0);

  EXPECT_NE(root->current_frame_host()->GetSiteInstance(),
            iframe->current_frame_host()->GetSiteInstance());

  // The iframe navigates same-document to a fragment.
  GURL iframe_fragment_url = GURL(iframe->current_url().spec() + "#foo");
  {
    TestNavigationObserver observer(shell()->web_contents());
    EXPECT_TRUE(ExecJs(iframe->current_frame_host(),
                       JsReplace("location.href=$1", iframe_fragment_url)));
    observer.Wait();
    EXPECT_TRUE(observer.last_navigation_succeeded());
    EXPECT_EQ(iframe_fragment_url, iframe->current_url());
  }

  // The parent frame wants the iframe do a navigation to the same URL. Because
  // the URL has a fragment, this will be treated as a same-document navigation,
  // and not as a normal load of the same URL. This should succeed.
  {
    TestNavigationObserver observer(shell()->web_contents());
    EXPECT_TRUE(ExecJs(root->current_frame_host(),
                       JsReplace("document.getElementById('child-0').src=$1",
                                 iframe_fragment_url)));
    observer.Wait();
    EXPECT_TRUE(observer.last_navigation_succeeded());
    EXPECT_EQ(iframe_fragment_url, iframe->current_url());
  }
}

// Verifies the the renderer has the size of the frame after commit.
// https://crbug/804046, https://crbug.com/801091
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest, SizeAvailableAfterCommit) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(a)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  FrameTreeNode* child = root->child_at(0);

  GURL b_url(embedded_test_server()->GetURL("b.com", "/title2.html"));
  TestFrameNavigationObserver commit_observer(child);
  NavigationController::LoadURLParams params(b_url);
  params.transition_type = PageTransitionFromInt(ui::PAGE_TRANSITION_LINK);
  params.frame_tree_node_id = child->frame_tree_node_id();
  child->navigator().controller().LoadURLWithParams(params);
  commit_observer.WaitForCommit();

  EXPECT_GT(EvalJs(child, "window.innerHeight;").ExtractDouble(), 0);
}

// Test that a late mojo::AgentSchedulingGroupHost::DidUnloadRenderFrame won't
// incorrectly mark RenderViewHost as inactive if it's already been reused and
// switched to active by another navigation.  See https://crbug.com/823567.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       RenderViewHostStaysActiveWithLateUnloadACK) {
  EXPECT_TRUE(NavigateToURL(
      shell(), embedded_test_server()->GetURL("a.com", "/title1.html")));

  // Open a popup and navigate it to a.com.
  Shell* popup = OpenPopup(
      shell(), embedded_test_server()->GetURL("a.com", "/title2.html"), "foo");
  WebContentsImpl* popup_contents =
      static_cast<WebContentsImpl*>(popup->web_contents());
  RenderFrameHostImpl* rfh = popup_contents->GetPrimaryMainFrame();
  RenderViewHostImpl* rvh = rfh->render_view_host();

  // Disable the unload ACK and the unload timer.
  auto unload_ack_filter = base::BindRepeating([] { return true; });
  rfh->SetUnloadACKCallbackForTesting(unload_ack_filter);
  rfh->DisableUnloadTimerForTesting();

  // Navigate popup to b.com.  Because there's an opener, the RVH for a.com
  // stays around in swapped-out state.
  EXPECT_TRUE(NavigateToURLInSameBrowsingInstance(
      popup, embedded_test_server()->GetURL("b.com", "/title3.html")));
  EXPECT_FALSE(rvh->is_active());

  // The old RenderFrameHost is now pending deletion.
  ASSERT_TRUE(rfh->IsRenderFrameLive());
  ASSERT_TRUE(rfh->IsPendingDeletion());

  // Kill the b.com process.
  RenderProcessHost* b_process =
      popup_contents->GetPrimaryMainFrame()->GetProcess();
  RenderProcessHostWatcher crash_observer(
      b_process, RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
  b_process->Shutdown(0);
  crash_observer.Wait();

  // Go back in the popup from b.com to a.com/title2.html.  Because the current
  // b.com RFH is dead, the new RFH is committed right away (without waiting
  // for renderer to commit), so that users don't need to look at the sad tab.
  TestNavigationObserver back_observer(popup_contents);
  popup_contents->GetController().GoBack();

  // Pretend that the original RFH in a.com now finishes running its unload
  // handler and sends the mojo::AgentSchedulingGroupHost::DidUnloadRenderFrame.
  rfh->OnUnloaded();

  // Wait for the new a.com navigation to finish.
  back_observer.Wait();

  // The RVH for a.com should've been reused, and it should be active.  Its
  // main frame should've been updated to the RFH from the back navigation.
  EXPECT_EQ(popup_contents->GetPrimaryMainFrame()->render_view_host(), rvh);
  EXPECT_TRUE(rvh->is_active());
  EXPECT_EQ(rvh->GetMainRenderFrameHost(),
            popup_contents->GetPrimaryMainFrame());
}

// Check that when A opens a new window with B which embeds an A subframe, the
// subframe is visible and generates paint events.  See
// https://crbug.com/638375.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       SubframeVisibleAfterRenderViewBecomesSwappedOut) {
  GURL main_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  GURL popup_url(embedded_test_server()->GetURL(
      "b.com", "/cross_site_iframe_factory.html?b(b)"));
  Shell* popup_shell = OpenPopup(shell()->web_contents(), popup_url, "popup");
  FrameTreeNode* popup_child =
      static_cast<WebContentsImpl*>(popup_shell->web_contents())
          ->GetPrimaryFrameTree()
          .root()
          ->child_at(0);

  // Navigate popup's subframe to a page on a.com, which will generate
  // continuous compositor frames by incrementing a counter on the page.
  EXPECT_TRUE(NavigateToURLFromRenderer(
      popup_child, embedded_test_server()->GetURL("a.com", "/counter.html")));

  RenderWidgetHostViewChildFrame* child_view =
      static_cast<RenderWidgetHostViewChildFrame*>(
          popup_child->current_frame_host()->GetView());

  // Make sure the child frame keeps generating compositor frames.
  RenderFrameSubmissionObserver frame_counter(
      child_view->host_->render_frame_metadata_provider());
  while (frame_counter.render_frame_count() < 10)
    frame_counter.WaitForAnyFrameSubmission();
}

IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest, FrameDepthSimple) {
  // Five nodes, from depth 0 to 4.
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b(c(d(e))))"));
  const size_t number_of_nodes = 5;
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  FrameTreeNode* node = web_contents()->GetPrimaryFrameTree().root();
  for (unsigned int expected_depth = 0; expected_depth < number_of_nodes;
       ++expected_depth) {
    CheckFrameDepth(expected_depth, node);

    if (expected_depth + 1 < number_of_nodes)
      node = node->child_at(0);
  }
}

IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest, FrameDepthTest) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(a,b(a))"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  CheckFrameDepth(0u, root);

  FrameTreeNode* child0 = root->child_at(0);
  {
    EXPECT_EQ(1u, child0->current_frame_host()->GetFrameDepth());
    RenderProcessHostPriorityClient::Priority priority =
        child0->current_frame_host()->GetRenderWidgetHost()->GetPriority();
    // Same site instance as root.
    EXPECT_EQ(0u, priority.frame_depth);
    EXPECT_EQ(0u, child0->current_frame_host()->GetProcess()->GetFrameDepth());
  }

  FrameTreeNode* child1 = root->child_at(1);
  CheckFrameDepth(1u, child1);
  // In addition, site b's inactive Widget should not contribute priority.
  RenderViewHostImpl* child1_rvh =
      child1->current_frame_host()->render_view_host();
  EXPECT_FALSE(child1_rvh->is_active());
  EXPECT_EQ(RenderProcessHostImpl::kMaxFrameDepthForPriority,
            child1_rvh->GetWidget()->GetPriority().frame_depth);
  EXPECT_FALSE(static_cast<RenderWidgetHostOwnerDelegate*>(child1_rvh)
                   ->ShouldContributePriorityToProcess());
  // The RenderWidgetHost of the RenderFrameHost is different from the
  // RenderWidgetHost of the RenderViewHost and contributes to the priority.
  EXPECT_NE(child1->current_frame_host()->GetRenderWidgetHost(),
            child1_rvh->GetWidget());
  EXPECT_EQ(1u, child1->current_frame_host()
                    ->GetLocalRenderWidgetHost()
                    ->GetPriority()
                    .frame_depth);
  EXPECT_EQ(1u, child1->current_frame_host()->GetProcess()->GetFrameDepth());

  FrameTreeNode* grand_child = root->child_at(1)->child_at(0);
  {
    EXPECT_EQ(2u, grand_child->current_frame_host()->GetFrameDepth());
    RenderProcessHostPriorityClient::Priority priority =
        grand_child->current_frame_host()->GetRenderWidgetHost()->GetPriority();
    EXPECT_EQ(2u, priority.frame_depth);
    // Same process as root
    EXPECT_EQ(0u,
              grand_child->current_frame_host()->GetProcess()->GetFrameDepth());
  }
}

// Disabled due to flakiness. crbug.com/1146083
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
#define MAYBE_VisibilityFrameDepthTest DISABLED_VisibilityFrameDepthTest
#else
#define MAYBE_VisibilityFrameDepthTest VisibilityFrameDepthTest
#endif
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       MAYBE_VisibilityFrameDepthTest) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)"));
  GURL popup_url(embedded_test_server()->GetURL("b.com", "/title1.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  Shell* new_shell = OpenPopup(root->child_at(0), popup_url, "");
  FrameTreeNode* popup_root =
      static_cast<WebContentsImpl*>(new_shell->web_contents())
          ->GetPrimaryFrameTree()
          .root();

  // Subframe and popup share the same process. Both are visible, so depth
  // should be 0.
  RenderProcessHost* subframe_process =
      root->child_at(0)->current_frame_host()->GetProcess();
  RenderProcessHost* popup_process =
      popup_root->current_frame_host()->GetProcess();
  EXPECT_EQ(subframe_process, popup_process);
  EXPECT_EQ(2, popup_process->VisibleClientCount());
  EXPECT_EQ(0u, popup_process->GetFrameDepth());

  // Hide popup. Process should have one visible client and depth should be 1,
  // since depth 0 popup is hidden.
  new_shell->web_contents()->WasHidden();
  EXPECT_EQ(1, popup_process->VisibleClientCount());
  EXPECT_EQ(1u, popup_process->GetFrameDepth());

  // Navigate main page to same origin as popup in same BrowsingInstance,
  // s main page should run in the same process as the popup. The depth on the
  // process should be 0, from the main frame of main page.
  EXPECT_TRUE(NavigateToURLInSameBrowsingInstance(shell(), popup_url));
  // Performing a Load causes aura window to be focused (see
  // Shell::LoadURLForFrame) which recomputes window occlusion for all windows
  // (on chromeos) which unhides the popup. Hide popup again.
  new_shell->web_contents()->WasHidden();
  RenderProcessHost* new_root_process =
      root->current_frame_host()->GetProcess();
  EXPECT_EQ(new_root_process, popup_process);
  EXPECT_EQ(1, popup_process->VisibleClientCount());
  EXPECT_EQ(0u, popup_process->GetFrameDepth());

  // Go back on main page. Should go back to same state as before navigation.
  TestNavigationObserver back_load_observer(shell()->web_contents());
  shell()->web_contents()->GetController().GoBack();
  back_load_observer.Wait();
  new_shell->web_contents()->WasHidden();
  EXPECT_EQ(1, popup_process->VisibleClientCount());
  EXPECT_EQ(1u, popup_process->GetFrameDepth());

  // Unhide popup. Should go back to same state as before hide.
  new_shell->web_contents()->WasShown();
  EXPECT_EQ(2, popup_process->VisibleClientCount());
  EXPECT_EQ(0u, popup_process->GetFrameDepth());
}

// Check that when a postMessage is called on a remote frame, it waits for the
// current script block to finish executing before forwarding the postMessage,
// so that if the script causes any other IPCs to be sent in the same event
// loop iteration, those IPCs are processed, and their side effects are
// observed by the target frame before it receives the forwarded postMessage.
// See https://crbug.com/828529.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       CrossProcessPostMessageWaitsForCurrentScriptToFinish) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  EXPECT_EQ(root, root->frame_tree().GetFocusedFrame());

  // Add an onmessage handler to the subframe to send back a bool of whether
  // the subframe has focus.
  EXPECT_TRUE(
      ExecJs(root->child_at(0), WaitForMessageScript("document.hasFocus()")));

  // Now, send a postMessage from main frame to subframe, and then focus the
  // subframe in the same script.  postMessage should be scheduled after the
  // focus() call, so the IPC to focus the subframe should arrive before the
  // postMessage IPC, and the subframe should already know that it's focused in
  // the onmessage handler.
  EXPECT_EQ(true, ExecJs(root,
                         "frames[0].postMessage('','*');\n"
                         "frames[0].focus();\n"));
  EXPECT_EQ(true, EvalJs(root->child_at(0), "onMessagePromise"));
}

// Ensure that if a cross-process postMessage is scheduled, and then the target
// frame is detached before the postMessage is forwarded, the source frame's
// renderer does not crash.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       CrossProcessPostMessageAndDetachTarget) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();

  // Send a postMessage to the subframe and then immediately detach the
  // subframe.
  EXPECT_TRUE(ExecJs(root,
                     "frames[0].postMessage('','*');\n"
                     "document.body.removeChild(\n"
                     "    document.querySelector('iframe'));\n"));

  // Test passes if the main renderer doesn't crash.  Use setTimeout to ensure
  // this ping is evaluated after the (scheduled) postMessage is processed.
  EXPECT_EQ(
      true,
      EvalJs(
          root,
          "new Promise(resolve => setTimeout(() => { resolve(true); }, 0))"));
}

// Tests that the last committed URL is preserved on an RFH even after the RFH
// goes into the pending deletion state.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       LastCommittedURLRetainedAfterUnload) {
  // Navigate to a.com.
  GURL start_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
  EXPECT_TRUE(NavigateToURL(shell(), start_url));
  RenderFrameHostImpl* rfh = web_contents()->GetPrimaryMainFrame();
  EXPECT_EQ(start_url, rfh->GetLastCommittedURL());

  // Disable the unload ACK and the unload timer.
  auto unload_ack_filter = base::BindRepeating([] { return true; });
  rfh->SetUnloadACKCallbackForTesting(unload_ack_filter);
  rfh->DisableUnloadTimerForTesting();

  // Open a popup on a.com to keep the process alive.
  OpenPopup(shell(), embedded_test_server()->GetURL("a.com", "/title2.html"),
            "foo");

  // Navigate cross-process to b.com.
  EXPECT_TRUE(NavigateToURL(
      shell(), embedded_test_server()->GetURL("b.com", "/title3.html")));

  // The old RFH should be pending deletion.
  EXPECT_TRUE(rfh->IsPendingDeletion());
  EXPECT_FALSE(rfh->IsActive());
  EXPECT_NE(rfh, web_contents()->GetPrimaryMainFrame());

  // Check that it still has a valid last committed URL.
  EXPECT_EQ(start_url, rfh->GetLastCommittedURL());
}

#if BUILDFLAG(IS_ANDROID)

// This test ensures that gestures from child frames notify the gesture manager
// which exists only on the root frame. i.e. the gesture manager knows we're in
// a scroll gesture when it's happening in a cross-process child frame. This is
// important in cases like hiding the text selection popup during a scroll.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       GestureManagerListensToChildFrames) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  FrameTreeNode* child = root->child_at(0);
  GURL b_url(embedded_test_server()->GetURL("b.com", "/scrollable_page.html"));
  EXPECT_TRUE(NavigateToURLFromRenderer(child, b_url));

  EXPECT_EQ(
      " Site A ------------ proxies for B\n"
      "   +--Site B ------- proxies for A\n"
      "Where A = http://a.com/\n"
      "      B = http://b.com/",
      DepictFrameTree(root));

  RenderWidgetHost* rwh = root->current_frame_host()->GetRenderWidgetHost();
  RenderWidgetHost* child_rwh =
      child->current_frame_host()->GetRenderWidgetHost();

  RunUntilInputProcessed(rwh);
  RunUntilInputProcessed(child_rwh);

  RenderWidgetHostViewAndroid* rwhv_root =
      static_cast<RenderWidgetHostViewAndroid*>(
          root->current_frame_host()->GetRenderWidgetHost()->GetView());

  ASSERT_FALSE(
      rwhv_root->gesture_listener_manager_->IsScrollInProgressForTesting());

  // Start a scroll gesture in the child frame, ensure the main frame's gesture
  // listener manager records that its in a scroll.
  {
    blink::WebGestureEvent gesture_scroll_begin(
        blink::WebGestureEvent::Type::kGestureScrollBegin,
        blink::WebInputEvent::kNoModifiers,
        blink::WebInputEvent::GetStaticTimeStampForTests(),
        blink::WebGestureDevice::kTouchscreen);
    gesture_scroll_begin.data.scroll_begin.delta_hint_units =
        ui::ScrollGranularity::kScrollByPrecisePixel;
    gesture_scroll_begin.data.scroll_begin.delta_x_hint = 0.f;
    // Note: Negative y-delta in a gesture event results in scrolling down on a
    // page (i.e. causes positive window.scrollY).
    gesture_scroll_begin.data.scroll_begin.delta_y_hint = -5.f;

    blink::WebMouseEvent mouse_move(
        blink::WebInputEvent::Type::kMouseMove,
        blink::WebInputEvent::kNoModifiers,
        blink::WebInputEvent::GetStaticTimeStampForTests());

    // We wait for the dummy mouse move event since the GestureScrollEnd ACK is
    // used change the gesture manager scrolling state but InputEventAckWaiter
    // is the first-in-line so the state won't yet be changed when it returns.
    // Thus we send a second event and when it's ACK'd we know the first has
    // already been processed (we do the same thing above but with a
    // ScrollUpdate).
    InputEventAckWaiter mouse_move_waiter(
        child_rwh, blink::WebInputEvent::Type::kMouseMove);

    child_rwh->ForwardGestureEvent(gesture_scroll_begin);
    child_rwh->ForwardMouseEvent(mouse_move);
    mouse_move_waiter.Wait();

    EXPECT_TRUE(
        rwhv_root->gesture_listener_manager_->IsScrollInProgressForTesting());
  }

  // Finish the scroll, ensure the gesture manager sees the scroll end.
  {
    blink::WebGestureEvent gesture_scroll_end(
        blink::WebGestureEvent::Type::kGestureScrollEnd,
        blink::WebInputEvent::kNoModifiers,
        blink::WebInputEvent::GetStaticTimeStampForTests(),
        blink::WebGestureDevice::kTouchscreen);

    // See comment above for why this is sent.
    blink::WebMouseEvent mouse_move(
        blink::WebInputEvent::Type::kMouseMove,
        blink::WebInputEvent::kNoModifiers,
        blink::WebInputEvent::GetStaticTimeStampForTests());

    InputEventAckWaiter mouse_move_waiter(
        child_rwh, blink::WebInputEvent::Type::kMouseMove);

    child_rwh->ForwardGestureEvent(gesture_scroll_end);
    child_rwh->ForwardMouseEvent(mouse_move);
    mouse_move_waiter.Wait();

    EXPECT_FALSE(
        rwhv_root->gesture_listener_manager_->IsScrollInProgressForTesting());
  }
}
#endif  // BUILDFLAG(IS_ANDROID)

IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest, DisplayLockThrottlesOOPIF) {
  GURL url_a(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)"));
  EXPECT_TRUE(NavigateToURL(shell(), url_a));
  FrameTreeNode* a_frame = web_contents()->GetPrimaryFrameTree().root();
  FrameTreeNode* b_frame = a_frame->child_at(0);

  // Force a lifecycle update in both frames to get to steady state.
  ASSERT_TRUE(EvalJsAfterLifecycleUpdate(a_frame->current_frame_host(), "", "")
                  .is_ok());
  ASSERT_TRUE(EvalJsAfterLifecycleUpdate(b_frame->current_frame_host(), "", "")
                  .is_ok());

  // Display lock an ancestor of the <iframe> element in a_frame. The display
  // lock status will be propagated to the OOPIF during lifecycle update.
  ASSERT_TRUE(EvalJsAfterLifecycleUpdate(
                  a_frame->current_frame_host(),
                  "document.body.style = 'content-visibility: hidden'", "")
                  .is_ok());

  // At this point, a_frame should have already sent an IPC to b_frame causing
  // b_frame to become throttled. Create an IntersectionObserver and observe a
  // visible element in b_frame. The display lock status should cause the
  // visible element to be reported as "not intersecting".
  static const char kObserverScript[] = R"(
      new Promise((resolve, reject) => {
        new IntersectionObserver((entries, observer) => {
          observer.unobserve(entries[0].target);
          resolve(String(entries[0].isIntersecting))
        }).observe(document.getElementById('siteNameHeading'))
      })
  )";
  EvalJsResult result1 = EvalJs(b_frame->current_frame_host(), kObserverScript);
  ASSERT_TRUE(result1.is_ok());
  EXPECT_EQ(result1.ExtractString(), "false");

  // Unlock the element in a_frame, run through the same steps, and look for an
  // "is intersecting" notification.
  ASSERT_TRUE(EvalJsAfterLifecycleUpdate(a_frame->current_frame_host(),
                                         "document.body.style = ''", "")
                  .is_ok());
  EvalJsResult result2 = EvalJs(b_frame->current_frame_host(), kObserverScript);
  EXPECT_EQ(result2.ExtractString(), "true");
}

namespace {

// Helper class to intercept DidCommitProvisionalLoad messages and inject a
// call to close the current tab right before them.
class ClosePageBeforeCommitHelper : public DidCommitNavigationInterceptor {
 public:
  explicit ClosePageBeforeCommitHelper(WebContents* web_contents)
      : DidCommitNavigationInterceptor(web_contents) {}

  ClosePageBeforeCommitHelper(const ClosePageBeforeCommitHelper&) = delete;
  ClosePageBeforeCommitHelper& operator=(const ClosePageBeforeCommitHelper&) =
      delete;

  void Wait() {
    run_loop_ = std::make_unique<base::RunLoop>();
    run_loop_->Run();
    run_loop_.reset();
  }

 private:
  // DidCommitNavigationInterceptor:
  bool WillProcessDidCommitNavigation(
      RenderFrameHost* render_frame_host,
      NavigationRequest* navigation_request,
      mojom::DidCommitProvisionalLoadParamsPtr* params,
      mojom::DidCommitProvisionalLoadInterfaceParamsPtr* interface_params)
      override {
    RenderFrameHostImpl* rfh =
        static_cast<RenderFrameHostImpl*>(render_frame_host);
    EXPECT_TRUE(rfh->render_view_host()->is_active());
    rfh->GetMainFrame()->ClosePage(
        RenderFrameHostImpl::ClosePageSource::kBrowser);
    if (run_loop_)
      run_loop_->Quit();
    return true;
  }

  std::unique_ptr<base::RunLoop> run_loop_;
};

}  // namespace

// Verify that when a tab is closed just before a commit IPC arrives for a
// subframe in the tab, a subsequent resource timing IPC from the subframe RFH
// won't generate a renderer kill.  See https://crbug.com/805705.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       CloseTabBeforeSubframeCommits) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();

  // Open a popup in a.com to keep that process alive.
  GURL same_site_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
  Shell* new_shell = OpenPopup(root, same_site_url, "");

  // Add a blank grandchild frame.
  RenderFrameHostCreatedObserver frame_observer(shell()->web_contents(), 1);
  EXPECT_TRUE(
      ExecJs(root->child_at(0),
             "document.body.appendChild(document.createElement('iframe'));"));
  frame_observer.Wait();
  FrameTreeNode* grandchild = root->child_at(0)->child_at(0);

  // Navigate grandchild to an a.com URL.  Note that only a frame's initial
  // navigation forwards resource timing info to parent, so it's important that
  // this iframe was initially blank.
  //
  // Just before this URL commits, close the page.
  ClosePageBeforeCommitHelper close_page_helper(web_contents());
  EXPECT_TRUE(ExecJs(grandchild, JsReplace("location = $1", same_site_url)));
  close_page_helper.Wait();

  // Test passes if the a.com renderer doesn't crash. Ping to verify.
  EXPECT_EQ(true, EvalJs(new_shell, "true;"));
}

class SitePerProcessBrowserTouchActionTest : public SitePerProcessBrowserTest {
 public:
  SitePerProcessBrowserTouchActionTest() = default;

  bool GetTouchActionForceEnableZoom(RenderWidgetHost* rwh) {
    input::InputRouterImpl* input_router = static_cast<input::InputRouterImpl*>(
        static_cast<RenderWidgetHostImpl*>(rwh)->input_router());
    return input_router->touch_action_filter_.force_enable_zoom_;
  }

  // Computes the effective and allowed touch action for |rwhv_child| by
  // dispatching a touch to it through |rwhv_root|. |rwhv_root| is the root
  // frame containing |rwhv_child|. |rwhv_child| is the child (or indirect
  // descendent) of |rwhv_root| to get the touch action of. |event_position|
  // should be within |rwhv_child| in |rwhv_root|'s coordinate space.
  void GetTouchActionsForChild(
      input::RenderWidgetHostInputEventRouter* router,
      RenderWidgetHostViewBase* rwhv_root,
      RenderWidgetHostViewBase* rwhv_child,
      const gfx::Point& event_position,
      std::optional<cc::TouchAction>& effective_touch_action,
      std::optional<cc::TouchAction>& allowed_touch_action) {
    InputEventAckWaiter ack_observer(
        rwhv_child->GetRenderWidgetHost(),
        base::BindRepeating([](blink::mojom::InputEventResultSource source,
                               blink::mojom::InputEventResultState state,
                               const blink::WebInputEvent& event) {
          return event.GetType() == blink::WebGestureEvent::Type::kTouchStart ||
                 event.GetType() == blink::WebGestureEvent::Type::kTouchMove ||
                 event.GetType() == blink::WebGestureEvent::Type::kTouchEnd;
        }));

    input::InputRouterImpl* input_router = static_cast<input::InputRouterImpl*>(
        static_cast<RenderWidgetHostImpl*>(rwhv_child->GetRenderWidgetHost())
            ->input_router());
    // Clear the touch actions that were set by previous touches.
    input_router->touch_action_filter_.allowed_touch_action_.reset();
    // Send a touch start event to child to get the TAF filled with child
    // frame's touch action.
    ack_observer.Reset();
    blink::SyntheticWebTouchEvent touch_event;
    int index = touch_event.PressPoint(event_position.x(), event_position.y());
    router->RouteTouchEvent(rwhv_root, &touch_event, ui::LatencyInfo());
    ack_observer.Wait();
    // Reset them to get the new value.
    effective_touch_action.reset();
    allowed_touch_action.reset();
    effective_touch_action =
        input_router->touch_action_filter_.allowed_touch_action_;
    // Effective touch action are sent from a separate IPC
    // channel, so it is not guaranteed to have value when the ACK for the
    // touch start arrived because the ACK is from the main thread.
    allowed_touch_action =
        input_router->touch_action_filter_.compositor_allowed_touch_action_;

    // Send a touch move and touch end to complete the sequence, this also
    // avoids triggering DCHECKs when sending followup events.
    ack_observer.Reset();
    touch_event.MovePoint(index, 1, 1);
    router->RouteTouchEvent(rwhv_root, &touch_event, ui::LatencyInfo());
    ack_observer.Wait();

    ack_observer.Reset();
    touch_event.ReleasePoint(index);
    router->RouteTouchEvent(rwhv_root, &touch_event, ui::LatencyInfo());
    ack_observer.Wait();
  }

  void GiveItSomeTime(const base::TimeDelta& t) {
    base::RunLoop run_loop;
    base::SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
        FROM_HERE, run_loop.QuitClosure(), t);
    run_loop.Run();
  }

  // Waits until the parent frame has had enough time to propagate the effective
  // touch action to the child frame and the child frame has had enough time to
  // process it.
  void WaitForTouchActionUpdated(
      MainThreadFrameObserver* root_thread_observer,
      MainThreadFrameObserver* child_thread_observer) {
    // Sends an event to the root frame's renderer main thread, upon return the
    // root frame should have calculated the new effective touch action for the
    // child frame.
    root_thread_observer->Wait();
    // Sends an event to the child frame's renderer main thread, upon return the
    // child frame should have received the effective touch action from parent
    // and propagated it.
    child_thread_observer->Wait();
    // The child's handling of the touch action may lead to further propagation
    // back to the parent. This sends an event to the root frame's renderer main
    // thread, upon return it should have handled any touch action update.
    root_thread_observer->Wait();
  }
};

#if BUILDFLAG(IS_ANDROID)
// Class to set |force_enable_zoom| to true in WebkitPrefs.
class EnableForceZoomContentClient
    : public ContentBrowserTestContentBrowserClient {
 public:
  EnableForceZoomContentClient() = default;

  EnableForceZoomContentClient(const EnableForceZoomContentClient&) = delete;
  EnableForceZoomContentClient& operator=(const EnableForceZoomContentClient&) =
      delete;

  void OverrideWebPreferences(WebContents* web_contents,
                              SiteInstance& main_frame_site,
                              blink::web_pref::WebPreferences* prefs) override {
    prefs->force_enable_zoom = true;
  }
};

class AndroidInputBrowserTest : public SitePerProcessBrowserTest {
 public:
  AndroidInputBrowserTest() {
    scoped_feature_list_.InitWithFeatureStates(
        {{input::features::kInputOnViz, true},
         {viz::mojom::EnableVizTestApis, true}});
  }

  bool GetRenderInputRouterForceEnableZoom(RenderWidgetHostImpl* rwh) {
    return rwh->GetRenderInputRouter()->GetForceEnableZoom();
  }

  RenderWidgetHostImpl* GetRenderWidgetHost() const {
    RenderWidgetHostImpl* const rwh =
        RenderWidgetHostImpl::From(shell()
                                       ->web_contents()
                                       ->GetRenderWidgetHostView()
                                       ->GetRenderWidgetHost());
    CHECK(rwh);
    return rwh;
  }

 private:
  base::test::ScopedFeatureList scoped_feature_list_;
};

// Check if browser's |force_enable_zoom| state is in sync with Viz's state with
// InputVizard enabled.
IN_PROC_BROWSER_TEST_P(AndroidInputBrowserTest, CheckForceEnableZoomValue) {
  // Return early if transferring input to Viz isn't supported.
  if (!input::InputUtils::IsTransferInputToVizSupported()) {
    return;
  }

  mojo::ScopedAllowSyncCallForTesting allowed_for_testing;
  content::RenderFrameSubmissionObserver render_frame_submission_observer(
      shell()->web_contents());

  EXPECT_TRUE(NavigateToURL(
      shell(), embedded_test_server()->GetURL("foo.com", "/title1.html")));
  if (render_frame_submission_observer.render_frame_count() == 0) {
    render_frame_submission_observer.WaitForAnyFrameSubmission();
  }

  EXPECT_FALSE(GetRenderInputRouterForceEnableZoom(GetRenderWidgetHost()));
  bool enabled = false;
  content::GetHostFrameSinkManager()
      ->GetFrameSinkManagerTestApi()
      .GetForceEnableZoomState(GetRenderWidgetHost()->GetFrameSinkId(),
                               &enabled);
  EXPECT_FALSE(enabled);

  EnableForceZoomContentClient new_client;

  web_contents()->OnWebPreferencesChanged();
  if (render_frame_submission_observer.render_frame_count() == 0) {
    render_frame_submission_observer.WaitForAnyFrameSubmission();
  }

  EXPECT_TRUE(GetRenderInputRouterForceEnableZoom(GetRenderWidgetHost()));
  content::GetHostFrameSinkManager()
      ->GetFrameSinkManagerTestApi()
      .GetForceEnableZoomState(GetRenderWidgetHost()->GetFrameSinkId(),
                               &enabled);
  EXPECT_TRUE(enabled);

  // Navigate to a cross-site website.
  EXPECT_TRUE(NavigateToURL(
      shell(), embedded_test_server()->GetURL("bar.com", "/title2.html")));
  if (render_frame_submission_observer.render_frame_count() == 0) {
    render_frame_submission_observer.WaitForAnyFrameSubmission();
  }

  EXPECT_TRUE(GetRenderInputRouterForceEnableZoom(GetRenderWidgetHost()));
  content::GetHostFrameSinkManager()
      ->GetFrameSinkManagerTestApi()
      .GetForceEnableZoomState(GetRenderWidgetHost()->GetFrameSinkId(),
                               &enabled);
  EXPECT_TRUE(enabled);
}

class GpuInfoUpdateObserver : public GpuDataManagerObserver {
 public:
  explicit GpuInfoUpdateObserver(base::OnceClosure callback)
      : callback_(std::move(callback)) {
    observation_.Observe(GpuDataManager::GetInstance());
  }
  ~GpuInfoUpdateObserver() override = default;

  void OnGpuInfoUpdate() override {
    if (callback_) {
      std::move(callback_).Run();
    }
  }

 private:
  base::OnceClosure callback_;
  base::ScopedObservation<GpuDataManager, GpuDataManagerObserver> observation_{
      this};
};

// Checks if RenderInputRouterDelegate mojo connection is reset when GPU process
// restarts. Disabled due to flake: crbug.com/439855865.
IN_PROC_BROWSER_TEST_P(AndroidInputBrowserTest,
                       DISABLED_RestartingGPUProcessResetsMojoConnection) {
  base::test::TestTraceProcessor ttp;
  ttp.StartTrace("viz");
  RenderFrameSubmissionObserver render_frame_submission_observer(
      web_contents());
  EXPECT_TRUE(NavigateToURL(
      shell(), embedded_test_server()->GetURL("foo.com", "/title1.html")));
  if (render_frame_submission_observer.render_frame_count() == 0) {
    render_frame_submission_observer.WaitForAnyFrameSubmission();
  }

  base::RunLoop run_loop;
  // This observer is begin used here to signal if the GPU process has
  // restarted.
  GpuInfoUpdateObserver gpu_observer(run_loop.QuitClosure());

  RenderFrameSubmissionObserver render_frame_submission_observer2(
      web_contents());

  // Kill GPU process explicitly, this should trigger a restart.
  KillGpuProcess();
  run_loop.Run();

  if (render_frame_submission_observer2.render_frame_count() == 0) {
    render_frame_submission_observer2.WaitForAnyFrameSubmission();
  }

  absl::Status status = ttp.StopAndParseTrace();
  ASSERT_TRUE(status.ok()) << status.message();

  std::string query = R"(
    SELECT COUNT(*) AS cnt
    FROM slice
    WHERE name = 'InputManager::SetupRenderInputRouterDelegateConnection'
    ORDER BY ts ASC
  )";
  auto result = ttp.RunQuery(query);
  ASSERT_TRUE(result.has_value());

  // `result.value()` would look something like this: {{"cnt"}, {"<num>"}}.
  EXPECT_THAT(
      result.value(),
      testing::ElementsAre(
          testing::ElementsAre("cnt"),
          testing::ElementsAre(
              input::InputUtils::IsTransferInputToVizSupported() ? "2" : "0")));
}

IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTouchActionTest,
                       ForceEnableZoomPropagatesToChild) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  ASSERT_EQ(1U, root->child_count());
  GURL b_url(embedded_test_server()->GetURL("b.com", "/title1.html"));
  FrameTreeNode* child = root->child_at(0);
  EXPECT_TRUE(NavigateToURLFromRenderer(child, b_url));
  WaitForHitTestData(child->current_frame_host());

  // Get access to child's TouchActionFilter.
  RenderWidgetHost* child_rwh =
      child->current_frame_host()->GetRenderWidgetHost();
  EXPECT_FALSE(GetTouchActionForceEnableZoom(child_rwh));

  EnableForceZoomContentClient new_client;

  web_contents()->OnWebPreferencesChanged();

  EXPECT_TRUE(GetTouchActionForceEnableZoom(child_rwh));

  // Add a new oopif child frame, and make sure it initializes with the correct
  // value of ForceEnableZoom.
  GURL c_url = embedded_test_server()->GetURL("c.com", "/title1.html");
  std::string create_frame_script = base::StringPrintf(
      "var new_iframe = document.createElement('iframe');"
      "new_iframe.src = '%s';"
      "document.body.appendChild(new_iframe);",
      c_url.spec().c_str());
  EXPECT_TRUE(ExecJs(root, create_frame_script));
  EXPECT_TRUE(WaitForLoadStop(web_contents()));
  ASSERT_EQ(2U, root->child_count());

  FrameTreeNode* new_child = root->child_at(1);
  EXPECT_NE(root->current_frame_host()->GetRenderWidgetHost(),
            new_child->current_frame_host()->GetRenderWidgetHost());
  EXPECT_TRUE(GetTouchActionForceEnableZoom(
      new_child->current_frame_host()->GetRenderWidgetHost()));
}

IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTouchActionTest,
                       CheckForceEnableZoomValue) {
  EXPECT_TRUE(NavigateToURL(
      shell(), embedded_test_server()->GetURL("foo.com", "/title1.html")));
  EXPECT_FALSE(GetTouchActionForceEnableZoom(
      web_contents()->GetPrimaryMainFrame()->GetRenderViewHost()->GetWidget()));

  EnableForceZoomContentClient new_client;

  web_contents()->OnWebPreferencesChanged();

  EXPECT_TRUE(GetTouchActionForceEnableZoom(
      web_contents()->GetPrimaryMainFrame()->GetRenderViewHost()->GetWidget()));

  EXPECT_TRUE(NavigateToURL(
      shell(), embedded_test_server()->GetURL("bar.com", "/title2.html")));

  EXPECT_TRUE(GetTouchActionForceEnableZoom(
      web_contents()->GetPrimaryMainFrame()->GetRenderViewHost()->GetWidget()));
}

#endif  // BUILDFLAG(IS_ANDROID)

// Flaky on every platform, failing most of the time on Android.
// See https://crbug.com/945734
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTouchActionTest,
                       DISABLED_EffectiveTouchActionPropagatesAcrossFrames) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  FrameTreeNode* child = root->child_at(0);
  RenderWidgetHostViewBase* rwhv_root = static_cast<RenderWidgetHostViewBase*>(
      root->current_frame_host()->GetRenderWidgetHost()->GetView());
  RenderWidgetHostViewBase* rwhv_child = static_cast<RenderWidgetHostViewBase*>(
      child->current_frame_host()->GetRenderWidgetHost()->GetView());
  std::unique_ptr<MainThreadFrameObserver> root_thread_observer(
      new MainThreadFrameObserver(
          root->current_frame_host()->GetRenderWidgetHost()));
  root_thread_observer->Wait();

  GURL b_url(embedded_test_server()->GetURL("b.com", "/title1.html"));
  EXPECT_TRUE(NavigateToURLFromRenderer(child, b_url));

  // Force the renderer to generate a new frame.
  EXPECT_TRUE(ExecJs(shell(), "document.body.style.touchAction = 'none'"));
  // Waits for the next frame.
  WaitForHitTestData(child->current_frame_host());
  std::unique_ptr<MainThreadFrameObserver> child_thread_observer(
      new MainThreadFrameObserver(
          child->current_frame_host()->GetRenderWidgetHost()));

  RenderWidgetHostViewChildFrame* child_view =
      static_cast<RenderWidgetHostViewChildFrame*>(
          child->current_frame_host()->GetRenderWidgetHost()->GetView());
  gfx::Point point_inside_child = ToFlooredPoint(
      child_view->TransformPointToRootCoordSpaceF(gfx::PointF(+5.f, +5.f)));

  input::RenderWidgetHostInputEventRouter* router =
      static_cast<WebContentsImpl*>(web_contents())->GetInputEventRouter();

  WaitForTouchActionUpdated(root_thread_observer.get(),
                            child_thread_observer.get());
  std::optional<cc::TouchAction> effective_touch_action;
  std::optional<cc::TouchAction> allowed_touch_action;
  cc::TouchAction expected_touch_action = cc::TouchAction::kPan;
  // Gestures are filtered by the intersection of touch-action values of the
  // touched element and all its ancestors up to the one that implements the
  // gesture. Since iframe allows scrolling, touch action pan restrictions will
  // not affect iframe's descendants, so we expect TouchAction::kPan instead of
  // TouchAction::kAuto in iframe's child.
  GetTouchActionsForChild(router, rwhv_root, rwhv_child, point_inside_child,
                          effective_touch_action, allowed_touch_action);
  if (allowed_touch_action.has_value())
    EXPECT_EQ(expected_touch_action, allowed_touch_action.value());

  EXPECT_TRUE(ExecJs(shell(), "document.body.style.touchAction = 'auto'"));
  WaitForTouchActionUpdated(root_thread_observer.get(),
                            child_thread_observer.get());
  expected_touch_action = cc::TouchAction::kAuto;
  GetTouchActionsForChild(router, rwhv_root, rwhv_child, point_inside_child,
                          effective_touch_action, allowed_touch_action);
  EXPECT_EQ(expected_touch_action, effective_touch_action.has_value()
                                       ? effective_touch_action.value()
                                       : cc::TouchAction::kAuto);
  if (allowed_touch_action.has_value())
    EXPECT_EQ(expected_touch_action, allowed_touch_action.value());
}

// Flaky on all platform. http://crbug.com/9515270
IN_PROC_BROWSER_TEST_F(
    SitePerProcessBrowserTouchActionTest,
    DISABLED_EffectiveTouchActionPropagatesAcrossNestedFrames) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b(c))"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  FrameTreeNode* parent = root->child_at(0);
  GURL b_url(embedded_test_server()->GetURL(
      "b.com", "/frame_tree/page_with_iframe_in_div.html"));
  EXPECT_TRUE(NavigateToURLFromRenderer(parent, b_url));

  ASSERT_EQ(1U, parent->child_count());
  EXPECT_EQ(
      " Site A ------------ proxies for B C\n"
      "   +--Site B ------- proxies for A C\n"
      "        +--Site C -- proxies for A B\n"
      "Where A = http://a.com/\n"
      "      B = http://b.com/\n"
      "      C = http://bar.com/",
      DepictFrameTree(root));

  FrameTreeNode* child = root->child_at(0)->child_at(0);
  RenderWidgetHostViewBase* rwhv_root = static_cast<RenderWidgetHostViewBase*>(
      root->current_frame_host()->GetRenderWidgetHost()->GetView());
  RenderWidgetHostViewBase* rwhv_child = static_cast<RenderWidgetHostViewBase*>(
      child->current_frame_host()->GetRenderWidgetHost()->GetView());
  std::unique_ptr<MainThreadFrameObserver> root_thread_observer(
      new MainThreadFrameObserver(
          root->current_frame_host()->GetRenderWidgetHost()));
  root_thread_observer->Wait();

  EXPECT_TRUE(ExecJs(shell(), "document.body.style.touchAction = 'none'"));

  // Wait for child frame ready in order to get the correct point inside child.
  WaitForHitTestData(child->current_frame_host());
  std::unique_ptr<MainThreadFrameObserver> child_thread_observer(
      new MainThreadFrameObserver(
          child->current_frame_host()->GetRenderWidgetHost()));
  RenderWidgetHostViewChildFrame* child_view =
      static_cast<RenderWidgetHostViewChildFrame*>(
          child->current_frame_host()->GetRenderWidgetHost()->GetView());
  gfx::Point point_inside_child = ToFlooredPoint(
      child_view->TransformPointToRootCoordSpaceF(gfx::PointF(+5.f, +5.f)));

  input::RenderWidgetHostInputEventRouter* router =
      static_cast<WebContentsImpl*>(web_contents())->GetInputEventRouter();

  // Child should inherit effective touch action none from root.
  WaitForTouchActionUpdated(root_thread_observer.get(),
                            child_thread_observer.get());
  std::optional<cc::TouchAction> effective_touch_action;
  std::optional<cc::TouchAction> allowed_touch_action;
  cc::TouchAction expected_touch_action = cc::TouchAction::kPan;
  GetTouchActionsForChild(router, rwhv_root, rwhv_child, point_inside_child,
                          effective_touch_action, allowed_touch_action);
  if (allowed_touch_action.has_value())
    EXPECT_EQ(expected_touch_action, allowed_touch_action.value());

  // Child should inherit effective touch action none from parent.
  EXPECT_TRUE(ExecJs(shell(), "document.body.style.touchAction = 'auto'"));
  EXPECT_TRUE(ExecJs(
      parent,
      "document.getElementById('parent-div').style.touchAction = 'none';"));
  WaitForTouchActionUpdated(root_thread_observer.get(),
                            child_thread_observer.get());
  GetTouchActionsForChild(router, rwhv_root, rwhv_child, point_inside_child,
                          effective_touch_action, allowed_touch_action);
  if (allowed_touch_action.has_value())
    EXPECT_EQ(expected_touch_action, allowed_touch_action.value());

  // Child should inherit effective touch action auto from root and parent.
  EXPECT_TRUE(ExecJs(
      parent,
      "document.getElementById('parent-div').style.touchAction = 'auto'"));
  WaitForTouchActionUpdated(root_thread_observer.get(),
                            child_thread_observer.get());
  expected_touch_action = cc::TouchAction::kAuto;
  GetTouchActionsForChild(router, rwhv_root, rwhv_child, point_inside_child,
                          effective_touch_action, allowed_touch_action);
  if (allowed_touch_action.has_value())
    EXPECT_EQ(expected_touch_action, allowed_touch_action.value());
}

IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTouchActionTest,
                       EffectiveTouchActionPropagatesWhenChildFrameNavigates) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  FrameTreeNode* child = root->child_at(0);
  GURL b_url(embedded_test_server()->GetURL("b.com", "/title1.html"));
  EXPECT_TRUE(NavigateToURLFromRenderer(child, b_url));

  EXPECT_EQ(
      " Site A ------------ proxies for B\n"
      "   +--Site B ------- proxies for A\n"
      "Where A = http://a.com/\n"
      "      B = http://b.com/",
      DepictFrameTree(root));

  RenderWidgetHostViewBase* rwhv_root = static_cast<RenderWidgetHostViewBase*>(
      root->current_frame_host()->GetRenderWidgetHost()->GetView());
  RenderWidgetHostViewBase* rwhv_child = static_cast<RenderWidgetHostViewBase*>(
      child->current_frame_host()->GetRenderWidgetHost()->GetView());
  std::unique_ptr<MainThreadFrameObserver> root_thread_observer(
      new MainThreadFrameObserver(
          root->current_frame_host()->GetRenderWidgetHost()));
  root_thread_observer->Wait();

  EXPECT_TRUE(ExecJs(shell(), "document.body.style.touchAction = 'none'"));

  // Wait for child frame ready in order to get the correct point inside child.
  WaitForHitTestData(child->current_frame_host());
  std::unique_ptr<MainThreadFrameObserver> child_thread_observer(
      new MainThreadFrameObserver(
          child->current_frame_host()->GetRenderWidgetHost()));
  RenderWidgetHostViewChildFrame* child_view =
      static_cast<RenderWidgetHostViewChildFrame*>(
          child->current_frame_host()->GetRenderWidgetHost()->GetView());
  gfx::Point point_inside_child = gfx::ToFlooredPoint(
      child_view->TransformPointToRootCoordSpaceF(gfx::PointF(+5.f, +5.f)));

  input::RenderWidgetHostInputEventRouter* router =
      static_cast<WebContentsImpl*>(web_contents())->GetInputEventRouter();
  // Child should inherit effective touch action none from root.
  WaitForTouchActionUpdated(root_thread_observer.get(),
                            child_thread_observer.get());
  std::optional<cc::TouchAction> effective_touch_action;
  std::optional<cc::TouchAction> allowed_touch_action;
  cc::TouchAction expected_touch_action =
      cc::TouchAction::kPan | cc::TouchAction::kInternalPanXScrolls |
      cc::TouchAction::kInternalNotWritable;
  GetTouchActionsForChild(router, rwhv_root, rwhv_child, point_inside_child,
                          effective_touch_action, allowed_touch_action);
  if (allowed_touch_action.has_value())
    EXPECT_EQ(expected_touch_action, allowed_touch_action.value());

  // After navigation, child should still inherit effective touch action none
  // from parent.
  GURL new_url(embedded_test_server()->GetURL("c.com", "/title2.html"));
  // Reset before navigation, as navigation destroys the underlying
  // RenderWidgetHost being observed.
  child_thread_observer.reset();
  EXPECT_TRUE(NavigateToURLFromRenderer(child, new_url));
  WaitForHitTestData(child->current_frame_host());
  // Navigation destroys the previous RenderWidgetHost, so we need to begin
  // observing the new renderer main thread associated with the child frame.
  child_thread_observer = std::make_unique<MainThreadFrameObserver>(
      child->current_frame_host()->GetRenderWidgetHost());

  rwhv_child = static_cast<RenderWidgetHostViewBase*>(
      child->current_frame_host()->GetRenderWidgetHost()->GetView());

  WaitForTouchActionUpdated(root_thread_observer.get(),
                            child_thread_observer.get());
  GetTouchActionsForChild(router, rwhv_root, rwhv_child, point_inside_child,
                          effective_touch_action, allowed_touch_action);
  if (allowed_touch_action.has_value())
    EXPECT_EQ(expected_touch_action, allowed_touch_action.value());
}

IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       ChildFrameCrashMetrics_KilledMainFrame) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(a(b(b,c)))"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();

  // Kill the main frame.
  base::HistogramTester histograms;
  RenderProcessHost* child_process = root->current_frame_host()->GetProcess();
  RenderProcessHostWatcher crash_observer(
      child_process, RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
  child_process->Shutdown(0);
  crash_observer.Wait();

  // Verify that no child frame metrics got logged.
  histograms.ExpectTotalCount("Stability.ChildFrameCrash.Visibility", 0);
}

IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       ChildFrameCrashMetrics_NeverShown) {
  // Set-up a frame tree that helps verify what the metrics tracks:
  // 1) frames (12 frames are affected if B process gets killed) or
  // 2) widgets (10 b widgets and 1 c widget are affected if B is killed) or
  // 3) crashes (1 crash if B process gets killed)?
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b(b,c),b,b,b,b,b,b,b,b,b)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();

  // Hide the web contents (UpdateWebContentsVisibility is called twice to avoid
  // hitting the |!did_first_set_visible_| case).
  web_contents()->UpdateWebContentsVisibility(Visibility::VISIBLE);
  web_contents()->UpdateWebContentsVisibility(Visibility::HIDDEN);

  // Kill the subframe.
  base::HistogramTester histograms;
  RenderProcessHost* child_process =
      root->child_at(0)->current_frame_host()->GetProcess();
  RenderProcessHostWatcher crash_observer(
      child_process, RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
  child_process->Shutdown(0);
  crash_observer.Wait();

  // Navigate away - this will trigger logging of the UMA.
  EXPECT_TRUE(NavigateToURL(shell(), GURL("about:blank")));

  // Wait until the page with the crashed frame gets unloaded (triggering its
  // evicton if it got into the back/forward cache), so that the histogram will
  // be recorded when the renderer process is gone.
  // TODO(crbug.com/40175240): Ensure pages with crashed subframes won't
  // get into back/forward cache.
  InactiveRenderFrameHostDeletionObserver inactive_rfh_deletion_observer(
      web_contents());
  inactive_rfh_deletion_observer.Wait();

  histograms.ExpectUniqueSample("Stability.ChildFrameCrash.Visibility",
                                CrashVisibility::kNeverVisibleAfterCrash, 10);
}

IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       ChildFrameCrashMetrics_ScrolledIntoView) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();

  // Fill the main frame so that the subframe is pushed below the fold (is
  // scrolled outside of the current view) and wait until the main frame redraws
  // itself (i.e. making sure CPFC::OnUpdateViewportIntersection has arrived).
  std::string filling_script = R"(
    var frame = document.body.querySelectorAll("iframe")[0];
    for (var i = 0; i < 100; i++) {
      var p = document.createElement("p");
      p.innerText = "blah";
      document.body.insertBefore(p, frame);
    }
  )";
  EXPECT_TRUE(ExecJs(root, filling_script));
  // This will ensure that browser has received the
  // FrameHostMsg_UpdateViewportIntersection IPC message from the renderer main
  // thread.
  EXPECT_EQ(true,
            EvalJsAfterLifecycleUpdate(root->current_frame_host(), "", "true"));

  // Kill the child frame.
  base::HistogramTester histograms;
  RenderProcessHost* child_process =
      root->child_at(0)->current_frame_host()->GetProcess();
  RenderProcessHostWatcher crash_observer(
      child_process, RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
  child_process->Shutdown(0);
  crash_observer.Wait();

  // Verify that no child frame metrics got logged (yet - while the subframe is
  // below the fold / is not scrolled into view).
  histograms.ExpectTotalCount("Stability.ChildFrameCrash.Visibility", 0);
  histograms.ExpectTotalCount(
      "Stability.ChildFrameCrash.ShownAfterCrashingReason", 0);

  // Scroll the subframe into view and wait until the scrolled frame draws
  // itself.
  std::string scrolling_script = R"(
    var frame = document.body.querySelectorAll("iframe")[0];
    frame.scrollIntoView();
  )";
  EXPECT_TRUE(ExecJs(root, scrolling_script));
  // Wait for FrameHostMsg_UpdateViewportIntersection again.
  EXPECT_EQ(true,
            EvalJsAfterLifecycleUpdate(root->current_frame_host(), "", "true"));

  // Verify that the expected metrics got logged.
  histograms.ExpectUniqueSample(
      "Stability.ChildFrameCrash.Visibility",
      CrossProcessFrameConnector::CrashVisibility::kShownAfterCrashing, 1);
  histograms.ExpectUniqueSample(
      "Stability.ChildFrameCrash.ShownAfterCrashingReason",
      CrossProcessFrameConnector::ShownAfterCrashingReason::
          kViewportIntersection,
      1);
}

class SitePerProcessAndProcessPerSiteBrowserTest
    : public SitePerProcessBrowserTest {
 public:
  SitePerProcessAndProcessPerSiteBrowserTest() {}

  SitePerProcessAndProcessPerSiteBrowserTest(
      const SitePerProcessAndProcessPerSiteBrowserTest&) = delete;
  SitePerProcessAndProcessPerSiteBrowserTest& operator=(
      const SitePerProcessAndProcessPerSiteBrowserTest&) = delete;

 protected:
  void SetUpCommandLine(base::CommandLine* command_line) override {
    SitePerProcessBrowserTestBase::SetUpCommandLine(command_line);
    command_line->AppendSwitch(switches::kProcessPerSite);
  }
};

// Verify that when --site-per-process is combined with --process-per-site, a
// cross-site, browser-initiated navigation with a generated page transition
// does not stay in the old SiteInstance.  See https://crbug.com/825411.
IN_PROC_BROWSER_TEST_P(SitePerProcessAndProcessPerSiteBrowserTest,
                       GeneratedTransitionsSwapProcesses) {
  EXPECT_TRUE(NavigateToURL(
      shell(), embedded_test_server()->GetURL("foo.com", "/title1.html")));
  scoped_refptr<SiteInstance> foo_site_instance(
      web_contents()->GetSiteInstance());

  // Navigate cross-site via a generated transition.  This would normally
  // happen for search queries.
  TestNavigationObserver observer(web_contents());
  NavigationController::LoadURLParams params(
      embedded_test_server()->GetURL("bar.com", "/title2.html"));
  params.transition_type = ui::PAGE_TRANSITION_GENERATED;
  web_contents()->GetController().LoadURLWithParams(params);
  observer.Wait();

  // Ensure the original SiteInstance wasn't reused.
  EXPECT_NE(foo_site_instance, web_contents()->GetSiteInstance());

  // Ensure the new page can access cookies without getting killed.
  EXPECT_TRUE(ExecJs(web_contents(), "document.cookie = 'foo=bar';"));
  EXPECT_EQ("foo=bar", EvalJs(web_contents(), "document.cookie;"));
}

namespace {

// Helper for waiting until next same-document navigation commits in
// |web_contents|.
class SameDocumentCommitObserver : public WebContentsObserver {
 public:
  explicit SameDocumentCommitObserver(WebContents* web_contents)
      : WebContentsObserver(web_contents) {
    EXPECT_TRUE(web_contents);
  }

  SameDocumentCommitObserver(const SameDocumentCommitObserver&) = delete;
  SameDocumentCommitObserver& operator=(const SameDocumentCommitObserver&) =
      delete;

  void Wait() { run_loop_.Run(); }

  const GURL& last_committed_url() { return last_committed_url_; }

 private:
  void DidFinishNavigation(NavigationHandle* navigation_handle) override {
    if (navigation_handle->IsSameDocument()) {
      last_committed_url_ = navigation_handle->GetURL();
      run_loop_.Quit();
    }
  }

  GURL last_committed_url_;
  base::RunLoop run_loop_;
};

}  // namespace

// Ensure that a same-document navigation does not cancel an ongoing
// cross-process navigation.  See https://crbug.com/825677.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       ReplaceStateDoesNotCancelCrossSiteNavigation) {
  GURL url(embedded_test_server()->GetURL("a.com", "/title1.html"));
  EXPECT_TRUE(NavigateToURL(shell(), url));
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();

  // Give the page a beforeunload handler that does a replaceState.  Do this
  // from setTimeout so that the navigation that triggers beforeunload is
  // already started when the replaceState happens.
  EXPECT_TRUE(ExecJs(root,
                     "window.onbeforeunload = function (e) {"
                     "  setTimeout(() => {"
                     "    history.replaceState({}, 'footitle', 'foo');"
                     "  }, 0);"
                     "};\n"));

  GURL url2 = embedded_test_server()->GetURL("b.com", "/title1.html");
  TestNavigationManager cross_site_navigation(web_contents(), url2);
  SameDocumentCommitObserver replace_state_observer(web_contents());

  // Start a cross-site navigation.  Using a renderer-initiated navigation
  // rather than a browser-initiated one is important here, since
  // https://crbug.com/825677 was triggered only when replaceState ran while
  // having a user gesture, which will be the case here since ExecJs
  // runs with a user gesture.
  EXPECT_TRUE(ExecJs(root, JsReplace("location.href = $1", url2)));
  EXPECT_TRUE(cross_site_navigation.WaitForRequestStart());

  // Now wait for the replaceState to commit while the cross-process navigation
  // is paused.
  replace_state_observer.Wait();
  GURL replace_state_url = embedded_test_server()->GetURL("a.com", "/foo");
  EXPECT_EQ(replace_state_url, replace_state_observer.last_committed_url());

  // The cross-process navigation should not be canceled after the
  // replaceState.
  ASSERT_TRUE(root->IsLoading());
  ASSERT_TRUE(root->navigation_request());

  // Resume and finish the cross-process navigation.
  cross_site_navigation.ResumeNavigation();
  ASSERT_TRUE(cross_site_navigation.WaitForNavigationFinished());
  EXPECT_TRUE(cross_site_navigation.was_successful());
  EXPECT_EQ(url2, web_contents()->GetLastCommittedURL());
}

// Test that a pending frame policy, such as an updated sandbox attribute, does
// not take effect after a same-document navigation.  See
// https://crbug.com/849311.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       SameDocumentNavigationDoesNotCommitPendingFramePolicy) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  FrameTreeNode* subframe = root->child_at(0);

  // The subframe should not be sandboxed.
  EXPECT_EQ(network::mojom::WebSandboxFlags::kNone,
            subframe->pending_frame_policy().sandbox_flags);
  EXPECT_EQ(network::mojom::WebSandboxFlags::kNone,
            subframe->effective_frame_policy().sandbox_flags);

  // Set the "sandbox" attribute on the subframe; pending policy should update.
  EXPECT_TRUE(ExecJs(
      root, "document.querySelector('iframe').sandbox = 'allow-scripts';"));
  // "allow-scripts" resets both SandboxFlags::Scripts and
  // SandboxFlags::AutomaticFeatures bits per blink::ParseSandboxPolicy().
  network::mojom::WebSandboxFlags expected_flags =
      network::mojom::WebSandboxFlags::kAll &
      ~network::mojom::WebSandboxFlags::kScripts &
      ~network::mojom::WebSandboxFlags::kAutomaticFeatures;
  EXPECT_EQ(expected_flags, subframe->pending_frame_policy().sandbox_flags);
  EXPECT_EQ(network::mojom::WebSandboxFlags::kNone,
            subframe->effective_frame_policy().sandbox_flags);

  // Commit a same-document navigation with replaceState.  The new sandbox
  // flags should still be pending but not effective.
  SameDocumentCommitObserver replace_state_observer(web_contents());
  EXPECT_TRUE(ExecJs(subframe, "history.replaceState({}, 'footitle', 'foo');"));
  replace_state_observer.Wait();

  EXPECT_EQ(expected_flags, subframe->pending_frame_policy().sandbox_flags);
  EXPECT_EQ(network::mojom::WebSandboxFlags::kNone,
            subframe->effective_frame_policy().sandbox_flags);

  // Also try a same-document navigation to a fragment, which also shouldn't
  // commit the pending sandbox flags.
  GURL fragment_url = GURL(subframe->current_url().spec() + "#foo");
  {
    SameDocumentCommitObserver fragment_observer(web_contents());
    EXPECT_TRUE(ExecJs(subframe, JsReplace("location.href=$1", fragment_url)));
    fragment_observer.Wait();
    EXPECT_EQ(fragment_url, subframe->current_url());
  }

  EXPECT_EQ(expected_flags, subframe->pending_frame_policy().sandbox_flags);
  EXPECT_EQ(network::mojom::WebSandboxFlags::kNone,
            subframe->effective_frame_policy().sandbox_flags);
}

// Ensure that when two cross-site frames have subframes with unique origins,
// and those subframes create blob URLs and navigate to them, the blob URLs end
// up in different processes. See https://crbug.com/863623.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       TwoBlobURLsWithNullOriginDontShareProcess) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/navigation_controller/page_with_data_iframe.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  FrameTreeNode* subframe = root->child_at(0);

  // Create a blob URL in the subframe, and navigate to it.
  TestNavigationObserver observer(shell()->web_contents());
  std::string blob_script =
      "var blob = new Blob(['foo'], {type : 'text/html'});"
      "var url = URL.createObjectURL(blob);"
      "location = url;";
  EXPECT_TRUE(ExecJs(subframe, blob_script));
  observer.Wait();
  RenderFrameHostImpl* subframe_rfh = subframe->current_frame_host();
  EXPECT_TRUE(subframe_rfh->GetLastCommittedURL().SchemeIsBlob());

  // Open a cross-site popup and repeat these steps.
  GURL popup_url(embedded_test_server()->GetURL(
      "b.com", "/navigation_controller/page_with_data_iframe.html"));
  Shell* new_shell = OpenPopup(root, popup_url, "");
  FrameTreeNode* popup_root =
      static_cast<WebContentsImpl*>(new_shell->web_contents())
          ->GetPrimaryFrameTree()
          .root();
  FrameTreeNode* popup_subframe = popup_root->child_at(0);

  TestNavigationObserver popup_observer(new_shell->web_contents());
  EXPECT_TRUE(ExecJs(popup_subframe, blob_script));
  popup_observer.Wait();
  RenderFrameHostImpl* popup_subframe_rfh =
      popup_subframe->current_frame_host();
  EXPECT_TRUE(popup_subframe_rfh->GetLastCommittedURL().SchemeIsBlob());

  // Ensure that the two blob subframes don't share a process or SiteInstance.
  EXPECT_NE(subframe->current_frame_host()->GetSiteInstance(),
            popup_subframe->current_frame_host()->GetSiteInstance());
  EXPECT_NE(
      subframe->current_frame_host()->GetSiteInstance()->GetProcess(),
      popup_subframe->current_frame_host()->GetSiteInstance()->GetProcess());
  EXPECT_NE(
      subframe->current_frame_host()->GetSiteInstance()->GetSiteURL(),
      popup_subframe->current_frame_host()->GetSiteInstance()->GetSiteURL());
}

// Ensure that when a process is about to be destroyed after the last active
// frame in it goes away, an attempt to reuse a proxy in that process doesn't
// result in a crash.  See https://crbug.com/794625.
// TODO(crbug.com/42050611): This is flaky on Fuchsia because the
// MessagePort is not cleared on the other side, resulting in Zircon killing the
// process. See the comment referencing the same bug in
// //mojo/core/channel_fuchsia.cc
#if BUILDFLAG(IS_FUCHSIA)
#define MAYBE_RenderFrameProxyNotRecreatedDuringProcessShutdown \
  DISABLED_RenderFrameProxyNotRecreatedDuringProcessShutdown
#else
#define MAYBE_RenderFrameProxyNotRecreatedDuringProcessShutdown \
  RenderFrameProxyNotRecreatedDuringProcessShutdown
#endif
IN_PROC_BROWSER_TEST_P(
    SitePerProcessBrowserTest,
    MAYBE_RenderFrameProxyNotRecreatedDuringProcessShutdown) {
  DisableBackForwardCacheForTesting(
      web_contents(), content::BackForwardCache::TEST_REQUIRES_NO_CACHING);
  GURL main_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();

  GURL popup_url(embedded_test_server()->GetURL(
      "b.com", "/title1.html"));
  Shell* new_shell = OpenPopup(root, popup_url, "foo");
  FrameTreeNode* popup_root =
      static_cast<WebContentsImpl*>(new_shell->web_contents())
          ->GetPrimaryFrameTree()
          .root();
  auto* rfh = popup_root->current_frame_host();

  // Disable the unload timer to prevent flakiness.
  rfh->DisableUnloadTimerForTesting();

  // This will be used to monitor that b.com process exits cleanly.
  RenderProcessHostWatcher b_process_observer(
      popup_root->current_frame_host()->GetProcess(),
      RenderProcessHostWatcher::WATCH_FOR_HOST_DESTRUCTION);

  // In the first tab, install a postMessage handler to navigate the popup to a
  // hung b.com URL once the first message is received.
  GURL hung_b_url(embedded_test_server()->GetURL("b.com", "/hung"));
  TestNavigationManager manager(new_shell->web_contents(), hung_b_url);
  EXPECT_TRUE(ExecJs(shell(), JsReplace(R"(
      window.done = false;
      window.onmessage = () => {
        if (!window.done) {
          window.open($1, 'foo');
          window.done = true;
        }
      };)",
                                        hung_b_url)));

  // In the popup, install a pagehide handler to send a lot of postMessages to
  // the opener.  This keeps the MessageLoop in the b.com process busy after
  // navigating away from the current document.  In https://crbug.com/794625,
  // this was needed so that a subsequent IPC to recreate a proxy arrives
  // before the process fully shuts down.
  EXPECT_TRUE(ExecJs(new_shell, R"(
      window.onpagehide = () => {
        for (var i=0; i<10000; i++)
          opener.postMessage('hi','*');
      })"));

  // Navigate popup to a.com.  This unloads the last active frame in the b.com
  // process, and hence initiates process shutdown.
  TestFrameNavigationObserver commit_observer(popup_root);
  GURL another_a_url(embedded_test_server()->GetURL("a.com", "/title3.html"));
  EXPECT_TRUE(ExecJs(new_shell, JsReplace("location = $1", another_a_url)));
  commit_observer.WaitForCommit();

  // At this point, popup's original RFH is pending deletion.
  EXPECT_TRUE(rfh->IsPendingDeletion());

  // When the opener receives a postMessage from the popup's pagehide handler,
  // it should start a navigation back to b.com.  Wait for it.  This navigation
  // creates a speculative RFH which reuses the proxy that was created as part
  // of navigating from |popup_url| to |another_a_url|.
  EXPECT_TRUE(manager.WaitForRequestStart());

  // Cancel the started navigation (to /hung) in the popup and make sure the
  // b.com renderer process exits cleanly without a crash.  In
  // https://crbug.com/794625, the crash was caused by trying to recreate the
  // reused proxy, which had been incorrectly set as non-live.
  popup_root->ResetNavigationRequest(
      NavigationDiscardReason::kExplicitCancellation);
  b_process_observer.Wait();
  EXPECT_TRUE(b_process_observer.did_exit_normally());
}

IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       CommitTimeoutForHungRenderer) {
  // Navigate first tab to a.com.
  GURL a_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
  EXPECT_TRUE(NavigateToURL(shell(), a_url));
  RenderProcessHost* a_process =
      shell()->web_contents()->GetPrimaryMainFrame()->GetProcess();

  // Open b.com in a second tab.  Using a renderer-initiated navigation is
  // important to leave a.com and b.com SiteInstances in the same
  // BrowsingInstance (so the b.com -> a.com navigation in the next test step
  // will reuse the process associated with the first a.com tab).
  GURL b_url(embedded_test_server()->GetURL("b.com", "/title2.html"));
  Shell* new_shell = OpenPopup(shell()->web_contents(), b_url, "newtab");
  WebContents* new_contents = new_shell->web_contents();
  EXPECT_TRUE(WaitForLoadStop(new_contents));
  RenderProcessHost* b_process =
      new_contents->GetPrimaryMainFrame()->GetProcess();
  EXPECT_NE(a_process, b_process);

  // Hang the first tab's renderer.
  const char* kHungScript = "setTimeout(function() { for (;;) {}; }, 0);";
  EXPECT_TRUE(ExecJs(shell()->web_contents(), kHungScript));

  // Attempt to navigate the second tab to a.com.  This will attempt to reuse
  // the hung process.
  NavigationRequest::SetCommitTimeoutForTesting(base::Milliseconds(100));
  GURL hung_url(embedded_test_server()->GetURL("a.com", "/title3.html"));
  UnresponsiveRendererObserver unresponsive_renderer_observer(new_contents);
  EXPECT_TRUE(
      ExecJs(new_contents, JsReplace("window.location = $1", hung_url)));

  // Verify that we will be notified about the unresponsive renderer.  Before
  // changes in https://crrev.com/c/1089797, the test would hang here forever.
  RenderProcessHost* hung_process = unresponsive_renderer_observer.Wait();
  EXPECT_EQ(hung_process, a_process);

  // Reset the timeout.
  NavigationRequest::SetCommitTimeoutForTesting(base::TimeDelta());
}

// This is a regression test for https://crbug.com/881812 which complained that
// the hung renderer dialog used to undesirably show up for background tabs
// (typically during session restore when many navigations would be happening in
// backgrounded processes).
// TODO(crbug.com/40196588): Flaky on Mac and Windows.
#if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN)
#define MAYBE_NoCommitTimeoutForInvisibleWebContents \
  DISABLED_NoCommitTimeoutForInvisibleWebContents
#else
#define MAYBE_NoCommitTimeoutForInvisibleWebContents \
  NoCommitTimeoutForInvisibleWebContents
#endif
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       MAYBE_NoCommitTimeoutForInvisibleWebContents) {
  // Navigate first tab to a.com.
  GURL a_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
  EXPECT_TRUE(NavigateToURL(shell(), a_url));
  RenderProcessHost* a_process =
      shell()->web_contents()->GetPrimaryMainFrame()->GetProcess();

  // Open b.com in a second tab.  Using a renderer-initiated navigation is
  // important to leave a.com and b.com SiteInstances in the same
  // BrowsingInstance (so the b.com -> a.com navigation in the next test step
  // will reuse the process associated with the first a.com tab).
  GURL b_url(embedded_test_server()->GetURL("b.com", "/title2.html"));
  Shell* new_shell = OpenPopup(shell()->web_contents(), b_url, "newtab");
  WebContents* new_contents = new_shell->web_contents();
  EXPECT_TRUE(WaitForLoadStop(new_contents));
  RenderProcessHost* b_process =
      new_contents->GetPrimaryMainFrame()->GetProcess();
  EXPECT_NE(a_process, b_process);

  // Hang the first tab's renderer.
  const char* kHungScript = "setTimeout(function() { for (;;) {}; }, 0);";
  EXPECT_TRUE(ExecJs(shell()->web_contents(), kHungScript));

  // Hide the second tab.  This should prevent reporting of hangs in this tab
  // (see https://crbug.com/881812).
  new_contents->WasHidden();
  EXPECT_EQ(Visibility::HIDDEN, new_contents->GetVisibility());

  // Attempt to navigate the second tab to a.com.  This will attempt to reuse
  // the hung process.
  base::TimeDelta kTimeout = base::Milliseconds(100);
  NavigationRequest::SetCommitTimeoutForTesting(kTimeout);
  GURL hung_url(embedded_test_server()->GetURL("a.com", "/title3.html"));
  UnresponsiveRendererObserver unresponsive_renderer_observer(new_contents);
  EXPECT_TRUE(
      ExecJs(new_contents, JsReplace("window.location = $1", hung_url)));

  // Verify that we will not be notified about the unresponsive renderer.
  // Before changes in https://crrev.com/c/1089797, the test would get notified
  // and therefore |hung_process| would be non-null.
  RenderProcessHost* hung_process =
      unresponsive_renderer_observer.Wait(kTimeout * 10);
  EXPECT_FALSE(hung_process);

  // Reset the timeout.
  NavigationRequest::SetCommitTimeoutForTesting(base::TimeDelta());
}

// Tests that an inner WebContents will reattach to its outer WebContents after
// a navigation that causes a process swap.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest, ProcessSwapOnInnerContents) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(a)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  FrameTreeNode* child_frame =
      web_contents()->GetPrimaryFrameTree().root()->child_at(0);
  WebContentsImpl* inner_contents =
      static_cast<WebContentsImpl*>(CreateAndAttachInnerContents(
          ToRenderFrameHost(child_frame).render_frame_host()));
  FrameTreeNode* inner_contents_root =
      inner_contents->GetPrimaryFrameTree().root();
  RenderFrameProxyHost* outer_proxy =
      inner_contents_root->render_manager()->GetProxyToOuterDelegate();
  CrossProcessFrameConnector* outer_connector =
      outer_proxy->cross_process_frame_connector();
  EXPECT_NE(nullptr, outer_connector->get_view_for_testing());

  GURL a_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
  EXPECT_TRUE(NavigateToURLFromRenderer(inner_contents_root, a_url));
  SiteInstance* a_site_instance =
      inner_contents->GetPrimaryMainFrame()->GetSiteInstance();
  RenderProcessHost* a_process = a_site_instance->GetProcess();
  RenderWidgetHostViewChildFrame* a_view =
      outer_connector->get_view_for_testing();

  GURL b_url(embedded_test_server()->GetURL("b.com", "/title1.html"));
  EXPECT_TRUE(NavigateToURLFromRenderer(inner_contents_root, b_url));
  SiteInstance* b_site_instance =
      inner_contents->GetPrimaryMainFrame()->GetSiteInstance();
  RenderProcessHost* b_process = b_site_instance->GetProcess();
  RenderWidgetHostViewChildFrame* b_view =
      outer_connector->get_view_for_testing();

  // Ensure that the SiteInstances have changed, we've completed a process swap
  // and reattached the inner WebContents creating a new RenderWidgetHostView.
  EXPECT_NE(a_site_instance, b_site_instance);
  EXPECT_NE(a_process, b_process);
  EXPECT_NE(nullptr, a_view);
  EXPECT_NE(nullptr, b_view);
  EXPECT_NE(a_view, b_view);
}

// This test ensures that WebContentsImpl::FocusOwningWebContents() focuses an
// inner WebContents when it is given an OOPIF's RenderWidgetHost inside that
// inner WebContents.  This setup isn't currently supported in Chrome
// (requiring issue 614463), but it can happen in embedders.  See
// https://crbug.com/1026056.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest, FocusInnerContentsFromOOPIF) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(a)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  // Set up and attach an artificial inner WebContents.
  FrameTreeNode* child_frame =
      web_contents()->GetPrimaryFrameTree().root()->child_at(0);
  WebContentsImpl* inner_contents =
      static_cast<WebContentsImpl*>(CreateAndAttachInnerContents(
          ToRenderFrameHost(child_frame).render_frame_host()));
  FrameTreeNode* inner_contents_root =
      inner_contents->GetPrimaryFrameTree().root();

  // Navigate inner WebContents to b.com, and then navigate a subframe on that
  // page to c.com.
  GURL b_url(embedded_test_server()->GetURL(
      "b.com", "/cross_site_iframe_factory.html?b(b)"));
  EXPECT_TRUE(NavigateToURLFromRenderer(inner_contents_root, b_url));
  GURL c_url(embedded_test_server()->GetURL("c.com", "/title1.html"));
  FrameTreeNode* inner_child = inner_contents_root->child_at(0);
  EXPECT_TRUE(NavigateToURLFromRenderer(inner_child, c_url));

  // Because |inner_contents| was set up without kGuestScheme, it can actually
  // have OOPIFs.  Ensure that the subframe is in an OOPIF.
  EXPECT_NE(inner_contents_root->current_frame_host()->GetSiteInstance(),
            inner_child->current_frame_host()->GetSiteInstance());
  EXPECT_TRUE(inner_child->current_frame_host()->IsCrossProcessSubframe());

  // Make sure the outer WebContents is focused to start with.
  web_contents()->Focus();
  web_contents()->SetAsFocusedWebContentsIfNecessary();
  EXPECT_EQ(web_contents(), web_contents()->GetFocusedWebContents());

  // Focus the inner WebContents as if an event were received and dispatched
  // directly on the |inner_child|'s RenderWidgetHost, and ensure that this
  // took effect.
  inner_contents->FocusOwningWebContents(
      inner_child->current_frame_host()->GetRenderWidgetHost());
  EXPECT_EQ(inner_contents, web_contents()->GetFocusedWebContents());
}

// Check that a web frame can't navigate a remote subframe to a file: URL.  The
// frame should stay at the old URL, and the navigation attempt should produce
// a console error message.  See https://crbug.com/894399.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       FileURLBlockedWithConsoleErrorInRemoteFrameNavigation) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  FrameTreeNode* child =
      web_contents()->GetPrimaryFrameTree().root()->child_at(0);
  GURL original_frame_url(child->current_frame_host()->GetLastCommittedURL());
  EXPECT_EQ("b.com", original_frame_url.host());

  WebContentsConsoleObserver console_observer(web_contents());
  console_observer.SetPattern("Not allowed to load local resource: file:*");

  GURL file_url("file:///");
  EXPECT_TRUE(
      ExecJs(web_contents(),
             JsReplace("document.querySelector('iframe').src = $1", file_url)));
  ASSERT_TRUE(console_observer.Wait());

  // The iframe should've stayed at the original URL.
  EXPECT_EQ(original_frame_url,
            child->current_frame_host()->GetLastCommittedURL());
}

// Touchscreen DoubleTapZoom is only supported on Android & ChromeOS at present.
#if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID)
// A test ContentBrowserClient implementation which enforces
// WebPreferences' |double_tap_to_zoom_enabled| to be true.
class DoubleTapZoomContentBrowserClient
    : public ContentBrowserTestContentBrowserClient {
 public:
  DoubleTapZoomContentBrowserClient() = default;

  DoubleTapZoomContentBrowserClient(const DoubleTapZoomContentBrowserClient&) =
      delete;
  DoubleTapZoomContentBrowserClient& operator=(
      const DoubleTapZoomContentBrowserClient&) = delete;

  void OverrideWebPreferences(
      content::WebContents* web_contents,
      SiteInstance& main_frame_site,
      blink::web_pref::WebPreferences* web_prefs) override {
    web_prefs->double_tap_to_zoom_enabled = true;
  }
};

IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       TouchscreenAnimateDoubleTapZoomInOOPIF) {
  // Install a client forcing double-tap zoom to be enabled.
  DoubleTapZoomContentBrowserClient content_browser_client;
  web_contents()->OnWebPreferencesChanged();

  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  ASSERT_EQ(1u, root->child_count());
  FrameTreeNode* child_b = root->child_at(0);
  ASSERT_TRUE(child_b);

  RenderFrameSubmissionObserver observer_a(root);
  // We need to observe a root frame submission to pick up the initial page
  // scale factor.
  observer_a.WaitForAnyFrameSubmission();
  float original_page_scale =
      observer_a.LastRenderFrameMetadata().page_scale_factor;

  // Must do this before it's safe to use the coordinate transform functions.
  WaitForHitTestData(child_b->current_frame_host());

  // Select a tap point inside the OOPIF.
  gfx::PointF tap_position =
      child_b->current_frame_host()
          ->GetRenderWidgetHost()
          ->GetView()
          ->TransformPointToRootCoordSpaceF(gfx::PointF(10, 10));

  // Generate a double-tap.
  static constexpr char kActionsTemplate[] = R"HTML(
      [{
        "source" : "touch",
        "actions" : [
          { "name": "pointerDown", "x": %f, "y": %f},
          { "name": "pointerUp"},
          { "name": "pause", "duration": 50 },
          { "name": "pointerDown", "x": %f, "y": %f},
          { "name": "pointerUp"}
        ]
      }]
  )HTML";
  std::string double_tap_actions_json =
      base::StringPrintf(kActionsTemplate, tap_position.x(), tap_position.y(),
                         tap_position.x(), tap_position.y());
  auto parsed_json =
      base::JSONReader::ReadAndReturnValueWithError(double_tap_actions_json);
  ASSERT_TRUE(parsed_json.has_value()) << parsed_json.error().message;
  ActionsParser actions_parser(std::move(*parsed_json));

  ASSERT_TRUE(actions_parser.Parse());
  auto synthetic_gesture_doubletap = std::make_unique<SyntheticPointerAction>(
      actions_parser.pointer_action_params());

  // Queue the event and wait for it to be acked.
  InputEventAckWaiter ack_waiter(
      child_b->current_frame_host()->GetRenderWidgetHost(),
      blink::WebInputEvent::Type::kGestureDoubleTap);
  auto* host = static_cast<RenderWidgetHostImpl*>(
      root->current_frame_host()->GetRenderWidgetHost());
  host->QueueSyntheticGesture(
      std::move(synthetic_gesture_doubletap),
      base::BindOnce([](SyntheticGesture::Result result) {
        EXPECT_EQ(SyntheticGesture::GESTURE_FINISHED, result);
      }));
  // Waiting for the ack on the child frame ensures the event actually routed
  // through the oopif.
  ack_waiter.Wait();

  // Wait for page scale to change. We'll assume the OOPIF is scaled up by
  // at least 10%.
  float target_scale = 1.1f * original_page_scale;
  float new_page_scale = original_page_scale;
  do {
    observer_a.WaitForAnyFrameSubmission();
    new_page_scale = observer_a.LastRenderFrameMetadata().page_scale_factor;
  } while (new_page_scale < target_scale);
}
#endif  // BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID)

class CrossProcessNavigationObjectElementTest
    : public SitePerProcessBrowserTestBase,
      public testing::WithParamInterface<
          std::tuple<std::string, std::string, std::string>> {};

// This test verifies the correctness of rendering fallback in <object> when the
// a cross-origin navigation leads to a 404 error. Assuming the page's origin
// is "a.com", the test cases are:
// 1- Navigating an <object> from "a.com" to invalid "b.com" resource. In this
//    case the load fails for a provisional frame and at that time there is no
//    proxy to parent.
// 2- Navigating an <object> from "b.com" to invalid "b.com". Since navigation
//    is not cross-origin the failure happens for a non-provisional frame.
// 3- Navigation an <object> from "b.com" to invalid "c.com". The load fails for
//    a provisional frame, and at that time there is a proxy to parent.
IN_PROC_BROWSER_TEST_P(CrossProcessNavigationObjectElementTest, FallbackShown) {
  const GURL main_url = embedded_test_server()->GetURL(
      base::StringPrintf("%s.com", std::get<0>(GetParam()).c_str()),
      "/page_with_object_fallback.html");
  const GURL object_valid_url = embedded_test_server()->GetURL(
      base::StringPrintf("%s.com", std::get<1>(GetParam()).c_str()),
      "/title1.html");
  const GURL object_invalid_url = embedded_test_server()->GetURL(
      base::StringPrintf("%s.com", std::get<2>(GetParam()).c_str()),
      "/does-not-exist-throws-404.html");

  ASSERT_TRUE(NavigateToURL(shell(), main_url));

  // Load the contents of <object> (first navigation which is to a valid
  // existing resource) and wait for 'load' event on <object>.
  ASSERT_EQ("OBJECT_LOAD",
            EvalJs(web_contents(), JsReplace("setUrl($1);", object_valid_url)));

  // Verify fallback content is not shown.
  ASSERT_EQ(false, EvalJs(web_contents(), "fallbackVisible()"));

  // Navigate the <object>'s frame to invalid origin. Make sure we do not report
  // the 'load' event (the 404 content loads inside the <object>'s frame and the
  // 'load' event might fire before fallback is detected).
  ASSERT_EQ(true, EvalJs(web_contents(), JsReplace("setUrl($1);"
                                                   "notifyWhenFallbackShown();",
                                                   object_invalid_url)));
}

INSTANTIATE_TEST_SUITE_P(SitePerProcess,
                         CrossProcessNavigationObjectElementTest,
                         testing::Values(std::make_tuple("a", "a", "b"),
                                         std::make_tuple("a", "b", "b"),
                                         std::make_tuple("a", "b", "c")));

#if !BUILDFLAG(IS_ANDROID)
// This test verifies that after occluding a WebContents the RAF inside a
// cross-process child frame is throttled.
// Disabled due to flakiness. crbug.com/1293207
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       DISABLED_OccludedRenderWidgetThrottlesRAF) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  FrameTreeNode* subframe = root->child_at(0);
  GURL page_with_raf_counter =
      embedded_test_server()->GetURL("a.com", "/page_with_raf_counter.html");
  EXPECT_TRUE(NavigateToURLFromRenderer(subframe, page_with_raf_counter));

  // Initially page is visible - wait some time and then ensure a good number of
  // rafs have been generated. On Mac the number of RAFs that occur in 500ms is
  // quite low, see https://crbug.com/1098715.
  auto allow_time_for_rafs = []() {
    base::RunLoop run_loop;
    base::SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
        FROM_HERE, run_loop.QuitClosure(), base::Milliseconds(1000));
    run_loop.Run();
  };

  ASSERT_TRUE(ExecJs(subframe, "reset_count();"));
  allow_time_for_rafs();
  int32_t default_raf_count = EvalJs(subframe, "raf_count").ExtractInt();
  // On a 60 fps we should expect more than 30 counts - however purely for
  // sanity checking and avoiding unnecessary flakes adding a comparison for a
  // much lower value. This verifies that we did get *some* rAFs.
  EXPECT_GT(default_raf_count, 5);
  web_contents()->WasOccluded();
  ASSERT_TRUE(ExecJs(subframe, "reset_count();"));
  allow_time_for_rafs();
  int32_t raf_count = EvalJs(subframe, "raf_count").ExtractInt();
  // If the frame is throttled, we should expect 0 rAFs.
  EXPECT_EQ(raf_count, 0);
  // Sanity-check: unoccluding will reverse the effect.
  web_contents()->WasShown();
  ASSERT_TRUE(ExecJs(subframe, "reset_count();"));
  allow_time_for_rafs();
  raf_count = EvalJs(subframe, "raf_count").ExtractInt();
  EXPECT_GT(raf_count, 5);
}
#endif

// Test that a renderer locked to origin A will be terminated if it tries to
// commit a navigation to origin B.  See also https://crbug.com/770239.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       CommittedOriginIncompatibleWithOriginLock) {
  GURL start_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
  EXPECT_TRUE(NavigateToURL(shell(), start_url));
  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
                            ->GetPrimaryFrameTree()
                            .root();

  GURL another_url(embedded_test_server()->GetURL("a.com", "/title2.html"));
  const GURL bad_url = GURL("https://b.com");

  // Sanity check the process lock logic.
  auto process_lock =
      root->current_frame_host()->GetProcess()->GetProcessLock();
  IsolationContext isolation_context(
      shell()->web_contents()->GetBrowserContext());
  ProcessLock start_url_lock = ProcessLock::FromSiteInfo(
      SiteInfo::CreateForTesting(isolation_context, start_url));
  ProcessLock another_url_lock = ProcessLock::FromSiteInfo(
      SiteInfo::CreateForTesting(isolation_context, another_url));
  ProcessLock bad_url_lock = ProcessLock::FromSiteInfo(
      SiteInfo::CreateForTesting(isolation_context, bad_url));
  EXPECT_EQ(start_url_lock, process_lock);
  EXPECT_EQ(another_url_lock, process_lock);
  EXPECT_NE(bad_url_lock, process_lock);

  // Leave the commit URL alone, so the URL checks will pass, but change the
  // origin to one that does not match the origin lock of the process.
  PwnCommitIPC(shell()->web_contents(), another_url, another_url,
               url::Origin::Create(bad_url));
  EXPECT_TRUE(
      BeginNavigateToURLFromRenderer(shell()->web_contents(), another_url));

  // Due to the origin lock mismatch, the render process should be killed when
  // it tries to commit.
  RenderProcessHostBadIpcMessageWaiter kill_waiter(
      root->current_frame_host()->GetProcess());
  EXPECT_EQ(bad_message::RFH_INVALID_ORIGIN_ON_COMMIT, kill_waiter.Wait());
}

// This test verifies that plugin elements containing cross-process-frames do
// not become unresponsive during style changes. (see https://crbug.com/781880).
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       PluginElementResponsiveInCrossProcessNavigations) {
  GURL main_frame_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
  ASSERT_TRUE(NavigateToURL(shell(), main_frame_url));
  GURL cross_origin(embedded_test_server()->GetURL("b.com", "/title1.html"));
  std::string msg =
      EvalJs(shell(), JsReplace("var object = document.createElement('object');"
                                "document.body.appendChild(object);"
                                "object.data = $1;"
                                "object.type='text/html';"
                                "object.notify = true;"
                                "new Promise(resolve => {"
                                "  object.onload = () => {"
                                "    if (!object.notify) return;"
                                "    object.notify = false;"
                                "    resolve('done');"
                                "  };"
                                "});",
                                cross_origin))
          .ExtractString();
  ASSERT_EQ("done", msg);
  // To track the frame's visibility an EmbeddedContentView is needed. The
  // following steps make sure the visibility is tracked properly on the browser
  // side.
  auto* frame_connector = web_contents()
                              ->GetPrimaryFrameTree()
                              .root()
                              ->child_at(0)
                              ->render_manager()
                              ->GetProxyToParent()
                              ->cross_process_frame_connector();
  ASSERT_FALSE(frame_connector->IsHidden());
  ASSERT_TRUE(ExecJs(
      shell(), "document.querySelector('object').style.display = 'none';"));
  EXPECT_TRUE(
      base::test::RunUntil([&]() { return frame_connector->IsHidden(); }));
  ASSERT_TRUE(ExecJs(
      shell(), "document.querySelector('object').style.display = 'block';"));
  EXPECT_TRUE(
      base::test::RunUntil([&]() { return !frame_connector->IsHidden(); }));
}

// Pending navigations must be canceled when a frame becomes pending deletion.
//
// 1) Initial state: A(B).
// 2) Navigation from B to C. Pause when the speculative RFH is created.
// 3) Deletion of B.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       NavigationCommitInIframePendingDeletionAB) {
  GURL url_a(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)"));
  GURL url_c(embedded_test_server()->GetURL("c.com", "/title1.html"));

  // 1) Initial state: A(B).
  EXPECT_TRUE(NavigateToURL(shell(), url_a));
  RenderFrameHostImpl* rfh_a = web_contents()->GetPrimaryMainFrame();
  RenderFrameHostImpl* rfh_b = rfh_a->child_at(0)->current_frame_host();

  // RFH B has an unload handler.
  rfh_b->DoNotDeleteForTesting();
  EXPECT_TRUE(ExecJs(rfh_b, "onunload=function(){}"));

  // 2) Navigation from B to C. The navigation will be paused
  // when the speculative RFH is created.
  TestNavigationManager navigation_observer(web_contents(), url_c);
  EXPECT_TRUE(ExecJs(rfh_b, JsReplace("location.href=$1;", url_c)));
  navigation_observer.WaitForSpeculativeRenderFrameHostCreation();
  RenderFrameHostImpl* rfh_c =
      rfh_b->frame_tree_node()->render_manager()->speculative_frame_host();

  EXPECT_EQ(RenderFrameHostImpl::LifecycleStateImpl::kActive,
            rfh_a->lifecycle_state());
  EXPECT_EQ(RenderFrameHostImpl::LifecycleStateImpl::kActive,
            rfh_b->lifecycle_state());
  EXPECT_EQ(RenderFrameHostImpl::LifecycleStateImpl::kSpeculative,
            rfh_c->lifecycle_state());

  // 3) Deletion of B. The unload handler takes times to execute.
  RenderFrameDeletedObserver delete_b(rfh_b), delete_c(rfh_c);
  EXPECT_TRUE(
      ExecJs(rfh_a, JsReplace("document.querySelector('iframe').remove();")));
  EXPECT_FALSE(delete_b.deleted());
  EXPECT_TRUE(delete_c.deleted());  // The speculative RFH is deleted.
  EXPECT_EQ(RenderFrameHostImpl::LifecycleStateImpl::kActive,
            rfh_a->lifecycle_state());
  EXPECT_EQ(RenderFrameHostImpl::LifecycleStateImpl::kRunningUnloadHandlers,
            rfh_b->lifecycle_state());

  // The navigation has been canceled.
  ASSERT_TRUE(navigation_observer.WaitForNavigationFinished());
  EXPECT_FALSE(navigation_observer.was_successful());

  // |rfh_b| will complete its deletion at some point:
  EXPECT_FALSE(delete_b.deleted());
  rfh_b->DetachForTesting();
  EXPECT_TRUE(delete_b.deleted());
}

// Pending navigations must be canceled when a frame becomes pending deletion.
//
// 1) Initial state: A(B(C)).
// 2) Navigation from C to D. Pause when the speculative RFH is created.
// 3) Deletion of B.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       NavigationCommitInIframePendingDeletionABC) {
  GURL url_a(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b(c))"));
  GURL url_d(embedded_test_server()->GetURL("d.com", "/title1.html"));

  // 1) Initial state: A(B(C)).
  EXPECT_TRUE(NavigateToURL(shell(), url_a));
  RenderFrameHostImpl* rfh_a = web_contents()->GetPrimaryMainFrame();
  RenderFrameHostImpl* rfh_b = rfh_a->child_at(0)->current_frame_host();
  RenderFrameHostImpl* rfh_c = rfh_b->child_at(0)->current_frame_host();

  // Leave rfh_c in pending deletion state.
  LeaveInPendingDeletionState(rfh_c);

  // 2) Navigation from C to D. The navigation will be paused
  // when the speculative RFH is created.
  TestNavigationManager navigation_observer(web_contents(), url_d);
  EXPECT_TRUE(ExecJs(rfh_c, JsReplace("location.href=$1;", url_d)));
  navigation_observer.WaitForSpeculativeRenderFrameHostCreation();
  RenderFrameHostImpl* rfh_d =
      rfh_c->frame_tree_node()->render_manager()->speculative_frame_host();

  EXPECT_EQ(RenderFrameHostImpl::LifecycleStateImpl::kActive,
            rfh_a->lifecycle_state());
  EXPECT_EQ(RenderFrameHostImpl::LifecycleStateImpl::kActive,
            rfh_b->lifecycle_state());
  EXPECT_EQ(RenderFrameHostImpl::LifecycleStateImpl::kActive,
            rfh_c->lifecycle_state());
  EXPECT_EQ(RenderFrameHostImpl::LifecycleStateImpl::kSpeculative,
            rfh_d->lifecycle_state());

  // 3) Deletion of D. The unload handler takes times to execute.
  RenderFrameDeletedObserver delete_b(rfh_b), delete_c(rfh_c), delete_d(rfh_d);
  EXPECT_TRUE(
      ExecJs(rfh_a, JsReplace("document.querySelector('iframe').remove();")));
  EXPECT_FALSE(delete_b.deleted());
  EXPECT_FALSE(delete_c.deleted());
  EXPECT_TRUE(delete_d.deleted());  // The speculative RFH is deleted.
  EXPECT_EQ(RenderFrameHostImpl::LifecycleStateImpl::kActive,
            rfh_a->lifecycle_state());
  EXPECT_EQ(RenderFrameHostImpl::LifecycleStateImpl::kReadyToBeDeleted,
            rfh_b->lifecycle_state());
  EXPECT_EQ(RenderFrameHost::LifecycleState::kPendingDeletion,
            rfh_b->GetLifecycleState());
  EXPECT_EQ(RenderFrameHostImpl::LifecycleStateImpl::kRunningUnloadHandlers,
            rfh_c->lifecycle_state());
  EXPECT_EQ(RenderFrameHost::LifecycleState::kPendingDeletion,
            rfh_c->GetLifecycleState());

  // The navigation has been canceled.
  ASSERT_TRUE(navigation_observer.WaitForNavigationFinished());
  EXPECT_FALSE(navigation_observer.was_successful());

  // |rfh_b| and |rfh_c| will complete their deletion at some point:
  EXPECT_FALSE(delete_b.deleted());
  EXPECT_FALSE(delete_c.deleted());
  rfh_c->DetachForTesting();
  EXPECT_TRUE(delete_b.deleted());
  EXPECT_TRUE(delete_c.deleted());
}

// A same document commit from the renderer process is received while the
// RenderFrameHost is pending deletion.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       SameDocumentCommitWhilePendingDeletion) {
  GURL url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)"));
  EXPECT_TRUE(NavigateToURL(shell(), url));
  RenderFrameHostImpl* rfh_a = web_contents()->GetPrimaryMainFrame();
  RenderFrameHostImpl* rfh_b = rfh_a->child_at(0)->current_frame_host();

  // Frame B has a unload handler. The browser process needs to wait before
  // deleting it.
  EXPECT_TRUE(ExecJs(rfh_b, "onunload=function(){}"));

  RenderFrameDeletedObserver deleted_observer(rfh_b);
  DidStartNavigationObserver did_start_navigation_observer(web_contents());

  // Start a same-document navigation on B.
  ExecuteScriptAsync(rfh_b, "location.href='#fragment'");

  // Simulate A deleting B.
  // It starts before receiving the same-document navigation. The detach ACK is
  // received after.
  rfh_b->DetachFromProxy();
  deleted_observer.WaitUntilDeleted();

  // The navigation was ignored.
  EXPECT_FALSE(did_start_navigation_observer.observed());
}

// An history navigation from the renderer process is received while the
// RenderFrameHost is pending deletion.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       HistoryNavigationWhilePendingDeletion) {
  GURL url_ab(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)"));
  GURL url_c(embedded_test_server()->GetURL("c.com", "/title1.html"));

  EXPECT_TRUE(NavigateToURL(shell(), url_ab));
  RenderFrameHostImpl* rfh_a = web_contents()->GetPrimaryMainFrame();
  RenderFrameHostImpl* rfh_b = rfh_a->child_at(0)->current_frame_host();
  EXPECT_TRUE(NavigateToURLFromRenderer(rfh_b->frame_tree_node(), url_c));
  RenderFrameHostImpl* rfh_c = rfh_a->child_at(0)->current_frame_host();

  // Set a value in rfh_a that we'll check later to ensure we didn't
  // incorrectly reload it.
  EXPECT_TRUE(ExecJs(rfh_a, "window.foo='bar';"));

  // Frame C has a unload handler. The browser process needs to wait before
  // deleting it.
  EXPECT_TRUE(ExecJs(rfh_c, "onunload=function(){}"));

  RenderFrameDeletedObserver deleted_observer(rfh_c);

  // History navigation on C.
  ExecuteScriptAsync(rfh_c, "history.back();");

  // Simulate A deleting C.
  // It starts before receiving the history navigation. The detach ACK is
  // received after.
  rfh_c->DetachFromProxy();
  deleted_observer.WaitUntilDeleted();

  // The NavigationController won't be able to find the subframe to navigate
  // since it was just detached, so it should cancel the history navigation and
  // not reload the main page.  Verify this by waiting for any pending
  // navigation (there shouldn't be any) and checking that JavaScript state in
  // rfh_a hasn't changed.  Note that because we've waited for rfh_c to be
  // deleted, we know that the browser process has already received an ack for
  // completion of its unload handler, and thus it has also processed the
  // preceding history.back() IPC.
  EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
  EXPECT_EQ("bar", EvalJs(rfh_a, "window.foo"));
}

// One frame navigates using window.open while it is pending deletion. The two
// frames lives in different processes.
// See https://crbug.com/932087.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       OpenUrlToRemoteFramePendingDeletion) {
  GURL url_ab(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)"));
  GURL url_c(embedded_test_server()->GetURL("c.com", "/title1.html"));

  EXPECT_TRUE(NavigateToURL(shell(), url_ab));
  RenderFrameHostImpl* rfh_a = web_contents()->GetPrimaryMainFrame();
  RenderFrameHostImpl* rfh_b = rfh_a->child_at(0)->current_frame_host();

  // Frame B has a unload handler. The browser process needs to wait before
  // deleting it.
  EXPECT_TRUE(ExecJs(rfh_b, "onunload=function(){}"));
  RenderFrameDeletedObserver deleted_observer(rfh_b);

  // window.open from A in B to url_c.
  DidStartNavigationObserver did_start_navigation_observer(web_contents());
  EXPECT_TRUE(ExecJs(rfh_b, "window.name = 'name';"));
  ExecuteScriptAsync(rfh_a, JsReplace("window.open($1, 'name');", url_c));

  // Simulate A deleting C.
  // It starts before receiving the navigation. The detach ACK is
  // received after.
  rfh_b->DetachFromProxy();
  deleted_observer.WaitUntilDeleted();

  EXPECT_FALSE(did_start_navigation_observer.observed());
}

// Check that if a frame starts a navigation, and the frame's current process
// dies before the response for the navigation comes back, the response will
// not trigger a process kill and will be allowed to commit in a new process.
// See https://crbug.com/968259.
// Note: This test needs to do a browser-initiated navigation because doing
// a renderer-initiated navigation would lead to the navigation being canceled.
// This behavior change has been introduced when navigation moved to use Mojo
// IPCs and is documented here https://crbug.com/988368.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       ProcessDiesBeforeCrossSiteNavigationCompletes) {
  GURL first_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
  EXPECT_TRUE(NavigateToURL(shell(), first_url));
  scoped_refptr<SiteInstanceImpl> first_site_instance(
      web_contents()->GetPrimaryMainFrame()->GetSiteInstance());

  // Start a cross-site navigation and proceed only up to the request start.
  GURL second_url(embedded_test_server()->GetURL("b.com", "/title1.html"));
  TestNavigationManager delayer(web_contents(), second_url);
  web_contents()->GetController().LoadURL(
      second_url, Referrer(), ui::PageTransition::PAGE_TRANSITION_TYPED,
      std::string());
  EXPECT_TRUE(delayer.WaitForRequestStart());

  // Terminate the current a.com process.
  RenderProcessHost* first_process =
      web_contents()->GetPrimaryMainFrame()->GetProcess();
  RenderProcessHostWatcher crash_observer(
      first_process, RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
  EXPECT_TRUE(first_process->Shutdown(0));
  crash_observer.Wait();
  EXPECT_FALSE(web_contents()->GetPrimaryMainFrame()->IsRenderFrameLive());

  // Resume the cross-site navigation and ensure it commits in a new
  // SiteInstance and process.
  ASSERT_TRUE(delayer.WaitForNavigationFinished());
  EXPECT_TRUE(web_contents()->GetPrimaryMainFrame()->IsRenderFrameLive());
  EXPECT_NE(web_contents()->GetPrimaryMainFrame()->GetProcess(), first_process);
  EXPECT_NE(web_contents()->GetPrimaryMainFrame()->GetSiteInstance(),
            first_site_instance);
  EXPECT_EQ(second_url,
            web_contents()->GetPrimaryMainFrame()->GetLastCommittedURL());
}

enum class InnerWebContentsAttachChildFrameOriginType {
  kSameOriginAboutBlank,
  kSameOriginOther,
  kCrossOrigin
};

class InnerWebContentsAttachTest
    : public SitePerProcessBrowserTestBase,
      public testing::WithParamInterface<
          std::tuple<InnerWebContentsAttachChildFrameOriginType,
                     bool /* original frame has beforeunload handlers */,
                     bool /* user proceeds with attaching */>> {
 public:
  InnerWebContentsAttachTest() {}

  InnerWebContentsAttachTest(const InnerWebContentsAttachTest&) = delete;
  InnerWebContentsAttachTest& operator=(const InnerWebContentsAttachTest&) =
      delete;

  ~InnerWebContentsAttachTest() override {}

 protected:
  // Helper class to initiate and conclude a frame preparation process for
  // attaching an inner WebContents.
  class PrepareFrameJob {
   public:
    PrepareFrameJob(RenderFrameHostImpl* original_render_frame_host,
                    bool proceed_through_beforeunload) {
      auto* web_contents =
          WebContents::FromRenderFrameHost(original_render_frame_host);
      // Need user gesture for 'beforeunload' to fire.
      PrepContentsForBeforeUnloadTest(web_contents);
      // Simulate user choosing to stay on the page after beforeunload fired.
      SetShouldProceedOnBeforeUnload(Shell::FromWebContents(web_contents),
                                     true /* always_proceed */,
                                     proceed_through_beforeunload);
      RenderFrameHost::PrepareForInnerWebContentsAttachCallback callback =
          base::BindOnce(&PrepareFrameJob::OnPrepare, base::Unretained(this));
      original_render_frame_host->PrepareForInnerWebContentsAttach(
          std::move(callback));
    }

    PrepareFrameJob(const PrepareFrameJob&) = delete;
    PrepareFrameJob& operator=(const PrepareFrameJob&) = delete;

    virtual ~PrepareFrameJob() {}

    void WaitForPreparedFrame() {
      if (did_call_prepare_)
        return;
      run_loop_.Run();
    }

    RenderFrameHostImpl* prepared_frame() const {
      return new_render_frame_host_;
    }

   private:
    void OnPrepare(RenderFrameHost* render_frame_host) {
      did_call_prepare_ = true;
      new_render_frame_host_ =
          static_cast<RenderFrameHostImpl*>(render_frame_host);
      if (run_loop_.running())
        run_loop_.Quit();
    }

    bool did_call_prepare_ = false;
    raw_ptr<RenderFrameHostImpl> new_render_frame_host_ = nullptr;
    base::RunLoop run_loop_;
  };
};

// This is a test for the FrameTreeNode preparation process for various types
// of outer WebContents RenderFrameHosts; essentially when connecting two
// WebContents through a frame in a WebPage it is possible that the frame itself
// has a nontrivial document (other than about:blank) with a beforeunload
// handler, or even it is a cross-process frame. For such cases the frame first
// needs to be sanitized to be later consumed by the WebContents attaching API.
IN_PROC_BROWSER_TEST_P(InnerWebContentsAttachTest, PrepareFrame) {
  ASSERT_TRUE(
      NavigateToURL(shell(), embedded_test_server()->GetURL(
                                 "a.com", "/page_with_object_fallback.html")));
  InnerWebContentsAttachChildFrameOriginType child_frame_origin_type =
      std::get<0>(GetParam());
  bool test_beforeunload = std::get<1>(GetParam());
  bool proceed_through_beforeunload = std::get<2>(GetParam());
  GURL child_frame_url =
      child_frame_origin_type ==
              InnerWebContentsAttachChildFrameOriginType::kSameOriginAboutBlank
          ? GURL(url::kAboutBlankURL)
          : child_frame_origin_type ==
                    InnerWebContentsAttachChildFrameOriginType::kSameOriginOther
                ? embedded_test_server()->GetURL("a.com", "/title1.html")
                : embedded_test_server()->GetURL("b.com", "/title1.html");
  SCOPED_TRACE(testing::Message()
               << " Child frame URL:" << child_frame_url.spec()
               << " 'beforeunload' modal shown: " << test_beforeunload
               << " proceed through'beforeunload':  "
               << proceed_through_beforeunload);
  auto* child_node = web_contents()->GetPrimaryFrameTree().root()->child_at(0);
  EXPECT_TRUE(NavigateToURLFromRenderer(child_node, child_frame_url));
  if (test_beforeunload) {
    EXPECT_TRUE(ExecJs(child_node,
                       "window.addEventListener('beforeunload', (e) => {"
                       "e.preventDefault(); return e; });"));
  }
  auto* original_child_frame = child_node->current_frame_host();
  RenderFrameDeletedObserver original_child_frame_observer(
      original_child_frame);
  AppModalDialogWaiter dialog_waiter(shell());
  PrepareFrameJob prepare_job(original_child_frame,
                              proceed_through_beforeunload);
  if (test_beforeunload)
    dialog_waiter.Wait();
  prepare_job.WaitForPreparedFrame();
  auto* new_render_frame_host = prepare_job.prepared_frame();
  bool did_prepare_frame = new_render_frame_host;
  bool same_frame_used = (new_render_frame_host == original_child_frame);
  // If a frame was not prepared, then it has to be due to beforeunload being
  // dismissed.
  ASSERT_TRUE(did_prepare_frame ||
              (test_beforeunload && !proceed_through_beforeunload));
  // If the original frame is in the same SiteInstance as its parent, then it
  // can be reused; otherwise a new frame is expected here.
  bool is_same_origin =
      child_frame_origin_type !=
      InnerWebContentsAttachChildFrameOriginType::kCrossOrigin;
  if (!is_same_origin && did_prepare_frame) {
    // For the cross-origin case we expect the original RenderFrameHost to go
    // away during preparation.
    original_child_frame_observer.WaitUntilDeleted();
  }
  ASSERT_TRUE(!did_prepare_frame || (is_same_origin == same_frame_used));
  ASSERT_TRUE(!did_prepare_frame ||
              (original_child_frame_observer.deleted() != is_same_origin));
  // Finally, try the WebContents attach API and make sure we are doing OK.
  if (new_render_frame_host)
    CreateAndAttachInnerContents(new_render_frame_host);
}

INSTANTIATE_TEST_SUITE_P(
    SitePerProcess,
    InnerWebContentsAttachTest,
    testing::Combine(
        testing::ValuesIn(
            {InnerWebContentsAttachChildFrameOriginType::kSameOriginAboutBlank,
             InnerWebContentsAttachChildFrameOriginType::kSameOriginOther,
             InnerWebContentsAttachChildFrameOriginType::kCrossOrigin}),
        testing::Bool(),
        testing::Bool()));

// This checks what process is used when an iframe is navigated to about:blank.
// The new document should be loaded in the process of its initiator.
//
// Test case:
// 1. Navigate to A1(B2).
// 2. B2 navigates itself to B3 = about:blank. Process B is used.
// 3. A1 makes B3 to navigate to A4 = about:blank. Process A is used.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       SameAndCrossProcessIframeAboutBlankNavigation) {
  // 1. Navigate to A1(B2).
  GURL a1_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)"));
  EXPECT_TRUE(NavigateToURL(shell(), a1_url));
  RenderFrameHostImpl* a1_rfh = web_contents()->GetPrimaryMainFrame();
  RenderFrameHostImpl* b2_rfh = a1_rfh->child_at(0)->current_frame_host();

  // 2. B2 navigates itself to B3 = about:blank. Process B is used.
  {
    scoped_refptr<SiteInstance> b2_site_instance = b2_rfh->GetSiteInstance();
    TestNavigationManager navigation_manager(web_contents(),
                                             GURL("about:blank"));
    EXPECT_TRUE(ExecJs(b2_rfh, "location.href = 'about:blank';"));
    ASSERT_TRUE(navigation_manager.WaitForNavigationFinished());

    RenderFrameHostImpl* b3_rfh = a1_rfh->child_at(0)->current_frame_host();
    DCHECK_EQ(b3_rfh->GetSiteInstance(), b2_site_instance);
    DCHECK_NE(a1_rfh->GetProcess(), b3_rfh->GetProcess());
  }

  // 3. A1 makes B3 to navigate to A4 = about:blank. Process A is used.
  {
    TestNavigationManager navigation_manager(web_contents(),
                                             GURL("about:blank"));
    EXPECT_TRUE(ExecJs(a1_rfh, R"(
      document.querySelector("iframe").src = "about:blank";
    )"));
    ASSERT_TRUE(navigation_manager.WaitForNavigationFinished());

    RenderFrameHostImpl* b4_rfh = a1_rfh->child_at(0)->current_frame_host();
    DCHECK_EQ(a1_rfh->GetSiteInstance(), b4_rfh->GetSiteInstance());
  }
}

// TODO(crbug.com/425866013): Fix and re-enable flaky test.
#if BUILDFLAG(IS_FUCHSIA)
#define MAYBE_AccessWindowProxyOfCrashedFrameAfterNavigation \
  DISABLED_AccessWindowProxyOfCrashedFrameAfterNavigation
#else
#define MAYBE_AccessWindowProxyOfCrashedFrameAfterNavigation \
  AccessWindowProxyOfCrashedFrameAfterNavigation
#endif
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       MAYBE_AccessWindowProxyOfCrashedFrameAfterNavigation) {
  EXPECT_TRUE(NavigateToURL(
      shell(), embedded_test_server()->GetURL("a.com", "/title1.html")));
  const GURL cross_site_url =
      embedded_test_server()->GetURL("b.com", "/title1.html");
  TestNavigationObserver observer(cross_site_url);
  observer.StartWatchingNewWebContents();
  EXPECT_TRUE(ExecJs(
      shell(), JsReplace("openedWindow = window.open($1)", cross_site_url)));
  observer.WaitForNavigationFinished();

  EXPECT_EQ(2u, Shell::windows().size());
  CrashTab(Shell::windows()[1]->web_contents());

  // When starting a navigation in a crashed frame, the navigation code
  // immediately swaps in the speculative RFH.
  EXPECT_TRUE(
      ExecJs(shell(), "openedWindow.location = 'data:text/html,content'"));
  // The early-swapped frame should not be scriptable from another frame--nor
  // should trying to script it result in a crash.
  std::string result =
      EvalJs(shell(),
             "try { openedWindow.document } catch (e) { e.toString(); }")
          .ExtractString();
  EXPECT_THAT(
      result,
      ::testing::MatchesRegex(
          "SecurityError: Failed to read a named property 'document' from "
          "'Window': Blocked a frame with origin \"http://a.com:\\d+\" "
          "from accessing a cross-origin frame."));
}

// Make sure that a popup with a cross site subframe can be closed from the
// subframe.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest, CloseNoopenerWindow) {
  GURL main_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  // Open a same site popup with a subframe using the noopener ref.
  GURL popup_url(
      embedded_test_server()->GetURL("a.com", "/page_with_blank_iframe.html"));
  ShellAddedObserver new_shell_observer;
  EXPECT_TRUE(ExecJs(
      shell(),
      JsReplace("popup = window.open($1,'_blank','noopener');", popup_url)));
  Shell* popup = new_shell_observer.GetShell();
  WebContentsImpl* popup_web_contents =
      static_cast<WebContentsImpl*>(popup->web_contents());
  FrameTreeNode* popup_root = popup_web_contents->GetPrimaryFrameTree().root();
  EXPECT_TRUE(WaitForLoadStop(popup_web_contents));

  // Navigate the popup subframe cross site to b.com.
  FrameTreeNode* child = popup_root->child_at(0);
  GURL cross_origin_url(
      embedded_test_server()->GetURL("b.com", "/title1.html"));
  EXPECT_TRUE(NavigateToURLFromRenderer(child, cross_origin_url));

  // Check that the popup successfully closes from the subframe.
  WebContentsDestroyedWatcher destroyed_watcher(popup->web_contents());
  EXPECT_TRUE(ExecJs(child, "window.parent.close()"));
  destroyed_watcher.Wait();
}

// Check that initial navigations to renderer debug URLs mark the renderer
// process as used, so that future navigations to sites that require a
// dedicated process do not reuse that process.
IN_PROC_BROWSER_TEST_P(
    SitePerProcessBrowserTest,
    ProcessNotReusedAfterInitialNavigationToRendererDebugURL) {
  // Load a javascript URL, which is a renderer debug URL.  This navigation
  // won't commit, but the renderer process will synchronously process the
  // javascript URL and install an HTML document that contains "foo".
  GURL javascript_url("javascript:'foo'");
  shell()->LoadURL(javascript_url);
  EXPECT_EQ("foo", EvalJs(shell(), "document.body.innerText"));

  RenderProcessHost* js_process =
      web_contents()->GetPrimaryMainFrame()->GetProcess();

  // Because the javascript URL can run arbitrary scripts in the renderer
  // process, it is unsafe to reuse the renderer process later for navigations
  // to sites that require a dedicated process.  Ensure that this is the case.
  EXPECT_FALSE(js_process->IsUnused());

  EXPECT_TRUE(NavigateToURL(
      shell(), embedded_test_server()->GetURL("a.com", "/title1.html")));
  EXPECT_NE(js_process, web_contents()->GetPrimaryMainFrame()->GetProcess());
}

namespace {

void CheckStickyUserActivationState(RenderFrameHostImpl* host, bool expected) {
  EXPECT_EQ(expected, host->HasStickyUserActivation());
  EXPECT_EQ(expected, EvalJs(host, "navigator.userActivation.hasBeenActive",
                             EXECUTE_SCRIPT_NO_USER_GESTURE));
}

}  // namespace

// Test that a cross-site navigation in an iframe clears user activation.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       UserActivationAfterCrossSiteNavInIframe) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  // It is safe to obtain the root frame tree node here, as it doesn't change.
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  FrameTreeNode* child = root->child_at(0);

  // Sanity check that there is no sticky user activation at first.
  CheckStickyUserActivationState(child->current_frame_host(), false);

  // Load cross-site page into iframe and verify there is still no sticky user
  // activation.
  GURL first_http_url(embedded_test_server()->GetURL("d.com", "/title1.html"));
  EXPECT_TRUE(
      NavigateToURLFromRendererWithoutUserGesture(child, first_http_url));
  CheckStickyUserActivationState(child->current_frame_host(), false);

  // Give the child iframe user activation.
  EXPECT_TRUE(ExecJs(child, "// No-op script"));
  CheckStickyUserActivationState(child->current_frame_host(), true);

  // Perform another cross-site navigation in the iframe.
  GURL http_url(embedded_test_server()->GetURL("c.com", "/title1.html"));
  EXPECT_TRUE(NavigateToURLFromRendererWithoutUserGesture(child, http_url));

  // The cross-site navigation should have cleared the user activation.
  CheckStickyUserActivationState(child->current_frame_host(), false);

  // Ensure that a top-level navigation from the iframe cannot happen.
  EXPECT_TRUE(ExecJs(child->current_frame_host(),
                     JsReplace("window.open($1, $2)", http_url, "_top"),
                     EXECUTE_SCRIPT_NO_USER_GESTURE));
  EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
  EXPECT_NE(http_url, shell()->web_contents()->GetLastCommittedURL());
}

// Test that a same-site cross-origin navigation in an iframe keeps user
// activation.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       UserActivationAfterSameSiteNavInIframe) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  // It is safe to obtain the root frame tree node here, as it doesn't change.
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  FrameTreeNode* child = root->child_at(0);

  // Sanity check that there is no sticky user activation at first.
  CheckStickyUserActivationState(child->current_frame_host(), false);

  // Load cross-origin same-site page into iframe and verify there is still no
  // sticky user activation.
  GURL first_http_url(
      embedded_test_server()->GetURL("subdomain.b.com", "/title1.html"));
  EXPECT_TRUE(
      NavigateToURLFromRendererWithoutUserGesture(child, first_http_url));
  CheckStickyUserActivationState(child->current_frame_host(), false);

  // Give the child iframe user activation.
  EXPECT_TRUE(ExecJs(child, "// No-op script"));
  CheckStickyUserActivationState(child->current_frame_host(), true);

  // Perform another same-site navigation in the iframe.
  GURL http_url(embedded_test_server()->GetURL("b.com", "/title1.html"));
  EXPECT_TRUE(NavigateToURLFromRendererWithoutUserGesture(child, http_url));

  // The cross-origin same-site navigation should keep the sticky user
  // activation from the previous page.
  CheckStickyUserActivationState(child->current_frame_host(), true);

  // Ensure that a top-level navigation from the iframe can still happen.
  EXPECT_TRUE(ExecJs(child->current_frame_host(),
                     JsReplace("window.open($1, $2)", http_url, "_top"),
                     EXECUTE_SCRIPT_NO_USER_GESTURE));
  EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
  EXPECT_EQ(http_url, shell()->web_contents()->GetLastCommittedURL());
}

// Test that a same-origin navigation in an iframe keeps user activation.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       UserActivationAfterSameOriginNavInIframe) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  // It is safe to obtain the root frame tree node here, as it doesn't change.
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  FrameTreeNode* child = root->child_at(0);

  // Sanity check that there is no sticky user activation at first.
  CheckStickyUserActivationState(child->current_frame_host(), false);

  // Load cross-site page into iframe and verify there is still no sticky user
  // activation.
  GURL first_http_url(embedded_test_server()->GetURL("c.com", "/title1.html"));
  EXPECT_TRUE(NavigateIframeToURL(web_contents(), "child-0", first_http_url));
  CheckStickyUserActivationState(child->current_frame_host(), false);

  // Give the child iframe user activation.
  EXPECT_TRUE(ExecJs(child, "// No-op script"));
  CheckStickyUserActivationState(child->current_frame_host(), true);

  // Load same-origin page into iframe.
  GURL http_url(embedded_test_server()->GetURL("c.com", "/title2.html"));
  EXPECT_TRUE(NavigateIframeToURL(web_contents(), "child-0", http_url));

  // The same-origin navigation should keep the sticky user activation from the
  // previous page.
  CheckStickyUserActivationState(child->current_frame_host(), true);

  // Ensure that a top-level navigation from the iframe can still happen.
  EXPECT_TRUE(ExecJs(child->current_frame_host(),
                     JsReplace("window.open($1, $2)", http_url, "_top"),
                     EXECUTE_SCRIPT_NO_USER_GESTURE));
  EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
  EXPECT_EQ(http_url, shell()->web_contents()->GetLastCommittedURL());
}

class StickyActivationAcrossSameOriginNavBrowserTest
    : public SitePerProcessBrowserTest {
 public:
  StickyActivationAcrossSameOriginNavBrowserTest() {
    scoped_feature_list_.InitAndEnableFeature(
        blink::features::kStickyUserActivationAcrossSameOriginNavigation);
  }

 private:
  base::test::ScopedFeatureList scoped_feature_list_;
};

// Test that a cross-site navigation in the top frame clears user activation.
IN_PROC_BROWSER_TEST_P(StickyActivationAcrossSameOriginNavBrowserTest,
                       UserActivationAfterCrossSiteNavInTopFrame) {
  GURL starting_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
  EXPECT_TRUE(NavigateToURL(shell(), starting_url));
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();

  // Sanity check that there is no sticky user activation at first.
  CheckStickyUserActivationState(root->current_frame_host(), false);

  // Perform a cross-site navigation and verify there is still no sticky user
  // activation.
  GURL first_nav_url(embedded_test_server()->GetURL("b.com", "/title1.html"));
  EXPECT_TRUE(
      NavigateToURLFromRendererWithoutUserGesture(shell(), first_nav_url));
  CheckStickyUserActivationState(root->current_frame_host(), false);

  // Give the frame user activation.
  EXPECT_TRUE(ExecJs(root, "// No-op script"));
  CheckStickyUserActivationState(root->current_frame_host(), true);

  // Perform another cross-site navigation.
  GURL second_nav_url(embedded_test_server()->GetURL(
      "c.com", "/cross_site_iframe_factory.html?c(c)"));
  EXPECT_TRUE(
      NavigateToURLFromRendererWithoutUserGesture(shell(), second_nav_url));

  // The navigation should have cleared the user activation.
  CheckStickyUserActivationState(root->current_frame_host(), false);
  CheckStickyUserActivationState(root->child_at(0)->current_frame_host(),
                                 false);
}

// Test that a same-site cross-origin navigation in the top frame clears user
// activation.
IN_PROC_BROWSER_TEST_P(StickyActivationAcrossSameOriginNavBrowserTest,
                       UserActivationAfterSameSiteNavInTopFrame) {
  GURL starting_url(
      embedded_test_server()->GetURL("sub1.a.com", "/title1.html"));
  EXPECT_TRUE(NavigateToURL(shell(), starting_url));
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();

  // Sanity check that there is no sticky user activation at first.
  CheckStickyUserActivationState(root->current_frame_host(), false);

  // Perform a same-site cross-origin navigation and verify there is still no
  // sticky user activation.
  GURL first_nav_url(
      embedded_test_server()->GetURL("sub2.a.com", "/title1.html"));
  EXPECT_TRUE(
      NavigateToURLFromRendererWithoutUserGesture(shell(), first_nav_url));
  CheckStickyUserActivationState(root->current_frame_host(), false);

  // Give the frame user activation.
  EXPECT_TRUE(ExecJs(root, "// No-op script"));
  CheckStickyUserActivationState(root->current_frame_host(), true);

  // Perform another same-site cross-origin navigation in the iframe.
  GURL second_nav_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(a)"));
  EXPECT_TRUE(
      NavigateToURLFromRendererWithoutUserGesture(shell(), second_nav_url));

  // The navigation should have cleared the user activation.
  CheckStickyUserActivationState(root->current_frame_host(), false);
  CheckStickyUserActivationState(root->child_at(0)->current_frame_host(),
                                 false);
}

// Test that a same-origin navigation in the top frame keeps user activation.
IN_PROC_BROWSER_TEST_P(StickyActivationAcrossSameOriginNavBrowserTest,
                       UserActivationAfterSameOriginNavInTopFrame) {
  GURL starting_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
  EXPECT_TRUE(NavigateToURL(shell(), starting_url));
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();

  // Sanity check that there is no sticky user activation at first.
  CheckStickyUserActivationState(root->current_frame_host(), false);

  // Perform a same-origin navigation and verify there is still no sticky user
  // activation.
  GURL first_nav_url(embedded_test_server()->GetURL("a.com", "/title2.html"));
  EXPECT_TRUE(
      NavigateToURLFromRendererWithoutUserGesture(shell(), first_nav_url));
  CheckStickyUserActivationState(root->current_frame_host(), false);

  // Give the frame user activation.
  EXPECT_TRUE(ExecJs(root, "// No-op script"));
  CheckStickyUserActivationState(root->current_frame_host(), true);

  // Perform another same-origin navigation in the iframe.
  GURL second_nav_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(a)"));
  EXPECT_TRUE(
      NavigateToURLFromRendererWithoutUserGesture(shell(), second_nav_url));

  // The navigation should keep the user activation at the top frame only.
  CheckStickyUserActivationState(root->current_frame_host(), true);
  CheckStickyUserActivationState(root->child_at(0)->current_frame_host(),
                                 false);
}

// Test which captures behavior of navigation to about:blank in a newly created
// WebContents when an initial SiteInstance is supplied as part of the creation.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       AboutBlankInNewWindowWithInitialSiteInstance) {
  // Start by navigating to a page on a normal web site.
  EXPECT_TRUE(
      NavigateToURL(shell(), embedded_test_server()->GetURL("/empty.html")));

  // Now do a browser-initiated navigation to about:blank in a new tab created
  // in the previous SiteInstance. The current behavior is for the navigation
  // to switch to a new SiteInstance, though there is no real requirement for
  // that. In the past the existing SiteInstance was used.
  WebContents::CreateParams new_contents_params(
      web_contents()->GetBrowserContext(), web_contents()->GetSiteInstance());
  std::unique_ptr<WebContents> new_web_contents(
      WebContents::Create(new_contents_params));

  EXPECT_TRUE(NavigateToURL(new_web_contents.get(), GURL(url::kAboutBlankURL)));
  EXPECT_NE(web_contents()->GetPrimaryMainFrame()->GetProcess(),
            new_web_contents->GetPrimaryMainFrame()->GetProcess());
}

// Tests that verify the feature disabling process reuse.
class DisableProcessReusePolicyTest : public SitePerProcessBrowserTest {
 public:
  DisableProcessReusePolicyTest() {
    scoped_feature_list_.InitAndEnableFeature(features::kDisableProcessReuse);
  }
  ~DisableProcessReusePolicyTest() override = default;

  DisableProcessReusePolicyTest(const DisableProcessReusePolicyTest&) = delete;
  DisableProcessReusePolicyTest& operator=(
      const DisableProcessReusePolicyTest&) = delete;

 private:
  base::test::ScopedFeatureList scoped_feature_list_;
};

// In two tabs with the same site, open a cross site iframe in each (same site
// for the iframes). Make sure these do not have the same process ID.
IN_PROC_BROWSER_TEST_P(DisableProcessReusePolicyTest,
                       DisableProcessReusePolicy) {
  GURL url(
      embedded_test_server()->GetURL("www.foo.com", "/page_with_iframe.html"));
  EXPECT_TRUE(NavigateToURL(shell(), url));
  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  FrameTreeNode* child = root->child_at(0);

  // Navigate the subframe cross site, and make sure it is an OOPIF.
  GURL cross_site_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
  TestNavigationObserver observer(shell()->web_contents());
  EXPECT_TRUE(NavigateToURLFromRenderer(child, cross_site_url));
  EXPECT_TRUE(child->current_frame_host()->IsCrossProcessSubframe());

  // Open an new tab in a separate BrowsingInstance with the same url as the
  // first tab and open a subframe, also to |cross_site_url|.
  Shell* second_shell = CreateBrowser();
  EXPECT_TRUE(NavigateToURL(second_shell, url));
  FrameTreeNode* second_root =
      static_cast<WebContentsImpl*>(second_shell->web_contents())
          ->GetPrimaryFrameTree()
          .root();
  FrameTreeNode* second_child = second_root->child_at(0);
  EXPECT_TRUE(NavigateToURLFromRenderer(second_child, cross_site_url));
  EXPECT_TRUE(second_child->current_frame_host()->IsCrossProcessSubframe());

  scoped_refptr<SiteInstanceImpl> second_shell_instance =
      second_child->current_frame_host()->GetSiteInstance();
  EXPECT_NE(ProcessReusePolicy::kReusePendingOrCommittedSiteWorker,
            second_shell_instance->process_reuse_policy());
  EXPECT_NE(ProcessReusePolicy::kReusePendingOrCommittedSiteSubframe,
            second_shell_instance->process_reuse_policy());

  EXPECT_NE(child->current_frame_host()->GetProcess(),
            second_child->current_frame_host()->GetProcess());
}

class SitePerProcessWithMainFrameThresholdTestBase
    : public SitePerProcessBrowserTestBase {
 public:
  static constexpr size_t kDefaultThreshold = 3;

  explicit SitePerProcessWithMainFrameThresholdTestBase(
      size_t frame_threshold = kDefaultThreshold,
      size_t total_memory_threshold = 0) {
    base::FieldTrialParams params = {
        {"ProcessPerSiteMainFrameThreshold",
         base::StringPrintf("%zu", frame_threshold)}};
    if (total_memory_threshold != 0) {
      params["ProcessPerSiteMainFrameTotalMemoryLimit"] =
          base::StringPrintf("%zu", total_memory_threshold);
    }
    scoped_feature_list_.InitAndEnableFeatureWithParameters(
        features::kProcessPerSiteUpToMainFrameThreshold, params);
  }
  ~SitePerProcessWithMainFrameThresholdTestBase() override = default;

  Shell* CreateShellAndNavigateToURL(const GURL& url) {
    const GURL kOtherUrl =
        embedded_test_server()->GetURL("bar.test", "/title1.html");

    Shell* shell = CreateBrowser();
    // Navigate to a different site first so that the new shell has  a non empty
    // site info before navigating to the target site.
    // TODO(crbug.com/40264958): Remove this workaround once we figure
    // out how to handle navigation from an empty site to a new site.
    CHECK(NavigateToURL(shell, kOtherUrl));
    CHECK(NavigateToURL(shell, url));
    return shell;
  }

 private:
  base::test::ScopedFeatureList scoped_feature_list_;
};

class SitePerProcessWithMainFrameThresholdTest
    : public SitePerProcessWithMainFrameThresholdTestBase,
      public ::testing::WithParamInterface<std::string> {
 public:
  SitePerProcessWithMainFrameThresholdTest() = default;
  ~SitePerProcessWithMainFrameThresholdTest() override = default;
};

// Tests that a RenderProcessHost is reused up to a certain threshold against
// number of main frames, if the corresponding SiteInstance requires a dedicated
// process. Subframes are irrelevant to the threshold. Once the number of main
// frame reaches to the threshold, a new RenderProcessHost should be created and
// the existing RenderProcessHost should not be reused.
IN_PROC_BROWSER_TEST_P(SitePerProcessWithMainFrameThresholdTest,
                       ReuseProcessUpToThreshold) {
  const GURL kUrl =
      embedded_test_server()->GetURL("foo.test", "/page_with_iframe.html");
  const GURL kOtherUrl =
      embedded_test_server()->GetURL("bar.test", "/title1.html");

  ASSERT_TRUE(NavigateToURL(shell(), kUrl));
  RenderFrameHostImpl* main_frame_in_main_shell =
      static_cast<WebContentsImpl*>(shell()->web_contents())
          ->GetPrimaryMainFrame();
  RenderFrameHostImpl* subframe_in_main_shell =
      main_frame_in_main_shell->child_at(0)->current_frame_host();
  ASSERT_EQ(main_frame_in_main_shell->GetProcess(),
            subframe_in_main_shell->GetProcess());

  std::vector<Shell*> shells;
  for (size_t i = 0; i < kDefaultThreshold - 1; ++i) {
    Shell* new_shell = CreateShellAndNavigateToURL(kUrl);
    RenderFrameHostImpl* new_frame =
        static_cast<WebContentsImpl*>(new_shell->web_contents())
            ->GetPrimaryMainFrame();
    // Currently the reuse policy is only applied for sites that require a
    // dedicated process, and if this not the case, the two main frames won't
    // share a process due to being under the process limit.
    if (main_frame_in_main_shell->GetSiteInstance()
            ->RequiresDedicatedProcess()) {
      ASSERT_EQ(main_frame_in_main_shell->GetProcess(),
                new_frame->GetProcess());
    } else {
      ASSERT_NE(main_frame_in_main_shell->GetProcess(),
                new_frame->GetProcess());
    }
    shells.emplace_back(new_shell);
  }

  Shell* non_shared_shell = CreateBrowser();
  // TODO(crbug.com/40264958): Remove this workaround once we figure
  // out how to handle navigation from an empty site to a new site.
  ASSERT_TRUE(NavigateToURL(non_shared_shell, kOtherUrl));
  ASSERT_TRUE(NavigateToURL(non_shared_shell, kUrl));
  RenderFrameHostImpl* main_frame_in_non_shared_frame =
      static_cast<WebContentsImpl*>(non_shared_shell->web_contents())
          ->GetPrimaryMainFrame();
  ASSERT_NE(main_frame_in_main_shell->GetProcess(),
            main_frame_in_non_shared_frame->GetProcess());
  shells.emplace_back(non_shared_shell);

  for (auto*& shell : shells) {
    shell->Close();
  }
}

// Tests that renderer process is not reused when it hangs:
// 1. For OOP iframe in a different tab;
// 2. For main frame in a different tab.
IN_PROC_BROWSER_TEST_P(SitePerProcessWithMainFrameThresholdTest,
                       DoNotReuseRenderProcessAfterHung) {
  const GURL kUrl_a_b(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)"));

  const GURL kUrl_c_b(embedded_test_server()->GetURL(
      "c.com", "/cross_site_iframe_factory.html?c(b)"));

  const GURL kUrl_b(embedded_test_server()->GetURL("b.com", "/title1.html"));

  // Ensure the reuse of processes for same-site URLs, to test
  // that the process is not reused when it becomes unresponsive.
  RenderProcessHost::SetMaxRendererProcessCount(1);

  ASSERT_TRUE(NavigateToURL(shell(), kUrl_a_b));
  RenderFrameHostImpl* main_frame =
      static_cast<WebContentsImpl*>(shell()->web_contents())
          ->GetPrimaryMainFrame();
  RenderFrameHostImpl* subframe = main_frame->child_at(0)->current_frame_host();
  RenderProcessHost* main_frame_process = main_frame->GetProcess();
  RenderProcessHost* b_subframe_process = subframe->GetProcess();
  ASSERT_NE(main_frame_process, b_subframe_process);

  // Hang b.com process with OOP iframe.
  {
    UnresponsiveRendererObserver unresponsive_renderer_observer(
        shell()->web_contents());

    // This is to simulate renderer hung event. Class
    // SimulateUnresponsiveRenderer does not work here, because it hits only
    // WebContents, while we need widget to know that it is unresponsive.
    static_cast<RenderWidgetHostImpl*>(subframe->GetRenderWidgetHost())
        ->OnInputEventAckTimeout(base::TimeTicks::Now() +
                                 input::kHungRendererDelay);

    RenderProcessHost* hung_process = unresponsive_renderer_observer.Wait();
    EXPECT_EQ(hung_process, b_subframe_process);
  }

  // 1. Navigate to url with b.com iframe, for which process is unresponsive.
  Shell* cb_shell = CreateShellAndNavigateToURL(kUrl_c_b);
  RenderFrameHostImpl* cb_main_frame =
      static_cast<WebContentsImpl*>(cb_shell->web_contents())
          ->GetPrimaryMainFrame();

  RenderFrameHostImpl* cb_subframe =
      cb_main_frame->child_at(0)->current_frame_host();

  // Check that b.com iframe is not reusing existing unresponsive process with
  // b.com.
  ASSERT_NE(b_subframe_process, cb_subframe->GetProcess());

  // 2. Navigate main frame to b.com, for which process is unresponsive.
  Shell* b_shell = CreateShellAndNavigateToURL(kUrl_b);
  RenderFrameHostImpl* b_main_frame =
      static_cast<WebContentsImpl*>(b_shell->web_contents())
          ->GetPrimaryMainFrame();

  // Check that b.com main frame is not reusing existing unresponsive process
  // with b.com.
  ASSERT_NE(b_subframe_process, b_main_frame->GetProcess());
}

// Test fixture that enables kProcessPerSiteUpToMainFrameThreshold and sets up
// a SitePerProcessWithMainFrameThresholdAndSiteRestrictionBrowserClient to
// restrict the sites for which ProcessPerSite is used.
class SitePerProcessWithMainFrameThresholdAndSiteRestrictionTest
    : public SitePerProcessWithMainFrameThresholdTest {
 public:
  SitePerProcessWithMainFrameThresholdAndSiteRestrictionTest() {
    // Initialize both features in a single call
    scoped_feature_list_.InitAndEnableFeature(
        features::kProcessPerSiteUpToMainFrameThreshold);
  }

  void SetUpOnMainThread() override {
    SitePerProcessWithMainFrameThresholdTest::SetUpOnMainThread();
    test_client_ = std::make_unique<
        SitePerProcessWithMainFrameThresholdAndSiteRestrictionBrowserClient>();
  }

 private:
  base::test::ScopedFeatureList scoped_feature_list_;
  std::unique_ptr<
      SitePerProcessWithMainFrameThresholdAndSiteRestrictionBrowserClient>
      test_client_;
};

// Verify that ShouldReuseExistingProcessForNewMainFrameSiteInstance is honored
// when deciding whether to reuse a process for a main frame navigation under
// the threshold, provided the controlling feature flag is enabled.
IN_PROC_BROWSER_TEST_P(
    SitePerProcessWithMainFrameThresholdAndSiteRestrictionTest,
    RestrictedToURLWithContentClient) {
  GURL foo_url = embedded_test_server()->GetURL("foo.com", "/title1.html");
  GURL bar_url = embedded_test_server()->GetURL("bar.com", "/title2.html");

  auto* shell_foo1 = CreateShellAndNavigateToURL(foo_url);
  RenderProcessHost* rph_foo1 =
      shell_foo1->web_contents()->GetPrimaryMainFrame()->GetProcess();

  auto* shell_foo2 = CreateShellAndNavigateToURL(foo_url);
  RenderProcessHost* rph_foo2 =
      shell_foo2->web_contents()->GetPrimaryMainFrame()->GetProcess();

  // Verify foo.com reuse processes.
  EXPECT_EQ(rph_foo1, rph_foo2);

  auto* shell_bar1 = CreateShellAndNavigateToURL(bar_url);
  RenderProcessHost* rph_bar1 =
      shell_bar1->web_contents()->GetPrimaryMainFrame()->GetProcess();

  auto* shell_bar2 = CreateShellAndNavigateToURL(bar_url);
  RenderProcessHost* rph_bar2 =
      shell_bar2->web_contents()->GetPrimaryMainFrame()->GetProcess();

  // Verify bar.com did not reuse processes.
  EXPECT_NE(rph_bar1, rph_bar2);

  // Verify foo.com and bar.com are in different processes.
  EXPECT_NE(rph_foo1, rph_bar1);
  EXPECT_NE(rph_foo1, rph_bar2);
}

// Verify that ShouldReuseExistingProcessForNewMainFrameSiteInstance's
// path-specific logic, using the original_url, correctly assigns different
// processes to main frame navigations on the same domain but with different
// paths, under the kProcessPerSiteUpToMainFrameThreshold policy.
IN_PROC_BROWSER_TEST_P(
    SitePerProcessWithMainFrameThresholdAndSiteRestrictionTest,
    PathSpecificOriginalUrlReuse) {
  GURL foo_url_path = embedded_test_server()->GetURL("foo.com", "/title1.html");
  GURL foo_url_path_noreuse =
      embedded_test_server()->GetURL("foo.com", "/title2.html");
  // Navigate to foo.com/title1.html (matches client rule for reuse) however
  // foo.com/title2.html should not be reused since they have different paths.
  auto* shell_foo_url_path = CreateShellAndNavigateToURL(foo_url_path);
  RenderProcessHost* rph_foo_url_path =
      shell_foo_url_path->web_contents()->GetPrimaryMainFrame()->GetProcess();

  auto* shell_foo_url_path_noreuse =
      CreateShellAndNavigateToURL(foo_url_path_noreuse);
  RenderProcessHost* rph_foo_url_path_noreuse =
      shell_foo_url_path_noreuse->web_contents()
          ->GetPrimaryMainFrame()
          ->GetProcess();

  EXPECT_NE(rph_foo_url_path, rph_foo_url_path_noreuse);
}

// A test fixture that provides an upper limit of 4 bytes, so should fail the
// assignment of another outermost main frame into the process.
class SitePerProcessWithMainFrameThresholdWithTotalLimitTest
    : public SitePerProcessWithMainFrameThresholdTestBase,
      public ::testing::WithParamInterface<std::string> {
 public:
  SitePerProcessWithMainFrameThresholdWithTotalLimitTest()
      : SitePerProcessWithMainFrameThresholdTestBase(
            /*frame_threshold=*/10,
            /*total_memory_threshold=*/9) {}
  ~SitePerProcessWithMainFrameThresholdWithTotalLimitTest() override = default;
};

class RendererHostInterceptor
    : public mojom::RendererHostInterceptorForTesting {
 public:
  explicit RendererHostInterceptor(RenderProcessHostImpl* process_host)
      : swapped_impl_(process_host->renderer_host_receiver_for_testing(),
                      this) {}
  mojom::RendererHost* GetForwardingInterface() override {
    return swapped_impl_.old_impl();
  }

#if BUILDFLAG(IS_ANDROID)
  void SetPrivateMemoryFootprint(
      uint64_t private_memory_footprint_bytes) override {
    // Drop this message from the renderer.
  }
#endif

 private:
  mojo::test::ScopedSwapImplForTesting<mojom::RendererHost> swapped_impl_;
};

// Tests that a RenderProcessHost is not reused when the private memory
// footprint of the process exceeds a certain amount.
IN_PROC_BROWSER_TEST_P(SitePerProcessWithMainFrameThresholdWithTotalLimitTest,
                       ExcessiveAllocation) {
  const GURL kUrl =
      embedded_test_server()->GetURL("foo.test", "/page_with_iframe.html");

  base::HistogramTester histograms;
  ASSERT_TRUE(NavigateToURL(shell(), kUrl));
  RenderFrameHostImpl* main_frame_in_main_shell =
      static_cast<WebContentsImpl*>(shell()->web_contents())
          ->GetPrimaryMainFrame();
  RenderFrameHostImpl* subframe_in_main_shell =
      main_frame_in_main_shell->child_at(0)->current_frame_host();
  ASSERT_EQ(main_frame_in_main_shell->GetProcess(),
            subframe_in_main_shell->GetProcess());

  Shell* new_shell = CreateShellAndNavigateToURL(kUrl);
  RenderFrameHostImpl* new_frame =
      static_cast<WebContentsImpl*>(new_shell->web_contents())
          ->GetPrimaryMainFrame();
  ASSERT_NE(main_frame_in_main_shell->GetProcess(), new_frame->GetProcess());
  new_shell->Close();

  // Verify that we hit a limit histogram.
  histograms.ExpectTotalCount(
      "BrowserRenderProcessHost.ProcessPerSiteMainFrameLimit", 1);
  histograms.ExpectBucketCount(
      "BrowserRenderProcessHost.ProcessPerSiteMainFrameLimit", 1, 1);
}

// Tests that opening a fourth tab will put it over the limit and will allocate
// a new process. We allocate 3 main frames that are 2 bytes each. Placing
// a fourth would exceeded the limit of 9.
IN_PROC_BROWSER_TEST_P(SitePerProcessWithMainFrameThresholdWithTotalLimitTest,
                       AllowedAllocation) {
  const GURL kUrl =
      embedded_test_server()->GetURL("foo.test", "/page_with_iframe.html");

  base::HistogramTester histograms;
  ASSERT_TRUE(NavigateToURL(shell(), kUrl));
  RenderFrameHostImpl* main_frame_in_main_shell =
      static_cast<WebContentsImpl*>(shell()->web_contents())
          ->GetPrimaryMainFrame();
  RenderFrameHostImpl* subframe_in_main_shell =
      main_frame_in_main_shell->child_at(0)->current_frame_host();
  ASSERT_EQ(main_frame_in_main_shell->GetProcess(),
            subframe_in_main_shell->GetProcess());

  auto* process_host = static_cast<RenderProcessHostImpl*>(
      main_frame_in_main_shell->GetProcess());
  RendererHostInterceptor interceptor(process_host);
  process_host->SetPrivateMemoryFootprintForTesting(2);

  std::vector<Shell*> shells;
  for (size_t i = 0; i < 2; ++i) {
    Shell* new_shell = CreateShellAndNavigateToURL(kUrl);
    RenderFrameHostImpl* new_frame =
        static_cast<WebContentsImpl*>(new_shell->web_contents())
            ->GetPrimaryMainFrame();
    // Currently the reuse policy is only applied for sites that require a
    // dedicated process, and if this not the case, the two main frames won't
    // share a process due to being under the process limit.
    if (main_frame_in_main_shell->GetSiteInstance()
            ->RequiresDedicatedProcess()) {
      ASSERT_EQ(main_frame_in_main_shell->GetProcess(),
                new_frame->GetProcess());
    } else {
      ASSERT_NE(main_frame_in_main_shell->GetProcess(),
                new_frame->GetProcess());
    }
    process_host->SetPrivateMemoryFootprintForTesting(2 * (i + 2));
    shells.emplace_back(new_shell);
  }
  EXPECT_EQ(
      6u, main_frame_in_main_shell->GetProcess()->GetPrivateMemoryFootprint());

  // The 4th outermostmain frame will not fit.
  // The expected size of a frame will be 2, with a scale factor of 1.5
  // 6 + (2 * 1.5) > 9 so the check should fail.
  Shell* fourth_shell = CreateShellAndNavigateToURL(kUrl);
  RenderFrameHostImpl* fourth_frame =
      static_cast<WebContentsImpl*>(fourth_shell->web_contents())
          ->GetPrimaryMainFrame();
  ASSERT_NE(main_frame_in_main_shell->GetProcess(), fourth_frame->GetProcess());
  shells.emplace_back(fourth_shell);
  for (auto*& shell : shells) {
    shell->Close();
  }
  // Verify that we hit a limit histogram.
  histograms.ExpectTotalCount(
      "BrowserRenderProcessHost.ProcessPerSiteMainFrameLimit", 1);
  histograms.ExpectBucketCount(
      "BrowserRenderProcessHost.ProcessPerSiteMainFrameLimit", 3, 1);
}

// Tests that opening a new tab from an existing page via ctrl-click reuses a
// process when both pages are the same-site.
IN_PROC_BROWSER_TEST_P(SitePerProcessWithMainFrameThresholdTest,
                       ReuseProcessOpenTabByCtrlClickLink) {
  const GURL kUrl = embedded_test_server()->GetURL(
      "foo.test", "/ctrl-click-subframe-link.html");
  ASSERT_TRUE(NavigateToURL(shell(), kUrl));
  RenderFrameHostImpl* main_frame =
      static_cast<WebContentsImpl*>(shell()->web_contents())
          ->GetPrimaryMainFrame();
  ShellAddedObserver new_shell_observer;
  ASSERT_TRUE(ExecJs(main_frame,
                     "window.domAutomationController.send(ctrlClickLink());"));
  Shell* popup = new_shell_observer.GetShell();
  ASSERT_EQ(main_frame->GetProcess(),
            static_cast<WebContentsImpl*>(popup->web_contents())
                ->GetPrimaryMainFrame()
                ->GetProcess());
}

// Tests that opening a new tab from an existing page via window.open reuses a
// process when both pages are the same-site.
// TODO(crbug.com/40264958): Change this test to use 'noopener' once we
// figure out how to handle navigation from an empty site to a new site.
IN_PROC_BROWSER_TEST_P(SitePerProcessWithMainFrameThresholdTest,
                       ReuseProcessWithOpener) {
  const GURL kUrl = embedded_test_server()->GetURL("foo.test", "/title1.html");
  ASSERT_TRUE(NavigateToURL(shell(), kUrl));
  RenderFrameHostImpl* main_frame =
      static_cast<WebContentsImpl*>(shell()->web_contents())
          ->GetPrimaryMainFrame();
  ShellAddedObserver new_shell_observer;
  ASSERT_TRUE(
      ExecJs(main_frame, "popup = window.open('/title1.html', '_blank');"));
  Shell* popup = new_shell_observer.GetShell();
  ASSERT_EQ(main_frame->GetProcess(),
            static_cast<WebContentsImpl*>(popup->web_contents())
                ->GetPrimaryMainFrame()
                ->GetProcess());
}

class SitePerProcessWithMainFrameThresholdLocalhostTest
    : public SitePerProcessWithMainFrameThresholdTestBase,
      public ::testing::WithParamInterface<bool> {
 public:
  SitePerProcessWithMainFrameThresholdLocalhostTest() {
    std::vector<base::test::FeatureRefAndParams> enabled_features = {
        {features::kProcessPerSiteUpToMainFrameThreshold,
         {
             {"ProcessPerSiteMainFrameThreshold",
              base::StringPrintf("%zu", kDefaultThreshold)},
         }}};
    std::vector<base::test::FeatureRef> disabled_features;
    if (IsLocalhostAllowed()) {
      enabled_features.emplace_back(base::test::FeatureRefAndParams(
          features::kMainFrameProcessReuseAllowIPAndLocalhost, {}));
    } else {
      disabled_features.emplace_back(
          features::kMainFrameProcessReuseAllowIPAndLocalhost);
    }
    scoped_feature_list_.InitWithFeaturesAndParameters(enabled_features,
                                                       disabled_features);
  }
  ~SitePerProcessWithMainFrameThresholdLocalhostTest() override = default;

  bool IsLocalhostAllowed() { return GetParam(); }

 private:
  base::test::ScopedFeatureList scoped_feature_list_;
};

// Tests that process reuse is allowed or disallowed for localhost based on a
// feature parameter.
IN_PROC_BROWSER_TEST_P(SitePerProcessWithMainFrameThresholdLocalhostTest,
                       AllowReuseLocalHost) {
  const GURL kUrl = embedded_test_server()->GetURL("localhost", "/title1.html");
  ASSERT_TRUE(net::IsLocalHostname(kUrl.host()));

  ASSERT_TRUE(NavigateToURL(shell(), kUrl));
  Shell* second_shell = CreateShellAndNavigateToURL(kUrl);

  RenderFrameHostImpl* main_frame =
      static_cast<WebContentsImpl*>(shell()->web_contents())
          ->GetPrimaryMainFrame();
  RenderFrameHostImpl* second_frame =
      static_cast<WebContentsImpl*>(second_shell->web_contents())
          ->GetPrimaryMainFrame();
  if (IsLocalhostAllowed()) {
    ASSERT_EQ(main_frame->GetProcess(), second_frame->GetProcess());
  } else {
    ASSERT_NE(main_frame->GetProcess(), second_frame->GetProcess());
  }
}

class SitePerProcessWithMainFrameThresholdDevToolsTest
    : public SitePerProcessWithMainFrameThresholdTestBase,
      public TestDevToolsProtocolClient {
 public:
  SitePerProcessWithMainFrameThresholdDevToolsTest() = default;
  ~SitePerProcessWithMainFrameThresholdDevToolsTest() override = default;

  void TearDown() override {
    DetachProtocolClient();
    SitePerProcessWithMainFrameThresholdTestBase::TearDown();
  }
};

// Tests that process reuse is diallowed when DevTools is attached to the
// renderer process.
IN_PROC_BROWSER_TEST_F(SitePerProcessWithMainFrameThresholdDevToolsTest,
                       DevToolsAttached) {
  const GURL kUrl = embedded_test_server()->GetURL("foo.test", "/title1.html");

  ASSERT_TRUE(NavigateToURL(shell(), kUrl));

  AttachToWebContents(shell()->web_contents());
  set_agent_host_can_close();

  Shell* second_shell = CreateShellAndNavigateToURL(kUrl);
  RenderFrameHostImpl* main_frame =
      static_cast<WebContentsImpl*>(shell()->web_contents())
          ->GetPrimaryMainFrame();
  RenderFrameHostImpl* second_frame =
      static_cast<WebContentsImpl*>(second_shell->web_contents())
          ->GetPrimaryMainFrame();
  ASSERT_NE(main_frame->GetProcess(), second_frame->GetProcess());
}

// Helper class to enable subframe process reuse thresholds and set the total
// allowed memory limit to 8 bytes.
class SitePerProcessWithSubframeProcessReuseThresholdsTest
    : public SitePerProcessBrowserTestBase,
      public ::testing::WithParamInterface<std::string> {
 public:
  SitePerProcessWithSubframeProcessReuseThresholdsTest() {
    size_t total_memory_limit = 8;
    base::FieldTrialParams params = {
        {"SubframeProcessReuseMemoryThreshold",
         base::StringPrintf("%zu", total_memory_limit)}};
    scoped_feature_list_.InitAndEnableFeatureWithParameters(
        features::kSubframeProcessReuseThresholds, params);
  }
  ~SitePerProcessWithSubframeProcessReuseThresholdsTest() override = default;

 private:
  base::test::ScopedFeatureList scoped_feature_list_;
};

// Verify that a subframe will only reuse an existing process if adding
// another subframe to that process won't exceed the memory threshold.
IN_PROC_BROWSER_TEST_P(SitePerProcessWithSubframeProcessReuseThresholdsTest,
                       SubframeReuseRespectsMemoryThreshold) {
  base::HistogramTester histograms;

  // Start with a simple a(b) page.
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));
  RenderFrameHostImpl* main_frame1 =
      static_cast<WebContentsImpl*>(shell()->web_contents())
          ->GetPrimaryMainFrame();
  RenderFrameHostImpl* subframe1 =
      main_frame1->child_at(0)->current_frame_host();
  auto* subframe_process =
      static_cast<RenderProcessHostImpl*>(subframe1->GetProcess());
  ASSERT_NE(main_frame1->GetProcess(), subframe_process);

  // Ignore private memory footprint updates from the renderer, and pretend
  // that the subframe process's PMF is currently 5 bytes.
  RendererHostInterceptor interceptor(subframe_process);
  subframe_process->SetPrivateMemoryFootprintForTesting(5);

  // Create an unrelated tab and navigate it to a(b).
  Shell* shell2 = CreateBrowser();
  EXPECT_TRUE(NavigateToURL(shell2, main_url));
  RenderFrameHostImpl* main_frame2 =
      static_cast<WebContentsImpl*>(shell2->web_contents())
          ->GetPrimaryMainFrame();
  RenderFrameHostImpl* subframe2 =
      main_frame2->child_at(0)->current_frame_host();
  ASSERT_NE(main_frame2->GetProcess(), subframe2->GetProcess());

  // The new b.com subframe should reuse the available b.com process from the
  // first tab. This is because the process uses 5 bytes of memory, which is
  // below the reuse threshold of 8 bytes.
  EXPECT_EQ(subframe2->GetProcess(), subframe_process);

  // Update the subframe process's PMF to 10, pretending that the second
  // subframe also takes up 5 bytes.
  subframe_process->SetPrivateMemoryFootprintForTesting(10);

  // Create a third tab and navigate it to a(b).
  Shell* shell3 = CreateBrowser();
  EXPECT_TRUE(NavigateToURL(shell3, main_url));
  RenderFrameHostImpl* main_frame3 =
      static_cast<WebContentsImpl*>(shell3->web_contents())
          ->GetPrimaryMainFrame();
  RenderFrameHostImpl* subframe3 =
      main_frame3->child_at(0)->current_frame_host();
  ASSERT_NE(main_frame3->GetProcess(), subframe3->GetProcess());

  // This time, the new b.com subframe should not reuse the available b.com
  // process from the first two tabs. This is because the process is consuming
  // 10 bytes of memory, which is above the reuse threshold of 8 bytes.
  EXPECT_NE(subframe3->GetProcess(), subframe_process);

  // Check that the histogram was recorded when the memory threshold was
  // exceeded for `subframe_process`. At that time, the process should've had
  // two total frames.
  histograms.ExpectTotalCount(
      "BrowserRenderProcessHost.SubframeProcessReuseThreshold.TotalFrames", 1);
  histograms.ExpectBucketCount(
      "BrowserRenderProcessHost.SubframeProcessReuseThreshold.TotalFrames", 2,
      1);
}

class CrossProcessSubframeRenderProcessGoneLogger
    : public ContentBrowserTestContentBrowserClient {
 public:
  CrossProcessSubframeRenderProcessGoneLogger() = default;
  ~CrossProcessSubframeRenderProcessGoneLogger() override = default;

  void CrossProcessSubframeRenderProcessGone(
      RenderFrameHost* render_frame_host) override {
    crashed_rfhs_.push_back(render_frame_host);
  }

  const std::vector<RenderFrameHost*>& crashed_rfhs() const {
    return crashed_rfhs_;
  }

 private:
  std::vector<RenderFrameHost*> crashed_rfhs_;
};

// Test that when a process hosting multiple subframes dies,
// ContentBrowserClient::SubframeProcessGone is called for each of them.
IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                       CrossProcessSubframeRenderProcessGone) {
  // Install a client that counts the number of times
  // CrossProcessSubframeRenderProcessGone is called.
  CrossProcessSubframeRenderProcessGoneLogger test_client;
  web_contents()->OnWebPreferencesChanged();

  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b,b(c(b)))"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  FrameTreeNode* child1 = root->child_at(0);
  FrameTreeNode* child2 = root->child_at(1);
  FrameTreeNode* grandchild = child2->child_at(0);
  FrameTreeNode* great_grandchild = grandchild->child_at(0);

  RenderFrameHost* rfh_b1 = child1->current_frame_host();
  RenderFrameHost* rfh_b2 = child2->current_frame_host();
  RenderFrameHost* rfh_b3 = great_grandchild->current_frame_host();

  RenderProcessHost* b_process = child1->current_frame_host()->GetProcess();
  EXPECT_EQ(b_process, child2->current_frame_host()->GetProcess());
  EXPECT_EQ(b_process, great_grandchild->current_frame_host()->GetProcess());

  RenderProcessHostWatcher crash_observer(
      b_process, RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
  b_process->Shutdown(0);
  crash_observer.Wait();

  EXPECT_EQ(test_client.crashed_rfhs().size(), 2u);
  EXPECT_TRUE(base::Contains(test_client.crashed_rfhs(), rfh_b1));
  EXPECT_TRUE(base::Contains(test_client.crashed_rfhs(), rfh_b2));
  EXPECT_FALSE(base::Contains(test_client.crashed_rfhs(), rfh_b3));
}

INSTANTIATE_TEST_SUITE_P(All,
                         RequestDelayingSitePerProcessBrowserTest,
                         testing::ValuesIn(RenderDocumentFeatureLevelValues()));
#if BUILDFLAG(IS_ANDROID)
INSTANTIATE_TEST_SUITE_P(All,
                         SitePerProcessAndroidImeTest,
                         testing::ValuesIn(RenderDocumentFeatureLevelValues()));
INSTANTIATE_TEST_SUITE_P(All,
                         AndroidInputBrowserTest,
                         testing::ValuesIn(RenderDocumentFeatureLevelValues()));
INSTANTIATE_TEST_SUITE_P(All,
                         SitePerProcessBrowserTestWithSubframePriority,
                         testing::ValuesIn(RenderDocumentFeatureLevelValues()));
#endif  // BUILDFLAG(IS_ANDROID)
INSTANTIATE_TEST_SUITE_P(All,
                         SitePerProcessAndProcessPerSiteBrowserTest,
                         testing::ValuesIn(RenderDocumentFeatureLevelValues()));
INSTANTIATE_TEST_SUITE_P(All,
                         SitePerProcessAutoplayBrowserTest,
                         testing::ValuesIn(RenderDocumentFeatureLevelValues()));
INSTANTIATE_TEST_SUITE_P(All,
                         SitePerProcessBrowserTest,
                         testing::ValuesIn(RenderDocumentFeatureLevelValues()));
INSTANTIATE_TEST_SUITE_P(All,
                         SitePerProcessNoSharingBrowserTest,
                         testing::ValuesIn(RenderDocumentFeatureLevelValues()));
INSTANTIATE_TEST_SUITE_P(All,
                         SitePerProcessBrowserTestWithoutSpeculativeRFHDelay,
                         testing::ValuesIn(RenderDocumentFeatureLevelValues()));
INSTANTIATE_TEST_SUITE_P(All,
                         SitePerProcessBrowserTouchActionTest,
                         testing::ValuesIn(RenderDocumentFeatureLevelValues()));
INSTANTIATE_TEST_SUITE_P(All,
                         SitePerProcessIgnoreCertErrorsBrowserTest,
                         testing::ValuesIn(RenderDocumentFeatureLevelValues()));
INSTANTIATE_TEST_SUITE_P(All,
                         DisableProcessReusePolicyTest,
                         testing::ValuesIn(RenderDocumentFeatureLevelValues()));
INSTANTIATE_TEST_SUITE_P(All,
                         SitePerProcessWithMainFrameThresholdTest,
                         testing::ValuesIn(RenderDocumentFeatureLevelValues()));
INSTANTIATE_TEST_SUITE_P(All,
                         SitePerProcessWithMainFrameThresholdWithTotalLimitTest,
                         testing::ValuesIn(RenderDocumentFeatureLevelValues()));
#if BUILDFLAG(IS_ANDROID)
INSTANTIATE_TEST_SUITE_P(All,
                         TouchSelectionControllerClientAndroidSiteIsolationTest,
                         testing::ValuesIn(RenderDocumentFeatureLevelValues()));
#endif  // BUILDFLAG(IS_ANDROID)
INSTANTIATE_TEST_SUITE_P(All,
                         SitePerProcessBrowserTestWithLeakDetector,
                         testing::ValuesIn(RenderDocumentFeatureLevelValues()));

INSTANTIATE_TEST_SUITE_P(All,
                         SitePerProcessWithMainFrameThresholdLocalhostTest,
                         testing::Bool());

INSTANTIATE_TEST_SUITE_P(All,
                         SitePerProcessWithSubframeProcessReuseThresholdsTest,
                         testing::ValuesIn(RenderDocumentFeatureLevelValues()));

INSTANTIATE_TEST_SUITE_P(
    All,
    SitePerProcessWithMainFrameThresholdAndSiteRestrictionTest,
    testing::ValuesIn(RenderDocumentFeatureLevelValues()));
INSTANTIATE_TEST_SUITE_P(All,
                         StickyActivationAcrossSameOriginNavBrowserTest,
                         testing::ValuesIn(RenderDocumentFeatureLevelValues()));

}  // namespace content
