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

#include "content/browser/site_per_process_browsertest.h"

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

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

#include "base/bind.h"
#include "base/callback.h"
#include "base/command_line.h"
#include "base/feature_list.h"
#include "base/json/json_reader.h"
#include "base/location.h"
#include "base/memory/ptr_util.h"
#include "base/path_service.h"
#include "base/run_loop.h"
#include "base/scoped_observer.h"
#include "base/sequenced_task_runner.h"
#include "base/single_thread_task_runner.h"
#include "base/stl_util.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/utf_string_conversions.h"
#include "base/task/post_task.h"
#include "base/test/bind_test_util.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/test_timeouts.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "build/build_config.h"
#include "cc/input/touch_action.h"
#include "components/network_session_configurator/common/network_switches.h"
#include "components/viz/common/features.h"
#include "content/browser/child_process_security_policy_impl.h"
#include "content/browser/frame_host/cross_process_frame_connector.h"
#include "content/browser/frame_host/frame_navigation_entry.h"
#include "content/browser/frame_host/frame_tree.h"
#include "content/browser/frame_host/interstitial_page_impl.h"
#include "content/browser/frame_host/navigation_controller_impl.h"
#include "content/browser/frame_host/navigation_entry_impl.h"
#include "content/browser/frame_host/navigator.h"
#include "content/browser/frame_host/render_frame_host_impl.h"
#include "content/browser/frame_host/render_frame_proxy_host.h"
#include "content/browser/gpu/compositor_util.h"
#include "content/browser/loader/resource_dispatcher_host_impl.h"
#include "content/browser/renderer_host/input/input_router.h"
#include "content/browser/renderer_host/input/synthetic_gesture.h"
#include "content/browser/renderer_host/input/synthetic_gesture_target.h"
#include "content/browser/renderer_host/input/synthetic_smooth_scroll_gesture.h"
#include "content/browser/renderer_host/input/synthetic_tap_gesture.h"
#include "content/browser/renderer_host/input/synthetic_touchscreen_pinch_gesture.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_input_event_router.h"
#include "content/browser/renderer_host/render_widget_host_view_child_frame.h"
#include "content/browser/storage_partition_impl.h"
#include "content/browser/url_loader_factory_getter.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/common/frame_messages.h"
#include "content/common/input/actions_parser.h"
#include "content/common/input/synthetic_pinch_gesture_params.h"
#include "content/common/input_messages.h"
#include "content/common/renderer.mojom.h"
#include "content/common/view_messages.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/interstitial_page_delegate.h"
#include "content/public/browser/javascript_dialog_manager.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_types.h"
#include "content/public/browser/render_widget_host_observer.h"
#include "content/public/common/content_features.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/navigation_policy.h"
#include "content/public/common/url_constants.h"
#include "content/public/common/use_zoom_for_dsf_policy.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test_utils.h"
#include "content/public/test/hit_test_region_observer.h"
#include "content/public/test/navigation_handle_observer.h"
#include "content/public/test/test_frame_navigation_observer.h"
#include "content/public/test/test_navigation_observer.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/shell_switches.h"
#include "content/test/content_browser_test_utils_internal.h"
#include "content/test/did_commit_navigation_interceptor.h"
#include "ipc/constants.mojom.h"
#include "ipc/ipc_security_test_util.h"
#include "media/base/media_switches.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
#include "net/dns/mock_host_resolver.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 "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/feature_policy/feature_policy.h"
#include "third_party/blink/public/common/feature_policy/policy_value.h"
#include "third_party/blink/public/common/frame/sandbox_flags.h"
#include "third_party/blink/public/platform/web_input_event.h"
#include "third_party/blink/public/platform/web_insecure_request_policy.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/gesture_detection/gesture_configuration.h"
#include "ui/events/keycodes/dom/dom_code.h"
#include "ui/events/keycodes/dom/dom_key.h"
#include "ui/events/keycodes/dom/keycode_converter.h"
#include "ui/events/keycodes/keyboard_codes.h"
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/latency/latency_info.h"
#include "ui/native_theme/native_theme_features.h"

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

#if defined(OS_MACOSX)
#include "content/browser/renderer_host/input/synthetic_touchpad_pinch_gesture.h"
#include "ui/base/test/scoped_preferred_scroller_style_mac.h"
#endif

#if defined(OS_ANDROID)
#include "base/android/jni_android.h"
#include "base/android/jni_string.h"
#include "base/android/scoped_java_ref.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.h"
#include "ui/gfx/geometry/point_f.h"
#endif

#if defined(OS_CHROMEOS)
#include "ui/aura/env.h"
#include "ui/aura/test/test_screen.h"
#endif

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

namespace content {

namespace {

// 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 ExecuteScript below, or
  // else it might miss the message of interest.  See https://crbug.com/518729.
  DOMMessageQueue msg_queue;

  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::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;");
}

double GetFrameDeviceScaleFactor(const ToRenderFrameHost& adapter) {
  return EvalJs(adapter, "window.devicePixelRatio;").ExtractDouble();
}

class RedirectNotificationObserver : public NotificationObserver {
 public:
  // Register to listen for notifications of the given type from either a
  // specific source, or from all sources if |source| is
  // NotificationService::AllSources().
  RedirectNotificationObserver(int notification_type,
                               const NotificationSource& source);
  ~RedirectNotificationObserver() override;

  // Wait until the specified notification occurs.  If the notification was
  // emitted between the construction of this object and this call then it
  // returns immediately.
  void Wait();

  // Returns NotificationService::AllSources() if we haven't observed a
  // notification yet.
  const NotificationSource& source() const {
    return source_;
  }

  const NotificationDetails& details() const {
    return details_;
  }

  // NotificationObserver:
  void Observe(int type,
               const NotificationSource& source,
               const NotificationDetails& details) override;

 private:
  bool seen_;
  bool seen_twice_;
  bool running_;
  NotificationRegistrar registrar_;

  NotificationSource source_;
  NotificationDetails details_;
  base::RunLoop run_loop_;

  DISALLOW_COPY_AND_ASSIGN(RedirectNotificationObserver);
};

RedirectNotificationObserver::RedirectNotificationObserver(
    int notification_type,
    const NotificationSource& source)
    : seen_(false),
      running_(false),
      source_(NotificationService::AllSources()) {
  registrar_.Add(this, notification_type, source);
}

RedirectNotificationObserver::~RedirectNotificationObserver() {}

void RedirectNotificationObserver::Wait() {
  if (seen_ && seen_twice_)
    return;

  running_ = true;
  run_loop_.Run();
  EXPECT_TRUE(seen_);
}

void RedirectNotificationObserver::Observe(
    int type,
    const NotificationSource& source,
    const NotificationDetails& details) {
  source_ = source;
  details_ = details;
  seen_twice_ = seen_;
  seen_ = true;
  if (!running_)
    return;

  run_loop_.Quit();
  running_ = false;
}

// This observer keeps track of the number of created RenderFrameHosts.  Tests
// can use this to ensure that a certain number of child frames has been
// created after navigating.
class RenderFrameHostCreatedObserver : public WebContentsObserver {
 public:
  RenderFrameHostCreatedObserver(WebContents* web_contents,
                                 int expected_frame_count)
      : WebContentsObserver(web_contents),
        expected_frame_count_(expected_frame_count),
        frames_created_(0) {}

  ~RenderFrameHostCreatedObserver() override;

  // Runs a nested run loop and blocks until the expected number of
  // RenderFrameHosts is created.
  void Wait();

 private:
  // WebContentsObserver
  void RenderFrameCreated(RenderFrameHost* render_frame_host) override;

  // The number of RenderFrameHosts to wait for.
  int expected_frame_count_;

  // The number of RenderFrameHosts that have been created.
  int frames_created_;

  // The RunLoop used to spin the message loop.
  base::RunLoop run_loop_;

  DISALLOW_COPY_AND_ASSIGN(RenderFrameHostCreatedObserver);
};

RenderFrameHostCreatedObserver::~RenderFrameHostCreatedObserver() {
}

void RenderFrameHostCreatedObserver::Wait() {
  run_loop_.Run();
}

void RenderFrameHostCreatedObserver::RenderFrameCreated(
    RenderFrameHost* render_frame_host) {
  frames_created_++;
  if (frames_created_ == expected_frame_count_) {
    run_loop_.Quit();
  }
}

// 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() 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::Type type) override {
    user_interaction_received_ = true;
  }

  bool user_interaction_received_;

  DISALLOW_COPY_AND_ASSIGN(UserInteractionObserver);
};

// 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();
}

class RenderWidgetHostVisibilityObserver : public RenderWidgetHostObserver {
 public:
  explicit RenderWidgetHostVisibilityObserver(RenderWidgetHostImpl* rwhi,
                                              bool expected_visibility_state)
      : expected_visibility_state_(expected_visibility_state),
        observer_(this),
        was_observed_(false),
        did_fail_(false),
        render_widget_(rwhi) {
    observer_.Add(render_widget_);
    message_loop_runner_ = new MessageLoopRunner;
  }

  bool WaitUntilSatisfied() {
    if (!was_observed_)
      message_loop_runner_->Run();
    if (observer_.IsObserving(render_widget_))
      observer_.Remove(render_widget_);
    return !did_fail_;
  }

 private:
  void RenderWidgetHostVisibilityChanged(RenderWidgetHost* widget_host,
                                         bool became_visible) override {
    was_observed_ = true;
    did_fail_ = expected_visibility_state_ != became_visible;
    if (message_loop_runner_->loop_running())
      message_loop_runner_->Quit();
  }

  void RenderWidgetHostDestroyed(RenderWidgetHost* widget_host) override {
    observer_.Remove(widget_host);
  }

  bool expected_visibility_state_;
  scoped_refptr<MessageLoopRunner> message_loop_runner_;
  ScopedObserver<RenderWidgetHost, RenderWidgetHostObserver> observer_;
  bool was_observed_;
  bool did_fail_;
  RenderWidgetHost* render_widget_;

  DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostVisibilityObserver);
};

class TestInterstitialDelegate : public InterstitialPageDelegate {
 private:
  // InterstitialPageDelegate:
  std::string GetHTMLContents() override { return "<p>Interstitial</p>"; }
};

bool ConvertJSONToPoint(const std::string& str, gfx::PointF* point) {
  std::unique_ptr<base::Value> value = base::JSONReader::ReadDeprecated(str);
  if (!value)
    return false;
  base::DictionaryValue* root;
  if (!value->GetAsDictionary(&root))
    return false;
  double x, y;
  if (!root->GetDouble("x", &x))
    return false;
  if (!root->GetDouble("y", &y))
    return false;
  point->set_x(x);
  point->set_y(y);
  return true;
}

void OpenURLBlockUntilNavigationComplete(Shell* shell, const GURL& url) {
  WaitForLoadStop(shell->web_contents());
  TestNavigationObserver same_tab_observer(shell->web_contents(), 1);

  OpenURLParams params(
      url,
      content::Referrer(shell->web_contents()->GetLastCommittedURL(),
                        network::mojom::ReferrerPolicy::kAlways),
      WindowOpenDisposition::CURRENT_TAB, ui::PAGE_TRANSITION_LINK,
      true /* is_renderer_initiated */);
  params.initiator_origin = url::Origin::Create(url);
  shell->OpenURLFromTab(shell->web_contents(), params);

  same_tab_observer.Wait();
}

// Helper function to generate a feature policy for a single feature and a list
// of origins. (Equivalent to the declared policy "feature origin1 origin2...".)
void SetParsedFeaturePolicyDeclaration(
    blink::ParsedFeaturePolicyDeclaration* declaration,
    blink::mojom::FeaturePolicyFeature feature,
    const std::vector<GURL>& origins) {
  declaration->feature = feature;
  blink::mojom::PolicyValueType feature_type =
      blink::FeaturePolicy::GetDefaultFeatureList().at(feature).second;
  declaration->fallback_value =
      blink::PolicyValue::CreateMinPolicyValue(feature_type);
  declaration->opaque_value = declaration->fallback_value;
  if (feature == blink::mojom::FeaturePolicyFeature::kOversizedImages) {
    declaration->fallback_value.SetDoubleValue(2.0);
    declaration->opaque_value.SetDoubleValue(2.0);
  }
  DCHECK(!origins.empty());
  for (const auto origin : origins)
    declaration->values.insert(std::pair<url::Origin, blink::PolicyValue>(
        url::Origin::Create(origin),
        blink::PolicyValue::CreateMaxPolicyValue(feature_type)));
}

blink::ParsedFeaturePolicy CreateFPHeader(
    blink::mojom::FeaturePolicyFeature feature1,
    blink::mojom::FeaturePolicyFeature feature2,
    const std::vector<GURL>& origins) {
  blink::ParsedFeaturePolicy result(2);
  SetParsedFeaturePolicyDeclaration(&(result[0]), feature1, origins);
  SetParsedFeaturePolicyDeclaration(&(result[1]), feature2, origins);
  return result;
}

// Helper function to generate a feature policy for a single feature which
// matches every origin. (Equivalent to the declared policy "feature1 *;
// feature2 *".)
blink::ParsedFeaturePolicy CreateFPHeaderMatchesAll(
    blink::mojom::FeaturePolicyFeature feature1,
    blink::mojom::FeaturePolicyFeature feature2) {
  blink::ParsedFeaturePolicy result(2);
  blink::mojom::PolicyValueType feature_type1 =
      blink::FeaturePolicy::GetDefaultFeatureList().at(feature1).second;
  blink::mojom::PolicyValueType feature_type2 =
      blink::FeaturePolicy::GetDefaultFeatureList().at(feature2).second;
  blink::PolicyValue max_value1 =
      blink::PolicyValue::CreateMaxPolicyValue(feature_type1);
  blink::PolicyValue max_value2 =
      blink::PolicyValue::CreateMaxPolicyValue(feature_type2);
  result[0].feature = feature1;
  result[0].fallback_value = max_value1;
  result[0].opaque_value = max_value1;
  result[1].feature = feature2;
  result[1].fallback_value = max_value2;
  result[1].opaque_value = max_value2;
  return result;
}

// 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->depth());
  RenderProcessHost::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());
}

// Check |intersects_viewport| on widget and process.
bool CheckIntersectsViewport(bool expected, FrameTreeNode* node) {
  RenderProcessHost::Priority priority =
      node->current_frame_host()->GetRenderWidgetHost()->GetPriority();
  return priority.intersects_viewport == expected &&
         node->current_frame_host()->GetProcess()->GetIntersectsViewport() ==
             expected;
}

// Layout child frames in cross_site_iframe_factory.html so that they are the
// same width as the viewport, and 75% of the height of the window. This is for
// testing viewport intersection. Note this does not recurse into child frames
// and re-layout in the same way since children might be in a different origin.
void LayoutNonRecursiveForTestingViewportIntersection(
    WebContents* web_contents) {
  static const char* script = R"(
      function relayoutNonRecursiveForTestingViewportIntersection() {
        var width = window.innerWidth;
        var height = window.innerHeight * 0.75;
        for (var i = 0; i < window.frames.length; i++) {
          child = document.getElementById("child-" + i);
          child.width = width;
          child.height = height;
        }
      }
      relayoutNonRecursiveForTestingViewportIntersection();
  )";
  EXPECT_TRUE(ExecuteScript(web_contents, script));
}

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

// Class to monitor incoming FrameHostMsg_UpdateViewportIntersection messages.
class UpdateViewportIntersectionMessageFilter
    : public content::BrowserMessageFilter {
 public:
  UpdateViewportIntersectionMessageFilter()
      : content::BrowserMessageFilter(FrameMsgStart), msg_received_(false) {}

  bool OnMessageReceived(const IPC::Message& message) override {
    IPC_BEGIN_MESSAGE_MAP(UpdateViewportIntersectionMessageFilter, message)
      IPC_MESSAGE_HANDLER(FrameHostMsg_UpdateViewportIntersection,
                          OnUpdateViewportIntersection)
    IPC_END_MESSAGE_MAP()
    return false;
  }

  gfx::Rect GetCompositingRect() const { return compositing_rect_; }
  gfx::Rect GetViewportIntersection() const { return viewport_intersection_; }
  bool GetOccludedOrObscured() const { return occluded_or_obscured_; }

  void Wait() {
    DCHECK(!run_loop_);
    if (msg_received_) {
      msg_received_ = false;
      return;
    }
    std::unique_ptr<base::RunLoop> run_loop(new base::RunLoop);
    run_loop_ = run_loop.get();
    run_loop_->Run();
    run_loop_ = nullptr;
    msg_received_ = false;
  }

  void set_run_loop(base::RunLoop* run_loop) { run_loop_ = run_loop; }

 private:
  ~UpdateViewportIntersectionMessageFilter() override {}

  void OnUpdateViewportIntersection(const gfx::Rect& viewport_intersection,
                                    const gfx::Rect& compositing_rect,
                                    bool occluded_or_obscured) {
    // The message is going to be posted to UI thread after
    // OnUpdateViewportIntersection returns. This additional post on the IO
    // thread guarantees that by the time OnUpdateViewportIntersectionOnUI runs,
    // the message has been handled on the UI thread.
    base::PostTaskWithTraits(
        FROM_HERE, {content::BrowserThread::IO},
        base::BindOnce(&UpdateViewportIntersectionMessageFilter::
                           OnUpdateViewportIntersectionPostOnIO,
                       this, viewport_intersection, compositing_rect,
                       occluded_or_obscured));
  }
  void OnUpdateViewportIntersectionPostOnIO(
      const gfx::Rect& viewport_intersection,
      const gfx::Rect& compositing_rect,
      bool occluded_or_obscured) {
    base::PostTaskWithTraits(
        FROM_HERE, {content::BrowserThread::UI},
        base::BindOnce(&UpdateViewportIntersectionMessageFilter::
                           OnUpdateViewportIntersectionOnUI,
                       this, viewport_intersection, compositing_rect,
                       occluded_or_obscured));
  }
  void OnUpdateViewportIntersectionOnUI(const gfx::Rect& viewport_intersection,
                                        const gfx::Rect& compositing_rect,
                                        bool occluded_or_obscured) {
    viewport_intersection_ = viewport_intersection;
    compositing_rect_ = compositing_rect;
    occluded_or_obscured_ = occluded_or_obscured;
    msg_received_ = true;
    if (run_loop_)
      run_loop_->Quit();
  }
  base::RunLoop* run_loop_ = nullptr;
  bool msg_received_;
  gfx::Rect compositing_rect_;
  gfx::Rect viewport_intersection_;
  bool occluded_or_obscured_ = false;
  DISALLOW_COPY_AND_ASSIGN(UpdateViewportIntersectionMessageFilter);
};

// Observes navigation start.
class DidStartNavigationObserver : public WebContentsObserver {
 public:
  explicit DidStartNavigationObserver(WebContents* web_contents)
      : WebContentsObserver(web_contents) {}
  void DidStartNavigation(NavigationHandle* navigation_handle) override {
    observed_ = true;
  }
  bool observed() { return observed_; }

 private:
  bool observed_ = false;
  DISALLOW_COPY_AND_ASSIGN(DidStartNavigationObserver);
};

}  // namespace

//
// SitePerProcessBrowserTest
//

SitePerProcessBrowserTest::SitePerProcessBrowserTest() {}

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

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

  command_line->AppendSwitch(switches::kValidateInputEventStream);

#if !defined(OS_ANDROID)
  // TODO(bokan): Needed for scrollability check in
  // FrameOwnerPropertiesPropagationScrolling. crbug.com/662196.
  feature_list_.InitAndDisableFeature(features::kOverlayScrollbar);
#endif
}

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

//
// SitePerProcessHighDPIBrowserTest
//

class SitePerProcessHighDPIBrowserTest : public SitePerProcessBrowserTest {
 public:
  const double kDeviceScaleFactor = 2.0;

  SitePerProcessHighDPIBrowserTest() {}

 protected:
  void SetUpCommandLine(base::CommandLine* command_line) override {
    SitePerProcessBrowserTest::SetUpCommandLine(command_line);
    command_line->AppendSwitchASCII(
        switches::kForceDeviceScaleFactor,
        base::StringPrintf("%f", kDeviceScaleFactor));
  }
};

// SitePerProcessIgnoreCertErrorsBrowserTest

class SitePerProcessIgnoreCertErrorsBrowserTest
    : public SitePerProcessBrowserTest {
 public:
  SitePerProcessIgnoreCertErrorsBrowserTest() {}

 protected:
  void SetUpCommandLine(base::CommandLine* command_line) override {
    SitePerProcessBrowserTest::SetUpCommandLine(command_line);
    command_line->AppendSwitch(switches::kIgnoreCertificateErrors);
  }
};

// SitePerProcessFeaturePolicyBrowserTest

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

  // Enable tests for parameterized features.
  void SetUpCommandLine(base::CommandLine* command_line) override {
    SitePerProcessBrowserTest::SetUpCommandLine(command_line);
    command_line->AppendSwitchASCII("enable-blink-features",
                                    "ExperimentalProductivityFeatures");
  }
};

// SitePerProcessFeaturePolicyJavaScriptBrowserTest

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

  // Enable the feature policy JavaScript interface
  void SetUpCommandLine(base::CommandLine* command_line) override {
    SitePerProcessBrowserTest::SetUpCommandLine(command_line);
    command_line->AppendSwitchASCII(
        "enable-blink-features",
        "FeaturePolicyJavaScriptInterface,ExperimentalProductivityFeatures");
  }
};

// SitePerProcessAutoplayBrowserTest

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

  void SetUpCommandLine(base::CommandLine* command_line) override {
    SitePerProcessBrowserTest::SetUpCommandLine(command_line);
    command_line->AppendSwitchASCII(
        switches::kAutoplayPolicy,
        switches::autoplay::kDocumentUserActivationRequiredPolicy);
    command_line->AppendSwitchASCII("enable-blink-features",
                                    "FeaturePolicyAutoplayFeature");
  }

  bool AutoplayAllowed(const ToRenderFrameHost& adapter,
                       bool with_user_gesture) {
    RenderFrameHost* rfh = adapter.render_frame_host();
    const char* test_script = "attemptPlay();";
    bool worked = false;
    if (with_user_gesture) {
      EXPECT_TRUE(ExecuteScriptAndExtractBool(rfh, test_script, &worked));
    } else {
      EXPECT_TRUE(ExecuteScriptWithoutUserGestureAndExtractBool(
          rfh, test_script, &worked));
    }
    return worked;
  }

  void NavigateFrameAndWait(FrameTreeNode* node, const GURL& url) {
    NavigateFrameToURL(node, url);
    EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
    EXPECT_EQ(url, node->current_url());
  }
};

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

  void SetUpCommandLine(base::CommandLine* command_line) override {
    SitePerProcessBrowserTest::SetUpCommandLine(command_line);
    command_line->AppendSwitchASCII("enable-blink-features",
                                    "ScrollAnchorSerialization");
  }
};

// SitePerProcessEmbedderCSPEnforcementBrowserTest

class SitePerProcessEmbedderCSPEnforcementBrowserTest
    : public SitePerProcessBrowserTest {
 public:
  SitePerProcessEmbedderCSPEnforcementBrowserTest() {}

 protected:
  void SetUpCommandLine(base::CommandLine* command_line) override {
    SitePerProcessBrowserTest::SetUpCommandLine(command_line);
    // TODO(amalika): Remove this switch when the EmbedderCSPEnforcement becomes
    // stable
    command_line->AppendSwitchASCII(switches::kEnableBlinkFeatures,
                                    "EmbedderCSPEnforcement");
  }
};

// SitePerProcessProgrammaticScrollTest.

class SitePerProcessProgrammaticScrollTest : public SitePerProcessBrowserTest {
 public:
  SitePerProcessProgrammaticScrollTest()
      : kInfinity(1000000U), kPositiveXYPlane(0, 0, kInfinity, kInfinity) {}

 protected:
  const size_t kInfinity;
  const std::string kIframeOutOfViewHTML = "/iframe_out_of_view.html";
  const std::string kIframeClippedHTML = "/iframe_clipped.html";
  const std::string kInputBoxHTML = "/input_box.html";
  const std::string kIframeSelector = "iframe";
  const std::string kInputSelector = "input";
  const gfx::Rect kPositiveXYPlane;

  // Waits until the |load| handle is called inside the frame.
  void WaitForOnLoad(FrameTreeNode* node) {
    RunCommandAndWaitForResponse(node, "notifyWhenLoaded();", "LOADED");
  }

  void WaitForElementVisible(FrameTreeNode* node, const std::string& sel) {
    RunCommandAndWaitForResponse(
        node,
        base::StringPrintf("notifyWhenVisible(document.querySelector('%s'));",
                           sel.c_str()),
        "VISIBLE");
  }

  void WaitForViewportToStabilize(FrameTreeNode* node) {
    RunCommandAndWaitForResponse(node, "notifyWhenViewportStable(0);",
                                 "VIEWPORT_STABLE");
  }

  void AddFocusedInputField(FrameTreeNode* node) {
    ASSERT_TRUE(ExecuteScript(node, "addFocusedInputField();"));
  }

  void SetWindowScroll(FrameTreeNode* node, int x, int y) {
    ASSERT_TRUE(ExecuteScript(
        node, base::StringPrintf("window.scrollTo(%d, %d);", x, y)));
  }

  // Helper function to retrieve the bounding client rect of the element
  // identified by |sel| inside |rfh|.
  gfx::Rect GetBoundingClientRect(FrameTreeNode* node, const std::string& sel) {
    std::string result;
    EXPECT_TRUE(ExecuteScriptAndExtractString(
        node,
        base::StringPrintf(
            "window.domAutomationController.send(rectAsString("
            "    document.querySelector('%s').getBoundingClientRect()));",
            sel.c_str()),
        &result));
    return GetRectFromString(result);
  }

  // Returns a rect representing the current |visualViewport| in the main frame
  // of |contents|.
  gfx::Rect GetVisualViewport(FrameTreeNode* node) {
    std::string result;
    EXPECT_TRUE(ExecuteScriptAndExtractString(
        node,
        "window.domAutomationController.send("
        "    rectAsString(visualViewportAsRect()));",
        &result));
    return GetRectFromString(result);
  }

  float GetVisualViewportScale(FrameTreeNode* node) {
    double scale;
    EXPECT_TRUE(ExecuteScriptAndExtractDouble(
        node, "window.domAutomationController.send(visualViewport.scale);",
        &scale));
    return static_cast<float>(scale);
  }

 private:
  void RunCommandAndWaitForResponse(FrameTreeNode* node,
                                    const std::string& command,
                                    const std::string& response) {
    std::string msg_from_renderer;
    ASSERT_TRUE(
        ExecuteScriptAndExtractString(node, command, &msg_from_renderer));
    ASSERT_EQ(response, msg_from_renderer);
  }

  gfx::Rect GetRectFromString(const std::string& str) {
    std::vector<std::string> tokens = base::SplitString(
        str, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
    EXPECT_EQ(4U, tokens.size());
    double x = 0.0, y = 0.0, width = 0.0, height = 0.0;
    EXPECT_TRUE(base::StringToDouble(tokens[0], &x));
    EXPECT_TRUE(base::StringToDouble(tokens[1], &y));
    EXPECT_TRUE(base::StringToDouble(tokens[2], &width));
    EXPECT_TRUE(base::StringToDouble(tokens[3], &height));
    return {static_cast<int>(x), static_cast<int>(y), static_cast<int>(width),
            static_cast<int>(height)};
  }

  DISALLOW_COPY_AND_ASSIGN(SitePerProcessProgrammaticScrollTest);
};

IN_PROC_BROWSER_TEST_F(SitePerProcessHighDPIBrowserTest,
                       SubframeLoadsWithCorrectDeviceScaleFactor) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  // On Android forcing device scale factor does not work for tests, therefore
  // we ensure that make frame and iframe have the same DIP scale there, but
  // not necessarily kDeviceScaleFactor.
  const double expected_dip_scale =
#if defined(OS_ANDROID)
      GetFrameDeviceScaleFactor(web_contents());
#else
      SitePerProcessHighDPIBrowserTest::kDeviceScaleFactor;
#endif

  EXPECT_EQ(expected_dip_scale, GetFrameDeviceScaleFactor(web_contents()));

  FrameTreeNode* root = web_contents()->GetFrameTree()->root();
  ASSERT_EQ(1U, root->child_count());

  FrameTreeNode* child = root->child_at(0);
  EXPECT_EQ(expected_dip_scale, GetFrameDeviceScaleFactor(child));
}

#if defined(OS_CHROMEOS)
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
                       SubframeUpdateToCorrectDeviceScaleFactor) {
  if (aura::Env::GetInstance()->mode() == aura::Env::Mode::MUS)
    return;

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

  EXPECT_EQ(1.0, GetFrameDeviceScaleFactor(web_contents()));

  FrameTreeNode* root = web_contents()->GetFrameTree()->root();
  ASSERT_EQ(1U, root->child_count());

  FrameTreeNode* child = root->child_at(0);
  EXPECT_EQ(1.0, GetFrameDeviceScaleFactor(child));

  double expected_dip_scale = 2.0;

  // TODO(oshima): allow DeviceScaleFactor change on other platforms
  // (win, linux, mac, android and mus).
  aura::TestScreen* test_screen =
      static_cast<aura::TestScreen*>(display::Screen::GetScreen());
  test_screen->CreateHostForPrimaryDisplay();
  test_screen->SetDeviceScaleFactor(expected_dip_scale);

  double device_scale_factor = 0;
  // Wait until dppx becomes 2 if the frame's dpr hasn't beeen updated
  // to 2 yet.
  const char kScript[] =
      "function sendDpr() "
      "{window.domAutomationController.send(window.devicePixelRatio);}; "
      "if (window.devicePixelRatio == 2) sendDpr();"
      "window.matchMedia('screen and "
      "(min-resolution: 2dppx)').addListener(function(e) { if (e.matches) { "
      "sendDpr();}})";
  // Make sure that both main frame and iframe are updated to 2x.
  EXPECT_TRUE(
      ExecuteScriptAndExtractDouble(child, kScript, &device_scale_factor));
  EXPECT_EQ(expected_dip_scale, device_scale_factor);

  device_scale_factor = 0;
  EXPECT_TRUE(ExecuteScriptAndExtractDouble(web_contents(), kScript,
                                            &device_scale_factor));
  EXPECT_EQ(expected_dip_scale, device_scale_factor);
}

#endif

// Ensure that navigating subframes in --site-per-process mode works and the
// correct documents are committed.
IN_PROC_BROWSER_TEST_F(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()->GetFrameTree()->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"));
  NavigateFrameToURL(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<RenderWidgetHostView*> views_set =
        web_contents()->GetRenderWidgetHostViewsInTree();
    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());
    NavigateFrameToURL(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()->GetRenderViewHost(), rvh);
  EXPECT_NE(shell()->web_contents()->GetSiteInstance(), site_instance);
  EXPECT_NE(shell()->web_contents()->GetMainFrame()->GetProcess(), rph);
  {
    // There should be now two RenderWidgetHosts, one for each process
    // rendering a frame.
    std::set<RenderWidgetHostView*> views_set =
        web_contents()->GetRenderWidgetHostViewsInTree();
    EXPECT_EQ(2U, views_set.size());
  }
  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());
    NavigateFrameToURL(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()->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()->GetMainFrame()->GetProcess(),
            child->current_frame_host()->GetProcess());
  EXPECT_NE(rph, child->current_frame_host()->GetProcess());
  {
    std::set<RenderWidgetHostView*> views_set =
        web_contents()->GetRenderWidgetHostViewsInTree();
    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));
}

// 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_F(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()->GetFrameTree()->root();

  // Make the main frame update its title after the subframe loads.
  EXPECT_TRUE(ExecuteScript(shell()->web_contents(),
                            "document.querySelector('iframe').onload = "
                            "    function() { document.title = 'loaded'; };"));
  EXPECT_TRUE(
      ExecuteScript(shell()->web_contents(), "document.title = 'not loaded';"));
  base::string16 expected_title(base::UTF8ToUTF16("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(ExecuteScript(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());
}

// Test that the physical backing size and view bounds for a scaled out-of-
// process iframe are set and updated correctly.
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
                       CompositorViewportPixelSizeTest) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/frame_tree/page_with_scaled_frame.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

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

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

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

  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://baz.com/",
      DepictFrameTree(root));

  FrameTreeNode* nested_iframe_node = parent_iframe_node->child_at(0);
  RenderFrameProxyHost* proxy_to_parent =
      nested_iframe_node->render_manager()->GetProxyToParent();
  CrossProcessFrameConnector* connector =
      proxy_to_parent->cross_process_frame_connector();
  RenderWidgetHostViewBase* rwhv_nested =
      static_cast<RenderWidgetHostViewBase*>(
          nested_iframe_node->current_frame_host()
              ->GetRenderWidgetHost()
              ->GetView());

  RenderFrameSubmissionObserver frame_observer(nested_iframe_node);
  frame_observer.WaitForMetadataChange();

  // Verify that applying a CSS scale transform does not impact the size of the
  // content of the nested iframe.
  // The screen_space_rect_in_dip may be off by 1 due to rounding. There is no
  // good way to avoid this due to various device-scale-factor. (e.g. when
  // dsf=3.375, ceil(round(50 * 3.375) / 3.375) = 51. Thus, we allow the screen
  // size in dip to be off by 1 here.
  EXPECT_NEAR(50, connector->screen_space_rect_in_dip().size().width(), 1);
  EXPECT_NEAR(50, connector->screen_space_rect_in_dip().size().height(), 1);
  EXPECT_EQ(gfx::Size(100, 100), rwhv_nested->GetViewBounds().size());
  EXPECT_EQ(gfx::Size(100, 100), connector->local_frame_size_in_dip());
  EXPECT_EQ(connector->local_frame_size_in_pixels(),
            rwhv_nested->GetCompositorViewportPixelSize());
}

// Verify an OOPIF resize handler doesn't fire immediately after load without
// the frame having been resized. See https://crbug.com/826457.
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, NoResizeAfterIframeLoad) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(a)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));
  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
                            ->GetFrameTree()
                            ->root();

  FrameTreeNode* iframe = root->child_at(0);
  GURL site_url =
      embedded_test_server()->GetURL("b.com", "/page_with_resize_handler.html");
  NavigateFrameToURL(iframe, site_url);
  base::RunLoop().RunUntilIdle();

  int resizes = -1;
  EXPECT_TRUE(ExecuteScriptAndExtractInt(
      iframe->current_frame_host(),
      "window.domAutomationController.send(resize_count);", &resizes));

  // Should be zero because the iframe only has its initial size from parent.
  EXPECT_EQ(resizes, 0);
}

// Test that the view bounds for an out-of-process iframe are set and updated
// correctly, including accounting for local frame offsets in the parent and
// scroll positions.
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, ViewBoundsInNestedFrameTest) {
  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 = static_cast<WebContentsImpl*>(shell()->web_contents())
                            ->GetFrameTree()
                            ->root();
  RenderWidgetHostViewBase* rwhv_root = static_cast<RenderWidgetHostViewBase*>(
      root->current_frame_host()->GetRenderWidgetHost()->GetView());
  ASSERT_EQ(1U, root->child_count());

  FrameTreeNode* parent_iframe_node = root->child_at(0);
  GURL site_url(embedded_test_server()->GetURL(
      "a.com", "/frame_tree/page_with_positioned_frame.html"));
  NavigateFrameToURL(parent_iframe_node, site_url);
  RenderFrameSubmissionObserver frame_observer(shell()->web_contents());

  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://baz.com/",
      DepictFrameTree(root));

  FrameTreeNode* nested_iframe_node = parent_iframe_node->child_at(0);
  RenderWidgetHostViewBase* rwhv_nested =
      static_cast<RenderWidgetHostViewBase*>(
          nested_iframe_node->current_frame_host()
              ->GetRenderWidgetHost()
              ->GetView());
  WaitForHitTestDataOrChildSurfaceReady(
      nested_iframe_node->current_frame_host());

  float scale_factor =
      frame_observer.LastRenderFrameMetadata().page_scale_factor;

  // Get the view bounds of the nested iframe, which should account for the
  // relative offset of its direct parent within the root frame.
  gfx::Rect bounds = rwhv_nested->GetViewBounds();

  scoped_refptr<SynchronizeVisualPropertiesMessageFilter> filter =
      new SynchronizeVisualPropertiesMessageFilter();
  root->current_frame_host()->GetProcess()->AddFilter(filter.get());

  // Scroll the parent frame downward to verify that the child rect gets updated
  // correctly.
  blink::WebMouseWheelEvent scroll_event(
      blink::WebInputEvent::kMouseWheel, blink::WebInputEvent::kNoModifiers,
      blink::WebInputEvent::GetStaticTimeStampForTests());

  scroll_event.SetPositionInWidget(
      gfx::ToFlooredInt((bounds.x() - rwhv_root->GetViewBounds().x() - 5) *
                        scale_factor),
      gfx::ToFlooredInt((bounds.y() - rwhv_root->GetViewBounds().y() - 5) *
                        scale_factor));
  scroll_event.delta_x = 0.0f;
  scroll_event.delta_y = -30.0f;
  scroll_event.phase = blink::WebMouseWheelEvent::kPhaseBegan;
  rwhv_root->ProcessMouseWheelEvent(scroll_event, ui::LatencyInfo());
  filter->WaitForRect();

  // The precise amount of scroll for the first view position update is not
  // deterministic, so this simply verifies that the OOPIF moved from its
  // earlier position.
  gfx::Rect update_rect = filter->last_rect();
  EXPECT_LT(update_rect.y(), bounds.y() - rwhv_root->GetViewBounds().y());
}

// 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_F(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())
                            ->GetFrameTree()
                            ->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::kGestureFlingStart);

  WaitForHitTestDataOrChildSurfaceReady(
      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::kGestureScrollBegin,
      blink::WebInputEvent::kNoModifiers,
      blink::WebInputEvent::GetStaticTimeStampForTests(),
      blink::kWebGestureDeviceTouchscreen);
  gesture_scroll_begin.data.scroll_begin.delta_hint_units =
      blink::WebGestureEvent::ScrollUnits::kPrecisePixels;
  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::kGestureScrollUpdate,
      blink::WebInputEvent::kNoModifiers,
      blink::WebInputEvent::GetStaticTimeStampForTests(),
      blink::kWebGestureDeviceTouchscreen);
  gesture_scroll_update.data.scroll_update.delta_units =
      blink::WebGestureEvent::ScrollUnits::kPrecisePixels;
  gesture_scroll_update.data.scroll_update.delta_x = 0.f;
  gesture_scroll_update.data.scroll_update.delta_y = 5.f;
  gesture_scroll_update.data.scroll_update.velocity_y = 5.f;

  child_rwh->ForwardGestureEvent(gesture_scroll_update);

  blink::WebGestureEvent gesture_fling_start(
      blink::WebGestureEvent::kGestureFlingStart,
      blink::WebInputEvent::kNoModifiers,
      blink::WebInputEvent::GetStaticTimeStampForTests(),
      blink::kWebGestureDeviceTouchscreen);
  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 scrolling a nested out-of-process iframe bubbles unused scroll
// delta to a parent frame.
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, ScrollBubblingFromOOPIFTest) {
  ui::GestureConfiguration::GetInstance()->set_scroll_debounce_interval_in_ms(
      0);
  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 = static_cast<WebContentsImpl*>(shell()->web_contents())
                            ->GetFrameTree()
                            ->root();
  ASSERT_EQ(1U, root->child_count());

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

  // This test uses the position of the nested iframe within the parent iframe
  // to infer the scroll position of the parent.
  // SynchronizeVisualPropertiesMessageFilter catches updates to the position in
  // order to avoid busy waiting. It gets created early to catch the initial
  // rects from the navigation.
  scoped_refptr<SynchronizeVisualPropertiesMessageFilter> filter =
      new SynchronizeVisualPropertiesMessageFilter();
  parent_iframe_node->current_frame_host()->GetProcess()->AddFilter(
      filter.get());

  InputEventAckWaiter ack_observer(
      parent_iframe_node->current_frame_host()->GetRenderWidgetHost(),
      blink::WebInputEvent::kGestureScrollEnd);

  GURL site_url(embedded_test_server()->GetURL(
      "b.com", "/frame_tree/page_with_positioned_frame.html"));
  NavigateFrameToURL(parent_iframe_node, site_url);

  // Navigate the nested frame to a page large enough to have scrollbars.
  FrameTreeNode* nested_iframe_node = parent_iframe_node->child_at(0);
  GURL nested_site_url(embedded_test_server()->GetURL(
      "baz.com", "/tall_page.html"));
  NavigateFrameToURL(nested_iframe_node, nested_site_url);

  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://baz.com/",
      DepictFrameTree(root));

  RenderWidgetHostViewBase* rwhv_parent =
      static_cast<RenderWidgetHostViewBase*>(
          parent_iframe_node->current_frame_host()
              ->GetRenderWidgetHost()
              ->GetView());

  RenderWidgetHostViewBase* rwhv_nested =
      static_cast<RenderWidgetHostViewBase*>(
          nested_iframe_node->current_frame_host()
              ->GetRenderWidgetHost()
              ->GetView());

  WaitForHitTestDataOrChildSurfaceReady(
      nested_iframe_node->current_frame_host());

  // Save the original offset as a point of reference.
  filter->WaitForRect();
  gfx::Rect update_rect = filter->last_rect();
  int initial_y = update_rect.y();
  filter->ResetRectRunLoop();

  // Scroll the parent frame downward.
  blink::WebMouseWheelEvent scroll_event(
      blink::WebInputEvent::kMouseWheel, blink::WebInputEvent::kNoModifiers,
      blink::WebInputEvent::GetStaticTimeStampForTests());
  scroll_event.SetPositionInWidget(1, 1);
  scroll_event.delta_x = 0.0f;
  scroll_event.delta_y = -5.0f;
  scroll_event.phase = blink::WebMouseWheelEvent::kPhaseBegan;
  // Set has_precise_scroll_deltas to keep these events off the animated scroll
  // pathways, which currently break this test.
  // https://bugs.chromium.org/p/chromium/issues/detail?id=710513
  scroll_event.has_precise_scrolling_deltas = true;
  rwhv_parent->ProcessMouseWheelEvent(scroll_event, ui::LatencyInfo());

  // The event router sends wheel events of a single scroll sequence to the
  // target under the first wheel event. Send a wheel end event to the current
  // target view before sending a wheel event to a different one.
  scroll_event.delta_y = 0.0f;
  scroll_event.phase = blink::WebMouseWheelEvent::kPhaseEnded;
  scroll_event.dispatch_type =
      blink::WebInputEvent::DispatchType::kEventNonBlocking;
  rwhv_parent->ProcessMouseWheelEvent(scroll_event, ui::LatencyInfo());

  // Ensure that the view position is propagated to the child properly.
  filter->WaitForRect();
  update_rect = filter->last_rect();
  EXPECT_LT(update_rect.y(), initial_y);
  filter->ResetRectRunLoop();
  ack_observer.Reset();

  // Now scroll the nested frame upward, which should bubble to the parent.
  // The upscroll exceeds the amount that the frame was initially scrolled
  // down to account for rounding.
  scroll_event.delta_y = 6.0f;
  scroll_event.dispatch_type = blink::WebInputEvent::DispatchType::kBlocking;
  scroll_event.phase = blink::WebMouseWheelEvent::kPhaseBegan;
  rwhv_nested->ProcessMouseWheelEvent(scroll_event, ui::LatencyInfo());

  filter->WaitForRect();
  // This loop isn't great, but it accounts for the possibility of multiple
  // incremental updates happening as a result of the scroll animation.
  // A failure condition of this test is that the loop might not terminate
  // due to bubbling not working properly. If the overscroll bubbles to the
  // parent iframe then the nested frame's y coord will return to its
  // initial position.
  update_rect = filter->last_rect();
  while (update_rect.y() > initial_y) {
    base::RunLoop run_loop;
    base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
        FROM_HERE, run_loop.QuitClosure(), TestTimeouts::tiny_timeout());
    run_loop.Run();
    update_rect = filter->last_rect();
  }

  // The event router sends wheel events of a single scroll sequence to the
  // target under the first wheel event. Send a wheel end event to the current
  // target view before sending a wheel event to a different one.
  scroll_event.delta_y = 0.0f;
  scroll_event.phase = blink::WebMouseWheelEvent::kPhaseEnded;
  scroll_event.dispatch_type =
      blink::WebInputEvent::DispatchType::kEventNonBlocking;
  rwhv_nested->ProcessMouseWheelEvent(scroll_event, ui::LatencyInfo());

  filter->ResetRectRunLoop();
  // Once we've sent a wheel to the nested iframe that we expect to turn into
  // a bubbling scroll, we need to delay to make sure the GestureScrollBegin
  // from this new scroll doesn't hit the RenderWidgetHostImpl before the
  // GestureScrollEnd bubbled from the child.
  // This timing only seems to be needed for CrOS, but we'll enable it on
  // all platforms just to lessen the possibility of tests being flakey
  // on non-CrOS platforms.
  ack_observer.Wait();

  // Scroll the parent down again in order to test scroll bubbling from
  // gestures.
  scroll_event.delta_y = -5.0f;
  scroll_event.dispatch_type = blink::WebInputEvent::DispatchType::kBlocking;
  scroll_event.phase = blink::WebMouseWheelEvent::kPhaseBegan;
  rwhv_parent->ProcessMouseWheelEvent(scroll_event, ui::LatencyInfo());

  // The event router sends wheel events of a single scroll sequence to the
  // target under the first wheel event. Send a wheel end event to the current
  // target view before sending a wheel event to a different one.
  scroll_event.delta_y = 0.0f;
  scroll_event.phase = blink::WebMouseWheelEvent::kPhaseEnded;
  scroll_event.dispatch_type =
      blink::WebInputEvent::DispatchType::kEventNonBlocking;
  rwhv_parent->ProcessMouseWheelEvent(scroll_event, ui::LatencyInfo());

  // Ensure ensuing offset change is received, and then reset the filter.
  filter->WaitForRect();
  filter->ResetRectRunLoop();

  // Scroll down the nested iframe via gesture. This requires 3 separate input
  // events.
  blink::WebGestureEvent gesture_event(
      blink::WebGestureEvent::kGestureScrollBegin,
      blink::WebInputEvent::kNoModifiers,
      blink::WebInputEvent::GetStaticTimeStampForTests(),
      blink::kWebGestureDeviceTouchpad);
  gesture_event.SetPositionInWidget(gfx::PointF(1, 1));
  gesture_event.data.scroll_begin.delta_x_hint = 0.0f;
  gesture_event.data.scroll_begin.delta_y_hint = 6.0f;
  rwhv_nested->GetRenderWidgetHost()->ForwardGestureEvent(gesture_event);

  gesture_event =
      blink::WebGestureEvent(blink::WebGestureEvent::kGestureScrollUpdate,
                             blink::WebInputEvent::kNoModifiers,
                             blink::WebInputEvent::GetStaticTimeStampForTests(),
                             blink::kWebGestureDeviceTouchpad);
  gesture_event.SetPositionInWidget(gfx::PointF(1, 1));
  gesture_event.data.scroll_update.delta_x = 0.0f;
  gesture_event.data.scroll_update.delta_y = 6.0f;
  gesture_event.data.scroll_update.velocity_x = 0;
  gesture_event.data.scroll_update.velocity_y = 0;
  rwhv_nested->GetRenderWidgetHost()->ForwardGestureEvent(gesture_event);

  gesture_event =
      blink::WebGestureEvent(blink::WebGestureEvent::kGestureScrollEnd,
                             blink::WebInputEvent::kNoModifiers,
                             blink::WebInputEvent::GetStaticTimeStampForTests(),
                             blink::kWebGestureDeviceTouchpad);
  gesture_event.SetPositionInWidget(gfx::PointF(1, 1));
  rwhv_nested->GetRenderWidgetHost()->ForwardGestureEvent(gesture_event);

  filter->WaitForRect();
  update_rect = filter->last_rect();
  // As above, if this loop does not terminate then it indicates an issue
  // with scroll bubbling.
  while (update_rect.y() > initial_y) {
    base::RunLoop run_loop;
    base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
        FROM_HERE, run_loop.QuitClosure(), TestTimeouts::tiny_timeout());
    run_loop.Run();
    update_rect = filter->last_rect();
  }

  // Test that when the child frame absorbs all of the scroll delta, it does
  // not propagate to the parent (see https://crbug.com/621624).
  filter->ResetRectRunLoop();
  scroll_event.delta_y = -5.0f;
  scroll_event.dispatch_type = blink::WebInputEvent::DispatchType::kBlocking;
  scroll_event.phase = blink::WebMouseWheelEvent::kPhaseBegan;
  rwhv_nested->ProcessMouseWheelEvent(scroll_event, ui::LatencyInfo());
  // It isn't possible to busy loop waiting on the renderer here because we
  // are explicitly testing that something does *not* happen. This creates a
  // small chance of false positives but shouldn't result in false negatives,
  // so flakiness implies this test is failing.
  {
    base::RunLoop run_loop;
    base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
        FROM_HERE, run_loop.QuitClosure(), TestTimeouts::action_timeout());
    run_loop.Run();
  }
  DCHECK_EQ(filter->last_rect().x(), 0);
  DCHECK_EQ(filter->last_rect().y(), 0);
}

// Tests that scrolling with the keyboard will bubble unused scroll to the
// OOPIF's parent.
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
                       KeyboardScrollBubblingFromOOPIF) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/frame_tree/page_with_iframe_in_scrollable_div.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())
                            ->GetFrameTree()
                            ->root();
  ASSERT_EQ(1U, root->child_count());

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

  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_child = static_cast<RenderWidgetHostViewBase*>(
      iframe_node->current_frame_host()->GetRenderWidgetHost()->GetView());

  double initial_y = 0.0;
  ASSERT_TRUE(content::ExecuteScriptAndExtractDouble(
      root,
      "var wrapperDiv = document.getElementById('wrapper-div');"
      "var initial_y = wrapperDiv.scrollTop;"
      "var waitForScrollDownPromise = new Promise(function(resolve) {"
      "  wrapperDiv.addEventListener('scroll', () => {"
      "    if (wrapperDiv.scrollTop > initial_y)"
      "      resolve(wrapperDiv.scrollTop);"
      "  });"
      "});"
      "window.domAutomationController.send(initial_y);",
      &initial_y));
  EXPECT_DOUBLE_EQ(0.0, initial_y);

  NativeWebKeyboardEvent key_event(
      blink::WebKeyboardEvent::kRawKeyDown, blink::WebInputEvent::kNoModifiers,
      blink::WebInputEvent::GetStaticTimeStampForTests());
  key_event.windows_key_code = ui::VKEY_DOWN;
  key_event.native_key_code =
      ui::KeycodeConverter::DomCodeToNativeKeycode(ui::DomCode::ARROW_DOWN);
  key_event.dom_code = static_cast<int>(ui::DomCode::ARROW_DOWN);
  key_event.dom_key = ui::DomKey::ARROW_DOWN;

  rwhv_child->GetRenderWidgetHost()->ForwardKeyboardEvent(key_event);

  key_event.SetType(blink::WebKeyboardEvent::kKeyUp);
  rwhv_child->GetRenderWidgetHost()->ForwardKeyboardEvent(key_event);

  double scrolled_y = 0.0;
  ASSERT_TRUE(content::ExecuteScriptAndExtractDouble(
      root,
      "waitForScrollDownPromise.then((scrolled_y) => {"
      "  window.domAutomationController.send(scrolled_y);"
      "});",
      &scrolled_y));
  EXPECT_GT(scrolled_y, 0.0);
}

// Test that fling on an out-of-process iframe progresses properly.
IN_PROC_BROWSER_TEST_F(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())
                            ->GetFrameTree()
                            ->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();
  WaitForHitTestDataOrChildSurfaceReady(
      child_iframe_node->current_frame_host());

  GenerateTapDownGesture(child_rwh);
  // Send a GSB to start scrolling sequence.
  blink::WebGestureEvent gesture_scroll_begin(
      blink::WebGestureEvent::kGestureScrollBegin,
      blink::WebInputEvent::kNoModifiers,
      blink::WebInputEvent::GetStaticTimeStampForTests());
  gesture_scroll_begin.SetSourceDevice(blink::kWebGestureDeviceTouchscreen);
  gesture_scroll_begin.data.scroll_begin.delta_hint_units =
      blink::WebGestureEvent::ScrollUnits::kPrecisePixels;
  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::kGestureScrollUpdate);
  gesture_scroll_update_ack_observer.Reset();
  blink::WebGestureEvent gesture_fling_start(
      blink::WebGestureEvent::kGestureFlingStart,
      blink::WebInputEvent::kNoModifiers,
      blink::WebInputEvent::GetStaticTimeStampForTests());
  gesture_fling_start.SetSourceDevice(blink::kWebGestureDeviceTouchscreen);
  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_F(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())
                            ->GetFrameTree()
                            ->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::kGestureScrollBegin);
  blink::WebMouseWheelEvent scroll_event(
      blink::WebInputEvent::kMouseWheel, blink::WebInputEvent::kNoModifiers,
      blink::WebInputEvent::GetStaticTimeStampForTests());
  scroll_event.delta_x = 0.0f;
  scroll_event.delta_y = 5.0f;
  scroll_event.phase = blink::WebMouseWheelEvent::kPhaseBegan;
  scroll_event.has_precise_scrolling_deltas = true;
  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::kGestureScrollUpdate);
  gesture_scroll_update_ack_observer.Reset();
  blink::WebGestureEvent gesture_fling_start(
      blink::WebGestureEvent::kGestureFlingStart,
      blink::WebInputEvent::kNoModifiers,
      blink::WebInputEvent::GetStaticTimeStampForTests());
  gesture_fling_start.SetSourceDevice(blink::kWebGestureDeviceTouchpad);
  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();
}

class ScrollObserver : public RenderWidgetHost::InputEventObserver {
 public:
  ScrollObserver(double delta_x, double delta_y) { Reset(delta_x, delta_y); }
  ~ScrollObserver() override {}

  void OnInputEvent(const blink::WebInputEvent& event) override {
    if (event.GetType() == blink::WebInputEvent::kGestureScrollUpdate) {
      blink::WebGestureEvent received_update =
          *static_cast<const blink::WebGestureEvent*>(&event);
      remaining_delta_x_ -= received_update.data.scroll_update.delta_x;
      remaining_delta_y_ -= received_update.data.scroll_update.delta_y;
    } else if (event.GetType() == blink::WebInputEvent::kGestureScrollEnd) {
      if (message_loop_runner_->loop_running())
        message_loop_runner_->Quit();
      DCHECK_EQ(0, remaining_delta_x_);
      DCHECK_EQ(0, remaining_delta_y_);
      scroll_end_received_ = true;
    }
  }

  void Wait() {
    if (!scroll_end_received_) {
      message_loop_runner_->Run();
    }
  }

  void Reset(double delta_x, double delta_y) {
    message_loop_runner_ = new content::MessageLoopRunner;
    remaining_delta_x_ = delta_x;
    remaining_delta_y_ = delta_y;
    scroll_end_received_ = false;
  }

 private:
  scoped_refptr<content::MessageLoopRunner> message_loop_runner_;
  double remaining_delta_x_;
  double remaining_delta_y_;
  bool scroll_end_received_;

  DISALLOW_COPY_AND_ASSIGN(ScrollObserver);
};

IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
                       ScrollBubblingFromNestedOOPIFTest) {
  ui::GestureConfiguration::GetInstance()->set_scroll_debounce_interval_in_ms(
      0);
  GURL main_url(embedded_test_server()->GetURL(
      "/frame_tree/page_with_positioned_nested_frames.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));
  RenderFrameSubmissionObserver frame_observer(shell()->web_contents());

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

  FrameTreeNode* parent_iframe_node = root->child_at(0);
  GURL site_url(embedded_test_server()->GetURL(
      "a.com", "/frame_tree/page_with_positioned_frame.html"));
  EXPECT_EQ(site_url, parent_iframe_node->current_url());

  FrameTreeNode* nested_iframe_node = parent_iframe_node->child_at(0);
  GURL nested_site_url(
      embedded_test_server()->GetURL("baz.com", "/title1.html"));
  EXPECT_EQ(nested_site_url, nested_iframe_node->current_url());

  RenderWidgetHostViewBase* root_view = static_cast<RenderWidgetHostViewBase*>(
      root->current_frame_host()->GetRenderWidgetHost()->GetView());

  RenderWidgetHostViewBase* rwhv_nested =
      static_cast<RenderWidgetHostViewBase*>(
          nested_iframe_node->current_frame_host()
              ->GetRenderWidgetHost()
              ->GetView());

  WaitForHitTestDataOrChildSurfaceReady(
      nested_iframe_node->current_frame_host());

  InputEventAckWaiter ack_observer(
      root->current_frame_host()->GetRenderWidgetHost(),
      blink::WebInputEvent::kGestureScrollBegin);

  std::unique_ptr<ScrollObserver> scroll_observer;

  // All GSU events will be wrapped between a single GSB-GSE pair. The expected
  // delta value is equal to summation of all scroll update deltas.
  scroll_observer = std::make_unique<ScrollObserver>(0, 15);

  root->current_frame_host()->GetRenderWidgetHost()->AddInputEventObserver(
      scroll_observer.get());

  // Now scroll the nested frame upward, this must bubble all the way up to the
  // root.
  blink::WebMouseWheelEvent scroll_event(
      blink::WebInputEvent::kMouseWheel, blink::WebInputEvent::kNoModifiers,
      blink::WebInputEvent::GetStaticTimeStampForTests());
  gfx::Rect bounds = rwhv_nested->GetViewBounds();
  float scale_factor =
      frame_observer.LastRenderFrameMetadata().page_scale_factor;
  scroll_event.SetPositionInWidget(
      gfx::ToCeiledInt((bounds.x() - root_view->GetViewBounds().x() + 10) *
                       scale_factor),
      gfx::ToCeiledInt((bounds.y() - root_view->GetViewBounds().y() + 10) *
                       scale_factor));
  scroll_event.delta_x = 0.0f;
  scroll_event.delta_y = 5.0f;
  scroll_event.phase = blink::WebMouseWheelEvent::kPhaseBegan;
  scroll_event.has_precise_scrolling_deltas = true;
  rwhv_nested->ProcessMouseWheelEvent(scroll_event, ui::LatencyInfo());
  ack_observer.Wait();

  // Send 10 wheel events with delta_y = 1 to the nested oopif.
  scroll_event.delta_y = 1.0f;
  scroll_event.phase = blink::WebMouseWheelEvent::kPhaseChanged;
  for (int i = 0; i < 10; i++)
    rwhv_nested->ProcessMouseWheelEvent(scroll_event, ui::LatencyInfo());

  // Send a wheel end event to complete the scrolling sequence.
  scroll_event.delta_y = 0.0f;
  scroll_event.phase = blink::WebMouseWheelEvent::kPhaseEnded;
  rwhv_nested->ProcessMouseWheelEvent(scroll_event, ui::LatencyInfo());
  scroll_observer->Wait();
}

// Tests that scrolling bubbles from an oopif if its source body has
// "overflow:hidden" style.
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
                       ScrollBubblingFromOOPIFWithBodyOverflowHidden) {
  GURL url_domain_a(embedded_test_server()->GetURL(
      "a.com", "/scrollable_page_with_iframe.html"));
  EXPECT_TRUE(NavigateToURL(shell(), url_domain_a));
  RenderFrameSubmissionObserver frame_observer(shell()->web_contents());
  FrameTreeNode* root = web_contents()->GetFrameTree()->root();

  FrameTreeNode* iframe_node = root->child_at(0);
  GURL url_domain_b(
      embedded_test_server()->GetURL("b.com", "/body_overflow_hidden.html"));
  NavigateFrameToURL(iframe_node, url_domain_b);
  WaitForHitTestDataOrChildSurfaceReady(iframe_node->current_frame_host());

  RenderWidgetHostViewBase* root_view = static_cast<RenderWidgetHostViewBase*>(
      root->current_frame_host()->GetRenderWidgetHost()->GetView());

  RenderWidgetHostViewBase* child_view = static_cast<RenderWidgetHostViewBase*>(
      iframe_node->current_frame_host()->GetRenderWidgetHost()->GetView());

  ScrollObserver scroll_observer(0, -5);
  root->current_frame_host()->GetRenderWidgetHost()->AddInputEventObserver(
      &scroll_observer);

  // Now scroll the nested frame downward, this must bubble to the root since
  // the iframe source body is not scrollable.
  blink::WebMouseWheelEvent scroll_event(
      blink::WebInputEvent::kMouseWheel, blink::WebInputEvent::kNoModifiers,
      blink::WebInputEvent::GetStaticTimeStampForTests());
  gfx::Rect bounds = child_view->GetViewBounds();
  float scale_factor =
      frame_observer.LastRenderFrameMetadata().page_scale_factor;
  scroll_event.SetPositionInWidget(
      gfx::ToCeiledInt((bounds.x() - root_view->GetViewBounds().x() + 10) *
                       scale_factor),
      gfx::ToCeiledInt((bounds.y() - root_view->GetViewBounds().y() + 10) *
                       scale_factor));
  scroll_event.delta_x = 0.0f;
  scroll_event.delta_y = -5.0f;
  scroll_event.phase = blink::WebMouseWheelEvent::kPhaseBegan;
  scroll_event.has_precise_scrolling_deltas = true;
  child_view->ProcessMouseWheelEvent(scroll_event, ui::LatencyInfo());

  // Send a wheel end event to complete the scrolling sequence.
  scroll_event.delta_y = 0.0f;
  scroll_event.phase = blink::WebMouseWheelEvent::kPhaseEnded;
  child_view->ProcessMouseWheelEvent(scroll_event, ui::LatencyInfo());

  scroll_observer.Wait();
}

// Ensure that the scrollability of a local subframe in an OOPIF is considered
// when acknowledging GestureScrollBegin events sent to OOPIFs.
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, ScrollLocalSubframeInOOPIF) {
  ui::GestureConfiguration::GetInstance()->set_scroll_debounce_interval_in_ms(
      0);

  // This must be tall enough such that the outer iframe is not scrollable.
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/frame_tree/page_with_tall_positioned_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()->GetFrameTree()->root();
  ASSERT_EQ(1U, root->child_count());

  FrameTreeNode* parent_iframe_node = root->child_at(0);
  GURL outer_frame_url(embedded_test_server()->GetURL(
      "baz.com", "/frame_tree/page_with_positioned_frame.html"));
  NavigateFrameToURL(parent_iframe_node, outer_frame_url);

  // This must be tall enough such that the inner iframe is scrollable.
  FrameTreeNode* nested_iframe_node = parent_iframe_node->child_at(0);
  GURL inner_frame_url(
      embedded_test_server()->GetURL("baz.com", "/tall_page.html"));
  NavigateFrameToURL(nested_iframe_node, inner_frame_url);

  ASSERT_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://baz.com/",
      DepictFrameTree(root));

  RenderWidgetHostViewBase* rwhv_child = static_cast<RenderWidgetHostViewBase*>(
      nested_iframe_node->current_frame_host()
          ->GetRenderWidgetHost()
          ->GetView());

  WaitForHitTestDataOrChildSurfaceReady(
      parent_iframe_node->current_frame_host());

  // When we scroll the inner frame, we should have the GSB be consumed.
  // The outer iframe not being scrollable should not cause the GSB to go
  // unconsumed.
  InputEventAckWaiter ack_observer(
      parent_iframe_node->current_frame_host()->GetRenderWidgetHost(),
      base::BindRepeating([](content::InputEventAckSource,
                             content::InputEventAckState state,
                             const blink::WebInputEvent& event) {
        return event.GetType() == blink::WebGestureEvent::kGestureScrollBegin &&
               state == content::INPUT_EVENT_ACK_STATE_CONSUMED;
      }));

  // Wait until renderer's compositor thread is synced. Otherwise the non fast
  // scrollable regions won't be set when the event arrives.
  MainThreadFrameObserver observer(rwhv_child->GetRenderWidgetHost());
  observer.Wait();

  // Now scroll the inner frame downward.
  blink::WebMouseWheelEvent scroll_event(
      blink::WebInputEvent::kMouseWheel, blink::WebInputEvent::kNoModifiers,
      blink::WebInputEvent::GetStaticTimeStampForTests());
  scroll_event.SetPositionInWidget(90, 110);
  scroll_event.delta_x = 0.0f;
  scroll_event.delta_y = -50.0f;
  scroll_event.phase = blink::WebMouseWheelEvent::kPhaseBegan;
  scroll_event.has_precise_scrolling_deltas = true;
  rwhv_child->ProcessMouseWheelEvent(scroll_event, ui::LatencyInfo());
  ack_observer.Wait();
}

// This test verifies that scrolling an element to view works across OOPIFs. The
// testing methodology is based on measuring bounding client rect position of
// nested <iframe>'s after the inner-most frame scrolls into view. The
// measurements are for two identical pages where one page does not have any
// OOPIFs while the other has some nested OOPIFs.
// TODO(crbug.com/827431): This test is flaking on all platforms.
IN_PROC_BROWSER_TEST_F(SitePerProcessProgrammaticScrollTest,
                       DISABLED_ScrollElementIntoView) {
  const GURL url_a(
      embedded_test_server()->GetURL("a.com", kIframeOutOfViewHTML));
  const GURL url_b(
      embedded_test_server()->GetURL("b.com", kIframeOutOfViewHTML));
  const GURL url_c(
      embedded_test_server()->GetURL("c.com", kIframeOutOfViewHTML));

  // Number of <iframe>'s which will not be empty. The actual frame tree has two
  // more nodes one for root and one for the inner-most empty <iframe>.
  const size_t kNonEmptyIframesCount = 5;
  const std::string kScrollIntoViewScript =
      "document.body.scrollIntoView({'behavior' : 'instant'});";
  const int kRectDimensionErrorTolerance = 0;

  // First, recursively set the |scrollTop| and |scrollLeft| of |document.body|
  // to its maximum and then navigate the <iframe> to |url_a|. The page will be
  // structured as a(a(a(a(a(a(a)))))) where the inner-most <iframe> is empty.
  ASSERT_TRUE(NavigateToURL(shell(), url_a));
  FrameTreeNode* node = web_contents()->GetFrameTree()->root();
  WaitForOnLoad(node);
  std::vector<gfx::Rect> reference_page_bounds_before_scroll = {
      GetBoundingClientRect(node, kIframeSelector)};
  node = node->child_at(0);
  for (size_t index = 0; index < kNonEmptyIframesCount; ++index) {
    NavigateFrameToURL(node, url_a);
    WaitForOnLoad(node);
    // Store |document.querySelector('iframe').getBoundingClientRect()|.
    reference_page_bounds_before_scroll.push_back(
        GetBoundingClientRect(node, kIframeSelector));
    node = node->child_at(0);
  }
  // Sanity-check: If the page is setup properly then all the <iframe>s should
  // be out of view and their bounding rect should not intersect with the
  // positive XY plane.
  for (const auto& rect : reference_page_bounds_before_scroll)
    ASSERT_FALSE(rect.Intersects(kPositiveXYPlane));
  // Now scroll the inner-most frame into view.
  ASSERT_TRUE(ExecuteScript(node, kScrollIntoViewScript));
  // Store current client bounds origins to later compare against those from the
  // page which contains OOPIFs.
  node = web_contents()->GetFrameTree()->root();
  std::vector<gfx::Rect> reference_page_bounds_after_scroll = {
      GetBoundingClientRect(node, kIframeSelector)};
  node = node->child_at(0);
  for (size_t index = 0; index < kNonEmptyIframesCount; ++index) {
    reference_page_bounds_after_scroll.push_back(
        GetBoundingClientRect(node, kIframeSelector));
    node = node->child_at(0);
  }

  // Repeat the same process for the page containing OOPIFs. The page is
  // structured as b(b(a(c(a(a(a)))))) where the inner-most <iframe> is empty.
  ASSERT_TRUE(NavigateToURL(shell(), url_b));
  node = web_contents()->GetFrameTree()->root();
  WaitForOnLoad(node);
  std::vector<gfx::Rect> test_page_bounds_before_scroll = {
      GetBoundingClientRect(node, kIframeSelector)};
  const GURL iframe_urls[] = {url_b, url_a, url_c, url_a, url_a};
  node = node->child_at(0);
  for (size_t index = 0; index < kNonEmptyIframesCount; ++index) {
    NavigateFrameToURL(node, iframe_urls[index]);
    WaitForOnLoad(node);
    test_page_bounds_before_scroll.push_back(
        GetBoundingClientRect(node, kIframeSelector));
    node = node->child_at(0);
  }
  // Sanity-check: The bounds should match those from non-OOPIF page.
  for (size_t index = 0; index < kNonEmptyIframesCount; ++index) {
    ASSERT_TRUE(test_page_bounds_before_scroll[index].ApproximatelyEqual(
        reference_page_bounds_before_scroll[index],
        kRectDimensionErrorTolerance));
  }
  // Scroll the inner most OOPIF.
  ASSERT_TRUE(ExecuteScript(node, kScrollIntoViewScript));
  // Now traverse the chain bottom to top and verify the bounds match for each
  // <iframe>.
  int index = kNonEmptyIframesCount;
  RenderFrameHostImpl* current_rfh = node->current_frame_host()->GetParent();
  while (current_rfh) {
    gfx::Rect current_bounds =
        GetBoundingClientRect(current_rfh->frame_tree_node(), kIframeSelector);
    gfx::Rect reference_bounds = reference_page_bounds_after_scroll[index];
    if (current_bounds.ApproximatelyEqual(reference_bounds,
                                          kRectDimensionErrorTolerance)) {
      current_rfh = current_rfh->GetParent();
      --index;
    } else {
      base::RunLoop run_loop;
      base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
          FROM_HERE, run_loop.QuitClosure(), TestTimeouts::tiny_timeout());
      run_loop.Run();
    }
  }
}

// This test verifies that ScrollFocusedEditableElementIntoView works correctly
// for OOPIFs. Essentially, the test verifies that in a similar setup, the
// resultant page scale factor is the same for OOPIF and non-OOPIF cases. This
// also verifies that in response to the scroll command, the root-layer scrolls
// correctly and the <input> is visible in visual viewport.
#if defined(OS_ANDROID)
// crbug.com/793616
#define MAYBE_ScrollFocusedEditableElementIntoView \
  DISABLED_ScrollFocusedEditableElementIntoView
#else
#define MAYBE_ScrollFocusedEditableElementIntoView \
  ScrollFocusedEditableElementIntoView
#endif
IN_PROC_BROWSER_TEST_F(SitePerProcessProgrammaticScrollTest,
                       MAYBE_ScrollFocusedEditableElementIntoView) {
  GURL url_a(embedded_test_server()->GetURL("a.com", kIframeOutOfViewHTML));
  GURL url_b(embedded_test_server()->GetURL("b.com", kIframeOutOfViewHTML));

#if defined(OS_ANDROID)
  // The reason for Android specific code is that
  // AutoZoomFocusedNodeToLegibleScale is in blink's WebSettings and difficult
  // to access from here. It so happens that the setting is on for Android.

  // A lower bound on the ratio of page scale factor after scroll. The actual
  // value depends on minReadableCaretHeight / caret_bounds.Height(). The page
  // is setup so caret height is quite small so the expected scale should be
  // larger than 2.0.
  float kLowerBoundOnScaleAfterScroll = 2.0;
  float kEpsilon = 0.1;
#endif

  ASSERT_TRUE(NavigateToURL(shell(), url_a));
  FrameTreeNode* root = web_contents()->GetFrameTree()->root();
  WaitForOnLoad(root);
  NavigateFrameToURL(root->child_at(0), url_a);
  WaitForOnLoad(root->child_at(0));
#if defined(OS_ANDROID)
  float scale_before_scroll_nonoopif = GetVisualViewportScale(root);
#endif
  AddFocusedInputField(root->child_at(0));
  // Focusing <input> causes scrollIntoView(). The following line makes sure
  // that the <iframe> is out of view again.
  SetWindowScroll(root, 0, 0);
  ASSERT_FALSE(GetVisualViewport(root).Intersects(
      GetBoundingClientRect(root, kIframeSelector)));
  root->child_at(0)
      ->current_frame_host()
      ->GetFrameInputHandler()
      ->ScrollFocusedEditableNodeIntoRect(gfx::Rect());
  WaitForElementVisible(root, kIframeSelector);
#if defined(OS_ANDROID)
  float scale_after_scroll_nonoopif = GetVisualViewportScale(root);
  // Increased scale means zoom triggered correctly.
  EXPECT_GT(scale_after_scroll_nonoopif - scale_before_scroll_nonoopif,
            kEpsilon);
  EXPECT_GT(scale_after_scroll_nonoopif, kLowerBoundOnScaleAfterScroll);
#endif

  // Retry the test on an OOPIF page.
  Shell* new_shell = CreateBrowser();
  ASSERT_TRUE(NavigateToURL(new_shell, url_b));
  root = static_cast<WebContentsImpl*>(new_shell->web_contents())
             ->GetFrameTree()
             ->root();
  WaitForOnLoad(root);
#if defined(OS_ANDROID)
  float scale_before_scroll_oopif = GetVisualViewportScale(root);
  // Sanity-check:
  ASSERT_NEAR(scale_before_scroll_oopif, scale_before_scroll_nonoopif,
              kEpsilon);
#endif
  NavigateFrameToURL(root->child_at(0), url_a);
  WaitForOnLoad(root->child_at(0));
  AddFocusedInputField(root->child_at(0));
  SetWindowScroll(root, 0, 0);
  ASSERT_FALSE(GetVisualViewport(root).Intersects(
      GetBoundingClientRect(root, kIframeSelector)));
  root->child_at(0)
      ->current_frame_host()
      ->GetFrameInputHandler()
      ->ScrollFocusedEditableNodeIntoRect(gfx::Rect());
  WaitForElementVisible(root, kIframeSelector);
#if defined(OS_ANDROID)
  float scale_after_scroll_oopif = GetVisualViewportScale(root);
  EXPECT_GT(scale_after_scroll_oopif - scale_before_scroll_oopif, kEpsilon);
  EXPECT_GT(scale_after_scroll_oopif, kLowerBoundOnScaleAfterScroll);
  // The scale is based on the caret height and it should be the same in both
  // OOPIF and non-OOPIF pages.
  EXPECT_NEAR(scale_after_scroll_oopif, scale_after_scroll_nonoopif, kEpsilon);
#endif
  // Make sure the <input> is at least partly visible in the |visualViewport|.
  gfx::Rect final_visual_viewport_oopif = GetVisualViewport(root);
  gfx::Rect iframe_bounds_after_scroll_oopif =
      GetBoundingClientRect(root, kIframeSelector);
  gfx::Rect input_bounds_after_scroll_oopif =
      GetBoundingClientRect(root->child_at(0), kInputSelector);
  input_bounds_after_scroll_oopif +=
      iframe_bounds_after_scroll_oopif.OffsetFromOrigin();
  ASSERT_TRUE(
      final_visual_viewport_oopif.Intersects(input_bounds_after_scroll_oopif));
}

IN_PROC_BROWSER_TEST_F(SitePerProcessProgrammaticScrollTest,
                       ScrollClippedFocusedEditableElementIntoView) {
  GURL url_a(embedded_test_server()->GetURL("a.com", kIframeClippedHTML));
  GURL child_url_b(embedded_test_server()->GetURL("b.com", kInputBoxHTML));

  ASSERT_TRUE(NavigateToURL(shell(), url_a));
  FrameTreeNode* root = web_contents()->GetFrameTree()->root();
  WaitForOnLoad(root);
  NavigateFrameToURL(root->child_at(0), child_url_b);
  WaitForOnLoad(root->child_at(0));

  SetWindowScroll(root, 0, 0);
  SetWindowScroll(root->child_at(0), 1000, 2000);

  float scale_before = GetVisualViewportScale(root);

  // The input_box page focuses the input box on load. This call should
  // simulate the scroll into view we do when an input box is tapped.
  root->child_at(0)
      ->current_frame_host()
      ->GetFrameInputHandler()
      ->ScrollFocusedEditableNodeIntoRect(gfx::Rect());

  // The scroll into view is animated on the compositor. Make sure we wait
  // until that's completed before testing the rects.
  WaitForElementVisible(root, kIframeSelector);
  WaitForViewportToStabilize(root);

  // These rects are in the coordinate space of the root frame.
  gfx::Rect visual_viewport_rect = GetVisualViewport(root);
  gfx::Rect window_rect = GetBoundingClientRect(root, ":root");
  gfx::Rect iframe_rect = GetBoundingClientRect(root, "iframe");
  gfx::Rect clip_rect = GetBoundingClientRect(root, "#clip");

  // This is in the coordinate space of the iframe, we'll add the iframe offset
  // after to put it into the root frame's coordinate space.
  gfx::Rect input_rect = GetBoundingClientRect(root->child_at(0), "input");

  // Make sure the input rect is visible in the iframe.
  EXPECT_TRUE(gfx::Rect(iframe_rect.size()).Intersects(input_rect))
      << "Input box [" << input_rect.ToString() << "] isn't visible in iframe ["
      << gfx::Rect(iframe_rect.size()).ToString() << "]";

  input_rect += iframe_rect.OffsetFromOrigin();

  // Make sure the input rect is visible through the clipping layer.
  EXPECT_TRUE(clip_rect.Intersects(input_rect))
      << "Input box [" << input_rect.ToString() << "] isn't scrolled into view "
      << "of the clipping layer [" << clip_rect.ToString() << "]";

  // And finally, it should be visible in the layout and visual viewports.
  EXPECT_TRUE(window_rect.Intersects(input_rect))
      << "Input box [" << input_rect.ToString() << "] isn't visible in the "
      << "layout viewport [" << window_rect.ToString() << "]";
  EXPECT_TRUE(visual_viewport_rect.Intersects(input_rect))
      << "Input box [" << input_rect.ToString() << "] isn't visible in the "
      << "visual viewport [" << visual_viewport_rect.ToString() << "]";

  float scale_after = GetVisualViewportScale(root);

// Make sure we still zoom in on the input box on platforms that zoom into the
// focused editable.
#if defined(OS_ANDROID)
  EXPECT_GT(scale_after, scale_before);
#else
  EXPECT_FLOAT_EQ(scale_after, scale_before);
#endif
}

IN_PROC_BROWSER_TEST_F(SitePerProcessProgrammaticScrollTest,
                       ScrolledOutOfView) {
  GURL main_frame(
      embedded_test_server()->GetURL("a.com", kIframeOutOfViewHTML));
  GURL child_url_b(
      embedded_test_server()->GetURL("b.com", kIframeOutOfViewHTML));

  // This will set up the page frame tree as A(B()).
  ASSERT_TRUE(NavigateToURL(shell(), main_frame));
  FrameTreeNode* root = web_contents()->GetFrameTree()->root();
  WaitForOnLoad(root);
  NavigateFrameToURL(root->child_at(0), child_url_b);
  WaitForOnLoad(root->child_at(0));

  FrameTreeNode* nested_iframe_node = root->child_at(0);
  RenderFrameProxyHost* proxy_to_parent =
      nested_iframe_node->render_manager()->GetProxyToParent();
  CrossProcessFrameConnector* connector =
      proxy_to_parent->cross_process_frame_connector();

  while (blink::mojom::FrameVisibility::kRenderedOutOfViewport !=
         connector->visibility()) {
    base::RunLoop run_loop;
    base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
        FROM_HERE, run_loop.QuitClosure(), TestTimeouts::tiny_timeout());
    run_loop.Run();
  }
}

// This test verifies that smooth scrolling works correctly inside nested OOPIFs
// which are same origin with the parent. Note that since the frame tree has
// a A(B(A1())) structure, if and A1 and A2 shared the same
// SmoothScrollSequencer, then this test would time out or at best be flaky with
// random time outs. See https://crbug.com/865446 for more context.
IN_PROC_BROWSER_TEST_F(SitePerProcessProgrammaticScrollTest,
                       SmoothScrollInNestedSameProcessOOPIF) {
  GURL main_frame(
      embedded_test_server()->GetURL("a.com", kIframeOutOfViewHTML));
  GURL child_url_b(
      embedded_test_server()->GetURL("b.com", kIframeOutOfViewHTML));
  GURL same_origin(
      embedded_test_server()->GetURL("a.com", kIframeOutOfViewHTML));

  // This will set up the page frame tree as A(B(A1(A2()))) where A1 is later
  // asked to scroll the <iframe> element of A2 into view. The important bit
  // here is that the inner frame A1 is recursively scrolling (smoothly) an
  // element inside its document into view (A2's origin is irrelevant here).
  ASSERT_TRUE(NavigateToURL(shell(), main_frame));
  FrameTreeNode* root = web_contents()->GetFrameTree()->root();
  WaitForOnLoad(root);
  NavigateFrameToURL(root->child_at(0), child_url_b);
  WaitForOnLoad(root->child_at(0));
  auto* nested_ftn = root->child_at(0)->child_at(0);
  NavigateFrameToURL(nested_ftn, same_origin);
  WaitForOnLoad(nested_ftn);

  // *Smoothly* scroll the inner most frame into view.
  ASSERT_TRUE(ExecuteScript(
      nested_ftn,
      "document.querySelector('iframe').scrollIntoView({behavior: 'smooth'})"));
  WaitForElementVisible(root, kIframeSelector);
  WaitForElementVisible(root->child_at(0), kIframeSelector);
  WaitForElementVisible(nested_ftn, kIframeSelector);
}

// Tests OOPIF rendering by checking that the RWH of the iframe generates
// OnSwapCompositorFrame message.
IN_PROC_BROWSER_TEST_F(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()->GetFrameTree()->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_F(SitePerProcessBrowserTest, CleanupCrossSiteIframe) {
  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()->GetFrameTree()->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");
  NavigateFrameToURL(root->child_at(0), foo_url);
  EXPECT_TRUE(observer.last_navigation_succeeded());
  EXPECT_EQ(foo_url, observer.last_navigation_url());
  NavigateFrameToURL(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()
                                ->GetID();
  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(ExecuteScript(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_F(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()->GetFrameTree()->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"));
  NavigateFrameToURL(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());
    NavigateFrameToURL(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());
    NavigateFrameToURL(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_F(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()->GetFrameTree()->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"));
  NavigateFrameToURL(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");
  NavigateFrameToURL(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 SiteInstance
  // as the parent frame.
  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.
  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");
  NavigateFrameToURL(child, url);
  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"
      "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");
  NavigateFrameToURL(child, url);
  EXPECT_TRUE(observer.last_navigation_succeeded());
  EXPECT_EQ(url, observer.last_navigation_url());
  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);
  ExecuteScriptAsync(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.
  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_F(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()->GetFrameTree()->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);
  NavigateFrameToURL(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_F(SitePerProcessBrowserTest, RemoveFocusFromKilledFrame) {
  GURL main_url(embedded_test_server()->GetURL(
      "foo.com", "/cross_site_iframe_factory.html?foo.com(bar.com)"));
  NavigateToURL(shell(), main_url);

  // It is safe to obtain the root frame tree node here, as it doesn't change.
  FrameTreeNode* root = web_contents()->GetFrameTree()->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());

  // 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_F(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()->GetFrameTree()->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");
  NavigateFrameToURL(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_F(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()->GetFrameTree()->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"));
    NavigateFrameToURL(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");
    NavigateFrameToURL(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_F(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()->GetFrameTree()->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");
  std::unique_ptr<URLLoaderInterceptor> url_loader_interceptor;
  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();

  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.GetOrigin().spec(),
            child->current_origin().Serialize() + '/');

  // Ensure that we have created a new process for the subframe.
  // PlzNavigate: the subframe should still be in its separate process.
  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.GetOrigin().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_F(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()->GetFrameTree()->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");
  NavigateFrameToURL(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_F(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()->GetFrameTree()->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));
  SiteInstance* 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(ExecuteScript(
      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->render_manager()->GetRenderFrameProxyHost(b_site_instance);
  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");
  NavigateFrameToURL(root->child_at(1), b_url);
  EXPECT_TRUE(observer.last_navigation_succeeded());
  EXPECT_EQ(b_url, observer.last_navigation_url());

  // Ensure that the grandchild RenderFrameProxy 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_F(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()->GetFrameTree()->root();
  SiteInstance* 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(ExecuteScript(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())
          ->GetFrameTree()
          ->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->render_manager()->GetRenderFrameProxyHost(site_instance_a);
  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(ExecuteScript(
      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)->render_manager()->GetRenderFrameProxyHost(
          site_instance_a);
  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_F(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()->GetFrameTree()->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|'s frames and proxies are expected to go away once we kill
  // |child_process_b| below.
  scoped_refptr<SiteInstanceImpl> site_instance_c =
      node4->current_frame_host()->GetSiteInstance();

  // 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->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->active_frame_count());
}

// Crash a subframe and ensures its children are cleared from the FrameTree.
// See http://crbug.com/338508.
IN_PROC_BROWSER_TEST_F(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()->GetFrameTree()->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());
  EXPECT_FALSE(child->current_frame_host()->render_frame_created_);

  // 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_F(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()->GetFrameTree()->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(ExecuteScript(shell(), "addFrame('data:text/html,foo');"));
  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_F(SitePerProcessBrowserTest,
                       DISABLED_CrossSiteIframeRedirectOnce) {
  net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS);
  https_server.ServeFilesFromSourceDirectory("content/test/data");
  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()));

    RedirectNotificationObserver load_observer2(
        NOTIFICATION_LOAD_STOP, Source<NavigationController>(
                                    &shell()->web_contents()->GetController()));

    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()));
    RedirectNotificationObserver load_observer2(
        NOTIFICATION_LOAD_STOP, Source<NavigationController>(
                                    &shell()->web_contents()->GetController()));

    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_F(SitePerProcessBrowserTest,
                       DISABLED_CrossSiteIframeRedirectTwice) {
  net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS);
  https_server.ServeFilesFromSourceDirectory("content/test/data");
  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.
    RedirectNotificationObserver load_observer2(
        NOTIFICATION_LOAD_STOP, Source<NavigationController>(
                                    &shell()->web_contents()->GetController()));

    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_F(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()->GetFrameTree()->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"));
    NavigateFrameToURL(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());
    TestFrameNavigationObserver navigation_observer(child);
    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()->GetController()->LoadURLWithParams(params);

    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.
    navigation_observer.Wait();
    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());
    TestFrameNavigationObserver navigation_observer(child);
    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()->GetController()->LoadURLWithParams(params);

    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));

    navigation_observer.Wait();
    EXPECT_TRUE(observer.last_navigation_succeeded());
    EXPECT_EQ(cross_site_url, observer.last_navigation_url());
    EXPECT_EQ(0U, child->child_count());
  }
}

// Verify that "scrolling" property on frame elements propagates to child frames
// correctly.
// Does not work on android since android has scrollbars overlayed.
// TODO(bokan): Pretty soon most/all platforms will use overlay scrollbars. This
// test should find a better way to check for scrollability. crbug.com/662196.
// Flaky on Linux. crbug.com/790929.
#if defined(OS_ANDROID) || defined(OS_LINUX)
#define MAYBE_FrameOwnerPropertiesPropagationScrolling \
  DISABLED_FrameOwnerPropertiesPropagationScrolling
#else
#define MAYBE_FrameOwnerPropertiesPropagationScrolling \
  FrameOwnerPropertiesPropagationScrolling
#endif
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
                       MAYBE_FrameOwnerPropertiesPropagationScrolling) {
#if defined(OS_MACOSX)
  ui::test::ScopedPreferredScrollerStyle scroller_style_override(false);
#endif
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/frame_owner_properties_scrolling.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()->GetFrameTree()->root();
  ASSERT_EQ(1u, root->child_count());

  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);

  // If the available client width within the iframe is smaller than the
  // frame element's width, we assume there's a scrollbar.
  // Also note that just comparing clientHeight and scrollHeight of the frame's
  // document will not work.
  auto has_scrollbar = [](RenderFrameHostImpl* rfh) {
    int client_width = EvalJs(rfh, "document.body.clientWidth").ExtractInt();
    const int kFrameElementWidth = 200;
    return client_width < kFrameElementWidth;
  };

  auto set_scrolling_property = [](RenderFrameHostImpl* parent_rfh,
                                   const std::string& value) {
    EXPECT_TRUE(ExecJs(
        parent_rfh,
        base::StringPrintf("document.getElementById('child-1').setAttribute("
                           "    'scrolling', '%s');",
                           value.c_str())));
  };

  // Run the test over variety of parent/child cases.
  GURL urls[] = {// Remote to remote.
                 embedded_test_server()->GetURL("c.com", "/tall_page.html"),
                 // Remote to local.
                 embedded_test_server()->GetURL("a.com", "/tall_page.html"),
                 // Local to remote.
                 embedded_test_server()->GetURL("b.com", "/tall_page.html")};
  const std::string scrolling_values[] = {"yes", "auto", "no"};

  for (size_t i = 0; i < base::size(scrolling_values); ++i) {
    bool expect_scrollbar = scrolling_values[i] != "no";
    set_scrolling_property(root->current_frame_host(), scrolling_values[i]);
    for (size_t j = 0; j < base::size(urls); ++j) {
      NavigateFrameToURL(child, urls[j]);
      EXPECT_EQ(expect_scrollbar, has_scrollbar(child->current_frame_host()));
    }
  }
}

// Verify that "marginwidth" and "marginheight" properties on frame elements
// propagate to child frames correctly.
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
                       FrameOwnerPropertiesPropagationMargin) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/frame_owner_properties_margin.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()->GetFrameTree()->root();
  ASSERT_EQ(1u, root->child_count());

  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_EQ("10", EvalJs(child, "document.body.getAttribute('marginwidth');"));
  EXPECT_EQ("50", EvalJs(child, "document.body.getAttribute('marginheight');"));

  // Run the test over variety of parent/child cases.
  GURL urls[] = {// Remote to remote.
                 embedded_test_server()->GetURL("c.com", "/title2.html"),
                 // Remote to local.
                 embedded_test_server()->GetURL("a.com", "/title1.html"),
                 // Local to remote.
                 embedded_test_server()->GetURL("b.com", "/title2.html")};

  int current_margin_width = 15;
  int current_margin_height = 25;

  // Before each navigation, we change the marginwidth and marginheight
  // properties of the frame. We then check whether those properties are applied
  // correctly after the navigation has completed.
  for (size_t i = 0; i < base::size(urls); ++i) {
    // Change marginwidth and marginheight before navigating.
    EXPECT_TRUE(ExecJs(
        root,
        base::StringPrintf("var child = document.getElementById('child-1');"
                           "child.setAttribute('marginwidth', '%d');"
                           "child.setAttribute('marginheight', '%d');",
                           current_margin_width, current_margin_height)));

    NavigateFrameToURL(child, urls[i]);

    EXPECT_EQ(base::NumberToString(current_margin_width),
              EvalJs(child, "document.body.getAttribute('marginwidth');"));
    EXPECT_EQ(base::NumberToString(current_margin_height),
              EvalJs(child, "document.body.getAttribute('marginheight');"));

    current_margin_width += 5;
    current_margin_height += 10;
  }
}

// Verify that "csp" property on frame elements propagates to child frames
// correctly. See  https://crbug.com/647588
IN_PROC_BROWSER_TEST_F(SitePerProcessEmbedderCSPEnforcementBrowserTest,
                       FrameOwnerPropertiesPropagationCSP) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/frame_owner_properties_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()->GetFrameTree()->root();
  ASSERT_EQ(1u, root->child_count());

  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_EQ(
      "object-src \'none\'",
      EvalJs(root, "document.getElementById('child-1').getAttribute('csp');"));

  // Run the test over variety of parent/child cases.
  GURL urls[] = {// Remote to remote.
                 embedded_test_server()->GetURL("c.com", "/title2.html"),
                 // Remote to local.
                 embedded_test_server()->GetURL("a.com", "/title1.html"),
                 // Local to remote.
                 embedded_test_server()->GetURL("b.com", "/title2.html")};

  std::vector<std::string> csp_values = {"default-src a.com",
                                         "default-src b.com", "img-src c.com"};

  // Before each navigation, we change the csp property of the frame.
  // We then check whether that property is applied
  // correctly after the navigation has completed.
  for (size_t i = 0; i < base::size(urls); ++i) {
    // Change csp before navigating.
    EXPECT_TRUE(ExecuteScript(
        root,
        base::StringPrintf("document.getElementById('child-1').setAttribute("
                           "    'csp', '%s');",
                           csp_values[i].c_str())));

    NavigateFrameToURL(child, urls[i]);
    EXPECT_EQ(csp_values[i], child->frame_owner_properties().required_csp);
    // TODO(amalika): add checks that the CSP replication takes effect
  }
}

// Verify origin replication with an A-embed-B-embed-C-embed-A hierarchy.
IN_PROC_BROWSER_TEST_F(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()->GetFrameTree()->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
  // RenderFrameProxy 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
  // mojom::Renderer::CreateFrameProxy 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.
IN_PROC_BROWSER_TEST_F(SitePerProcessAutoplayBrowserTest,
                       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.
  OpenURLBlockUntilNavigationComplete(shell(), main_url);
  FrameTreeNode* root = web_contents()->GetFrameTree()->root();

  // Navigate the subframes to cross-origin pages.
  NavigateFrameAndWait(root->child_at(0), foo_url);
  NavigateFrameAndWait(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.
  OpenURLBlockUntilNavigationComplete(shell(), secondary_url);
  root = web_contents()->GetFrameTree()->root();

  // Navigate the subframes to cross-origin pages.
  NavigateFrameAndWait(root->child_at(0), foo_url);
  NavigateFrameAndWait(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.
  OpenURLBlockUntilNavigationComplete(shell(), disabled_url);
  NavigateFrameAndWait(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.
  OpenURLBlockUntilNavigationComplete(shell(), foo_url);
  NavigateFrameAndWait(root->child_at(0), bar_url);
  EXPECT_FALSE(AutoplayAllowed(shell(), false));
  EXPECT_FALSE(AutoplayAllowed(shell(), false));
}

IN_PROC_BROWSER_TEST_F(SitePerProcesScrollAnchorTest,
                       RemoteToLocalScrollAnchorRestore) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/page_with_samesite_iframe.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

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

  GURL frame_url(embedded_test_server()->GetURL("b.com", "/title1.html"));
  NavigateFrameToURL(child, frame_url);

  EXPECT_NE(child->current_frame_host()->GetSiteInstance(),
            root->current_frame_host()->GetSiteInstance());

  TestFrameNavigationObserver frame_observer2(child);
  EXPECT_TRUE(ExecuteScript(root, "window.history.back()"));
  frame_observer2.Wait();

  EXPECT_EQ(child->current_frame_host()->GetSiteInstance(),
            root->current_frame_host()->GetSiteInstance());
}

// Check that iframe sandbox flags are replicated correctly.
IN_PROC_BROWSER_TEST_F(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()->GetFrameTree()->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"));
  NavigateFrameToURL(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"));
  NavigateFrameToURL(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_F(SitePerProcessBrowserTest, DynamicSandboxFlags) {
  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()->GetFrameTree()->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"));
  NavigateFrameToURL(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(blink::WebSandboxFlags::kNone,
            root->child_at(0)->pending_frame_policy().sandbox_flags);
  EXPECT_EQ(blink::WebSandboxFlags::kNone,
            root->child_at(0)->effective_frame_policy().sandbox_flags);
  EXPECT_EQ(blink::WebSandboxFlags::kNone,
            root->child_at(1)->pending_frame_policy().sandbox_flags);
  EXPECT_EQ(blink::WebSandboxFlags::kNone,
            root->child_at(1)->effective_frame_policy().sandbox_flags);

  // Dynamically update sandbox flags for the first frame.
  EXPECT_TRUE(ExecuteScript(
      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().
  blink::WebSandboxFlags expected_flags =
      blink::WebSandboxFlags::kAll & ~blink::WebSandboxFlags::kScripts &
      ~blink::WebSandboxFlags::kAutomaticFeatures;
  EXPECT_EQ(expected_flags,
            root->child_at(0)->pending_frame_policy().sandbox_flags);
  EXPECT_EQ(blink::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"));
  NavigateFrameToURL(root->child_at(0), bar_url);
  // (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(
      " 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/\n"
      "      C = http://baz.com/",
      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.
  GURL baz_child_url(embedded_test_server()->GetURL("baz.com", "/title2.html"));
  NavigateFrameToURL(root->child_at(0)->child_at(0), baz_child_url);
  EXPECT_TRUE(observer.last_navigation_succeeded());
  EXPECT_EQ(baz_child_url, observer.last_navigation_url());

  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_F(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()->GetFrameTree()->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(ExecuteScript(
      shell(),
      "document.querySelectorAll('iframe')[1].sandbox='allow-scripts'"));

  // Check that the current sandbox flags are updated but the effective
  // sandbox flags are not.
  blink::WebSandboxFlags expected_flags =
      blink::WebSandboxFlags::kAll & ~blink::WebSandboxFlags::kScripts &
      ~blink::WebSandboxFlags::kAutomaticFeatures;
  EXPECT_EQ(expected_flags,
            root->child_at(1)->pending_frame_policy().sandbox_flags);
  EXPECT_EQ(blink::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"));
  NavigateFrameToURL(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_F(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()->GetFrameTree()->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(blink::WebSandboxFlags::kNone,
            root->child_at(0)->pending_frame_policy().sandbox_flags);
  EXPECT_EQ(blink::WebSandboxFlags::kNone,
            root->child_at(0)->effective_frame_policy().sandbox_flags);

  // Dynamically update the frame's sandbox flags.
  EXPECT_TRUE(ExecuteScript(
      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().
  blink::WebSandboxFlags expected_flags =
      blink::WebSandboxFlags::kAll & ~blink::WebSandboxFlags::kScripts &
      ~blink::WebSandboxFlags::kAutomaticFeatures;
  EXPECT_EQ(expected_flags,
            root->child_at(0)->pending_frame_policy().sandbox_flags);
  EXPECT_EQ(blink::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(
      ExecuteScript(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.
// TODO(alexmos): Re-enable when https://crbug.com/610893 is fixed.
IN_PROC_BROWSER_TEST_F(
    SitePerProcessBrowserTest,
    DISABLED_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()->GetFrameTree()->root();
  TestNavigationObserver observer(shell()->web_contents());

  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
  // pending RFH when starting the cross-site navigation to baz.com.
  RenderFrameHostCreatedObserver frame_observer(shell()->web_contents(), 3);
  EXPECT_TRUE(ExecuteScript(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.
  FrameTreeNode* bottom_child = root->child_at(1)->child_at(0);
  TestFrameNavigationObserver navigation_observer(bottom_child);
  navigation_observer.Wait();

  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.
  EXPECT_EQ(ListValueOf(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 WebSandboxFlags::Scripts and
  // WebSandboxFlags::AutomaticFeatures bits per blink::parseSandboxPolicy().
  blink::WebSandboxFlags expected_flags =
      blink::WebSandboxFlags::kAll & ~blink::WebSandboxFlags::kScripts &
      ~blink::WebSandboxFlags::kAutomaticFeatures &
      ~blink::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_F(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()->GetFrameTree()->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");
  NavigateFrameToURL(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_F(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()->GetFrameTree()->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");
  NavigateFrameToURL(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(
      ExecuteScript(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.
  //
  // TODO(yukishiino): The following expectation should be |true|, but we're
  // intentionally disabling the name and origin check of the named access on
  // window.  See also crbug.com/538562 and crbug.com/701489.
  EXPECT_EQ(false, 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(ExecuteScript(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(ExecuteScript(
      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_F(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()->GetFrameTree()->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");
  NavigateFrameToURL(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).
  std::unique_ptr<ConsoleObserverDelegate> console_delegate(
      new ConsoleObserverDelegate(
          shell()->web_contents(),
          "Unsafe JavaScript attempt to initiate navigation*"));
  shell()->web_contents()->SetDelegate(console_delegate.get());

  // 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(ExecuteScript(root->child_at(0),
                            "try { parent.frames['frame2'].location.href = "
                            "'data:text/html,foo'; } catch (e) {}"));
  console_delegate->Wait();

  std::string frame_origin = root->child_at(1)->current_origin().Serialize();
  EXPECT_EQ(frame_origin + "/", frame_url.GetOrigin().spec());
  EXPECT_TRUE(
      base::MatchPattern(console_delegate->message(), "*" + 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_F(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()->GetFrameTree()->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"));
  NavigateFrameToURL(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()->GetController()->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_F(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()->GetFrameTree()->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");
  NavigateFrameToURL(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_F(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()->GetFrameTree()->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");
  NavigateFrameToURL(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");
  NavigateFrameToURL(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.
  NavigateFrameToURL(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_F(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"));
    base::string16 expected_title(base::UTF8ToUTF16("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()->GetFrameTree()->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"));
    base::string16 expected_title(base::UTF8ToUTF16("LOADEDLOADED"));
    TitleWatcher title_watcher(shell()->web_contents(), expected_title);
    TestNavigationObserver observer(shell()->web_contents());
    NavigateFrameToURL(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_F(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()->GetFrameTree()->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.
  base::string16 expected_title(base::ASCIIToUTF16("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 renderer initiated navigations which commit a new RenderFrameHost
// do not crash if the original RenderFrameHost was being covered by an
// interstitial. See crbug.com/607964.
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
                       NavigateOpenerWithInterstitial) {
  EXPECT_TRUE(NavigateToURL(
      shell(), embedded_test_server()->GetURL("a.com", "/title1.html")));

  // Open a popup and navigate it to bar.com.
  ShellAddedObserver new_shell_observer;
  EXPECT_TRUE(ExecuteScript(web_contents(), "window.open('about:blank');"));
  Shell* popup = new_shell_observer.GetShell();
  EXPECT_TRUE(NavigateToURLFromRenderer(
      popup,
      embedded_test_server()->GetURL("bar.com", "/navigate_opener.html")));

  // Show an interstitial in the opener.
  TestInterstitialDelegate* delegate = new TestInterstitialDelegate;
  WebContentsImpl* opener_contents =
      static_cast<WebContentsImpl*>(web_contents());
  GURL interstitial_url("http://interstitial");
  InterstitialPageImpl* interstitial = new InterstitialPageImpl(
      opener_contents, static_cast<RenderWidgetHostDelegate*>(opener_contents),
      true, interstitial_url, delegate);
  interstitial->Show();
  WaitForInterstitialAttach(opener_contents);

  // Now, navigate the opener cross-process using the popup while it still has
  // an interstitial. This should not crash.
  TestNavigationObserver navigation_observer(opener_contents);
  EXPECT_TRUE(ExecuteScript(popup, "navigateOpener();"));
  navigation_observer.Wait();
}

// 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_F(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()->GetFrameTree()->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(ExecuteScript(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(ExecuteScript(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())
          ->GetFrameTree()
          ->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(ExecuteScript(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())
          ->GetFrameTree()
          ->root();
  EXPECT_TRUE(ExecuteScript(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 parent.frames[num] references correct sibling frames when the
// parent is remote.  See https://crbug.com/478792.
IN_PROC_BROWSER_TEST_F(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()->GetFrameTree()->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"));
  NavigateFrameToURL(child0, b_url);
  NavigateFrameToURL(child1, c_url);
  NavigateFrameToURL(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_F(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()->GetFrameTree()->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());
    NavigateFrameToURL(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");
    NavigateFrameToURL(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_F(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()->GetFrameTree()->root();

  // Navigate first child cross-site.
  GURL frame_url(embedded_test_server()->GetURL("b.com", "/title1.html"));
  NavigateFrameToURL(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())
          ->GetFrameTree()
          ->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())
          ->GetFrameTree()
          ->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_F(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());

  ConsoleObserverDelegate console_delegate(
      web_contents(), "Not allowed to load local resource:*");
  web_contents()->SetDelegate(&console_delegate);

  // 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_delegate.message(),
                                 "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_delegate.message(),
                         "Not allowed to load local resource: chrome:*"));
}

// Verify that named frames are discoverable from their opener's ancestors.
// See https://crbug.com/511474.
IN_PROC_BROWSER_TEST_F(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()->GetFrameTree()->root();

  // Navigate first child cross-site.
  GURL frame_url(embedded_test_server()->GetURL("b.com", "/title1.html"));
  NavigateFrameToURL(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())
          ->GetFrameTree()
          ->root();
  SiteInstance* site_instance_a = root->current_frame_host()->GetSiteInstance();
  RenderFrameProxyHost* popup_rfph_for_a =
      foo_root->render_manager()->GetRenderFrameProxyHost(site_instance_a);
  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());
}

// 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_F(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()->GetFrameTree()->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"));
  NavigateFrameToURL(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())
          ->GetFrameTree()
          ->root();
  SiteInstance* site_instance_a = root->current_frame_host()->GetSiteInstance();
  EXPECT_FALSE(
      foo_root->render_manager()->GetRenderFrameProxyHost(site_instance_a));

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

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

  // 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_F(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()->GetFrameTree()->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())
          ->GetFrameTree()
          ->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_F(SitePerProcessBrowserTest,
                       NavigatingSubframePreservesOpenerInParent) {
  GURL main_url = embedded_test_server()->GetURL("a.com", "/post_message.html");
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  FrameTreeNode* root = web_contents()->GetFrameTree()->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())
          ->GetFrameTree()
          ->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"));
  NavigateFrameToURL(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;"));

  base::string16 expected_title = base::ASCIIToUTF16("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_F(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()->GetFrameTree()->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"));
  NavigateFrameToURL(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"));
  NavigateFrameToURL(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
// RenderFrameProxy is created for that subframe in another renderer process.
// Similar to NavigateSubframeWithOpener, but this test verifies the subframe
// opener plumbing for mojom::Renderer::CreateFrameProxy(), whereas
// NavigateSubframeWithOpener targets mojom::Renderer::CreateFrame().
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
                       NewRenderFrameProxyPreservesOpener) {
  GURL main_url(
      embedded_test_server()->GetURL("foo.com", "/post_message.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  FrameTreeNode* root = web_contents()->GetFrameTree()->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())
          ->GetFrameTree()
          ->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"));
  NavigateFrameToURL(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;"));

  base::string16 expected_title = base::ASCIIToUTF16("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, A->B->A, and
// drop the SwapOut ACK from the A->B navigation, so that the second B->A
// navigation is initiated before the first page receives the SwapOut ACK.
// Ensure that this doesn't crash and that the RVH(A) is not reused in that
// case.
#if defined(OS_MACOSX)
#define MAYBE_RenderViewHostIsNotReusedAfterDelayedSwapOutACK \
  DISABLED_RenderViewHostIsNotReusedAfterDelayedSwapOutACK
#else
#define MAYBE_RenderViewHostIsNotReusedAfterDelayedSwapOutACK \
  RenderViewHostIsNotReusedAfterDelayedSwapOutACK
#endif
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
                       MAYBE_RenderViewHostIsNotReusedAfterDelayedSwapOutACK) {
  GURL a_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
  EXPECT_TRUE(NavigateToURL(shell(), a_url));

  FrameTreeNode* root = web_contents()->GetFrameTree()->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()->GetID();
  SiteInstanceImpl* site_instance = rfh->GetSiteInstance();
  RenderFrameDeletedObserver deleted_observer(rfh);

  // Install a BrowserMessageFilter to drop SwapOut ACK messages in A's
  // process.
  auto filter = base::MakeRefCounted<DropMessageFilter>(
      FrameMsgStart, FrameHostMsg_SwapOut_ACK::ID);
  rfh->GetProcess()->AddFilter(filter.get());
  rfh->DisableSwapOutTimerForTesting();

  // Navigate to B.  This must wait for DidCommitProvisionalLoad and not
  // DidStopLoading, so that the SwapOut timer doesn't call OnSwappedOut 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(ExecuteScript(shell(), JsReplace("location = $1", b_url)));
  commit_observer.WaitForCommit();
  EXPECT_FALSE(deleted_observer.deleted());

  // Since the SwapOut ACK for A->B is dropped, the first page's
  // RenderFrameHost should be pending deletion after the last navigation.
  EXPECT_FALSE(rfh->is_active());

  // Without the SwapOut ACK 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));
  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.
  TestNavigationObserver navigation_observer(shell()->web_contents());
  shell()->LoadURLForFrame(a_url, std::string(),
                           ui::PageTransitionFromInt(ui::PAGE_TRANSITION_LINK));
  RenderViewHostImpl* pending_rvh =
      root->render_manager()->speculative_frame_host()->render_view_host();
  EXPECT_EQ(site_instance, pending_rvh->GetSiteInstance());
  EXPECT_FALSE(rvh_routing_id == pending_rvh->GetRoutingID() &&
               rvh_process_id == pending_rvh->GetProcess()->GetID());

  // Make sure the last navigation finishes without crashing.
  navigation_observer.Wait();
}

// 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_F(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(ExecuteScript(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_F(SitePerProcessBrowserTest,
                       CrossProcessFocusChangeFiresBlurEvents) {
  GURL main_url(
      embedded_test_server()->GetURL("a.com", "/page_with_input_field.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  FrameTreeNode* root = web_contents()->GetFrameTree()->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.
  std::string result;
  EXPECT_TRUE(
      ExecuteScriptAndExtractString(shell(), "focusInputField()", &result));
  EXPECT_EQ(result, "input-focus");

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

  DOMMessageQueue msg_queue;

  // 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.
  std::string status;
  while (msg_queue.WaitForMessage(&status)) {
    if (status == "\"input-blur\"")
      break;
  }

  // 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()->GetRenderViewHost()->GetWidget(),
                     1, 1);

  // Check that the subframe lost focus and fired blur event on its
  // document's body.
  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_F(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));

  FrameTreeNode* root = web_contents()->GetFrameTree()->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_F(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()->GetFrameTree()->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_F(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()->GetFrameTree()->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"));
  NavigateFrameToURL(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.
  std::string activeTag;
  EXPECT_TRUE(ExecuteScriptAndExtractString(
      child1, "domAutomationController.send(document.activeElement.tagName)",
      &activeTag));
  EXPECT_EQ("input", base::ToLowerASCII(activeTag));
}

// Tests that we are using the correct RenderFrameProxy when navigating an
// opener window.
IN_PROC_BROWSER_TEST_F(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(ExecuteScript(
      popup, JsReplace("window.opener.location.href = $1", cross_url)));
  EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
  EXPECT_EQ(shell()->web_contents()->GetLastCommittedURL(), cross_url);
}

// 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_F(SitePerProcessBrowserTest,
                       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)->GetFrameTree()->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(ExecuteScript(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_F(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)->GetFrameTree()->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()->GetController()->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(ExecuteScript(
      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_F(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)->GetFrameTree()->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(ExecuteScript(
      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;"));
}

// Test for https://crbug.com/568670.  In A-embed-B, simultaneously have B
// create a new (local) child frame, and have A detach B's proxy.  The child
// frame creation sends an IPC to create a new proxy in A's process, and if
// that IPC arrives after the detach, the new frame's parent (a proxy) won't be
// available, and this shouldn't cause RenderFrameProxy::CreateFrameProxy to
// crash.
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
                       RaceBetweenCreateChildFrameAndDetachParentProxy) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  WebContents* contents = shell()->web_contents();
  FrameTreeNode* root =
      static_cast<WebContentsImpl*>(contents)->GetFrameTree()->root();

  // Simulate subframe B creating a new child frame in parallel to main frame A
  // detaching subframe B.  We can't use ExecuteScript in both A and B to do
  // this simultaneously, as that won't guarantee the timing that we want.
  // Instead, tell A to detach B and then send a fake proxy creation IPC to A
  // that would've come from create-child-frame code in B.  Prepare parameters
  // for that IPC ahead of the detach, while B's FrameTreeNode still exists.
  SiteInstance* site_instance_a = root->current_frame_host()->GetSiteInstance();
  RenderProcessHost* process_a =
      root->render_manager()->current_frame_host()->GetProcess();
  int new_routing_id = process_a->GetNextRoutingID();
  int view_routing_id =
      root->frame_tree()->GetRenderViewHost(site_instance_a)->GetRoutingID();
  int parent_routing_id =
      root->child_at(0)->render_manager()->GetProxyToParent()->GetRoutingID();

  // Tell main frame A to delete its subframe B.
  FrameDeletedObserver observer(root->child_at(0)->current_frame_host());
  EXPECT_TRUE(ExecuteScript(
      root, "document.body.removeChild(document.querySelector('iframe'));"));

  // Send the message to create a proxy for B's new child frame in A.  This
  // used to crash, as parent_routing_id refers to a proxy that doesn't exist
  // anymore.
  process_a->GetRendererInterface()->CreateFrameProxy(
      new_routing_id, view_routing_id, MSG_ROUTING_NONE, parent_routing_id,
      FrameReplicationState(), base::UnguessableToken::Create());

  // Ensure the subframe is detached in the browser process.
  observer.Wait();
  EXPECT_EQ(0U, root->child_count());

  // Make sure process A did not crash.
  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_F(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()->GetFrameTree()->root()->child_at(0);
  EXPECT_TRUE(node);
  EXPECT_NE(node->current_frame_host()->GetSiteInstance(),
            node->parent()->current_frame_host()->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()->GetController()->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();
  RenderProcessHostWatcher watcher(
      process, RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
  int frame_routing_id =
      node->render_manager()->speculative_frame_host()->GetRoutingID();
  int previous_routing_id =
      node->render_manager()->GetProxyToParent()->GetRoutingID();

  // 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.
  NavigateFrameToURL(node,
                     embedded_test_server()->GetURL("c.com", "/title2.html"));
  {
    mojom::CreateFrameParamsPtr params = mojom::CreateFrameParams::New();
    params->routing_id = frame_routing_id;
    params->interface_bundle = mojom::DocumentScopedInterfaceBundle::New();
    mojo::MakeRequest(&params->interface_bundle->interface_provider);
    mojo::MakeRequest(
        &params->interface_bundle->document_interface_broker_content);
    mojo::MakeRequest(
        &params->interface_bundle->document_interface_broker_blink);
    params->previous_routing_id = previous_routing_id;
    params->opener_routing_id = IPC::mojom::kRoutingIdNone;
    params->parent_routing_id =
        shell()->web_contents()->GetMainFrame()->GetRoutingID();
    params->previous_sibling_routing_id = IPC::mojom::kRoutingIdNone;
    params->widget_params = mojom::CreateFrameWidgetParams::New();
    params->widget_params->routing_id = IPC::mojom::kRoutingIdNone;
    params->widget_params->hidden = true;
    params->replication_state.name = "name";
    params->replication_state.unique_name = "name";
    params->devtools_frame_token = base::UnguessableToken::Create();
    process->GetRendererInterface()->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 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_F(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->GetFrameTree()->root()->child_count());

  // Capture the FrameTreeNode this test will be navigating.
  FrameTreeNode* node = contents->GetFrameTree()->root()->child_at(0);
  EXPECT_TRUE(node);
  EXPECT_NE(node->current_frame_host()->GetSiteInstance(),
            node->parent()->current_frame_host()->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();
  RenderProcessHostWatcher watcher(
      process, RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
  int frame_routing_id = node->current_frame_host()->GetRoutingID();
  int widget_routing_id =
      node->current_frame_host()->GetRenderWidgetHost()->GetRoutingID();
  int parent_routing_id =
      node->parent()->render_manager()->GetRoutingIdForSiteInstance(
          node->current_frame_host()->GetSiteInstance());

  // 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(ExecuteScript(contents,
                            "document.body.removeChild("
                            "document.querySelectorAll('iframe')[0])"));
  EXPECT_EQ(1U, contents->GetFrameTree()->root()->child_count());

  {
    mojom::CreateFrameParamsPtr params = mojom::CreateFrameParams::New();
    params->routing_id = frame_routing_id;
    params->interface_bundle = mojom::DocumentScopedInterfaceBundle::New();
    mojo::MakeRequest(&params->interface_bundle->interface_provider);
    mojo::MakeRequest(
        &params->interface_bundle->document_interface_broker_content);
    mojo::MakeRequest(
        &params->interface_bundle->document_interface_broker_blink);
    params->previous_routing_id = IPC::mojom::kRoutingIdNone;
    params->opener_routing_id = IPC::mojom::kRoutingIdNone;
    params->parent_routing_id = parent_routing_id;
    params->previous_sibling_routing_id = IPC::mojom::kRoutingIdNone;
    params->widget_params = mojom::CreateFrameWidgetParams::New();
    params->widget_params->routing_id = widget_routing_id;
    params->widget_params->hidden = true;
    params->replication_state.name = "name";
    params->replication_state.unique_name = "name";
    params->devtools_frame_token = base::UnguessableToken::Create();
    process->GetRendererInterface()->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.
  NavigateFrameToURL(contents->GetFrameTree()->root()->child_at(0),
                     embedded_test_server()->GetURL("d.com", "/title3.html"));
  watcher.Wait();
  EXPECT_TRUE(watcher.did_exit_normally());
}

// TODO(ekaramad): Move this test out of this file when addressing
// https://crbug.com/754726.
// This test verifies that RFHImpl::ForEachImmediateLocalRoot works as expected.
// The frame tree used in the test is:
//                                A0
//                            /    |    \
//                          A1     B1    A2
//                         /  \    |    /  \
//                        B2   A3  B3  A4   C2
//                       /    /   / \    \
//                      D1   D2  C3  C4  C5
//
// As an example, the expected set of immediate local roots for the root node A0
// should be {B1, B2, C2, D2, C5}. Note that the order is compatible with that
// of a BFS traversal from root node A0.
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, FindImmediateLocalRoots) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com",
      "/cross_site_iframe_factory.html?a(a(b(d),a(d)),b(b(c,c)),a(a(c),c))"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  // Each entry is of the frame "LABEL:ILR1ILR2..." where ILR stands for
  // immediate local root.
  std::string immediate_local_roots[] = {
      "A0:B1B2C2D2C5", "A1:B2D2", "B1:C3C4", "A2:C2C5", "B2:D1",
      "A3:D2",         "B3:C3C4", "A4:C5",   "C2:",     "D1:",
      "D2:",           "C3:",     "C4:",     "C5:"};

  std::map<RenderFrameHostImpl*, std::string>
      frame_to_immediate_local_roots_map;
  std::map<RenderFrameHostImpl*, std::string> frame_to_label_map;
  size_t index = 0;
  // Map each RenderFrameHostImpl to its label and set of immediate local roots.
  for (auto* ftn : web_contents()->GetFrameTree()->Nodes()) {
    std::string roots = immediate_local_roots[index++];
    frame_to_immediate_local_roots_map[ftn->current_frame_host()] = roots;
    frame_to_label_map[ftn->current_frame_host()] = roots.substr(0, 2);
  }

  // For each frame in the tree, verify that ForEachImmediateLocalRoot properly
  // visits each and only each immediate local root in a BFS traversal order.
  for (auto* ftn : web_contents()->GetFrameTree()->Nodes()) {
    RenderFrameHostImpl* current_frame_host = ftn->current_frame_host();
    std::list<RenderFrameHostImpl*> frame_list;
    current_frame_host->ForEachImmediateLocalRoot(
        base::Bind([](std::list<RenderFrameHostImpl*>* ilr_list,
                      RenderFrameHostImpl* rfh) { ilr_list->push_back(rfh); },
                   &frame_list));

    std::string result = frame_to_label_map[current_frame_host];
    result.append(":");
    for (auto* ilr_ptr : frame_list)
      result.append(frame_to_label_map[ilr_ptr]);
    EXPECT_EQ(frame_to_immediate_local_roots_map[current_frame_host], result);
  }
}

// This test verifies that changing the CSS visibility of a cross-origin
// <iframe> is forwarded to its corresponding RenderWidgetHost and all other
// RenderWidgetHosts corresponding to the nested cross-origin frame.
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, CSSVisibilityChanged) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b(b(c(d(d(a))))))"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  // Find all child RenderWidgetHosts.
  std::vector<RenderWidgetHostImpl*> child_widget_hosts;
  FrameTreeNode* first_cross_process_child =
      web_contents()->GetFrameTree()->root()->child_at(0);
  for (auto* ftn : web_contents()->GetFrameTree()->SubtreeNodes(
           first_cross_process_child)) {
    RenderFrameHostImpl* frame_host = ftn->current_frame_host();
    if (!frame_host->is_local_root())
      continue;

    child_widget_hosts.push_back(frame_host->GetRenderWidgetHost());
  }

  // Ignoring the root, there is exactly 4 local roots and hence 5
  // RenderWidgetHosts on the page.
  EXPECT_EQ(4U, child_widget_hosts.size());

  // Initially all the RenderWidgetHosts should be visible.
  for (size_t index = 0; index < child_widget_hosts.size(); ++index) {
    EXPECT_FALSE(child_widget_hosts[index]->is_hidden())
        << "The RWH at distance " << index + 1U
        << " from root RWH should not be hidden.";
  }

  std::string show_script =
      "document.querySelector('iframe').style.visibility = 'visible';";
  std::string hide_script =
      "document.querySelector('iframe').style.visibility = 'hidden';";

  // Define observers for notifications about hiding child RenderWidgetHosts.
  std::vector<std::unique_ptr<RenderWidgetHostVisibilityObserver>>
      hide_widget_host_observers(child_widget_hosts.size());
  for (size_t index = 0U; index < child_widget_hosts.size(); ++index) {
    hide_widget_host_observers[index].reset(
        new RenderWidgetHostVisibilityObserver(child_widget_hosts[index],
                                               false));
  }

  EXPECT_TRUE(ExecuteScript(shell(), hide_script));
  for (size_t index = 0U; index < child_widget_hosts.size(); ++index) {
    EXPECT_TRUE(hide_widget_host_observers[index]->WaitUntilSatisfied())
        << "Expected RenderWidgetHost at distance " << index + 1U
        << " from root RenderWidgetHost to become hidden.";
  }

  // Define observers for notifications about showing child RenderWidgetHosts.
  std::vector<std::unique_ptr<RenderWidgetHostVisibilityObserver>>
      show_widget_host_observers(child_widget_hosts.size());
  for (size_t index = 0U; index < child_widget_hosts.size(); ++index) {
    show_widget_host_observers[index].reset(
        new RenderWidgetHostVisibilityObserver(child_widget_hosts[index],
                                               true));
  }

  EXPECT_TRUE(ExecuteScript(shell(), show_script));
  for (size_t index = 0U; index < child_widget_hosts.size(); ++index) {
    EXPECT_TRUE(show_widget_host_observers[index]->WaitUntilSatisfied())
        << "Expected RenderWidgetHost at distance " << index + 1U
        << " from root RenderWidgetHost to become shown.";
  }
}

// This test verifies that hiding an OOPIF in CSS will stop generating
// compositor frames for the OOPIF and any nested OOPIFs inside it. This holds
// even when the whole page is shown.
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
                       HiddenOOPIFWillNotGenerateCompositorFrames) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/frame_tree/page_with_two_frames.html"));
  ASSERT_TRUE(NavigateToURL(shell(), main_url));
  ASSERT_EQ(shell()->web_contents()->GetLastCommittedURL(), main_url);

  GURL cross_site_url_b =
      embedded_test_server()->GetURL("b.com", "/counter.html");

  FrameTreeNode* root = web_contents()->GetFrameTree()->root();

  NavigateFrameToURL(root->child_at(0), cross_site_url_b);

  NavigateFrameToURL(root->child_at(1), cross_site_url_b);

  // Now inject code in the first frame to create a nested OOPIF.
  RenderFrameHostCreatedObserver new_frame_created_observer(
      shell()->web_contents(), 1);
  ASSERT_TRUE(ExecuteScript(
      root->child_at(0)->current_frame_host(),
      "document.body.appendChild(document.createElement('iframe'));"));
  new_frame_created_observer.Wait();

  GURL cross_site_url_a =
      embedded_test_server()->GetURL("a.com", "/counter.html");

  // Navigate the nested frame.
  TestFrameNavigationObserver observer(root->child_at(0)->child_at(0));
  ASSERT_TRUE(
      ExecuteScript(root->child_at(0)->current_frame_host(),
                    JsReplace("document.querySelector('iframe').src = $1",
                              cross_site_url_a)));
  observer.Wait();

  RenderWidgetHostViewChildFrame* first_child_view =
      static_cast<RenderWidgetHostViewChildFrame*>(
          root->child_at(0)->current_frame_host()->GetView());
  RenderWidgetHostViewChildFrame* second_child_view =
      static_cast<RenderWidgetHostViewChildFrame*>(
          root->child_at(1)->current_frame_host()->GetView());
  RenderWidgetHostViewChildFrame* nested_child_view =
      static_cast<RenderWidgetHostViewChildFrame*>(
          root->child_at(0)->child_at(0)->current_frame_host()->GetView());

  RenderFrameSubmissionObserver first_frame_counter(
      first_child_view->host_->render_frame_metadata_provider());
  RenderFrameSubmissionObserver second_frame_counter(
      second_child_view->host_->render_frame_metadata_provider());
  RenderFrameSubmissionObserver third_frame_counter(
      nested_child_view->host_->render_frame_metadata_provider());

  const int kFrameCountLimit = 20;

  // Wait for a minimum number of compositor frames for the second frame.
  while (second_frame_counter.render_frame_count() < kFrameCountLimit)
    second_frame_counter.WaitForAnyFrameSubmission();
  ASSERT_LE(kFrameCountLimit, second_frame_counter.render_frame_count());

  // Now make sure all frames have roughly the counter value in the sense that
  // no counter value is more than twice any other.
  float ratio = static_cast<float>(first_frame_counter.render_frame_count()) /
                static_cast<float>(second_frame_counter.render_frame_count());
  EXPECT_GT(2.5f, ratio + 1 / ratio) << "Ratio is: " << ratio;

  ratio = static_cast<float>(first_frame_counter.render_frame_count()) /
          static_cast<float>(third_frame_counter.render_frame_count());
  EXPECT_GT(2.5f, ratio + 1 / ratio) << "Ratio is: " << ratio;

  // Make sure all views can become visible.
  EXPECT_TRUE(first_child_view->CanBecomeVisible());
  EXPECT_TRUE(second_child_view->CanBecomeVisible());
  EXPECT_TRUE(nested_child_view->CanBecomeVisible());

  // Hide the first frame and wait for the notification to be posted by its
  // RenderWidgetHost.
  RenderWidgetHostVisibilityObserver hide_observer(
      root->child_at(0)->current_frame_host()->GetRenderWidgetHost(), false);

  // Hide the first frame.
  ASSERT_TRUE(ExecuteScript(
      shell(),
      "document.getElementsByName('frame1')[0].style.visibility = 'hidden'"));
  ASSERT_TRUE(hide_observer.WaitUntilSatisfied());
  EXPECT_TRUE(first_child_view->FrameConnectorForTesting()->IsHidden());

  // Verify that only the second view can become visible now.
  EXPECT_FALSE(first_child_view->CanBecomeVisible());
  EXPECT_TRUE(second_child_view->CanBecomeVisible());
  EXPECT_FALSE(nested_child_view->CanBecomeVisible());

  // Now hide and show the WebContents (to simulate a tab switch).
  shell()->web_contents()->WasHidden();
  shell()->web_contents()->WasShown();

  first_frame_counter.ResetCounter();
  second_frame_counter.ResetCounter();
  third_frame_counter.ResetCounter();

  // We expect the second counter to keep running.
  while (second_frame_counter.render_frame_count() < kFrameCountLimit)
    second_frame_counter.WaitForAnyFrameSubmission();
  ASSERT_LT(kFrameCountLimit, second_frame_counter.render_frame_count() + 1);

  // Verify that the counter for other two frames did not count much.
  ratio = static_cast<float>(first_frame_counter.render_frame_count()) /
          static_cast<float>(second_frame_counter.render_frame_count());
  EXPECT_GT(0.5f, ratio) << "Ratio is: " << ratio;

  ratio = static_cast<float>(third_frame_counter.render_frame_count()) /
          static_cast<float>(second_frame_counter.render_frame_count());
  EXPECT_GT(0.5f, ratio) << "Ratio is: " << ratio;
}

// This test verifies that navigating a hidden OOPIF to cross-origin will not
// lead to creating compositor frames for the new OOPIF renderer.
IN_PROC_BROWSER_TEST_F(
    SitePerProcessBrowserTest,
    HiddenOOPIFWillNotGenerateCompositorFramesAfterNavigation) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/frame_tree/page_with_two_frames.html"));
  ASSERT_TRUE(NavigateToURL(shell(), main_url));
  ASSERT_EQ(shell()->web_contents()->GetLastCommittedURL(), main_url);

  GURL cross_site_url_b =
      embedded_test_server()->GetURL("b.com", "/counter.html");

  FrameTreeNode* root = web_contents()->GetFrameTree()->root();

  NavigateFrameToURL(root->child_at(0), cross_site_url_b);

  NavigateFrameToURL(root->child_at(1), cross_site_url_b);

  // Hide the first frame and wait for the notification to be posted by its
  // RenderWidgetHost.
  RenderWidgetHostVisibilityObserver hide_observer(
      root->child_at(0)->current_frame_host()->GetRenderWidgetHost(), false);

  // Hide the first frame.
  ASSERT_TRUE(ExecuteScript(
      shell(),
      "document.getElementsByName('frame1')[0].style.visibility = 'hidden'"));
  ASSERT_TRUE(hide_observer.WaitUntilSatisfied());

  // Now navigate the first frame to another OOPIF process.
  TestFrameNavigationObserver navigation_observer(
      root->child_at(0)->current_frame_host());
  GURL cross_site_url_c =
      embedded_test_server()->GetURL("c.com", "/counter.html");
  ASSERT_TRUE(ExecuteScript(
      web_contents(),
      JsReplace("document.getElementsByName('frame1')[0].src = $1",
                cross_site_url_c)));
  navigation_observer.Wait();

  // Now investigate compositor frame creation.
  RenderWidgetHostViewChildFrame* first_child_view =
      static_cast<RenderWidgetHostViewChildFrame*>(
          root->child_at(0)->current_frame_host()->GetView());

  RenderWidgetHostViewChildFrame* second_child_view =
      static_cast<RenderWidgetHostViewChildFrame*>(
          root->child_at(1)->current_frame_host()->GetView());

  EXPECT_FALSE(first_child_view->CanBecomeVisible());

  RenderFrameSubmissionObserver first_frame_counter(
      first_child_view->host_->render_frame_metadata_provider());
  RenderFrameSubmissionObserver second_frame_counter(
      second_child_view->host_->render_frame_metadata_provider());

  const int kFrameCountLimit = 20;

  // Wait for a certain number of swapped compositor frames generated for the
  // second child view. During the same interval the first frame should not have
  // swapped any compositor frames.
  while (second_frame_counter.render_frame_count() < kFrameCountLimit)
    second_frame_counter.WaitForAnyFrameSubmission();
  ASSERT_LT(kFrameCountLimit, second_frame_counter.render_frame_count() + 1);

  float ratio = static_cast<float>(first_frame_counter.render_frame_count()) /
                static_cast<float>(second_frame_counter.render_frame_count());
  EXPECT_GT(0.5f, ratio) << "Ratio is: " << ratio;
}

// Verify that sandbox flags inheritance works across multiple levels of
// frames.  See https://crbug.com/576845.
IN_PROC_BROWSER_TEST_F(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()->GetFrameTree()->root();

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

  // Calculate expected flags.  Note that "allow-scripts" resets both
  // WebSandboxFlags::Scripts and WebSandboxFlags::AutomaticFeatures bits per
  // blink::parseSandboxPolicy().
  blink::WebSandboxFlags expected_flags =
      blink::WebSandboxFlags::kAll & ~blink::WebSandboxFlags::kScripts &
      ~blink::WebSandboxFlags::kAutomaticFeatures;
  EXPECT_EQ(expected_flags,
            root->child_at(0)->pending_frame_policy().sandbox_flags);
  EXPECT_EQ(blink::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))"));
  NavigateFrameToURL(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_F(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()->GetFrameTree()->root();

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

  // These flags should be pending but not take effect, since there's been no
  // navigation.
  blink::WebSandboxFlags expected_flags =
      blink::WebSandboxFlags::kAll & ~blink::WebSandboxFlags::kScripts &
      ~blink::WebSandboxFlags::kAutomaticFeatures;
  FrameTreeNode* child = root->child_at(0);
  EXPECT_EQ(expected_flags, child->pending_frame_policy().sandbox_flags);
  EXPECT_EQ(blink::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(ExecuteScript(
      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);
  NavigateFrameToURL(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(blink::WebSandboxFlags::kNone,
            grandchild->pending_frame_policy().sandbox_flags);
  EXPECT_EQ(blink::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").
  std::string expected_origin = url::Origin::Create(frame_url).Serialize();
  EXPECT_EQ(expected_origin, 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_F(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()->GetFrameTree()->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
  // WebSandboxFlags::Scripts and WebSandboxFlags::AutomaticFeatures bits per
  // blink::parseSandboxPolicy().
  blink::WebSandboxFlags expected_flags =
      blink::WebSandboxFlags::kAll & ~blink::WebSandboxFlags::kScripts &
      ~blink::WebSandboxFlags::kAutomaticFeatures &
      ~blink::WebSandboxFlags::kPopups;
  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));
  NavigateFrameToURL(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())
          ->GetFrameTree()
          ->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_F(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()->GetFrameTree()->root();

  // Set sandbox flags for child frame, specifying that popups opened from it
  // should not be sandboxed.
  EXPECT_TRUE(ExecuteScript(
      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 WebSandboxFlags::Scripts and WebSandboxFlags::AutomaticFeatures bits
  // per blink::parseSandboxPolicy().
  blink::WebSandboxFlags expected_flags =
      blink::WebSandboxFlags::kAll & ~blink::WebSandboxFlags::kScripts &
      ~blink::WebSandboxFlags::kAutomaticFeatures &
      ~blink::WebSandboxFlags::kPopups &
      ~blink::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));
  NavigateFrameToURL(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())
          ->GetFrameTree()
          ->root();

  // Check that the sandbox flags for new popup are correct in the browser
  // process.  They should not have been inherited.
  EXPECT_EQ(blink::WebSandboxFlags::kNone,
            foo_root->effective_frame_policy().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;"));
}

// Tests that the WebContents is notified when passive mixed content is
// displayed in an OOPIF. The test ignores cert errors so that an HTTPS
// iframe can be loaded from a site other than localhost (the
// EmbeddedTestServer serves a certificate that is valid for localhost).
// This test crashes on Windows under Dr. Memory, see https://crbug.com/600942.
#if defined(OS_WIN)
#define MAYBE_PassiveMixedContentInIframe DISABLED_PassiveMixedContentInIframe
#else
#define MAYBE_PassiveMixedContentInIframe PassiveMixedContentInIframe
#endif
IN_PROC_BROWSER_TEST_F(SitePerProcessIgnoreCertErrorsBrowserTest,
                       MAYBE_PassiveMixedContentInIframe) {
  net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS);
  https_server.ServeFilesFromSourceDirectory("content/test/data");
  SetupCrossSiteRedirector(&https_server);
  ASSERT_TRUE(https_server.Start());

  WebContentsImpl* web_contents =
      static_cast<WebContentsImpl*>(shell()->web_contents());

  GURL iframe_url(
      https_server.GetURL("/mixed-content/basic-passive-in-iframe.html"));
  EXPECT_TRUE(NavigateToURL(shell(), iframe_url));
  NavigationEntry* entry = web_contents->GetController().GetVisibleEntry();
  EXPECT_TRUE(!!(entry->GetSSL().content_status &
                 SSLStatus::DISPLAYED_INSECURE_CONTENT));

  // When the subframe navigates, the WebContents should still be marked
  // as having displayed insecure content.
  GURL navigate_url(https_server.GetURL("/title1.html"));
  FrameTreeNode* root = web_contents->GetFrameTree()->root();
  NavigateFrameToURL(root->child_at(0), navigate_url);
  entry = web_contents->GetController().GetVisibleEntry();
  EXPECT_TRUE(!!(entry->GetSSL().content_status &
                 SSLStatus::DISPLAYED_INSECURE_CONTENT));

  // When the main frame navigates, it should no longer be marked as
  // displaying insecure content.
  EXPECT_TRUE(
      NavigateToURL(shell(), https_server.GetURL("b.com", "/title1.html")));
  entry = web_contents->GetController().GetVisibleEntry();
  EXPECT_FALSE(!!(entry->GetSSL().content_status &
                  SSLStatus::DISPLAYED_INSECURE_CONTENT));
}

// Tests that, when a parent frame is set to strictly block mixed
// content via Content Security Policy, child OOPIFs cannot display
// mixed content.
IN_PROC_BROWSER_TEST_F(SitePerProcessIgnoreCertErrorsBrowserTest,
                       PassiveMixedContentInIframeWithStrictBlocking) {
  net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS);
  https_server.ServeFilesFromSourceDirectory("content/test/data");
  SetupCrossSiteRedirector(&https_server);
  ASSERT_TRUE(https_server.Start());

  WebContentsImpl* web_contents =
      static_cast<WebContentsImpl*>(shell()->web_contents());

  GURL iframe_url_with_strict_blocking(https_server.GetURL(
      "/mixed-content/basic-passive-in-iframe-with-strict-blocking.html"));
  EXPECT_TRUE(NavigateToURL(shell(), iframe_url_with_strict_blocking));
  NavigationEntry* entry = web_contents->GetController().GetVisibleEntry();
  EXPECT_FALSE(!!(entry->GetSSL().content_status &
                  SSLStatus::DISPLAYED_INSECURE_CONTENT));

  FrameTreeNode* root = web_contents->GetFrameTree()->root();
  EXPECT_EQ(blink::kBlockAllMixedContent,
            root->current_replication_state().insecure_request_policy);
  EXPECT_EQ(
      blink::kBlockAllMixedContent,
      root->child_at(0)->current_replication_state().insecure_request_policy);

  // When the subframe navigates, it should still be marked as enforcing
  // strict mixed content.
  GURL navigate_url(https_server.GetURL("/title1.html"));
  NavigateFrameToURL(root->child_at(0), navigate_url);
  EXPECT_EQ(blink::kBlockAllMixedContent,
            root->current_replication_state().insecure_request_policy);
  EXPECT_EQ(
      blink::kBlockAllMixedContent,
      root->child_at(0)->current_replication_state().insecure_request_policy);

  // When the main frame navigates, it should no longer be marked as
  // enforcing strict mixed content.
  EXPECT_TRUE(
      NavigateToURL(shell(), https_server.GetURL("b.com", "/title1.html")));
  EXPECT_EQ(blink::kLeaveInsecureRequestsAlone,
            root->current_replication_state().insecure_request_policy);
}

// Tests that, when a parent frame is set to upgrade insecure requests
// via Content Security Policy, child OOPIFs will upgrade as well.
IN_PROC_BROWSER_TEST_F(SitePerProcessIgnoreCertErrorsBrowserTest,
                       PassiveMixedContentInIframeWithUpgrade) {
  net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS);
  https_server.ServeFilesFromSourceDirectory("content/test/data");
  SetupCrossSiteRedirector(&https_server);
  ASSERT_TRUE(https_server.Start());

  WebContentsImpl* web_contents =
      static_cast<WebContentsImpl*>(shell()->web_contents());

  GURL iframe_url_with_upgrade(https_server.GetURL(
      "/mixed-content/basic-passive-in-iframe-with-upgrade.html"));
  EXPECT_TRUE(NavigateToURL(shell(), iframe_url_with_upgrade));
  NavigationEntry* entry = web_contents->GetController().GetVisibleEntry();
  EXPECT_FALSE(!!(entry->GetSSL().content_status &
                  SSLStatus::DISPLAYED_INSECURE_CONTENT));

  FrameTreeNode* root = web_contents->GetFrameTree()->root();
  EXPECT_EQ(blink::kUpgradeInsecureRequests,
            root->current_replication_state().insecure_request_policy);
  EXPECT_EQ(
      blink::kUpgradeInsecureRequests,
      root->child_at(0)->current_replication_state().insecure_request_policy);

  // When the subframe navigates, it should still be marked as upgrading
  // insecure requests.
  GURL navigate_url(https_server.GetURL("/title1.html"));
  NavigateFrameToURL(root->child_at(0), navigate_url);
  EXPECT_EQ(blink::kUpgradeInsecureRequests,
            root->current_replication_state().insecure_request_policy);
  EXPECT_EQ(
      blink::kUpgradeInsecureRequests,
      root->child_at(0)->current_replication_state().insecure_request_policy);

  // When the main frame navigates, it should no longer be marked as
  // upgrading insecure requests.
  EXPECT_TRUE(
      NavigateToURL(shell(), https_server.GetURL("b.com", "/title1.html")));
  EXPECT_EQ(blink::kLeaveInsecureRequestsAlone,
            root->current_replication_state().insecure_request_policy);
}

// Tests that active mixed content is blocked in an OOPIF. The test
// ignores cert errors so that an HTTPS iframe can be loaded from a site
// other than localhost (the EmbeddedTestServer serves a certificate
// that is valid for localhost).
IN_PROC_BROWSER_TEST_F(SitePerProcessIgnoreCertErrorsBrowserTest,
                       ActiveMixedContentInIframe) {
  net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS);
  https_server.ServeFilesFromSourceDirectory("content/test/data");
  SetupCrossSiteRedirector(&https_server);
  ASSERT_TRUE(https_server.Start());

  GURL iframe_url(
      https_server.GetURL("/mixed-content/basic-active-in-iframe.html"));
  EXPECT_TRUE(NavigateToURL(shell(), iframe_url));
  FrameTreeNode* root = web_contents()->GetFrameTree()->root();
  ASSERT_EQ(1U, root->child_count());
  FrameTreeNode* mixed_child = root->child_at(0)->child_at(0);
  ASSERT_TRUE(mixed_child);
  // The child iframe attempted to create a mixed iframe; this should
  // have been blocked, so the mixed iframe should not have committed a
  // load.
  EXPECT_FALSE(mixed_child->has_committed_real_load());
}

// 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.
IN_PROC_BROWSER_TEST_F(SitePerProcessIgnoreCertErrorsBrowserTest,
                       SubresourceWithCertificateErrors) {
  net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS);
  https_server.ServeFilesFromSourceDirectory("content/test/data");
  SetupCrossSiteRedirector(&https_server);
  ASSERT_TRUE(https_server.Start());

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

  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));

  // The image that the iframe loaded had certificate errors also, so
  // the page should be marked as having displayed subresources with
  // cert errors.
  EXPECT_TRUE(!!(entry->GetSSL().content_status &
                 SSLStatus::DISPLAYED_CONTENT_WITH_CERT_ERRORS));
}

// Test setting a cross-origin iframe to display: none.
IN_PROC_BROWSER_TEST_F(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()->GetFrameTree()->root();
  RenderWidgetHost* root_render_widget_host =
      root->current_frame_host()->GetRenderWidgetHost();

  // Set the iframe to display: none.
  EXPECT_TRUE(ExecuteScript(
      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(
      ExecuteScript(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_F(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()->GetFrameTree()->root();

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

  const struct {
    const char* url;
    bool use_error_page;
  } kTestCases[] = {
      {"/frame-ancestors-none.html", false},
      {"/x-frame-options-deny.html", true},
  };

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

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

    // The blocked frame's origin should become unique.
    EXPECT_EQ("null", root->child_at(0)->current_origin().Serialize());

    // X-Frame-Options and CSP frame-ancestors behave differently. XFO commits
    // an error page, while CSP commits a "data:," URL.
    // TODO(https://crbug.com/870815): Use an error page for both.
    if (test.use_error_page) {
      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"));
    } else {
      EXPECT_TRUE(load_observer.last_navigation_succeeded());
      EXPECT_EQ(net::OK, load_observer.last_net_error_code());
      // Ensure that we don't use the blocked URL as the blocked frame's last
      // committed URL (see https://crbug.com/622385).
      EXPECT_EQ(root->child_at(0)->current_frame_host()->GetLastCommittedURL(),
                GURL("data:,"));

      // The blocked navigation should behave like an empty 200 response. Make
      // sure that the frame's document.title is empty: this double-checks both
      // that the blocked URL's contents wasn't loaded, and that the old page
      // isn't active anymore (both of these pages have non-empty titles).
      EXPECT_EQ("", 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());

    // 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.GetOrigin().spec(),
              root->child_at(0)->current_origin().Serialize() + "/");
    EXPECT_EQ(blink::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_F(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()->GetFrameTree()->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<ContentSecurityPolicyHeader>& root_csp =
      root->current_replication_state().accumulated_csp_headers;
  EXPECT_EQ(1u, root_csp.size());
  EXPECT_EQ("frame-src 'self' http://b.com:*", root_csp[0].header_value);

  // Monitor subframe's load events via main frame's title.
  EXPECT_TRUE(ExecuteScript(shell(),
                            "document.querySelector('iframe').onload = "
                            "    function() { document.title = 'loaded'; };"));
  EXPECT_TRUE(ExecuteScript(shell(), "document.title = 'not loaded';"));
  base::string16 expected_title(base::UTF8ToUTF16("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(ExecuteScript(
      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_EQ(old_subframe_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_F(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()->GetFrameTree()->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"));
  NavigateFrameToURL(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<ContentSecurityPolicyHeader>& root_csp =
      root->current_replication_state().accumulated_csp_headers;
  EXPECT_EQ(1u, root_csp.size());
  EXPECT_EQ("frame-src https://a.com:*", root_csp[0].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';"));
  base::string16 expected_title(base::UTF8ToUTF16("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_EQ(old_subframe_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_F(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()->GetFrameTree()->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<ContentSecurityPolicyHeader>& srcdoc_csp =
      srcdoc_frame->current_replication_state().accumulated_csp_headers;
  EXPECT_EQ(1u, srcdoc_csp.size());
  EXPECT_EQ("frame-src 'self' http://b.com:*", srcdoc_csp[0].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';"));
  base::string16 expected_title(base::UTF8ToUTF16("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_EQ(old_subframe_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.
  NavigateFrameToURL(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_replication_state().accumulated_csp_headers.size());
}

IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, ScreenCoordinates) {
  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()->GetFrameTree()->root();
  FrameTreeNode* child = root->child_at(0);

  const char* properties[] = {"screenX", "screenY", "outerWidth",
                              "outerHeight"};

  for (const char* property : properties) {
    std::string script = base::StringPrintf("window.%s;", property);
    int root_value = EvalJs(root, script).ExtractInt();
    int child_value = EvalJs(child, script).ExtractInt();
    EXPECT_EQ(root_value, child_value);
  }
}

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

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

  // Ensure the RenderViewHost for the SiteInstance of the child is considered
  // in swapped out state.
  RenderViewHostImpl* rvh = contents->GetFrameTree()->GetRenderViewHost(
      root->child_at(0)->current_frame_host()->GetSiteInstance());
  EXPECT_TRUE(rvh->is_swapped_out_);

  // 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(ExecuteScript(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 no longer
  // in swapped out state.
  EXPECT_EQ(rvh, contents->GetFrameTree()->GetRenderViewHost(
                     root->current_frame_host()->GetSiteInstance()));
  EXPECT_FALSE(rvh->is_swapped_out_);
}

// 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 two WidgetMsg_Close messages sent to the subframe's
// RenderWidget and to the RenderView, in that order.  In the bug, the latter
// crashed while detaching the subframe's LocalFrame (triggered as part of
// closing the RenderView), because this tried to access the subframe's
// WebFrameWidget (from RenderFrameImpl::didChangeSelection), which had already
// been cleared by the former.
IN_PROC_BROWSER_TEST_F(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())
                            ->GetFrameTree()
                            ->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()->GetFrameInputHandler()->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 RenderView,
  // which is where the original bug was triggered.  Incrementing the keep alive
  // ref count will cause RenderProcessHostImpl::Cleanup to forego process
  // termination.
  RenderProcessHost* subframe_process =
      root->child_at(0)->current_frame_host()->GetProcess();
  subframe_process->IncrementKeepAliveRefCount(
      RenderProcessHostImpl::KeepAliveClientType::kFetch);

  // Navigate the subframe away from b.com.  Since this is the last active
  // frame in the b.com process, this causes the RenderWidget and RenderView to
  // be closed.
  NavigateFrameToURL(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->DecrementKeepAliveRefCount(
      RenderProcessHostImpl::KeepAliveClientType::kFetch);
  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_F(SitePerProcessBrowserTest,
                       UserInteractionForChildFrameTest) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  UserInteractionObserver observer(web_contents());

  // Target an event to the child frame's RenderWidgetHostView.
  FrameTreeNode* root = web_contents()->GetFrameTree()->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_F(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()->GetFrameTree()->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");
  NavigateFrameToURL(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"));
  NavigateFrameToURL(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());
}

// 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_F(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()->GetFrameTree()->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 SiteInstances.
  TestNavigationObserver observer(shell()->web_contents());
  GURL data_url_0("data:text/html,dataurl_0");
  {
    TestFrameNavigationObserver commit_observer(child_0);
    EXPECT_TRUE(
        ExecuteScript(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());
  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(
        ExecuteScript(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());
  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(), ui::PAGE_TRANSITION_RELOAD, false,
              std::string(), controller.GetBrowserContext(),
              nullptr /* blob_url_loader_factory */));
  EXPECT_EQ(0U, restored_entry->root_node()->children.size());
  restored_entry->SetPageState(entry->GetPageState());
  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::EmptyGURL(), nullptr, gfx::Size());
  FrameTreeNode* new_root =
      static_cast<WebContentsImpl*>(new_shell->web_contents())
          ->GetFrameTree()
          ->root();
  NavigationControllerImpl& new_controller =
      static_cast<NavigationControllerImpl&>(
          new_shell->web_contents()->GetController());
  new_controller.Restore(entries.size() - 1,
                         RestoreType::LAST_SESSION_EXITED_CLEANLY, &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, but ensures that about:blank frames
// do get put into their parent process after restore, even if they weren't
// originally.  This is safe because they do not contain active content (even
// when there's a fragment in the URL), and it avoids unnecessary OOPIFs.
IN_PROC_BROWSER_TEST_F(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()->GetFrameTree()->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(
        ExecuteScript(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(
        ExecuteScript(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(), ui::PAGE_TRANSITION_RELOAD, false,
              std::string(), controller.GetBrowserContext(),
              nullptr /* blob_url_loader_factory */));
  EXPECT_EQ(0U, restored_entry->root_node()->children.size());
  restored_entry->SetPageState(entry->GetPageState());
  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::EmptyGURL(), nullptr, gfx::Size());
  FrameTreeNode* new_root =
      static_cast<WebContentsImpl*>(new_shell->web_contents())
          ->GetFrameTree()
          ->root();
  NavigationControllerImpl& new_controller =
      static_cast<NavigationControllerImpl&>(
          new_shell->web_contents()->GetController());
  new_controller.Restore(entries.size() - 1,
                         RestoreType::LAST_SESSION_EXITED_CLEANLY, &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_TRUE(new_root->child_at(0)->current_url().IsAboutBlank());
  EXPECT_TRUE(new_root->child_at(1)->current_url().IsAboutBlank());

  EXPECT_EQ(new_root->current_frame_host()->GetSiteInstance(),
            new_root->child_at(0)->current_frame_host()->GetSiteInstance());
  EXPECT_EQ(new_root->current_frame_host()->GetSiteInstance(),
            new_root->child_at(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_F(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()->GetFrameTree()->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(), ui::PAGE_TRANSITION_RELOAD, false,
              std::string(), controller.GetBrowserContext(),
              nullptr /* blob_url_loader_factory */));
  EXPECT_EQ(0U, restored_entry->root_node()->children.size());
  restored_entry->SetPageState(entry->GetPageState());
  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::EmptyGURL(), nullptr, gfx::Size());
  FrameTreeNode* new_root =
      static_cast<WebContentsImpl*>(new_shell->web_contents())
          ->GetFrameTree()
          ->root();
  NavigationControllerImpl& new_controller =
      static_cast<NavigationControllerImpl&>(
          new_shell->web_contents()->GetController());
  new_controller.Restore(entries.size() - 1,
                         RestoreType::LAST_SESSION_EXITED_CLEANLY, &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_EQ(GURL(content::kAboutSrcDocURL),
            new_root->child_at(0)->current_url());

  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_F(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()->GetFrameTree()->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");
  NavigateFrameToURL(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"));
  NavigateFrameToURL(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());
}

// Helper filter class to wait for a ShowCreatedWindow or ShowWidget message,
// record the routing ID from the message, and then drop the message.
const uint32_t kMessageClasses[] = {ViewMsgStart, FrameMsgStart};
class PendingWidgetMessageFilter : public BrowserMessageFilter {
 public:
  PendingWidgetMessageFilter()
      : BrowserMessageFilter(kMessageClasses, base::size(kMessageClasses)),
        routing_id_(MSG_ROUTING_NONE) {}

  bool OnMessageReceived(const IPC::Message& message) override {
    bool handled = true;
    IPC_BEGIN_MESSAGE_MAP(PendingWidgetMessageFilter, message)
      IPC_MESSAGE_HANDLER(FrameHostMsg_ShowCreatedWindow, OnShowCreatedWindow)
      IPC_MESSAGE_HANDLER(ViewHostMsg_ShowWidget, OnShowWidget)
      IPC_MESSAGE_UNHANDLED(handled = false)
    IPC_END_MESSAGE_MAP()
    return handled;
  }

  void Wait() { run_loop_.Run(); }

  int routing_id() { return routing_id_; }

 private:
  ~PendingWidgetMessageFilter() override {}

  void OnShowCreatedWindow(int pending_widget_routing_id,
                           WindowOpenDisposition disposition,
                           const gfx::Rect& initial_rect,
                           bool user_gesture) {
    base::PostTaskWithTraits(
        FROM_HERE, {content::BrowserThread::UI},
        base::BindOnce(&PendingWidgetMessageFilter::OnReceivedRoutingIDOnUI,
                       this, pending_widget_routing_id));
  }

  void OnShowWidget(int routing_id, const gfx::Rect& initial_rect) {
    base::PostTaskWithTraits(
        FROM_HERE, {content::BrowserThread::UI},
        base::BindOnce(&PendingWidgetMessageFilter::OnReceivedRoutingIDOnUI,
                       this, routing_id));
  }

  void OnReceivedRoutingIDOnUI(int widget_routing_id) {
    routing_id_ = widget_routing_id;
    run_loop_.Quit();
  }

  int routing_id_;
  base::RunLoop run_loop_;

  DISALLOW_COPY_AND_ASSIGN(PendingWidgetMessageFilter);
};

// 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_F(SitePerProcessBrowserTest,
                       TwoSubframesCreatePopupsSimultaneously) {
  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()->GetFrameTree()->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();

  // Call window.open simultaneously in both subframes to create two popups.
  // Wait for and then drop both FrameHostMsg_ShowCreatedWindow messages.  This
  // will ensure that both CreateNewWindow calls happen before either
  // ShowCreatedWindow call.
  scoped_refptr<PendingWidgetMessageFilter> filter1 =
      new PendingWidgetMessageFilter();
  process1->AddFilter(filter1.get());
  EXPECT_TRUE(ExecuteScript(child1, "window.open();"));
  filter1->Wait();

  scoped_refptr<PendingWidgetMessageFilter> filter2 =
      new PendingWidgetMessageFilter();
  process2->AddFilter(filter2.get());
  EXPECT_TRUE(ExecuteScript(child2, "window.open();"));
  filter2->Wait();

  // At this point, we should have two pending WebContents.
  EXPECT_TRUE(base::ContainsKey(
      web_contents()->pending_contents_,
      GlobalRoutingID(process1->GetID(), filter1->routing_id())));
  EXPECT_TRUE(base::ContainsKey(
      web_contents()->pending_contents_,
      GlobalRoutingID(process2->GetID(), filter2->routing_id())));

  // 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(filter1->routing_id(), filter2->routing_id());

  // Now, simulate that both FrameHostMsg_ShowCreatedWindow messages arrive by
  // showing both of the pending WebContents.
  web_contents()->ShowCreatedWindow(process1->GetID(), filter1->routing_id(),
                                    WindowOpenDisposition::NEW_FOREGROUND_TAB,
                                    gfx::Rect(), true);
  web_contents()->ShowCreatedWindow(process2->GetID(), filter2->routing_id(),
                                    WindowOpenDisposition::NEW_FOREGROUND_TAB,
                                    gfx::Rect(), true);

  // Verify that both shells were properly created.
  EXPECT_EQ(3u, Shell::windows().size());
}

// 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 !defined(OS_MACOSX) && !defined(OS_ANDROID)
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
                       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()->GetFrameTree()->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.
  NavigateFrameToURL(child1, embedded_test_server()->GetURL(
      "b.com", "/site_isolation/page-with-select.html"));
  NavigateFrameToURL(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.
  NativeWebKeyboardEvent event(
      blink::WebKeyboardEvent::kChar, blink::WebInputEvent::kNoModifiers,
      blink::WebInputEvent::GetStaticTimeStampForTests());
  event.text[0] = ' ';

  scoped_refptr<PendingWidgetMessageFilter> filter1 =
      new PendingWidgetMessageFilter();
  process1->AddFilter(filter1.get());
  EXPECT_TRUE(ExecuteScript(child1, "focusSelectMenu();"));
  child1->current_frame_host()->GetRenderWidgetHost()->ForwardKeyboardEvent(
      event);
  filter1->Wait();

  scoped_refptr<PendingWidgetMessageFilter> filter2 =
      new PendingWidgetMessageFilter();
  process2->AddFilter(filter2.get());
  EXPECT_TRUE(ExecuteScript(child2, "focusSelectMenu();"));
  child2->current_frame_host()->GetRenderWidgetHost()->ForwardKeyboardEvent(
      event);
  filter2->Wait();

  // At this point, we should have two pending widgets.
  EXPECT_TRUE(base::ContainsKey(
      web_contents()->pending_widget_views_,
      GlobalRoutingID(process1->GetID(), filter1->routing_id())));
  EXPECT_TRUE(base::ContainsKey(
      web_contents()->pending_widget_views_,
      GlobalRoutingID(process2->GetID(), filter2->routing_id())));

  // 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(filter1->routing_id(), filter2->routing_id());

  // Now simulate both widgets being shown.
  web_contents()->ShowCreatedWidget(process1->GetID(), filter1->routing_id(),
                                    false, gfx::Rect());
  web_contents()->ShowCreatedWidget(process2->GetID(), filter2->routing_id(),
                                    false, gfx::Rect());
  EXPECT_FALSE(base::ContainsKey(
      web_contents()->pending_widget_views_,
      GlobalRoutingID(process1->GetID(), filter1->routing_id())));
  EXPECT_FALSE(base::ContainsKey(
      web_contents()->pending_widget_views_,
      GlobalRoutingID(process2->GetID(), filter2->routing_id())));
}
#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_F(SitePerProcessBrowserTest, FileChooserInSubframe) {
  EXPECT_TRUE(NavigateToURL(shell(), embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)")));
  FrameTreeNode* root = web_contents()->GetFrameTree()->root();

  GURL url(embedded_test_server()->GetURL("b.com", "/file_input.html"));
  NavigateFrameToURL(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(ExecuteScript(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;"));
}

// Tests that an out-of-process iframe receives the visibilitychange event.
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, VisibilityChange) {
  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())
                            ->GetFrameTree()
                            ->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));

  EXPECT_TRUE(
      ExecJs(root->child_at(0),
             "var event_fired = 0;\n"
             "document.addEventListener('visibilitychange',\n"
             "                          function() { event_fired++; });\n"));

  shell()->web_contents()->WasHidden();

  EXPECT_EQ(1, EvalJs(root->child_at(0), "event_fired"));

  shell()->web_contents()->WasShown();

  EXPECT_EQ(2, EvalJs(root->child_at(0), "event_fired"));
}

// 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_F(SitePerProcessBrowserTest,
                       PendingRFHIsCanceledWhenItsProcessDies) {
  GURL main_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));
  FrameTreeNode* root = web_contents()->GetFrameTree()->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.
  SiteInstance* b_instance = popup_shell->web_contents()->GetSiteInstance();
  RenderViewHostImpl* rvh =
      web_contents()->GetFrameTree()->GetRenderViewHost(b_instance);
  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(ExecuteScript(shell(), JsReplace("location = $1", stall_url)));
  EXPECT_TRUE(delayer.WaitForRequestStart());

  // 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()->GetMainFrame()->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.
  {
    RenderFrameHostImpl* pending_rfh =
        root->render_manager()->speculative_frame_host();
    EXPECT_FALSE(pending_rfh);
  }

  // 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_F(SitePerProcessBrowserTest,
                       RenderViewHostKeepsSwappedOutStateIfPendingRFHDies) {
  GURL main_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));
  FrameTreeNode* root = web_contents()->GetFrameTree()->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.
  SiteInstance* b_instance = popup_shell->web_contents()->GetSiteInstance();
  RenderViewHostImpl* rvh =
      web_contents()->GetFrameTree()->GetRenderViewHost(b_instance);
  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(ExecuteScript(shell(), JsReplace("location = $1", stall_url)));
  EXPECT_TRUE(delayer.WaitForRequestStart());

  // Kill the b.com process, currently in use by the pending RenderFrameHost
  // and the popup.
  RenderProcessHost* pending_process =
      popup_shell->web_contents()->GetMainFrame()->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 RenderView 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_F(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()->GetFrameTree()->root();
  FrameTreeNode* child = root->child_at(0);

  // Set up a postMessage handler in the main frame for later use.
  EXPECT_TRUE(ExecuteScript(
      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.
  base::string16 expected_title(base::UTF8ToUTF16("I am alive!"));
  TitleWatcher title_watcher(shell()->web_contents(), expected_title);
  EXPECT_TRUE(ExecuteScript(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_F(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()->GetFrameTree()->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.
  NavigateFrameToURL(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"));
  NavigateFrameToURL(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"));
  NavigateFrameToURL(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(ExecuteScript(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(ExecuteScript(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());
}

// A BrowserMessageFilter that drops FrameHostMsg_OnDispatchLoad messages.
class DispatchLoadMessageFilter : public BrowserMessageFilter {
 public:
  DispatchLoadMessageFilter() : BrowserMessageFilter(FrameMsgStart) {}

 protected:
  ~DispatchLoadMessageFilter() override {}

 private:
  // BrowserMessageFilter:
  bool OnMessageReceived(const IPC::Message& message) override {
    return message.type() == FrameHostMsg_DispatchLoad::ID;
  }

  DISALLOW_COPY_AND_ASSIGN(DispatchLoadMessageFilter);
};

// 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_F(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()->GetFrameTree()->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);

  // Install a filter to drop DispatchLoad messages from b.com.
  scoped_refptr<DispatchLoadMessageFilter> filter =
      new DispatchLoadMessageFilter();
  RenderProcessHost* b_process =
      popup_shell->web_contents()->GetMainFrame()->GetProcess();
  b_process->AddFilter(filter.get());

  // 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(ExecuteScript(child, JsReplace("location.href = $1", b_url)));
    commit_observer.WaitForCommit();
  }
  RenderFrameHostImpl* child_rfh = child->current_frame_host();
  child_rfh->DisableSwapOutTimerForTesting();

  // At this point, the subframe should have a proxy in its parent's
  // SiteInstance, a.com.
  EXPECT_TRUE(child->render_manager()->GetProxyToParent());

  // 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_FALSE(child_rfh->is_active());
  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->OnDispatchLoad();

  // In the bug, OnDispatchLoad 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(ExecuteScript(popup_shell->web_contents(), "true"));
}

IN_PROC_BROWSER_TEST_F(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())
                            ->GetFrameTree()
                            ->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(
      ExecuteScript(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.
  cross_site_manager.WaitForNavigationFinished();

  // Resume the navigation in the previous RFH that has just been marked as
  // pending deletion. We should not crash.
  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_F(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(
      ExecuteScript(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 RenderView's renderer process,
// the RenderViewHost isn't reused in an improper state later.  Previously this
// led to a crash in CreateRenderView when recreating the RenderView due to a
// stale main frame routing ID.  See https://crbug.com/627400.
IN_PROC_BROWSER_TEST_F(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 RenderFrameProxy that
  // replaced the pending RenderFrame in |popup2|, as well as the RenderFrame
  // for |popup|).
  RenderProcessHost* b_process =
      popup->web_contents()->GetMainFrame()->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
  // RenderView, 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_F(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.
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
                       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())
          ->GetFrameTree()
          ->root();
  RenderFrameProxyHost* proxy =
      popup2_root->render_manager()->GetRenderFrameProxyHost(b_instance);
  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(
      ExecuteScript(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));

  base::string16 expected_title(base::UTF8ToUTF16("foo"));
  TitleWatcher title_watcher(popup2->web_contents(), expected_title);
  EXPECT_TRUE(ExecuteScript(
      shell(), "window.open('','popup2').postMessage('foo', '*');"));
  EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
}

IN_PROC_BROWSER_TEST_F(SitePerProcessFeaturePolicyBrowserTest,
                       TestPolicyReplicationOnSameOriginNavigation) {
  GURL start_url(
      embedded_test_server()->GetURL("a.com", "/feature-policy1.html"));
  GURL first_nav_url(
      embedded_test_server()->GetURL("a.com", "/feature-policy2.html"));
  GURL second_nav_url(embedded_test_server()->GetURL("a.com", "/title2.html"));

  EXPECT_TRUE(NavigateToURL(shell(), start_url));

  FrameTreeNode* root = web_contents()->GetFrameTree()->root();
  EXPECT_EQ(CreateFPHeader(blink::mojom::FeaturePolicyFeature::kGeolocation,
                           blink::mojom::FeaturePolicyFeature::kOversizedImages,
                           {start_url.GetOrigin()}),
            root->current_replication_state().feature_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(CreateFPHeaderMatchesAll(
                blink::mojom::FeaturePolicyFeature::kGeolocation,
                blink::mojom::FeaturePolicyFeature::kOversizedImages),
            root->current_replication_state().feature_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().feature_policy_header.empty());
}

IN_PROC_BROWSER_TEST_F(SitePerProcessFeaturePolicyBrowserTest,
                       TestPolicyReplicationOnCrossOriginNavigation) {
  GURL start_url(
      embedded_test_server()->GetURL("a.com", "/feature-policy1.html"));
  GURL first_nav_url(
      embedded_test_server()->GetURL("b.com", "/feature-policy2.html"));
  GURL second_nav_url(embedded_test_server()->GetURL("c.com", "/title2.html"));

  EXPECT_TRUE(NavigateToURL(shell(), start_url));

  FrameTreeNode* root = web_contents()->GetFrameTree()->root();
  EXPECT_EQ(CreateFPHeader(blink::mojom::FeaturePolicyFeature::kGeolocation,
                           blink::mojom::FeaturePolicyFeature::kOversizedImages,
                           {start_url.GetOrigin()}),
            root->current_replication_state().feature_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(CreateFPHeaderMatchesAll(
                blink::mojom::FeaturePolicyFeature::kGeolocation,
                blink::mojom::FeaturePolicyFeature::kOversizedImages),
            root->current_replication_state().feature_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().feature_policy_header.empty());
}

// Test that the replicated feature policy header is correct in subframes as
// they navigate.
IN_PROC_BROWSER_TEST_F(SitePerProcessFeaturePolicyBrowserTest,
                       TestPolicyReplicationFromRemoteFrames) {
  GURL main_url(
      embedded_test_server()->GetURL("a.com", "/feature-policy-main.html"));
  GURL first_nav_url(
      embedded_test_server()->GetURL("b.com", "/feature-policy2.html"));
  GURL second_nav_url(embedded_test_server()->GetURL("c.com", "/title2.html"));

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

  FrameTreeNode* root = web_contents()->GetFrameTree()->root();
  EXPECT_EQ(CreateFPHeader(blink::mojom::FeaturePolicyFeature::kGeolocation,
                           blink::mojom::FeaturePolicyFeature::kOversizedImages,
                           {main_url.GetOrigin(), GURL("http://example.com/")}),
            root->current_replication_state().feature_policy_header);
  EXPECT_EQ(1UL, root->child_count());
  EXPECT_EQ(
      CreateFPHeader(blink::mojom::FeaturePolicyFeature::kGeolocation,
                     blink::mojom::FeaturePolicyFeature::kOversizedImages,
                     {main_url.GetOrigin()}),
      root->child_at(0)->current_replication_state().feature_policy_header);

  // Navigate the iframe cross-site.
  NavigateFrameToURL(root->child_at(0), first_nav_url);
  EXPECT_EQ(
      CreateFPHeaderMatchesAll(
          blink::mojom::FeaturePolicyFeature::kGeolocation,
          blink::mojom::FeaturePolicyFeature::kOversizedImages),
      root->child_at(0)->current_replication_state().feature_policy_header);

  // Navigate the iframe to another location, this one with no policy header
  NavigateFrameToURL(root->child_at(0), second_nav_url);
  EXPECT_TRUE(root->child_at(0)
                  ->current_replication_state()
                  .feature_policy_header.empty());

  // Navigate the iframe back to a page with a policy
  NavigateFrameToURL(root->child_at(0), first_nav_url);
  EXPECT_EQ(
      CreateFPHeaderMatchesAll(
          blink::mojom::FeaturePolicyFeature::kGeolocation,
          blink::mojom::FeaturePolicyFeature::kOversizedImages),
      root->child_at(0)->current_replication_state().feature_policy_header);
}

// Test that the replicated feature policy header is correct in remote proxies
// after the local frame has navigated.
IN_PROC_BROWSER_TEST_F(SitePerProcessFeaturePolicyJavaScriptBrowserTest,
                       TestFeaturePolicyReplicationToProxyOnNavigation) {
  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", "/feature-policy3.html"));
  GURL second_nav_url(
      embedded_test_server()->GetURL("a.com", "/feature-policy4.html"));

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

  FrameTreeNode* root = web_contents()->GetFrameTree()->root();
  EXPECT_TRUE(root->current_replication_state().feature_policy_header.empty());
  EXPECT_EQ(2UL, root->child_count());
  EXPECT_TRUE(root->child_at(1)
                  ->current_replication_state()
                  .feature_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.)
  NavigateFrameToURL(root->child_at(1), first_nav_url);
  EXPECT_EQ(
      CreateFPHeaderMatchesAll(
          blink::mojom::FeaturePolicyFeature::kGeolocation,
          blink::mojom::FeaturePolicyFeature::kOversizedImages),
      root->child_at(1)->current_replication_state().feature_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 enabled. Otherwise, it will be disabled, as
  // geolocation is disabled by default in cross-origin frames.
  EXPECT_EQ(true,
            EvalJs(root->child_at(1)->child_at(0),
                   "document.featurePolicy.allowsFeature('geolocation')"));
  // TODO(loonybear): Add JS test for parameterized features.

  // Now navigate the iframe to a page with no policy, and the same nested
  // cross-site iframe. The policy should be cleared in the proxy.
  NavigateFrameToURL(root->child_at(1), second_nav_url);
  EXPECT_TRUE(root->child_at(1)
                  ->current_replication_state()
                  .feature_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 disabled.
  EXPECT_EQ(false,
            EvalJs(root->child_at(1)->child_at(0),
                   "document.featurePolicy.allowsFeature('geolocation')"));
}

// Test that the constructed feature 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_F(SitePerProcessFeaturePolicyJavaScriptBrowserTest,
                       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()->GetFrameTree()->root();
  EXPECT_TRUE(root->current_replication_state().feature_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.
  bool success = false;
  EXPECT_TRUE(ExecuteScriptAndExtractBool(
      root->child_at(0),
      "window.domAutomationController.send("
      "document.featurePolicy.allowsFeature('geolocation'));",
      &success));
  EXPECT_TRUE(success);

  TestNavigationObserver load_observer(shell()->web_contents());
  EXPECT_TRUE(ExecuteScript(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_TRUE(ExecuteScriptAndExtractBool(
      root->child_at(0),
      "window.domAutomationController.send("
      "document.featurePolicy.allowsFeature('geolocation'));",
      &success));
  EXPECT_TRUE(success);
}

// Test that the constructed feature 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_F(SitePerProcessFeaturePolicyJavaScriptBrowserTest,
                       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()->GetFrameTree()->root();
  EXPECT_TRUE(root->current_replication_state().feature_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.
  bool success = false;
  EXPECT_TRUE(ExecuteScriptAndExtractBool(
      root->child_at(0),
      "window.domAutomationController.send("
      "document.featurePolicy.allowsFeature('geolocation'));",
      &success));
  EXPECT_TRUE(success);

  TestNavigationObserver load_observer(shell()->web_contents());
  EXPECT_TRUE(ExecuteScript(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_TRUE(ExecuteScriptAndExtractBool(
      root->child_at(0),
      "window.domAutomationController.send("
      "document.featurePolicy.allowsFeature('geolocation'));",
      &success));
  EXPECT_FALSE(success);
}

// 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_F(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()"));
  GURL srcdoc_url(kAboutSrcDocURL);

  // #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()->GetFrameTree()->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(ExecuteScript(
      root, "document.getElementById('child-0').srcdoc = 'srcdoc content';"));
  load_observer.Wait();

  // Ensure that the iframe reuses its parent's process.
  EXPECT_EQ(srcdoc_url, child->current_url());
  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_F(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()->GetFrameTree()->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(ExecuteScript(
      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_F(SitePerProcessBrowserTest,
                       ContextMenuAfterCrossProcessNavigation) {
  // Navigate to a.com.
  EXPECT_TRUE(NavigateToURL(
      shell(), embedded_test_server()->GetURL("a.com", "/title1.html")));

  // Disable the swapout ACK and the swapout timer.
  RenderFrameHostImpl* rfh = static_cast<RenderFrameHostImpl*>(
      shell()->web_contents()->GetMainFrame());
  auto filter = base::MakeRefCounted<DropMessageFilter>(
      FrameMsgStart, FrameHostMsg_SwapOut_ACK::ID);
  rfh->GetProcess()->AddFilter(filter.get());
  rfh->DisableSwapOutTimerForTesting();

  // 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 swapped and
  // added to pending delete list.
  rfh->OnMessageReceived(
      FrameHostMsg_ContextMenu(rfh->GetRoutingID(), ContextMenuParams()));
}

// Test iframe container policy is replicated properly to the browser.
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, ContainerPolicy) {
  GURL url(embedded_test_server()->GetURL("/allowed_frames.html"));
  EXPECT_TRUE(NavigateToURL(shell(), url));

  FrameTreeNode* root = web_contents()->GetFrameTree()->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_F(SitePerProcessBrowserTest, ContainerPolicyDynamic) {
  GURL main_url(embedded_test_server()->GetURL("/allowed_frames.html"));
  GURL nav_url(
      embedded_test_server()->GetURL("b.com", "/feature-policy2.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  FrameTreeNode* root = web_contents()->GetFrameTree()->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(ExecuteScript(
      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.
  NavigateFrameToURL(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_F(SitePerProcessBrowserTest,
                       ContainerPolicyCrossOriginNavigation) {
  WebContentsImpl* contents = web_contents();
  FrameTreeNode* root = contents->GetFrameTree()->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(ExecuteScript(
      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.
  NavigateFrameToURL(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_F(SitePerProcessBrowserTest,
                       ContainerPolicySandboxDynamic) {
  GURL main_url(embedded_test_server()->GetURL("/allowed_frames.html"));
  GURL nav_url(
      embedded_test_server()->GetURL("b.com", "/feature-policy2.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  FrameTreeNode* root = web_contents()->GetFrameTree()->root();

  // Validate that the effective container policy contains a single non-unique
  // origin.
  const blink::ParsedFeaturePolicy initial_effective_policy =
      root->child_at(2)->effective_frame_policy().container_policy;
  EXPECT_EQ(1UL, initial_effective_policy[0].values.size());
  EXPECT_FALSE(initial_effective_policy[0].values.begin()->first.opaque());

  // 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(ExecuteScript(
      root, "document.getElementById('child-2').setAttribute('sandbox','')"));
  const blink::ParsedFeaturePolicy updated_effective_policy =
      root->child_at(2)->effective_frame_policy().container_policy;
  const blink::ParsedFeaturePolicy updated_pending_policy =
      root->child_at(2)->pending_frame_policy().container_policy;
  EXPECT_EQ(1UL, updated_effective_policy[0].values.size());
  EXPECT_FALSE(updated_effective_policy[0].values.begin()->first.opaque());
  EXPECT_GE(updated_pending_policy[0].opaque_value, blink::PolicyValue(true));
  EXPECT_EQ(0UL, updated_pending_policy[0].values.size());

  // Navigate the frame; pending policy should now be committed.
  NavigateFrameToURL(root->child_at(2), nav_url);
  const blink::ParsedFeaturePolicy final_effective_policy =
      root->child_at(2)->effective_frame_policy().container_policy;
  EXPECT_GE(final_effective_policy[0].opaque_value, blink::PolicyValue(true));
  EXPECT_EQ(0UL, final_effective_policy[0].values.size());
}

// Test that creating a new remote frame at the same origin as its parent
// results in the correct feature policy in the RemoteSecurityContext.
// https://crbug.com/852102
IN_PROC_BROWSER_TEST_F(SitePerProcessFeaturePolicyJavaScriptBrowserTest,
                       FeaturePolicyConstructionInExistingProxy) {
  WebContentsImpl* contents = web_contents();
  FrameTreeNode* root = contents->GetFrameTree()->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(ExecuteScript(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.
  bool success = false;
  EXPECT_TRUE(ExecuteScriptAndExtractBool(
      root->child_at(1)->child_at(0),
      "window.domAutomationController.send("
      "document.featurePolicy.allowsFeature('autoplay'));",
      &success));
  EXPECT_TRUE(success);
}

// 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::Bind(
        &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(const net::test_server::SendBytesCallback& send,
                          const net::test_server::SendCompleteCallback& done) {
    // Just create a closure that closes the socket without sending a response.
    // This will propagate an error to the underlying request.
    send_response_closures_.push_back(base::Bind(send, "", done));
  }

  // 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 std::unique_ptr<net::test_server::BasicHttpResponse>();
  }

  // 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 (const auto it : send_response_closures_) {
      it.Run();
    }
  }

  // This class passes the callbacks 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) {}
    void SendResponse(
        const net::test_server::SendBytesCallback& send,
        const net::test_server::SendCompleteCallback& done) override {
      test_harness_->AddDelayedResponse(send, done);
    }

   private:
    RequestDelayingSitePerProcessBrowserTest* test_harness_;

    DISALLOW_COPY_AND_ASSIGN(DelayedResponse);
  };

  // Set of closures to call which will complete delayed requests. May only be
  // modified on the test_server_'s thread.
  std::vector<base::Closure> send_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_F(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));
  bool result;
  EXPECT_TRUE(ExecuteScriptAndExtractBool(shell(), "createFrames()", &result));
  EXPECT_TRUE(result);
}

IN_PROC_BROWSER_TEST_F(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));
  bool result;
  EXPECT_TRUE(ExecuteScriptAndExtractBool(shell(), "createFrames()", &result));
  EXPECT_TRUE(result);
}

#if defined(OS_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() { 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();
  }

  TextInputManager* const text_input_manager_;
  std::string last_selected_text_;
  std::string expected_text_;
  scoped_refptr<MessageLoopRunner> loop_runner_;

  DISALLOW_COPY_AND_ASSIGN(TextSelectionObserver);
};

class SitePerProcessAndroidImeTest : public SitePerProcessBrowserTest {
 public:
  SitePerProcessAndroidImeTest() : SitePerProcessBrowserTest() {}
  ~SitePerProcessAndroidImeTest() override {}

 protected:
  ImeAdapterAndroid* ime_adapter() {
    return static_cast<RenderWidgetHostViewAndroid*>(
               web_contents()->GetRenderWidgetHostView())
        ->ime_adapter_for_testing();
  }

  void FocusInputInFrame(RenderFrameHostImpl* frame) {
    ASSERT_TRUE(ExecuteScript(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()->GetFrameTree()->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 (auto* frame : frames_)
      ASSERT_TRUE(ExecuteScript(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, base::android::JavaParamRef<jobject>(env, caller.obj()),
        base::android::JavaParamRef<jobject>(env, jtext.obj()),
        base::android::JavaParamRef<jstring>(env, jtext.obj()), 0);
  }

  std::vector<RenderFrameHostImpl*> frames_;

 private:
  DISALLOW_COPY_AND_ASSIGN(SitePerProcessAndroidImeTest);
};

// This test verifies that committing text will be applied on the focused
// RenderWidgetHost.
IN_PROC_BROWSER_TEST_F(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  // OS_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_F(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())
                            ->GetFrameTree()
                            ->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_F(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_F(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())
                            ->GetFrameTree()
                            ->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(ExecuteScript(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_F(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()->GetFrameTree()->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(ExecuteScript(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.
  std::string body;
  EXPECT_TRUE(ExecuteScriptAndExtractString(root, R"(
    var body = document.getElementsByTagName('pre')[0].innerText;
    window.domAutomationController.send(body);)", &body));
  EXPECT_EQ("my_token=my_value\n", body);

  // 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()));
  body = "";
  EXPECT_TRUE(ExecuteScriptAndExtractString(root, R"(
    var body = document.getElementsByTagName('pre')[0].innerText;
    window.domAutomationController.send(body);)", &body));
  EXPECT_EQ("my_token=my_value\n", body);
}

// 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_F(
    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()->GetMainFrame()->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()->GetMainFrame()->GetLastCommittedURL());
}

// Class to sniff incoming IPCs for FrameHostMsg_SetIsInert messages.
class SetIsInertMessageFilter : public content::BrowserMessageFilter {
 public:
  SetIsInertMessageFilter()
      : content::BrowserMessageFilter(FrameMsgStart),
        msg_received_(false) {}

  bool OnMessageReceived(const IPC::Message& message) override {
    IPC_BEGIN_MESSAGE_MAP(SetIsInertMessageFilter, message)
      IPC_MESSAGE_HANDLER(FrameHostMsg_SetIsInert, OnSetIsInert)
    IPC_END_MESSAGE_MAP()
    return false;
  }

  bool is_inert() const { return is_inert_; }

  void Wait() { run_loop_.Run(); }

 private:
  ~SetIsInertMessageFilter() override {}

  void OnSetIsInert(bool is_inert) {
    base::PostTaskWithTraits(
        FROM_HERE, {content::BrowserThread::UI},
        base::BindOnce(&SetIsInertMessageFilter::OnSetIsInertOnUI, this,
                       is_inert));
  }
  void OnSetIsInertOnUI(bool is_inert) {
    is_inert_ = is_inert;
    if (!msg_received_) {
      msg_received_ = true;
      run_loop_.Quit();
    }
  }
  base::RunLoop run_loop_;
  bool msg_received_;
  bool is_inert_;
  DISALLOW_COPY_AND_ASSIGN(SetIsInertMessageFilter);
};

// Tests that when a frame contains a modal <dialog> element, out-of-process
// iframe children cannot take focus, because they are inert.
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, 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())
                            ->GetFrameTree()
                            ->root();
  ASSERT_EQ(2U, root->child_count());

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

  EXPECT_TRUE(ExecuteScript(
      iframe_node,
      "document.head.innerHTML = '';"
      "document.body.innerHTML = '<input id=\"text1\"> <input id=\"text2\">';"
      "text1.focus();"));

  // Add a filter to the parent frame's process to monitor for inert bit
  // updates. These are sent through the proxy for b.com child frame.
  scoped_refptr<SetIsInertMessageFilter> filter = new SetIsInertMessageFilter();
  root->current_frame_host()->GetProcess()->AddFilter(filter.get());

  // Add a <dialog> to the root frame and call showModal on it.
  EXPECT_TRUE(ExecuteScript(root,
                            "let dialog = "
                            "document.body.appendChild(document.createElement('"
                            "dialog'));"
                            "dialog.innerHTML = 'Modal dialog <input>';"
                            "dialog.showModal();"));
  filter->Wait();
  EXPECT_TRUE(filter->is_inert());

  // 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();

  std::string focused_element;

  // Attempt to change focus in the inert subframe. This should fail.
  // The setTimeout ensures that the inert bit can propagate before the
  // test JS code runs.
  EXPECT_TRUE(ExecuteScriptAndExtractString(
      iframe_node,
      "window.setTimeout(() => {text2.focus();"
      "domAutomationController.send(document.activeElement.id);}, 0)",
      &focused_element));
  EXPECT_EQ("", focused_element);

  // 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"));
  NavigateFrameToURL(iframe_node, site_url);

  // NavigateFrameToURL 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(ExecuteScript(
      iframe_node,
      "document.head.innerHTML = '';"
      "document.body.innerHTML = '<input id=\"text1\"> <input id=\"text2\">';"
      "text1.focus();"));

  // Verify that inertness was preserved across the navigation.
  EXPECT_TRUE(ExecuteScriptAndExtractString(
      iframe_node,
      "text2.focus();"
      "domAutomationController.send(document.activeElement.id);",
      &focused_element));
  EXPECT_EQ("", focused_element);

  // Navigate the subframe back into its parent process to verify that the
  // new local frame remains inert.
  GURL same_site_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
  NavigateFrameToURL(iframe_node, same_site_url);

  EXPECT_TRUE(ExecuteScript(
      iframe_node,
      "document.head.innerHTML = '';"
      "document.body.innerHTML = '<input id=\"text1\"> <input id=\"text2\">';"
      "text1.focus();"));

  // Verify that inertness was preserved across the navigation.
  EXPECT_TRUE(ExecuteScriptAndExtractString(
      iframe_node,
      "text2.focus();"
      "domAutomationController.send(document.activeElement.id);",
      &focused_element));
  EXPECT_EQ("", focused_element);
}

// 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_F(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()->GetFrameTree()->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())
          ->GetFrameTree()
          ->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_F(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()->GetFrameTree()->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())
          ->GetFrameTree()
          ->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 RenderFrameProxy 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_F(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()->GetFrameTree()->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(ExecuteScript(web_contents(), script));

  // Wait for main frame request, but don't commit it yet.  This should create
  // a speculative RenderFrameHost.
  ASSERT_TRUE(manager1.WaitForRequestStart());
  RenderFrameHostImpl* root_speculative_rfh =
      root->render_manager()->speculative_frame_host();
  EXPECT_TRUE(root_speculative_rfh);
  scoped_refptr<SiteInstanceImpl> b_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->render_manager()->GetRenderFrameProxyHost(b_site_instance.get());
  EXPECT_TRUE(root_proxy);
  EXPECT_TRUE(root_proxy->is_render_frame_proxy_live());

  // Wait for subframe request, but don't commit it yet.
  ASSERT_TRUE(manager2.WaitForRequestStart());
  EXPECT_TRUE(child->render_manager()->speculative_frame_host());

  // 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->render_manager()->GetRenderFrameProxyHost(b_site_instance.get());
  EXPECT_TRUE(child_proxy);
  EXPECT_TRUE(child_proxy->is_render_frame_proxy_live());

  // Now let the main frame commit.
  manager1.WaitForNavigationFinished();

  // Make sure the process is live and at the new URL.
  EXPECT_TRUE(b_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.
  manager2.WaitForNavigationFinished();

  // The new commit should have detached the old child frame.
  EXPECT_EQ(0U, root->child_count());
  int length = -1;
  EXPECT_TRUE(ExecuteScriptAndExtractInt(
      web_contents(), "domAutomationController.send(frames.length);", &length));
  EXPECT_EQ(0, length);

  // The root proxy should be gone.
  EXPECT_FALSE(
      root->render_manager()->GetRenderFrameProxyHost(b_site_instance.get()));
}

// 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_F(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()->GetFrameTree()->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(
      ExecuteScript(root->current_frame_host(),
                    "window.addEventListener('message', function(event) {\n"
                    "  event.source.postMessage(event.data + '-reply', '*');\n"
                    "});"));
  EXPECT_TRUE(ExecuteScript(
      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(
      ExecuteScript(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.
  ASSERT_TRUE(manager1.WaitForRequestStart());
  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(ExecuteScript(web_contents(),
                            JsReplace("frames[0].location = $1", new_url_2)));

  // Wait for subframe request.
  ASSERT_TRUE(manager2.WaitForRequestStart());
  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.
  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.
  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.
  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(
      ExecuteScript(child->current_frame_host(),
                    "window.addEventListener('message', function(event) {\n"
                    "  domAutomationController.send(event.data);\n"
                    "});"));
  std::string response;
  EXPECT_TRUE(ExecuteScriptAndExtractString(
      child, "parent.postMessage('root-ping', '*')", &response));
  EXPECT_EQ("root-ping-reply", response);

  EXPECT_TRUE(ExecuteScriptAndExtractString(
      child, "parent.frames[1].postMessage('sibling-ping', '*')", &response));
  EXPECT_EQ("sibling-ping-subframe-reply", response);

  // Cancel the pending main frame navigation, and verify that the subframe can
  // still communicate with the (old) main frame.
  root->navigator()->CancelNavigation(root, true /* inform_renderer */);
  EXPECT_FALSE(root->render_manager()->speculative_frame_host());
  response = "";
  EXPECT_TRUE(ExecuteScriptAndExtractString(
      child, "parent.postMessage('root-ping', '*')", &response));
  EXPECT_EQ("root-ping-reply", response);
}

// 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_F(SitePerProcessBrowserTest,
                       TwoCrossSitePendingNavigationsWithOpener) {
  GURL main_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));
  FrameTreeNode* root = web_contents()->GetFrameTree()->root();

  // Install a postMessage handler in main frame for later use.
  EXPECT_TRUE(
      ExecuteScript(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(
      ExecuteScript(web_contents(), JsReplace("location = $1", new_url_1)));
  ASSERT_TRUE(manager.WaitForRequestStart());

  // 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->render_manager()->GetRenderFrameProxyHost(b_site_instance.get());
  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(
      ExecuteScript(popup_shell->web_contents(),
                    "window.addEventListener('message', function(event) {\n"
                    "  domAutomationController.send(event.data);\n"
                    "});"));

  std::string response;
  EXPECT_TRUE(ExecuteScriptAndExtractString(
      popup_shell->web_contents(), "opener.postMessage('opener-ping', '*');",
      &response));
  EXPECT_EQ("opener-ping-reply", response);

  // Cancel the pending main frame navigation, and verify that the subframe can
  // still communicate with the (old) main frame.
  root->navigator()->CancelNavigation(root, true /* inform_renderer */);
  EXPECT_FALSE(root->render_manager()->speculative_frame_host());
  response = "";
  EXPECT_TRUE(ExecuteScriptAndExtractString(
      popup_shell->web_contents(), "opener.postMessage('opener-ping', '*')",
      &response));
  EXPECT_EQ("opener-ping-reply", response);
}

#if defined(OS_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_F(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()->GetFrameTree()->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.
  ASSERT_TRUE(nav_manager.WaitForRequestStart());
  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->GetSize();
  float x = size.width() / 2;
  float y = size.height() / 2;
  ui::MotionEventAndroid::Pointer pointer0(0, x, y, 0, 0, 0, 0, 0);
  ui::MotionEventAndroid::Pointer pointer1(0, 0, 0, 0, 0, 0, 0, 0);
  ui::MotionEventAndroid event(nullptr, nullptr, 1.f / root_view->GetDipScale(),
                               0.f, 0.f, 0.f, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
                               false, &pointer0, &pointer1);
  root_view->OnTouchEventForTesting(event);

  EXPECT_TRUE(mock_handler.did_receive_event());
  EXPECT_FALSE(mock_handler_speculative.did_receive_event());
}

IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, TestChildProcessImportance) {
  web_contents()->SetMainFrameImportance(ChildProcessImportance::MODERATE);

  // 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()->GetFrameTree()->root();
  ASSERT_EQ(1u, root->child_count());
  FrameTreeNode* child = root->child_at(0);

  // Importance should survive initial navigation. Note importance only affect
  // main frame, so sub frame process should remain NORMAL throughout.
  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()->SetMainFrameImportance(ChildProcessImportance::NORMAL);
  EXPECT_EQ(ChildProcessImportance::NORMAL,
            root->current_frame_host()->GetProcess()->GetEffectiveImportance());
  EXPECT_EQ(
      ChildProcessImportance::NORMAL,
      child->current_frame_host()->GetProcess()->GetEffectiveImportance());
  web_contents()->SetMainFrameImportance(ChildProcessImportance::IMPORTANT);
  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()->GetID();
  GURL url = embedded_test_server()->GetURL("foo.com", "/title2.html");
  {
    RenderFrameDeletedObserver deleted_observer(child->current_frame_host());
    NavigateFrameToURL(root->child_at(0), url);
    deleted_observer.WaitUntilDeleted();
  }
  int new_child_process_id = child->current_frame_host()->GetProcess()->GetID();
  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()->GetID();
  child = nullptr;  // Going to navigate root to page without any child.
  {
    RenderFrameDeletedObserver deleted_observer(root->current_frame_host());
    NavigateFrameToURL(root, url);
    deleted_observer.WaitUntilDeleted();
  }
  EXPECT_EQ(0u, root->child_count());
  int new_root_process_id = root->current_frame_host()->GetProcess()->GetID();
  EXPECT_NE(old_root_process_id, new_root_process_id);
  EXPECT_EQ(ChildProcessImportance::IMPORTANT,
            root->current_frame_host()->GetProcess()->GetEffectiveImportance());

  // Check interstitial maintains importance.
  TestInterstitialDelegate* delegate = new TestInterstitialDelegate;
  WebContentsImpl* contents_impl =
      static_cast<WebContentsImpl*>(web_contents());
  GURL interstitial_url("http://interstitial");
  InterstitialPageImpl* interstitial = new InterstitialPageImpl(
      contents_impl, contents_impl, true, interstitial_url, delegate);
  interstitial->Show();
  WaitForInterstitialAttach(contents_impl);
  RenderProcessHost* interstitial_process =
      interstitial->GetMainFrame()->GetProcess();
  EXPECT_EQ(ChildProcessImportance::IMPORTANT,
            interstitial_process->GetEffectiveImportance());

  web_contents()->SetMainFrameImportance(ChildProcessImportance::MODERATE);
  EXPECT_EQ(ChildProcessImportance::MODERATE,
            interstitial_process->GetEffectiveImportance());
}

// Tests for Android TouchSelectionEditing.
class FrameStableObserver {
 public:
  FrameStableObserver(RenderWidgetHostViewBase* view, base::TimeDelta delta)
      : view_(view), delta_(delta) {}
  virtual ~FrameStableObserver() {}

  void WaitUntilStable() {
    uint32_t current_frame_number = view_->RendererFrameNumber();
    uint32_t previous_frame_number;

    do {
      base::RunLoop run_loop;
      base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
          FROM_HERE, run_loop.QuitClosure(), delta_);
      run_loop.Run();
      previous_frame_number = current_frame_number;
      current_frame_number = view_->RendererFrameNumber();
    } while (current_frame_number != previous_frame_number);
  }

 private:
  RenderWidgetHostViewBase* view_;
  base::TimeDelta delta_;

  DISALLOW_COPY_AND_ASSIGN(FrameStableObserver);
};

class TouchSelectionControllerClientTestWrapper
    : public ui::TouchSelectionControllerClient {
 public:
  explicit TouchSelectionControllerClientTestWrapper(
      ui::TouchSelectionControllerClient* client)
      : expected_event_(ui::SELECTION_HANDLES_SHOWN), client_(client) {}

  ~TouchSelectionControllerClientTestWrapper() override {}

  void InitWaitForSelectionEvent(ui::SelectionEventType expected_event) {
    DCHECK(!run_loop_);
    expected_event_ = expected_event;
    run_loop_.reset(new 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 gfx::PointF& position) override {}

  ui::SelectionEventType expected_event_;
  std::unique_ptr<base::RunLoop> run_loop_;
  // Not owned.
  ui::TouchSelectionControllerClient* client_;

  DISALLOW_COPY_AND_ASSIGN(TouchSelectionControllerClientTestWrapper);
};

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 {
    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::TimeDelta::FromMilliseconds(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::TimeDelta::FromMilliseconds(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())
                              ->GetFrameTree()
                              ->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(
            root_rwhv_->GetSelectionControllerClientManagerForTesting());
    root_rwhv_->SetSelectionControllerClientForTesting(
        base::WrapUnique(selection_controller_client_));

    // 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"));
    NavigateFrameToURL(child_frame_tree_node_, 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);
    WaitForHitTestDataOrChildSurfaceReady(
        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());
    FrameStableObserver child_frame_stable_observer(
        child_rwhv_, TestTimeouts::tiny_timeout());
    child_frame_stable_observer.WaitUntilStable();
  }

  // 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;
    EXPECT_TRUE(ExecuteScriptAndExtractString(
        child_frame_tree_node_->current_frame_host(), "get_point_inside_text()",
        &str));
    ConvertJSONToPoint(str, &point_f);
    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::TimeDelta::FromMilliseconds(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::ThreadTaskRunnerHandle::Get()->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);
    JNIEnv* env = base::android::AttachCurrentThread();
    auto time_ms = (ui::EventTimeForNow() - base::TimeTicks()).InMilliseconds();
    ui::MotionEventAndroid touch(
        env, nullptr, 1.f, 0, 0, 0, time_ms,
        ui::MotionEventAndroid::GetAndroidAction(action), 1, 0, 0, 0, 0, 0, 0,
        0, false, &p, nullptr);
    view->OnTouchEvent(touch);
  }

  RenderWidgetHostViewAndroid* root_rwhv_;
  RenderWidgetHostViewChildFrame* child_rwhv_;
  FrameTreeNode* child_frame_tree_node_;
  std::unique_ptr<RenderFrameSubmissionObserver> frame_observer_;
  TouchSelectionControllerClientTestWrapper* selection_controller_client_;

  std::unique_ptr<base::RunLoop> gesture_run_loop_;
};

IN_PROC_BROWSER_TEST_F(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::TimeDelta::FromMilliseconds(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 defined(OS_ANDROID)  // Flaky on Android.  See https://crbug.com/906204.
#define MAYBE_SelectionThenPinchInOOPIF DISABLED_SelectionThenPinchInOOPIF
#else
#define MAYBE_SelectionThenPinchInOOPIF SelectionThenPinchInOOPIF
#endif
IN_PROC_BROWSER_TEST_F(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::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  // defined(OS_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) {}

  void OnInputEvent(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(InputEventAckSource source,
                       InputEventAckState 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:
  std::vector<uint32_t>* outgoing_touch_event_ids_;
  std::vector<uint32_t>* acked_touch_event_ids_;
  DISALLOW_COPY_AND_ASSIGN(TouchEventObserver);
};

// 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.
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, 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()->GetFrameTree()->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(ExecuteScript(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 });"));

  WaitForHitTestDataOrChildSurfaceReady(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::kTouchEnd);
  InputEventAckWaiter child_ack_waiter(child_host,
                                       blink::WebInputEvent::kTouchEnd);
  InputEventAckWaiter child_gesture_tap_ack_waiter(
      child_host, blink::WebInputEvent::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;
    EXPECT_TRUE(ExecuteScriptAndExtractString(
        child_node,
        "var rect = document.body.getBoundingClientRect();\
         var point = {\
           x: rect.left + rect.width / 2,\
           y: rect.top + rect.height / 2\
         };\
         window.domAutomationController.send(JSON.stringify(point));",
        &str));
    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 = SyntheticGestureParams::TOUCH_INPUT;
  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 = SyntheticGestureParams::TOUCH_INPUT;
  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.
  int child_touch_event_count = 0;
  EXPECT_TRUE(ExecuteScriptAndExtractInt(
      child_node, "window.domAutomationController.send(touch_event_count);",
      &child_touch_event_count));
  EXPECT_EQ(2, child_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();
}

// This test verifies that the main-frame's page scale factor propagates to
// the compositor layertrees in each of the child processes.
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
                       PageScaleFactorPropagatesToOOPIFs) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b(c),d)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  FrameTreeNode* root = web_contents()->GetFrameTree()->root();
  ASSERT_EQ(2u, root->child_count());
  FrameTreeNode* child_b = root->child_at(0);
  FrameTreeNode* child_c = root->child_at(1);
  ASSERT_EQ(1U, child_b->child_count());
  FrameTreeNode* child_d = child_b->child_at(0);

  ASSERT_TRUE(child_b);
  ASSERT_TRUE(child_c);
  ASSERT_TRUE(child_d);

  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));

  RenderFrameSubmissionObserver observer_a(root);
  RenderFrameSubmissionObserver observer_b(child_b);
  RenderFrameSubmissionObserver observer_c(child_c);
  RenderFrameSubmissionObserver observer_d(child_d);

  // We need to observe a root frame submission to pick up the initial page
  // scale factor.
  observer_a.WaitForAnyFrameSubmission();

  const float kPageScaleDelta = 2.f;
  // On desktop systems we expect |current_page_scale| to be 1.f, but on
  // Android it will typically be less than 1.f, and may take on arbitrary
  // values.
  float current_page_scale =
      observer_a.LastRenderFrameMetadata().page_scale_factor;
  float target_page_scale = current_page_scale * kPageScaleDelta;

  SyntheticPinchGestureParams params;
  auto* host = static_cast<RenderWidgetHostImpl*>(
      root->current_frame_host()->GetRenderWidgetHost());
  gfx::Rect bounds(host->GetView()->GetViewBounds().size());
  // The synthetic gesture code expects a location in root-view coordinates.
  params.anchor = gfx::PointF(bounds.CenterPoint());
  // In SyntheticPinchGestureParams, |scale_factor| is really a delta.
  params.scale_factor = kPageScaleDelta;
#if defined(OS_MACOSX)
  auto synthetic_pinch_gesture =
      std::make_unique<SyntheticTouchpadPinchGesture>(params);
#else
  auto synthetic_pinch_gesture =
      std::make_unique<SyntheticTouchscreenPinchGesture>(params);
#endif

  // Send pinch gesture and verify we receive the ack.
  InputEventAckWaiter ack_waiter(host, blink::WebInputEvent::kGesturePinchEnd);
  host->QueueSyntheticGesture(
      std::move(synthetic_pinch_gesture),
      base::BindOnce([](SyntheticGesture::Result result) {
        EXPECT_EQ(SyntheticGesture::GESTURE_FINISHED, result);
      }));
  ack_waiter.Wait();

  // Make sure all the page scale values behave as expected.
  const float kScaleTolerance = 0.1f;
  observer_a.WaitForPageScaleFactor(target_page_scale, kScaleTolerance);
  observer_b.WaitForExternalPageScaleFactor(target_page_scale, kScaleTolerance);
  observer_c.WaitForExternalPageScaleFactor(target_page_scale, kScaleTolerance);
  observer_d.WaitForExternalPageScaleFactor(target_page_scale, kScaleTolerance);
}

// 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_F(SitePerProcessBrowserTest,
                       ActiveSandboxFlagsMaintainedAcrossNavigation) {
  GURL main_url(
      embedded_test_server()->GetURL("a.com", "/sandbox_main_frame_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()->GetFrameTree()->root();
  ASSERT_EQ(1u, root->child_count());

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

  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(blink::WebSandboxFlags::kNone,
            root->pending_frame_policy().sandbox_flags);
  EXPECT_EQ(blink::WebSandboxFlags::kNone,
            root->effective_frame_policy().sandbox_flags);
  EXPECT_EQ(blink::WebSandboxFlags::kAll & ~blink::WebSandboxFlags::kPopups &
                ~blink::WebSandboxFlags::kPointerLock &
                ~blink::WebSandboxFlags::kScripts &
                ~blink::WebSandboxFlags::kAutomaticFeatures,
            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(blink::WebSandboxFlags::kAll & ~blink::WebSandboxFlags::kPopups &
                ~blink::WebSandboxFlags::kScripts &
                ~blink::WebSandboxFlags::kAutomaticFeatures,
            root->child_at(0)->pending_frame_policy().sandbox_flags);
  EXPECT_EQ(blink::WebSandboxFlags::kAll & ~blink::WebSandboxFlags::kPopups &
                ~blink::WebSandboxFlags::kScripts &
                ~blink::WebSandboxFlags::kAutomaticFeatures,
            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(blink::WebSandboxFlags::kAll & ~blink::WebSandboxFlags::kPopups &
                ~blink::WebSandboxFlags::kScripts &
                ~blink::WebSandboxFlags::kAutomaticFeatures,
            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"));
  NavigateFrameToURL(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(blink::WebSandboxFlags::kAll & ~blink::WebSandboxFlags::kPopups &
                ~blink::WebSandboxFlags::kScripts &
                ~blink::WebSandboxFlags::kAutomaticFeatures,
            root->child_at(0)->active_sandbox_flags());
  EXPECT_EQ(blink::WebSandboxFlags::kAll & ~blink::WebSandboxFlags::kPopups &
                ~blink::WebSandboxFlags::kScripts &
                ~blink::WebSandboxFlags::kAutomaticFeatures,
            root->child_at(0)->pending_frame_policy().sandbox_flags);
  EXPECT_EQ(blink::WebSandboxFlags::kAll & ~blink::WebSandboxFlags::kPopups &
                ~blink::WebSandboxFlags::kScripts &
                ~blink::WebSandboxFlags::kAutomaticFeatures,
            root->child_at(0)->effective_frame_policy().sandbox_flags);
}

// Test that after an RFH is swapped out, its old sandbox flags remain active.
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
                       ActiveSandboxFlagsRetainedAfterSwapOut) {
  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())
                            ->GetFrameTree()
                            ->root();

  RenderFrameHostImpl* rfh =
      static_cast<WebContentsImpl*>(shell()->web_contents())->GetMainFrame();

  // Check sandbox flags on RFH before navigating away.
  EXPECT_EQ(blink::WebSandboxFlags::kAll & ~blink::WebSandboxFlags::kPopups &
                ~blink::WebSandboxFlags::kPointerLock &
                ~blink::WebSandboxFlags::kScripts &
                ~blink::WebSandboxFlags::kAutomaticFeatures,
            rfh->active_sandbox_flags());

  // Set up a slow unload handler to force the RFH to linger in the swapped
  // out but not-yet-deleted state.
  EXPECT_TRUE(
      ExecuteScript(rfh, "window.onunload=function(e){ while(1); };\n"));

  rfh->DisableSwapOutTimerForTesting();
  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 still be pending deletion, as we wait for either
  // the SwapOut ACK or a timeout.
  ASSERT_TRUE(rfh->IsRenderFrameLive());
  ASSERT_FALSE(rfh->is_active());
  ASSERT_FALSE(rfh_observer.deleted());

  // Check sandbox flags on old RFH -- they should be unchanged.
  EXPECT_EQ(blink::WebSandboxFlags::kAll & ~blink::WebSandboxFlags::kPopups &
                ~blink::WebSandboxFlags::kPointerLock &
                ~blink::WebSandboxFlags::kScripts &
                ~blink::WebSandboxFlags::kAutomaticFeatures,
            rfh->active_sandbox_flags());

  // The FrameTreeNode should have flags which represent the new state.
  EXPECT_EQ(blink::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_F(SitePerProcessBrowserTest,
                       ActiveSandboxFlagsCorrectInProxies) {
  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()->GetFrameTree()->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.
  NavigateFrameToURL(
      root->child_at(0),
      embedded_test_server()->GetURL("bar.com", "/csp_sandboxed_frame.html"));

  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.
  NavigateFrameToURL(root->child_at(0)->child_at(0),
                     embedded_test_server()->GetURL("foo.com", "/title1.html"));

  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(
      blink::WebSandboxFlags::kAll & ~blink::WebSandboxFlags::kScripts &
          ~blink::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);
  bool success = false;
  EXPECT_TRUE(ExecuteScriptAndExtractBool(
      root->child_at(0)->child_at(0),
      "window.domAutomationController.send("
      "    !window.open('data:text/html,dataurl'));",
      &success));
  EXPECT_TRUE(success);
  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.
  NavigateFrameToURL(root->child_at(0)->child_at(0),
                     embedded_test_server()->GetURL("baz.com", "/title1.html"));

  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(
      blink::WebSandboxFlags::kAll & ~blink::WebSandboxFlags::kScripts &
          ~blink::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);
  success = false;
  EXPECT_TRUE(ExecuteScriptAndExtractBool(
      root->child_at(0)->child_at(0),
      "window.domAutomationController.send("
      "    !window.open('data:text/html,dataurl'));",
      &success));
  EXPECT_TRUE(success);
  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_F(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()->GetFrameTree()->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.
  NavigateFrameToURL(
      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.
  NavigateFrameToURL(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(
      blink::WebSandboxFlags::kAll & ~blink::WebSandboxFlags::kScripts &
          ~blink::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);
  bool success = false;
  EXPECT_TRUE(ExecuteScriptAndExtractBool(
      root->child_at(0)->child_at(0),
      "window.domAutomationController.send("
      "    !window.open('data:text/html,dataurl'));",
      &success));
  EXPECT_TRUE(success);
  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(ExecuteScript(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.
  NavigateFrameToURL(root->child_at(0)->child_at(0),
                     embedded_test_server()->GetURL("foo.com", "/title2.html"));
  EXPECT_EQ(
      blink::WebSandboxFlags::kAll & ~blink::WebSandboxFlags::kScripts &
          ~blink::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);
  success = false;
  EXPECT_TRUE(ExecuteScriptAndExtractBool(
      root->child_at(0)->child_at(0),
      "window.domAutomationController.send("
      "    !window.open('data:text/html,dataurl'));",
      &success));
  EXPECT_TRUE(success);
  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_F(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()->GetFrameTree()->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(blink::WebSandboxFlags::kAll &
                ~blink::WebSandboxFlags::kPointerLock &
                ~blink::WebSandboxFlags::kOrientationLock &
                ~blink::WebSandboxFlags::kScripts &
                ~blink::WebSandboxFlags::kAutomaticFeatures,
            root->child_at(1)->effective_frame_policy().sandbox_flags);
  EXPECT_EQ(blink::WebSandboxFlags::kAll &
                ~blink::WebSandboxFlags::kPointerLock &
                ~blink::WebSandboxFlags::kScripts &
                ~blink::WebSandboxFlags::kAutomaticFeatures,
            root->child_at(1)->active_sandbox_flags());

  NavigateFrameToURL(
      root->child_at(1),
      embedded_test_server()->GetURL("bar.com", "/sandboxed_child_frame.html"));
  EXPECT_EQ(blink::WebSandboxFlags::kAll &
                ~blink::WebSandboxFlags::kPointerLock &
                ~blink::WebSandboxFlags::kOrientationLock &
                ~blink::WebSandboxFlags::kScripts &
                ~blink::WebSandboxFlags::kAutomaticFeatures,
            root->child_at(1)->effective_frame_policy().sandbox_flags);
  EXPECT_EQ(blink::WebSandboxFlags::kAll &
                ~blink::WebSandboxFlags::kPointerLock &
                ~blink::WebSandboxFlags::kScripts &
                ~blink::WebSandboxFlags::kAutomaticFeatures,
            root->child_at(1)->active_sandbox_flags());

  // Remove the sandbox attribute from the child frame.
  EXPECT_TRUE(ExecuteScript(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.
  NavigateFrameToURL(
      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(blink::WebSandboxFlags::kNone,
            root->child_at(1)->effective_frame_policy().sandbox_flags);
  EXPECT_EQ(blink::WebSandboxFlags::kNone,
            root->child_at(1)->active_sandbox_flags());

  // Check the sandbox flags on the grandchid frame in the browser process.
  EXPECT_EQ(
      blink::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.
  bool success = false;
  EXPECT_TRUE(ExecuteScriptAndExtractBool(
      root->child_at(1)->child_at(0),
      "window.domAutomationController.send("
      "    !!window.open('data:text/html,dataurl'));",
      &success));
  EXPECT_TRUE(success);
  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_F(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()->GetFrameTree()->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()->GetMainFrame()->GetSiteInstance());
  EXPECT_FALSE(second_shell_instance->IsRelatedSiteInstance(
      root->current_frame_host()->GetSiteInstance()));
  RenderProcessHost* bar_process = second_shell_instance->GetProcess();
  EXPECT_EQ(SiteInstanceImpl::ProcessReusePolicy::DEFAULT,
            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(
      SiteInstanceImpl::ProcessReusePolicy::REUSE_PENDING_OR_COMMITTED_SITE,
      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()->GetMainFrame()->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())
          ->GetFrameTree()
          ->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()->GetMainFrame()->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);
}

// 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_F(SitePerProcessBrowserTest,
                       NoProcessSharingAfterSubframeReusesExistingProcess) {
  GURL foo_url(embedded_test_server()->GetURL("foo.com", "/title1.html"));
  EXPECT_TRUE(NavigateToURL(shell(), foo_url));
  FrameTreeNode* root = web_contents()->GetFrameTree()->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())
          ->GetFrameTree()
          ->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(
      SiteInstanceImpl::ProcessReusePolicy::REUSE_PENDING_OR_COMMITTED_SITE,
      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->GetProcess());
}

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 FrameNavigationControl::CommitNavigation;
// 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() override = default;

  void WaitForBothCommits() { outer_run_loop.Run(); }

 protected:
  bool WillProcessDidCommitNavigation(
      RenderFrameHost* render_frame_host,
      NavigationRequest* navigation_request,
      ::FrameHostMsg_DidCommitProvisionalLoad_Params* 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_;

  DISALLOW_COPY_AND_ASSIGN(CommitMessageOrderReverser);
};

}  // namespace

// Regression test for https://crbug.com/877239, simulating the following
// scenario:
//
//  1) http://a.com/empty.html is loaded in a main frame.
//  2) Dynamically by JS, a same-site child frame is added:
//       <iframe 'src=http://a.com/title1.html'/>.
//  3) The initial byte of the response for `title1.html` arrives, causing
//     FrameMsg_CommitNavigation to be sent to the same renderer.
//  4) Just before processing this message, however, `main.html` navigates
//     the iframe to http://baz.com/title2.html, which results in mojom::Frame::
//     BeginNavigation being called on the RenderFrameHost.
//  5) Suppose that immediately afterwards, `main.html` enters a busy-loop.
//  6) The cross site navigation in the child frame starts, the first response
//     byte arrives quickly, and thus the navigation commits quickly.
//  6.1) FrameTreeNode::has_committed_real_load is set to true for the child.
//  6.2) The same-site RenderFrame in the child FrameTreeNode is swapped out,
//       i.e. FrameMsg_SwapOut is sent.
//  7) The renderer for site instance `a.com` exits from the busy loop,
//     and starts processing messages in order:
//  7.1) The first being processed is FrameMsg_CommitNavigation, so a
//       provisional load is created and immediately committed to
//       http://a.com/title1.html.
//  7.2) Because at the time the same-site child RenderFrame was created,
//       there had been no real load committed in the child frame, and because
//       the navigation from the initial empty document to the first real
//       document was same-origin, the global object is reused and the
//       RemoteInterfaceProvider of the RenderFrame is not rebound.
//  7.3) The obsoleted load in the same-site child frame commits, calling
//       mojom::Frame::DidCommitProvisionalLoad, however, with
//       |interface_provider_request| being null.
//  8) RenderFrameHostImpl::DidCommitProvisionalLoad sees that a real load was
//     already committed in the frame, but |interface_provider_request| is
//     missing. However, it also sees that the frame was waiting for a swap-out
//     ACK, so ignores the commit, and does not kill the renderer process.
//
// In the simulation of this scenario, we simulate (5) not by delaying
// renderer-side processing of the CommmitNavigation message, but by delaying
// browser-side processing of the response to it, of DidCommitProvisionalLoad.
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
                       InterfaceProviderRequestIsOptionalForRaceyFirstCommits) {
  // This test does not make sense anymore for the new NavigationClient way
  // of doing navigations. The first iframe navigation will get instantly
  // destroyed by the NavigationClient disconnection handle
  // NavigationRequest::OnRendererAbortedNavigation.
  // The pipe gets closed in the renderer when the javascript starts the
  // second navigation.
  // TODO(ahemery): Remove this test when IsPerNavigationMojoInterfaceEnabled
  // is on by default.
  if (IsPerNavigationMojoInterfaceEnabled())
    return;

  const GURL kMainFrameUrl(
      embedded_test_server()->GetURL("a.com", "/empty.html"));
  const GURL kSubframeSameSiteUrl(
      embedded_test_server()->GetURL("a.com", "/title1.html"));
  const GURL kCrossSiteSubframeUrl(
      embedded_test_server()->GetURL("baz.com", "/title2.html"));

  const auto kAddSameSiteDynamicSubframe = JsReplace(
      "var f = document.createElement(\"iframe\");"
      "f.src=$1;"
      "document.body.append(f);",
      kSubframeSameSiteUrl);
  const auto kNavigateSubframeCrossSite =
      JsReplace("f.src = $1;", kCrossSiteSubframeUrl);
  const std::string kExtractSubframeUrl =
      "window.domAutomationController.send(f.src);";

  ASSERT_TRUE(NavigateToURL(shell(), kMainFrameUrl));

  const auto* main_rfh_site_instance =
      shell()->web_contents()->GetMainFrame()->GetSiteInstance();

  auto did_start_deferring_commit_callback =
      base::BindLambdaForTesting([&](RenderFrameHost* subframe_rfh) {
        // Verify that the subframe starts out as same-process with its parent.
        ASSERT_EQ(main_rfh_site_instance, subframe_rfh->GetSiteInstance());

        // Trigger the second commit now that we are deferring the first one.
        ASSERT_TRUE(ExecuteScript(shell(), kNavigateSubframeCrossSite));
      });

  CommitMessageOrderReverser commit_order_reverser(
      shell()->web_contents(), kSubframeSameSiteUrl /* deferred_url */,
      std::move(did_start_deferring_commit_callback));

  ASSERT_TRUE(ExecuteScript(shell(), kAddSameSiteDynamicSubframe));
  commit_order_reverser.WaitForBothCommits();

  // Verify that:
  //  - The cross-site navigation in the sub-frame was committed and the
  //    same-site navigation was ignored.
  //  - The parent frame thinks so, too.
  //  - The renderer process corresponding to the sub-frame with the ignored
  //    commit was not killed. This is verified implicitly: this is the same
  //    renderer process where the parent RenderFrame lives, so if the call to
  //    ExecuteScriptAndExtractString succeeds here, the process is still alive.
  std::string actual_subframe_url;
  ASSERT_TRUE(ExecuteScriptAndExtractString(shell(), kExtractSubframeUrl,
                                            &actual_subframe_url));
  EXPECT_EQ(kCrossSiteSubframeUrl.spec(), actual_subframe_url);
}

// Create an out-of-process iframe that causes itself to be detached during
// its layout/animate phase. See https://crbug.com/802932.
// Disabled on Android due to flakiness, https://crbug.com/809580.
#if defined(OS_ANDROID)
#define MAYBE_OOPIFDetachDuringAnimation DISABLED_OOPIFDetachDuringAnimation
#else
#define MAYBE_OOPIFDetachDuringAnimation OOPIFDetachDuringAnimation
#endif
IN_PROC_BROWSER_TEST_F(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()->GetFrameTree()->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);
  WaitForHitTestDataOrChildSurfaceReady(nested_child->current_frame_host());

  EXPECT_TRUE(
      ExecuteScript(nested_child->current_frame_host(), "startTest();"));

  // Test passes if the main renderer doesn't crash. Ping to verify.
  bool success;
  EXPECT_TRUE(ExecuteScriptAndExtractBool(
      root->current_frame_host(), "window.domAutomationController.send(true);",
      &success));
  EXPECT_TRUE(success);
}

// Tests that a cross-process iframe asked to navigate to the same URL will
// successfully commit the navigation.
IN_PROC_BROWSER_TEST_F(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()->GetFrameTree()->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(
        ExecuteScript(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(
        ExecuteScript(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_F(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()->GetFrameTree()->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()->GetController()->LoadURLWithParams(params);
  commit_observer.WaitForCommit();

  int height = -1;
  EXPECT_TRUE(ExecuteScriptAndExtractInt(
      child, "window.domAutomationController.send(window.innerHeight);",
      &height));

  EXPECT_GT(height, 0);
}
// Test that a late swapout ACK 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_F(SitePerProcessBrowserTest,
                       RenderViewHostStaysActiveWithLateSwapoutACK) {
  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->GetMainFrame();
  RenderViewHostImpl* rvh = rfh->render_view_host();

  // Disable the swapout ACK and the swapout timer.
  auto filter = base::MakeRefCounted<DropMessageFilter>(
      FrameMsgStart, FrameHostMsg_SwapOut_ACK::ID);
  rfh->GetProcess()->AddFilter(filter.get());
  rfh->DisableSwapOutTimerForTesting();

  // 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_FALSE(rfh->is_active());

  // Kill the b.com process.
  RenderProcessHost* b_process = popup_contents->GetMainFrame()->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 swapout ACK.
  rfh->OnSwappedOut();

  // 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->GetMainFrame()->render_view_host(), rvh);
  EXPECT_TRUE(rvh->is_active());
  EXPECT_EQ(rvh->GetMainFrame(), popup_contents->GetMainFrame());
}

// 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_F(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())
          ->GetFrameTree()
          ->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.
  NavigateFrameToURL(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_F(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()->GetFrameTree()->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_F(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()->GetFrameTree()->root();
  CheckFrameDepth(0u, root);

  FrameTreeNode* child0 = root->child_at(0);
  {
    EXPECT_EQ(1u, child0->depth());
    RenderProcessHost::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());

  FrameTreeNode* grand_child = root->child_at(1)->child_at(0);
  {
    EXPECT_EQ(2u, grand_child->depth());
    RenderProcessHost::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());
  }
}

IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, 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()->GetFrameTree()->root();
  Shell* new_shell = OpenPopup(root->child_at(0), popup_url, "");
  FrameTreeNode* popup_root =
      static_cast<WebContentsImpl*>(new_shell->web_contents())
          ->GetFrameTree()
          ->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();
  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());
}

IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
                       FrameViewportIntersectionTestSimple) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b(c),d,e(f))"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  FrameTreeNode* root = web_contents()->GetFrameTree()->root();
  scoped_refptr<UpdateViewportIntersectionMessageFilter> root_filter =
      new UpdateViewportIntersectionMessageFilter();
  root->current_frame_host()->GetProcess()->AddFilter(root_filter.get());

  scoped_refptr<UpdateViewportIntersectionMessageFilter> child0_filter =
      new UpdateViewportIntersectionMessageFilter();
  root->child_at(0)->current_frame_host()->GetProcess()->AddFilter(
      child0_filter.get());

  scoped_refptr<UpdateViewportIntersectionMessageFilter> child2_filter =
      new UpdateViewportIntersectionMessageFilter();
  root->child_at(2)->current_frame_host()->GetProcess()->AddFilter(
      child2_filter.get());

  // Each immediate child is sized to 100% width and 75% height.
  LayoutNonRecursiveForTestingViewportIntersection(shell()->web_contents());

  while (true) {
    base::RunLoop run_loop;
    root_filter->set_run_loop(&run_loop);
    child0_filter->set_run_loop(&run_loop);
    child2_filter->set_run_loop(&run_loop);
    run_loop.Run();
    root_filter->set_run_loop(nullptr);
    child0_filter->set_run_loop(nullptr);
    child2_filter->set_run_loop(nullptr);

    if (  // Root should always intersect.
        CheckIntersectsViewport(true, root) &&
        // Child 0 should be entirely in viewport.
        CheckIntersectsViewport(true, root->child_at(0)) &&
        // Grand child should match parent.
        CheckIntersectsViewport(true, root->child_at(0)->child_at(0)) &&
        // Child 1 should be partially in viewport.
        CheckIntersectsViewport(true, root->child_at(1)) &&
        // Child 2 should be not be in viewport.
        CheckIntersectsViewport(false, root->child_at(2)) &&
        // Grand child should match parent.
        CheckIntersectsViewport(false, root->child_at(2)->child_at(0))) {
      break;
    }
  }
}

IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
                       FrameViewportIntersectionTestAggregate) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b,c,a,b)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  FrameTreeNode* root = web_contents()->GetFrameTree()->root();
  scoped_refptr<UpdateViewportIntersectionMessageFilter> filter =
      new UpdateViewportIntersectionMessageFilter();
  root->current_frame_host()->GetProcess()->AddFilter(filter.get());

  // Each immediate child is sized to 100% width and 75% height.
  LayoutNonRecursiveForTestingViewportIntersection(shell()->web_contents());

  while (true) {
    filter->Wait();

    bool pass = true;
    {
      // Child 2 does not intersect, but shares widget with the main frame.
      FrameTreeNode* node = root->child_at(2);
      RenderProcessHost::Priority priority =
          node->current_frame_host()->GetRenderWidgetHost()->GetPriority();
      pass = pass && priority.intersects_viewport;
      pass = pass &&
             node->current_frame_host()->GetProcess()->GetIntersectsViewport();
    }

    {
      // Child 3 does not intersect, but shares a process with child 0.
      FrameTreeNode* node = root->child_at(3);
      RenderProcessHost::Priority priority =
          node->current_frame_host()->GetRenderWidgetHost()->GetPriority();
      pass = pass && !priority.intersects_viewport;
      pass = pass &&
             node->current_frame_host()->GetProcess()->GetIntersectsViewport();
    }

    if (pass)
      break;
  }
}

// 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_F(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()->GetFrameTree()->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(
      ExecuteScript(root->child_at(0),
                    "window.addEventListener('message', function(event) {\n"
                    "  domAutomationController.send(document.hasFocus());\n"
                    "});"));

  // 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.
  bool child_has_focus = false;
  EXPECT_TRUE(ExecuteScriptAndExtractBool(root,
                                          "frames[0].postMessage('','*');\n"
                                          "frames[0].focus();\n",
                                          &child_has_focus));
  EXPECT_TRUE(child_has_focus);
}

// 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_F(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()->GetFrameTree()->root();

  // Send a postMessage to the subframe and then immediately detach the
  // subframe.
  EXPECT_TRUE(ExecuteScript(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.
  bool success;
  EXPECT_TRUE(ExecuteScriptAndExtractBool(
      root,
      "setTimeout(() => { window.domAutomationController.send(true); }, 0)",
      &success));
  EXPECT_TRUE(success);
}

// 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_F(SitePerProcessBrowserTest,
                       LastCommittedURLRetainedAfterSwapOut) {
  // 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()->GetMainFrame();
  EXPECT_EQ(start_url, rfh->GetLastCommittedURL());

  // Disable the swapout ACK and the swapout timer.
  auto filter = base::MakeRefCounted<DropMessageFilter>(
      FrameMsgStart, FrameHostMsg_SwapOut_ACK::ID);
  rfh->GetProcess()->AddFilter(filter.get());
  rfh->DisableSwapOutTimerForTesting();

  // 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_FALSE(rfh->is_active());
  EXPECT_FALSE(rfh->IsCurrent());
  EXPECT_NE(rfh, web_contents()->GetMainFrame());

  // Check that it still has a valid last committed URL.
  EXPECT_EQ(start_url, rfh->GetLastCommittedURL());
}

// Tests that when a large OOPIF has been scaled, the compositor raster area
// sent from the embedder is correct.
#if defined(OS_ANDROID) || defined(OS_MACOSX)
// Temporarily disabled on Android because this doesn't account for browser
// control height or page scale factor.
// Flaky on Mac. https://crbug.com/840314
#define MAYBE_ScaledIframeRasterSize DISABLED_ScaledframeRasterSize
#else
#define MAYBE_ScaledIframeRasterSize ScaledIframeRasterSize
#endif
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
                       MAYBE_ScaledIframeRasterSize) {
  GURL http_url(embedded_test_server()->GetURL(
      "a.com", "/frame_tree/page_with_scaled_large_frame.html"));
  EXPECT_TRUE(NavigateToURL(shell(), http_url));

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

  scoped_refptr<UpdateViewportIntersectionMessageFilter> filter =
      new UpdateViewportIntersectionMessageFilter();
  root->current_frame_host()->GetProcess()->AddFilter(filter.get());

  EXPECT_TRUE(ExecuteScript(
      root, "document.getElementsByTagName('div')[0].scrollTo(0, 5000);"));

  gfx::Rect compositing_rect;
  while (compositing_rect.y() == 0) {
    // Ignore any messages that arrive before the compositing_rect scrolls
    // away from the origin.
    filter->Wait();
    compositing_rect = filter->GetCompositingRect();
  }

  float scale_factor = 1.0f;
  if (IsUseZoomForDSFEnabled())
    scale_factor = GetFrameDeviceScaleFactor(shell()->web_contents());

  // The math below replicates the calculations in
  // RemoteFrameView::GetCompositingRect(). That could be subject to tweaking,
  // which would have to be reflected in these test expectations. Also, any
  // changes to Blink that would affect the size of the frame rect or the
  // visibile viewport would need to be accounted for.
  // The multiplication by 5 accounts for the 0.2 scale factor in the test,
  // which increases the area that has to be drawn in the OOPIF.
  int view_height = root->current_frame_host()
                        ->GetRenderWidgetHost()
                        ->GetView()
                        ->GetViewBounds()
                        .height() *
                    5 * scale_factor;
  int expected_height = view_height * 13 / 10;

  // 185 is the height of the div in the main page after subtracting scroll
  // bar height.
  int expected_offset =
      (5000 * scale_factor) - (expected_height - 185 * scale_factor) / 2;

  // Allow a small amount for rounding differences from applying page and
  // device scale factors at different times.
  EXPECT_GE(compositing_rect.height(), expected_height - 2);
  EXPECT_LE(compositing_rect.height(), expected_height + 2);
  EXPECT_GE(compositing_rect.y(), expected_offset - 2);
  EXPECT_LE(compositing_rect.y(), expected_offset + 2);
}

// Similar to ScaledIFrameRasterSize but with nested OOPIFs to ensure
// propagation works correctly.
#if defined(OS_ANDROID)
// Temporarily disabled on Android because this doesn't account for browser
// control height or page scale factor.
#define MAYBE_ScaledNestedIframeRasterSize DISABLED_ScaledNestedIframeRasterSize
#else
#define MAYBE_ScaledNestedIframeRasterSize ScaledNestedIframeRasterSize
#endif
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
                       MAYBE_ScaledNestedIframeRasterSize) {
  GURL http_url(embedded_test_server()->GetURL(
      "a.com", "/frame_tree/page_with_scaled_large_frames_nested.html"));
  EXPECT_TRUE(NavigateToURL(shell(), http_url));

  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
                            ->GetFrameTree()
                            ->root();
  FrameTreeNode* child = root->child_at(0);

  NavigateFrameToURL(
      child,
      embedded_test_server()->GetURL(
          "bar.com", "/frame_tree/page_with_large_scrollable_frame.html"));

  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));

  // This adds the filter to the immediate child iframe. It verifies that the
  // child sets the nested iframe's compositing rect correctly.
  scoped_refptr<UpdateViewportIntersectionMessageFilter> filter =
      new UpdateViewportIntersectionMessageFilter();
  child->current_frame_host()->GetProcess()->AddFilter(filter.get());

  // This scrolls the div containing in the 'Site B' iframe that contains the
  // 'Site C' iframe, and then we verify that the 'Site C' frame receives the
  // correct compositor frame.
  EXPECT_TRUE(ExecuteScript(
      child, "document.getElementsByTagName('div')[0].scrollTo(0, 5000);"));

  gfx::Rect compositing_rect;
  while (compositing_rect.y() == 0) {
    // Ignore any messages that arrive before the compositing_rect scrolls
    // away from the origin.
    filter->Wait();
    compositing_rect = filter->GetCompositingRect();
  }

  float scale_factor = 1.0f;
  if (IsUseZoomForDSFEnabled())
    scale_factor = GetFrameDeviceScaleFactor(shell()->web_contents());

  // See comment in ScaledIframeRasterSize for explanation of this. In this
  // case, the raster area of the large iframe should be restricted to
  // approximately the area of the smaller iframe in which it is embedded.
  int view_height = child->current_frame_host()
                        ->GetRenderWidgetHost()
                        ->GetView()
                        ->GetViewBounds()
                        .height() *
                    scale_factor;
  int expected_height = view_height * 13 / 10;
  int expected_offset =
      (5000 * scale_factor) - (expected_height - 185 * scale_factor) / 2;

  // Allow a small amount for rounding differences from applying page and
  // device scale factors at different times.
  EXPECT_GE(compositing_rect.height(), expected_height - 3);
  EXPECT_LE(compositing_rect.height(), expected_height + 3);
  EXPECT_GE(compositing_rect.y(), expected_offset - 3);
  EXPECT_LE(compositing_rect.y(), expected_offset + 3);
}

// Verify that OOPIF select element popup menu coordinates account for scroll
// offset in containers embedding frame.
// TODO(crbug.com/859552): Reenable this.
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
                       DISABLED_PopupMenuInTallIframeTest) {
  GURL main_url(embedded_test_server()->GetURL(
      "/frame_tree/page_with_tall_positioned_frame.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  FrameTreeNode* root = web_contents()->GetFrameTree()->root();
  FrameTreeNode* child_node = root->child_at(0);
  GURL site_url(embedded_test_server()->GetURL(
      "baz.com", "/site_isolation/page-with-select.html"));
  NavigateFrameToURL(child_node, site_url);

  scoped_refptr<UpdateViewportIntersectionMessageFilter> filter =
      new UpdateViewportIntersectionMessageFilter();
  root->current_frame_host()->GetProcess()->AddFilter(filter.get());

  // Position the select element so that it is out of the viewport, then scroll
  // it into view.
  EXPECT_TRUE(ExecuteScript(
      child_node, "document.querySelector('select').style.top='2000px';"));
  EXPECT_TRUE(ExecuteScript(root, "window.scrollTo(0, 1900);"));

  // Wait for a viewport intersection update to be dispatched to the child, and
  // ensure it is processed by the browser before continuing.
  filter->Wait();
  {
    // This yields the UI thread in order to ensure that the new viewport
    // intersection is sent to the to child renderer before the mouse click
    // below.
    base::RunLoop loop;
    base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
                                                  loop.QuitClosure());
    loop.Run();
  }

  scoped_refptr<ShowWidgetMessageFilter> show_widget_filter =
      new ShowWidgetMessageFilter();
  child_node->current_frame_host()->GetProcess()->AddFilter(
      show_widget_filter.get());

  SimulateMouseClick(child_node->current_frame_host()->GetRenderWidgetHost(),
                     55, 2005);

  // Dismiss the popup.
  SimulateMouseClick(child_node->current_frame_host()->GetRenderWidgetHost(), 1,
                     1);

  // The test passes if this wait returns, indicating that the popup was
  // scrolled into view and the OOPIF renderer displayed it. Other tests verify
  // the correctness of popup menu coordinates.
  show_widget_filter->Wait();
}

// Test to verify that viewport intersection is propagated to nested OOPIFs
// even when a parent OOPIF has been throttled.
// TODO(crbug.com/869758) The test is flaky on android and Linux.
#if defined(OS_ANDROID) || defined(OS_LINUX)
#define MAYBE_NestedFrameViewportIntersectionUpdated \
  DISABLED_NestedFrameViewportIntersectionUpdated
#else
#define MAYBE_NestedFrameViewportIntersectionUpdated \
  NestedFrameViewportIntersectionUpdated
#endif
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
                       MAYBE_NestedFrameViewportIntersectionUpdated) {
  GURL main_url(embedded_test_server()->GetURL(
      "foo.com", "/frame_tree/scrollable_page_with_positioned_frame.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  FrameTreeNode* root = web_contents()->GetFrameTree()->root();
  FrameTreeNode* child_node = root->child_at(0);
  GURL site_url(embedded_test_server()->GetURL(
      "bar.com", "/frame_tree/page_with_positioned_frame.html"));
  NavigateFrameToURL(child_node, site_url);

  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://foo.com/\n"
      "      B = http://bar.com/\n"
      "      C = http://baz.com/",
      DepictFrameTree(root));

  scoped_refptr<UpdateViewportIntersectionMessageFilter> filter =
      new UpdateViewportIntersectionMessageFilter();
  child_node->current_frame_host()->GetProcess()->AddFilter(filter.get());

  // Scroll the child frame out of view, causing it to become throttled.
  EXPECT_TRUE(ExecuteScript(root, "window.scrollTo(0, 5000);"));
  while (true) {
    filter->Wait();
    if (filter->GetViewportIntersection().IsEmpty())
      break;
  }

  // Scroll the frame back into view.
  EXPECT_TRUE(ExecuteScript(root, "window.scrollTo(0, 0);"));
  while (true) {
    filter->Wait();
    if (!filter->GetViewportIntersection().IsEmpty())
      break;
  }
}

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) {}

  void Wait() {
    run_loop_.reset(new base::RunLoop());
    run_loop_->Run();
    run_loop_.reset();
  }

 private:
  // DidCommitNavigationInterceptor:
  bool WillProcessDidCommitNavigation(
      RenderFrameHost* render_frame_host,
      NavigationRequest* navigation_request,
      ::FrameHostMsg_DidCommitProvisionalLoad_Params* params,
      mojom::DidCommitProvisionalLoadInterfaceParamsPtr* interface_params)
      override {
    RenderViewHostImpl* rvh = static_cast<RenderViewHostImpl*>(
        render_frame_host->GetRenderViewHost());
    EXPECT_TRUE(rvh->is_active());
    rvh->ClosePage();
    if (run_loop_)
      run_loop_->Quit();
    return true;
  }

  std::unique_ptr<base::RunLoop> run_loop_;

  DISALLOW_COPY_AND_ASSIGN(ClosePageBeforeCommitHelper);
};

}  // 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_F(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()->GetFrameTree()->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(ExecuteScript(
      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(
      ExecuteScript(grandchild, JsReplace("location = $1", same_site_url)));
  close_page_helper.Wait();

  // Test passes if the a.com renderer doesn't crash. Ping to verify.
  bool success;
  EXPECT_TRUE(ExecuteScriptAndExtractBool(
      new_shell, "window.domAutomationController.send(true);", &success));
  EXPECT_TRUE(success);
}

class SitePerProcessBrowserTouchActionTest : public SitePerProcessBrowserTest {
 public:
  SitePerProcessBrowserTouchActionTest()
      : compositor_touch_action_enabled_(
            base::FeatureList::IsEnabled(features::kCompositorTouchAction)) {}

  // Computes the effective and white-listed 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(
      RenderWidgetHostInputEventRouter* router,
      RenderWidgetHostViewBase* rwhv_root,
      RenderWidgetHostViewBase* rwhv_child,
      const gfx::Point& event_position,
      base::Optional<cc::TouchAction>& effective_touch_action,
      base::Optional<cc::TouchAction>& whitelisted_touch_action) {
    InputEventAckWaiter ack_observer(
        rwhv_child->GetRenderWidgetHost(),
        base::BindRepeating([](content::InputEventAckSource source,
                               content::InputEventAckState state,
                               const blink::WebInputEvent& event) {
          return event.GetType() == blink::WebGestureEvent::kTouchStart ||
                 event.GetType() == blink::WebGestureEvent::kTouchMove ||
                 event.GetType() == blink::WebGestureEvent::kTouchEnd;
        }));

    InputRouterImpl* input_router = static_cast<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();
    SyntheticWebTouchEvent touch_event;
    int index = touch_event.PressPoint(event_position.x(), event_position.y());
    router->RouteTouchEvent(rwhv_root, &touch_event,
                            ui::LatencyInfo(ui::SourceEventType::TOUCH));
    ack_observer.Wait();
    // Reset them to get the new value.
    effective_touch_action.reset();
    whitelisted_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.
    whitelisted_touch_action =
        input_router->touch_action_filter_.white_listed_touch_action_;
    // When flag is enabled, we may not have the value for the effective touch
    // action when ack is received.
    if (!compositor_touch_action_enabled_) {
      while (!effective_touch_action.has_value()) {
        GiveItSomeTime(TestTimeouts::tiny_timeout());
        effective_touch_action =
            input_router->touch_action_filter_.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(ui::SourceEventType::TOUCH));
    ack_observer.Wait();

    ack_observer.Reset();
    touch_event.ReleasePoint(index);
    router->RouteTouchEvent(rwhv_root, &touch_event,
                            ui::LatencyInfo(ui::SourceEventType::TOUCH));
    ack_observer.Wait();
  }

  void GiveItSomeTime(const base::TimeDelta& t) {
    base::RunLoop run_loop;
    base::ThreadTaskRunnerHandle::Get()->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();
  }

 protected:
  const bool compositor_touch_action_enabled_;
};

IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTouchActionTest,
                       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()->GetFrameTree()->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"));
  NavigateFrameToURL(child, b_url);

  // Force the renderer to generate a new frame.
  EXPECT_TRUE(
      ExecuteScript(shell(), "document.body.style.touchAction = 'none'"));
  // Waits for the next frame.
  WaitForHitTestDataOrChildSurfaceReady(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)));

  RenderWidgetHostInputEventRouter* router =
      static_cast<WebContentsImpl*>(web_contents())->GetInputEventRouter();

  WaitForTouchActionUpdated(root_thread_observer.get(),
                            child_thread_observer.get());
  base::Optional<cc::TouchAction> effective_touch_action;
  base::Optional<cc::TouchAction> whitelisted_touch_action;
  cc::TouchAction expected_touch_action = cc::kTouchActionPan;
  // 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 kTouchActionPan instead of
  // kTouchActionAuto in iframe's child.
  GetTouchActionsForChild(router, rwhv_root, rwhv_child, point_inside_child,
                          effective_touch_action, whitelisted_touch_action);
  if (!compositor_touch_action_enabled_) {
    EXPECT_EQ(expected_touch_action, effective_touch_action.has_value()
                                         ? effective_touch_action.value()
                                         : cc::kTouchActionAuto);
  }
  if (whitelisted_touch_action.has_value())
    EXPECT_EQ(expected_touch_action, whitelisted_touch_action.value());

  EXPECT_TRUE(
      ExecuteScript(shell(), "document.body.style.touchAction = 'auto'"));
  WaitForTouchActionUpdated(root_thread_observer.get(),
                            child_thread_observer.get());
  expected_touch_action = cc::kTouchActionAuto;
  GetTouchActionsForChild(router, rwhv_root, rwhv_child, point_inside_child,
                          effective_touch_action, whitelisted_touch_action);
  if (compositor_touch_action_enabled_) {
    EXPECT_EQ(expected_touch_action, effective_touch_action.has_value()
                                         ? effective_touch_action.value()
                                         : cc::kTouchActionAuto);
  }
  if (whitelisted_touch_action.has_value())
    EXPECT_EQ(expected_touch_action, whitelisted_touch_action.value());
}

IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTouchActionTest,
                       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()->GetFrameTree()->root();
  FrameTreeNode* parent = root->child_at(0);
  GURL b_url(embedded_test_server()->GetURL(
      "b.com", "/frame_tree/page_with_iframe_in_div.html"));
  NavigateFrameToURL(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(
      ExecuteScript(shell(), "document.body.style.touchAction = 'none'"));

  // Wait for child frame ready in order to get the correct point inside child.
  WaitForHitTestDataOrChildSurfaceReady(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)));

  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());
  base::Optional<cc::TouchAction> effective_touch_action;
  base::Optional<cc::TouchAction> whitelisted_touch_action;
  cc::TouchAction expected_touch_action = cc::kTouchActionPan;
  GetTouchActionsForChild(router, rwhv_root, rwhv_child, point_inside_child,
                          effective_touch_action, whitelisted_touch_action);
  cc::TouchAction effective_touch_action_result =
      effective_touch_action.has_value() ? effective_touch_action.value()
                                         : cc::kTouchActionAuto;
  // TouchAction might have not been propagated to child frames yet, loop until
  // we get the expected touch action value.
  if (!compositor_touch_action_enabled_) {
    while (expected_touch_action != effective_touch_action_result) {
      GetTouchActionsForChild(router, rwhv_root, rwhv_child, point_inside_child,
                              effective_touch_action, whitelisted_touch_action);
      effective_touch_action_result = effective_touch_action.has_value()
                                          ? effective_touch_action.value()
                                          : cc::kTouchActionAuto;
    }
  }
  if (whitelisted_touch_action.has_value())
    EXPECT_EQ(expected_touch_action, whitelisted_touch_action.value());

  // Child should inherit effective touch action none from parent.
  EXPECT_TRUE(
      ExecuteScript(shell(), "document.body.style.touchAction = 'auto'"));
  EXPECT_TRUE(ExecuteScript(
      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, whitelisted_touch_action);
  effective_touch_action_result = effective_touch_action.has_value()
                                      ? effective_touch_action.value()
                                      : cc::kTouchActionAuto;
  if (!compositor_touch_action_enabled_) {
    while (expected_touch_action != effective_touch_action_result) {
      GetTouchActionsForChild(router, rwhv_root, rwhv_child, point_inside_child,
                              effective_touch_action, whitelisted_touch_action);
      effective_touch_action_result = effective_touch_action.has_value()
                                          ? effective_touch_action.value()
                                          : cc::kTouchActionAuto;
    }
  }
  if (whitelisted_touch_action.has_value())
    EXPECT_EQ(expected_touch_action, whitelisted_touch_action.value());

  // Child should inherit effective touch action auto from root and parent.
  EXPECT_TRUE(ExecuteScript(
      parent,
      "document.getElementById('parent-div').style.touchAction = 'auto'"));
  WaitForTouchActionUpdated(root_thread_observer.get(),
                            child_thread_observer.get());
  expected_touch_action = cc::kTouchActionAuto;
  GetTouchActionsForChild(router, rwhv_root, rwhv_child, point_inside_child,
                          effective_touch_action, whitelisted_touch_action);
  effective_touch_action_result = effective_touch_action.has_value()
                                      ? effective_touch_action.value()
                                      : cc::kTouchActionAuto;
  if (!compositor_touch_action_enabled_) {
    while (expected_touch_action != effective_touch_action_result) {
      GetTouchActionsForChild(router, rwhv_root, rwhv_child, point_inside_child,
                              effective_touch_action, whitelisted_touch_action);
      effective_touch_action_result = effective_touch_action.has_value()
                                          ? effective_touch_action.value()
                                          : cc::kTouchActionAuto;
    }
  }
  if (whitelisted_touch_action.has_value())
    EXPECT_EQ(expected_touch_action, whitelisted_touch_action.value());
}

IN_PROC_BROWSER_TEST_F(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()->GetFrameTree()->root();
  FrameTreeNode* child = root->child_at(0);
  GURL b_url(embedded_test_server()->GetURL("b.com", "/title1.html"));
  NavigateFrameToURL(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(
      ExecuteScript(shell(), "document.body.style.touchAction = 'none'"));

  // Wait for child frame ready in order to get the correct point inside child.
  WaitForHitTestDataOrChildSurfaceReady(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)));

  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());
  base::Optional<cc::TouchAction> effective_touch_action;
  base::Optional<cc::TouchAction> whitelisted_touch_action;
  cc::TouchAction expected_touch_action = cc::kTouchActionPan;
  GetTouchActionsForChild(router, rwhv_root, rwhv_child, point_inside_child,
                          effective_touch_action, whitelisted_touch_action);
  if (!compositor_touch_action_enabled_) {
    EXPECT_EQ(expected_touch_action, effective_touch_action.has_value()
                                         ? effective_touch_action.value()
                                         : cc::kTouchActionAuto);
  }
  if (whitelisted_touch_action.has_value())
    EXPECT_EQ(expected_touch_action, whitelisted_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();
  NavigateFrameToURL(child, new_url);
  WaitForHitTestDataOrChildSurfaceReady(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.reset(new 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, whitelisted_touch_action);
  if (!compositor_touch_action_enabled_) {
    EXPECT_EQ(expected_touch_action, effective_touch_action.has_value()
                                         ? effective_touch_action.value()
                                         : cc::kTouchActionAuto);
  }
  if (whitelisted_touch_action.has_value())
    EXPECT_EQ(expected_touch_action, whitelisted_touch_action.value());
}

IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
                       ChildFrameCrashMetrics_KilledWhileVisible) {
  // 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) crashes (simply 1 crash if B process gets killed)?
  // 3) widgets (10 b widgets and 1 c widget are affected if B is killed,
  //    but a sad frame will appear only in 9 widgets - this excludes
  //    widgets for the b,c(b) part of the frame tree) or
  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()->GetFrameTree()->root();

  // 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 the expected metrics got logged.
  histograms.ExpectUniqueSample(
      "Stability.ChildFrameCrash.Visibility",
      CrossProcessFrameConnector::CrashVisibility::kCrashedWhileVisible, 9);

  // Hide and show the web contents and verify that no more metrics got logged.
  web_contents()->UpdateWebContentsVisibility(Visibility::HIDDEN);
  web_contents()->UpdateWebContentsVisibility(Visibility::VISIBLE);
  histograms.ExpectUniqueSample(
      "Stability.ChildFrameCrash.Visibility",
      CrossProcessFrameConnector::CrashVisibility::kCrashedWhileVisible, 9);
}

IN_PROC_BROWSER_TEST_F(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()->GetFrameTree()->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_F(SitePerProcessBrowserTest,
                       ChildFrameCrashMetrics_KilledWhileHiddenThenShown) {
  // 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()->GetFrameTree()->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();

  // Verify that no child frame metrics got logged (yet - while WebContents are
  // hidden).
  histograms.ExpectTotalCount("Stability.ChildFrameCrash.Visibility", 0);
  histograms.ExpectTotalCount(
      "Stability.ChildFrameCrash.ShownAfterCrashingReason", 0);

  // Show the web contents and verify that the expected metrics got logged.
  web_contents()->UpdateWebContentsVisibility(Visibility::VISIBLE);
  histograms.ExpectUniqueSample(
      "Stability.ChildFrameCrash.Visibility",
      CrossProcessFrameConnector::CrashVisibility::kShownAfterCrashing, 10);
  histograms.ExpectUniqueSample(
      "Stability.ChildFrameCrash.ShownAfterCrashingReason",
      CrossProcessFrameConnector::ShownAfterCrashingReason::kTabWasShown, 10);

  // Hide and show the web contents again and verify that no more metrics got
  // logged.
  web_contents()->UpdateWebContentsVisibility(Visibility::HIDDEN);
  web_contents()->UpdateWebContentsVisibility(Visibility::VISIBLE);
  histograms.ExpectUniqueSample(
      "Stability.ChildFrameCrash.Visibility",
      CrossProcessFrameConnector::CrashVisibility::kShownAfterCrashing, 10);
  histograms.ExpectUniqueSample(
      "Stability.ChildFrameCrash.ShownAfterCrashingReason",
      CrossProcessFrameConnector::ShownAfterCrashingReason::kTabWasShown, 10);
}

IN_PROC_BROWSER_TEST_F(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()->GetFrameTree()->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")));
  histograms.ExpectUniqueSample(
      "Stability.ChildFrameCrash.Visibility",
      CrossProcessFrameConnector::CrashVisibility::kNeverVisibleAfterCrash, 10);
}

IN_PROC_BROWSER_TEST_F(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()->GetFrameTree()->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(ExecuteScript(root, filling_script));
  MainThreadFrameObserver main_widget_observer(
      root->current_frame_host()->GetRenderWidgetHost());
  main_widget_observer.Wait();

  // 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(ExecuteScript(root, scrolling_script));
  main_widget_observer.Wait();

  // 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);
}

IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
                       ChildFrameCrashMetrics_ScrolledIntoViewAfterTabIsShown) {
  // Start on a page that has a single iframe, which is positioned out of
  // view, and navigate that iframe cross-site.
  GURL main_url(
      embedded_test_server()->GetURL("a.com", "/iframe_out_of_view.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));
  FrameTreeNode* root = web_contents()->GetFrameTree()->root();
  NavigateFrameToURL(root->child_at(0),
                     embedded_test_server()->GetURL("b.com", "/title1.html"));

  // 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 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 crash metrics got logged yet.
  histograms.ExpectTotalCount("Stability.ChildFrameCrash.Visibility", 0);
  histograms.ExpectTotalCount(
      "Stability.ChildFrameCrash.ShownAfterCrashingReason", 0);

  // Show the web contents.  The crash metrics still shouldn't be logged, since
  // the crashed frame is out of view.
  web_contents()->UpdateWebContentsVisibility(Visibility::VISIBLE);
  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.
  MainThreadFrameObserver main_widget_observer(
      root->current_frame_host()->GetRenderWidgetHost());
  std::string scrolling_script = R"(
    var frame = document.body.querySelector("iframe");
    frame.scrollIntoView();
  )";
  EXPECT_TRUE(ExecuteScript(root, scrolling_script));
  main_widget_observer.Wait();

  // Verify that the expected metrics got logged.
  histograms.ExpectUniqueSample(
      "Stability.ChildFrameCrash.Visibility",
      CrossProcessFrameConnector::CrashVisibility::kShownAfterCrashing, 1);
  histograms.ExpectUniqueSample(
      "Stability.ChildFrameCrash.ShownAfterCrashingReason",
      CrossProcessFrameConnector::ShownAfterCrashingReason::
          kViewportIntersectionAfterTabWasShown,
      1);

  // Hide and show the web contents again and verify that no more metrics got
  // logged.
  web_contents()->UpdateWebContentsVisibility(Visibility::HIDDEN);
  web_contents()->UpdateWebContentsVisibility(Visibility::VISIBLE);
  histograms.ExpectUniqueSample(
      "Stability.ChildFrameCrash.Visibility",
      CrossProcessFrameConnector::CrashVisibility::kShownAfterCrashing, 1);
  histograms.ExpectUniqueSample(
      "Stability.ChildFrameCrash.ShownAfterCrashingReason",
      CrossProcessFrameConnector::ShownAfterCrashingReason::
          kViewportIntersectionAfterTabWasShown,
      1);
}

// Check that when a frame changes a subframe's size twice and then sends a
// postMessage to the subframe, the subframe's onmessage handler sees the new
// size.  In particular, ensure that the postMessage won't get reordered with
// the second resize, which might be throttled if the first resize is still in
// progress. See https://crbug.com/828529.
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
                       ResizeAndCrossProcessPostMessagePreserveOrder) {
  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()->GetFrameTree()->root();

  // Add an onmessage handler to the subframe to send back its width.
  EXPECT_TRUE(ExecuteScript(root->child_at(0), R"(
      window.addEventListener('message', function(event) {
        domAutomationController.send(document.body.clientWidth);
      });)"));

  // Drop the visual properties ACKs from the child renderer.  To do this,
  // unsubscribe the child's RenderWidgetHost from its
  // RenderFrameMetadataProvider, which ensures that
  // DidUpdateVisualProperties() won't be called on it, and the ACK won't be
  // reset.  This simulates that the ACK for the first resize below does not
  // arrive before the second resize IPC arrives from the
  // parent, and that the second resize IPC early-exits in
  // SynchronizeVisualProperties() due to the pending visual properties ACK.
  RenderWidgetHostImpl* rwh =
      root->child_at(0)->current_frame_host()->GetRenderWidgetHost();
  rwh->render_frame_metadata_provider_.RemoveObserver(rwh);

  // Now, resize the subframe twice from the main frame and send it a
  // postMessage. The postMessage handler should see the second updated size.
  int width = 0;
  EXPECT_TRUE(ExecuteScriptAndExtractInt(root, R"(
      var f = document.querySelector('iframe');
      f.width = 500;
      f.offsetTop; // force layout; this sends a resize IPC for width of 500.
      f.width = 700;
      f.offsetTop; // force layout; this sends a resize IPC for width of 700.
      f.contentWindow.postMessage('foo', '*');)", &width));
  EXPECT_EQ(width, 700);
}

class SitePerProcessAndProcessPerSiteBrowserTest
    : public SitePerProcessBrowserTest {
 public:
  SitePerProcessAndProcessPerSiteBrowserTest() {}

 protected:
  void SetUpCommandLine(base::CommandLine* command_line) override {
    SitePerProcessBrowserTest::SetUpCommandLine(command_line);
    command_line->AppendSwitch(switches::kProcessPerSite);
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(SitePerProcessAndProcessPerSiteBrowserTest);
};

// 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_F(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(ExecuteScript(web_contents(), "document.cookie = 'foo=bar';"));
  std::string cookie;
  EXPECT_TRUE(ExecuteScriptAndExtractString(
      web_contents(), "window.domAutomationController.send(document.cookie);",
      &cookie));
  EXPECT_EQ("foo=bar", 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);
  }

  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_;

  DISALLOW_COPY_AND_ASSIGN(SameDocumentCommitObserver);
};

}  // namespace

// Ensure that a same-document navigation does not cancel an ongoing
// cross-process navigation.  See https://crbug.com/825677.
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
                       ReplaceStateDoesNotCancelCrossSiteNavigation) {
  GURL url(embedded_test_server()->GetURL("a.com", "/title1.html"));
  EXPECT_TRUE(NavigateToURL(shell(), url));
  FrameTreeNode* root = web_contents()->GetFrameTree()->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(ExecuteScript(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 ExecuteScript
  // runs with a user gesture.
  EXPECT_TRUE(ExecuteScript(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();
  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_F(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()->GetFrameTree()->root();
  FrameTreeNode* subframe = root->child_at(0);

  // The subframe should not be sandboxed.
  EXPECT_EQ(blink::WebSandboxFlags::kNone,
            subframe->pending_frame_policy().sandbox_flags);
  EXPECT_EQ(blink::WebSandboxFlags::kNone,
            subframe->effective_frame_policy().sandbox_flags);

  // Set the "sandbox" attribute on the subframe; pending policy should update.
  EXPECT_TRUE(ExecuteScript(
      root, "document.querySelector('iframe').sandbox = 'allow-scripts';"));
  // "allow-scripts" resets both SandboxFlags::Scripts and
  // SandboxFlags::AutomaticFeatures bits per blink::ParseSandboxPolicy().
  blink::WebSandboxFlags expected_flags =
      blink::WebSandboxFlags::kAll & ~blink::WebSandboxFlags::kScripts &
      ~blink::WebSandboxFlags::kAutomaticFeatures;
  EXPECT_EQ(expected_flags, subframe->pending_frame_policy().sandbox_flags);
  EXPECT_EQ(blink::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(
      ExecuteScript(subframe, "history.replaceState({}, 'footitle', 'foo');"));
  replace_state_observer.Wait();

  EXPECT_EQ(expected_flags, subframe->pending_frame_policy().sandbox_flags);
  EXPECT_EQ(blink::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(
        ExecuteScript(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(blink::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_F(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()->GetFrameTree()->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(ExecuteScript(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())
          ->GetFrameTree()
          ->root();
  FrameTreeNode* popup_subframe = popup_root->child_at(0);

  TestNavigationObserver popup_observer(new_shell->web_contents());
  EXPECT_TRUE(ExecuteScript(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.
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
                       RenderFrameProxyNotRecreatedDuringProcessShutdown) {
  GURL main_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));
  FrameTreeNode* root = web_contents()->GetFrameTree()->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())
          ->GetFrameTree()
          ->root();
  auto* rfh = popup_root->current_frame_host();

  // Disable the swapout timer to prevent flakiness.
  rfh->DisableSwapOutTimerForTesting();

  // 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(ExecuteScript(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 an unload 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(ExecuteScript(new_shell, R"(
      window.onunload = () => {
        for (var i=0; i<10000; i++)
          opener.postMessage('hi','*');
      })"));

  // Navigate popup to a.com.  This swaps out 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(
      ExecuteScript(new_shell, JsReplace("location = $1", another_a_url)));
  commit_observer.WaitForCommit();

  // At this point, popup's original RFH is pending deletion.
  EXPECT_FALSE(rfh->is_active());

  // When the opener receives a postMessage from the popup's unload 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 swapping out 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(false, false);
  b_process_observer.Wait();
  EXPECT_TRUE(b_process_observer.did_exit_normally());
}

IN_PROC_BROWSER_TEST_F(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()->GetMainFrame()->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->GetMainFrame()->GetProcess();
  EXPECT_NE(a_process, b_process);

  // Hang the first tab's renderer.
  const char* kHungScript = "setTimeout(function() { for (;;) {}; }, 0);";
  EXPECT_TRUE(ExecuteScript(shell()->web_contents(), kHungScript));

  // Attempt to navigate the second tab to a.com.  This will attempt to reuse
  // the hung process.
  NavigationHandleImpl::SetCommitTimeoutForTesting(
      base::TimeDelta::FromMilliseconds(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.
  NavigationHandleImpl::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).
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
                       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()->GetMainFrame()->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->GetMainFrame()->GetProcess();
  EXPECT_NE(a_process, b_process);

  // Hang the first tab's renderer.
  const char* kHungScript = "setTimeout(function() { for (;;) {}; }, 0);";
  EXPECT_TRUE(ExecuteScript(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::TimeDelta::FromMilliseconds(100);
  NavigationHandleImpl::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.
  NavigationHandleImpl::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_F(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()->GetFrameTree()->root()->child_at(0);
  WebContentsImpl* inner_contents =
      static_cast<WebContentsImpl*>(CreateAndAttachInnerContents(
          ToRenderFrameHost(child_frame).render_frame_host()));
  FrameTreeNode* inner_contents_root = inner_contents->GetFrameTree()->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"));
  NavigateFrameToURL(inner_contents_root, a_url);
  SiteInstance* a_site_instance =
      inner_contents->GetMainFrame()->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"));
  NavigateFrameToURL(inner_contents_root, b_url);
  SiteInstance* b_site_instance =
      inner_contents->GetMainFrame()->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);
}

// 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_F(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()->GetFrameTree()->root()->child_at(0);
  GURL original_frame_url(child->current_frame_host()->GetLastCommittedURL());
  EXPECT_EQ("b.com", original_frame_url.host());

  ConsoleObserverDelegate console_delegate(
      web_contents(), "Not allowed to load local resource: file:*");
  web_contents()->SetDelegate(&console_delegate);

  GURL file_url("file:///");
  EXPECT_TRUE(
      ExecJs(web_contents(),
             JsReplace("document.querySelector('iframe').src = $1", file_url)));
  console_delegate.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 defined(OS_CHROMEOS) || defined(OS_ANDROID)
namespace {

class SitePerProcessDoubleTapZoomBrowserTest
    : public SitePerProcessBrowserTest {
 public:
  SitePerProcessDoubleTapZoomBrowserTest() {}

 protected:
  void SetUpCommandLine(base::CommandLine* command_line) override {
    SitePerProcessBrowserTest::SetUpCommandLine(command_line);
    feature_list_.InitAndEnableFeature(features::kEnableVizHitTestDrawQuad);
  }

  base::test::ScopedFeatureList feature_list_;
};

void EnableDoubleTapZoomInRenderView(FrameTreeNode* node) {
  content::RenderViewHost* rvh =
      node->current_frame_host()->GetRenderViewHost();
  content::WebPreferences web_prefs = rvh->GetWebkitPreferences();
  if (web_prefs.double_tap_to_zoom_enabled)
    return;
  web_prefs.double_tap_to_zoom_enabled = true;
  rvh->UpdateWebkitPreferences(web_prefs);
}

}  // namespace

IN_PROC_BROWSER_TEST_F(SitePerProcessDoubleTapZoomBrowserTest,
                       TouchscreenAnimateDoubleTapZoomInOOPIF) {
  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()->GetFrameTree()->root();
  ASSERT_EQ(1u, root->child_count());
  FrameTreeNode* child_b = root->child_at(0);
  ASSERT_TRUE(child_b);

  // Enable double-tap zoom. This must be done separately for the main frame and
  // for the oopif frame since RenderViewHost::UpdateWebkitPreferences() only
  // sends the IPC to its own RenderView.
  EnableDoubleTapZoomInRenderView(root);
  EnableDoubleTapZoomInRenderView(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.
  WaitForHitTestDataOrChildSurfaceReady(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.
  std::string actions_template = 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(actions_template.c_str(), tap_position.x(),
                         tap_position.y(), tap_position.x(), tap_position.y());
  base::JSONReader json_reader;
  std::unique_ptr<base::Value> params =
      json_reader.ReadToValueDeprecated(double_tap_actions_json);
  ASSERT_TRUE(params.get()) << json_reader.GetErrorMessage();
  ActionsParser actions_parser(params.get());

  ASSERT_TRUE(actions_parser.ParsePointerActionSequence());
  auto synthetic_gesture_doubletap =
      SyntheticGesture::Create(actions_parser.gesture_params());

  // Queue the event and wait for it to be acked.
  InputEventAckWaiter ack_waiter(
      child_b->current_frame_host()->GetRenderWidgetHost(),
      blink::WebInputEvent::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  // defined(OS_CHROMEOS) || defined(OS_ANDROID)

class CrossProcessNavigationObjectElementTest
    : public SitePerProcessBrowserTest,
      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>.
  std::string result;
  ASSERT_TRUE(ExecuteScriptAndExtractString(
      web_contents(), JsReplace("setUrl($1, true);", object_valid_url),
      &result));
  ASSERT_EQ("OBJECT_LOAD", result);

  // Verify fallback content is not shown.
  bool fallback_visible = true;
  ASSERT_TRUE(ExecuteScriptAndExtractBool(
      web_contents(), "fallbackVisible(true)", &fallback_visible));
  ASSERT_FALSE(fallback_visible);

  // 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).
  fallback_visible = false;
  ASSERT_TRUE(
      ExecuteScriptAndExtractBool(web_contents(),
                                  JsReplace("setUrl($1, false);"
                                            "notifyWhenFallbackShown();",
                                            object_invalid_url),
                                  &fallback_visible));
  ASSERT_TRUE(fallback_visible);
}

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")));

class ScrollingIntegrationTest : public SitePerProcessBrowserTest {
 public:
  ScrollingIntegrationTest() = default;
  ~ScrollingIntegrationTest() override = default;

  void DoScroll(const gfx::Point& point,
                const gfx::Vector2d& distance,
                SyntheticGestureParams::GestureSourceType source) {
    SyntheticSmoothScrollGestureParams params;
    params.gesture_source_type = source;
    params.anchor = gfx::PointF(point);
    params.distances.push_back(-distance);
    params.precise_scrolling_deltas = true;

    auto gesture = std::make_unique<SyntheticSmoothScrollGesture>(params);

    // Runs until we get the SyntheticGestureCompleted callback
    base::RunLoop run_loop;
    GetRenderWidgetHostImpl()->QueueSyntheticGesture(
        std::move(gesture),
        base::BindLambdaForTesting([&](SyntheticGesture::Result result) {
          EXPECT_EQ(SyntheticGesture::GESTURE_FINISHED, result);
          run_loop.Quit();
        }));
    run_loop.Run();
  }

  double GetScrollTop() {
    FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
                              ->GetFrameTree()
                              ->root();
    return EvalJs(root, "window.scrollY").ExtractDouble();
  }

  void WaitForVerticalScroll() {
    RenderFrameSubmissionObserver frame_observer(shell()->web_contents());
    gfx::Vector2dF default_scroll_offset;
    while (frame_observer.LastRenderFrameMetadata()
               .root_scroll_offset.value_or(default_scroll_offset)
               .y() <= 0) {
      frame_observer.WaitForMetadataChange();
    }
  }

  RenderWidgetHostImpl* GetRenderWidgetHostImpl() {
    FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
                              ->GetFrameTree()
                              ->root();
    return root->current_frame_host()->GetRenderWidgetHost();
  }
};

// Tests basic scrolling after navigating to a new origin works. Guards against
// bugs like https://crbug.com/899234 which are caused by invalid
// initialization due to the cross-origin provisional frame swap.
IN_PROC_BROWSER_TEST_F(ScrollingIntegrationTest,
                       ScrollAfterCrossOriginNavigation) {
  // Navigate to the a.com domain first.
  GURL url_domain_a(
      embedded_test_server()->GetURL("a.com", "/simple_page.html"));
  EXPECT_TRUE(NavigateToURL(shell(), url_domain_a));

  // Now navigate to baz.com, this should cause a cross-origin navigation which
  // will load into a provisional frame and then swap in as a local main frame.
  // This test ensures all the correct initialization takes place in the
  // renderer so that a basic scrolling smoke test works.
  GURL url_domain_b(embedded_test_server()->GetURL(
      "baz.com", "/scrollable_page_with_iframe.html"));
  EXPECT_TRUE(NavigateToURL(shell(), url_domain_b));
  ASSERT_TRUE(WaitForLoadStop(shell()->web_contents()));

  {
    // TODO(bokan): We currently don't have a good way to know when the
    // compositor's scrolling layers are ready after changes on the main thread.
    // We wait a timeout but that's really a hack. Fixing is tracked in
    // https://crbug.com/897520
    base::RunLoop run_loop;
    base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
        FROM_HERE, run_loop.QuitClosure(),
        base::TimeDelta::FromMilliseconds(3000));
    run_loop.Run();
  }

  SyntheticGestureParams::GestureSourceType source;

// TODO(bokan): Mac doesn't support touch events and for an unknown reason,
// Android doesn't like mouse wheel here. https://crbug.com/897520.
#if defined(OS_ANDROID)
  source = SyntheticGestureParams::TOUCH_INPUT;
#else
  source = SyntheticGestureParams::TOUCHPAD_INPUT;
#endif

  // Perform the scroll (below the iframe), ensure it's correctly processed.
  DoScroll(gfx::Point(100, 110), gfx::Vector2d(0, 500), source);
  WaitForVerticalScroll();
  EXPECT_GT(GetScrollTop(), 0);
}

#if !defined(OS_ANDROID)
// This test verifies that after occluding a WebContents the RAF inside a
// cross-process child frame is throttled.
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
                       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()->GetFrameTree()->root();
  FrameTreeNode* subframe = root->child_at(0);
  GURL page_with_raf_counter =
      embedded_test_server()->GetURL("a.com", "/page_with_raf_counter.html");
  NavigateFrameToURL(subframe, page_with_raf_counter);

  // Initially page is visible - wait some time and then ensure a good number of
  // rafs have been generated.
  auto wait_for_half_a_second = []() {
    base::RunLoop run_loop;
    base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
        FROM_HERE, run_loop.QuitClosure(),
        base::TimeDelta::FromMilliseconds(500));
    run_loop.Run();
  };

  ASSERT_TRUE(ExecuteScript(subframe, "reset_count();"));
  wait_for_half_a_second();
  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(ExecuteScript(subframe, "reset_count();"));
  wait_for_half_a_second();
  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(ExecuteScript(subframe, "reset_count();"));
  wait_for_half_a_second();
  ASSERT_TRUE(ExecuteScriptAndExtractInt(
      subframe, "window.domAutomationController.send(raf_count)", &raf_count));
  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_F(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())
                            ->GetFrameTree()
                            ->root();

  // Setup an URL which will never commit, allowing this test to send its own,
  // malformed, commit message.
  GURL another_url(embedded_test_server()->GetURL("b.com", "/hung"));

  // Use LoadURL, as the test shouldn't wait for navigation commit.
  NavigationController& controller = shell()->web_contents()->GetController();
  controller.LoadURL(another_url, Referrer(), ui::PAGE_TRANSITION_LINK,
                     std::string());
  EXPECT_TRUE(controller.GetPendingEntry());
  EXPECT_EQ(another_url, controller.GetPendingEntry()->GetURL());

  RenderProcessHostKillWaiter kill_waiter(
      root->current_frame_host()->GetProcess());

  // Create commit params with the same URL as the start one, so URL checks
  // pass, but use a different origin than the origin lock of the process.
  std::unique_ptr<FrameHostMsg_DidCommitProvisionalLoad_Params> params =
      std::make_unique<FrameHostMsg_DidCommitProvisionalLoad_Params>();
  params->nav_entry_id = 0;
  params->did_create_new_entry = false;
  params->url = start_url;
  params->transition = ui::PAGE_TRANSITION_LINK;
  params->should_update_history = false;
  params->gesture = NavigationGestureAuto;
  params->method = "GET";
  params->page_state = PageState::CreateFromURL(start_url);

  // Use an origin mismatched with the origin lock.
  params->origin = url::Origin::Create(another_url);
  auto* policy = ChildProcessSecurityPolicyImpl::GetInstance();
  int process_id = root->current_frame_host()->GetProcess()->GetID();
  EXPECT_EQ("http://a.com/", policy->GetOriginLock(process_id));
  EXPECT_EQ(start_url.host(), policy->GetOriginLock(process_id).host());
  EXPECT_NE(another_url.host(), policy->GetOriginLock(process_id).host());

  // Simulate a commit IPC.
  service_manager::mojom::InterfaceProviderPtr interface_provider;
  blink::mojom::DocumentInterfaceBrokerPtrInfo
      document_interface_broker_content;
  blink::mojom::DocumentInterfaceBrokerPtrInfo document_interface_broker_blink;
  static_cast<mojom::FrameHost*>(root->current_frame_host())
      ->DidCommitProvisionalLoad(
          std::move(params),
          mojom::DidCommitProvisionalLoadInterfaceParams::New(
              mojo::MakeRequest(&interface_provider),
              mojo::MakeRequest(&document_interface_broker_content),
              mojo::MakeRequest(&document_interface_broker_blink)));

  // When the IPC message is received and validation fails, the process is
  // terminated. However, the notification for that should be processed in a
  // separate task of the message loop, so ensure that the process is still
  // considered alive.
  EXPECT_TRUE(
      root->current_frame_host()->GetProcess()->IsInitializedAndNotDead());

  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_F(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 =
      EvalJsWithManualReply(
          shell(), JsReplace("var object = document.createElement('object');"
                             "document.body.appendChild(object);"
                             "object.data = $1;"
                             "object.type='text/html';"
                             "object.notify = true;"
                             "object.onload = () => {"
                             "  if (!object.notify) return;"
                             "  object.notify = false;"
                             "  window.domAutomationController.send('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()
                              ->GetFrameTree()
                              ->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';"));
  while (!frame_connector->IsHidden()) {
    base::RunLoop run_loop;
    base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
        FROM_HERE, run_loop.QuitClosure(), TestTimeouts::tiny_timeout());
    run_loop.Run();
  }
  ASSERT_TRUE(ExecJs(
      shell(), "document.querySelector('object').style.display = 'block';"));
  while (frame_connector->IsHidden()) {
    base::RunLoop run_loop;
    base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
        FROM_HERE, run_loop.QuitClosure(), TestTimeouts::tiny_timeout());
    run_loop.Run();
  }
}

// Pending navigations must be canceled when a frame becomes pending deletion.
//
// 1) Initial state: A(B).
// 2) Navigation from B to C. The server is slow to respond.
// 3) Deletion of B.
IN_PROC_BROWSER_TEST_F(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", "/hung"));

  // 1) Initial state: A(B).
  EXPECT_TRUE(NavigateToURL(shell(), url_a));
  RenderFrameHostImpl* rfh_a = web_contents()->GetMainFrame();
  RenderFrameHostImpl* rfh_b = rfh_a->child_at(0)->current_frame_host();

  // RFH B has an unload handler.
  auto detach_filter_b = base::MakeRefCounted<DropMessageFilter>(
      FrameMsgStart, FrameHostMsg_Detach::ID);
  rfh_b->GetProcess()->AddFilter(detach_filter_b.get());
  EXPECT_TRUE(ExecJs(rfh_b, "onunload=function(){}"));

  // 2) Navigation from B to C. The server is slow to respond.
  TestNavigationManager navigation_observer(web_contents(), url_c);
  EXPECT_TRUE(ExecJs(rfh_b, JsReplace("location.href=$1;", url_c)));
  EXPECT_TRUE(navigation_observer.WaitForRequestStart());
  RenderFrameHostImpl* rfh_c =
      rfh_b->frame_tree_node()->render_manager()->speculative_frame_host();

  EXPECT_EQ(RenderFrameHostImpl::UnloadState::NotRun, rfh_a->unload_state_);
  EXPECT_EQ(RenderFrameHostImpl::UnloadState::NotRun, rfh_b->unload_state_);
  EXPECT_EQ(RenderFrameHostImpl::UnloadState::NotRun, rfh_c->unload_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::UnloadState::NotRun, rfh_a->unload_state_);
  EXPECT_EQ(RenderFrameHostImpl::UnloadState::InProgress, rfh_b->unload_state_);

  // The navigation has been canceled.
  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->OnDetach();
  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. The server is slow to respond.
// 3) Deletion of B.
IN_PROC_BROWSER_TEST_F(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", "/hung"));

  // 1) Initial state: A(B(C)).
  EXPECT_TRUE(NavigateToURL(shell(), url_a));
  RenderFrameHostImpl* rfh_a = web_contents()->GetMainFrame();
  RenderFrameHostImpl* rfh_b = rfh_a->child_at(0)->current_frame_host();
  RenderFrameHostImpl* rfh_c = rfh_b->child_at(0)->current_frame_host();

  // RFH C has an unload handler.
  auto detach_filter_c = base::MakeRefCounted<DropMessageFilter>(
      FrameMsgStart, FrameHostMsg_Detach::ID);
  rfh_c->GetProcess()->AddFilter(detach_filter_c.get());
  EXPECT_TRUE(ExecJs(rfh_c, "onunload=function(){}"));

  // 2) Navigation from C to D. The server is slow to respond.
  TestNavigationManager navigation_observer(web_contents(), url_d);
  EXPECT_TRUE(ExecJs(rfh_c, JsReplace("location.href=$1;", url_d)));
  EXPECT_TRUE(navigation_observer.WaitForRequestStart());
  RenderFrameHostImpl* rfh_d =
      rfh_c->frame_tree_node()->render_manager()->speculative_frame_host();

  EXPECT_EQ(RenderFrameHostImpl::UnloadState::NotRun, rfh_a->unload_state_);
  EXPECT_EQ(RenderFrameHostImpl::UnloadState::NotRun, rfh_b->unload_state_);
  EXPECT_EQ(RenderFrameHostImpl::UnloadState::NotRun, rfh_c->unload_state_);
  EXPECT_EQ(RenderFrameHostImpl::UnloadState::NotRun, rfh_d->unload_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::UnloadState::NotRun, rfh_a->unload_state_);
  EXPECT_EQ(RenderFrameHostImpl::UnloadState::Completed, rfh_b->unload_state_);
  EXPECT_EQ(RenderFrameHostImpl::UnloadState::InProgress, rfh_c->unload_state_);

  // The navigation has been canceled.
  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->OnDetach();
  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_F(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()->GetMainFrame();
  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_F(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()->GetMainFrame();
  RenderFrameHostImpl* rfh_b = rfh_a->child_at(0)->current_frame_host();
  NavigateFrameToURL(rfh_b->frame_tree_node(), url_c);
  RenderFrameHostImpl* rfh_c = rfh_a->child_at(0)->current_frame_host();

  // 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);
  TestNavigationManager navigation_observer(web_contents(), url_ab);

  // 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 fall back to navigating the main
  // frame
  navigation_observer.WaitForNavigationFinished();
  EXPECT_TRUE(navigation_observer.was_successful());
}

// 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_F(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()->GetMainFrame();
  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(ExecuteScript(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());
}

// This test verifies that when scrolling an OOPIF in a pinched-zoomed page,
// that the scroll-delta matches the distance between TouchStart/End as seen
// by the oopif, i.e. the oopif content 'sticks' to the finger during scrolling.
// The relation is not exact, but should be close.
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
                       ScrollOopifInPinchZoomedPage) {
  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()->GetFrameTree()->root();
  ASSERT_EQ(1u, root->child_count());
  FrameTreeNode* child = root->child_at(0);
  ASSERT_TRUE(child);

  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));

  // Make B scrollable. The call to document.write will erase the html inside
  // the OOPIF, leaving just a vertical column of 'Hello's.
  std::string script =
      "var s = '<div>Hello</div>\\n';\n"
      "document.write(s.repeat(200));";
  EXPECT_TRUE(ExecuteScript(child, script));

  RenderFrameSubmissionObserver observer_a(root);
  RenderFrameSubmissionObserver observer_b(child);

  // We need to observe a root frame submission to pick up the initial page
  // scale factor.
  observer_a.WaitForAnyFrameSubmission();

  const float kPageScaleDelta = 2.f;
  // On desktop systems we expect |current_page_scale| to be 1.f, but on
  // Android it will typically be less than 1.f, and may take on arbitrary
  // values.
  float original_page_scale =
      observer_a.LastRenderFrameMetadata().page_scale_factor;
  float target_page_scale = original_page_scale * kPageScaleDelta;

  SyntheticPinchGestureParams params;
  auto* host = static_cast<RenderWidgetHostImpl*>(
      root->current_frame_host()->GetRenderWidgetHost());
  RenderWidgetHostViewBase* root_view = host->GetView();
  RenderWidgetHostViewBase* child_view =
      static_cast<RenderWidgetHostImpl*>(
          child->current_frame_host()->GetRenderWidgetHost())
          ->GetView();
  gfx::Rect bounds(root_view->GetViewBounds().size());
  // The synthetic gesture code expects a location in root-view coordinates.
  params.anchor = gfx::PointF(bounds.CenterPoint().x(), 70.f);
  // In SyntheticPinchGestureParams, |scale_factor| is really a delta.
  params.scale_factor = kPageScaleDelta;
#if defined(OS_MACOSX)
  auto synthetic_pinch_gesture =
      std::make_unique<SyntheticTouchpadPinchGesture>(params);
#else
  auto synthetic_pinch_gesture =
      std::make_unique<SyntheticTouchscreenPinchGesture>(params);
#endif

  // Send pinch gesture and verify we receive the ack.
  {
    InputEventAckWaiter ack_waiter(host,
                                   blink::WebInputEvent::kGesturePinchEnd);
    host->QueueSyntheticGesture(
        std::move(synthetic_pinch_gesture),
        base::BindOnce([](SyntheticGesture::Result result) {
          EXPECT_EQ(SyntheticGesture::GESTURE_FINISHED, result);
        }));
    ack_waiter.Wait();
  }

  // Make sure all the page scale values behave as expected.
  const float kScaleTolerance = 0.07f;
  observer_a.WaitForPageScaleFactor(target_page_scale, kScaleTolerance);
  observer_b.WaitForExternalPageScaleFactor(target_page_scale, kScaleTolerance);
  float final_page_scale =
      observer_a.LastRenderFrameMetadata().page_scale_factor;

  // Verify scroll position of OOPIF.
  float initial_child_scroll = EvalJs(child, "window.scrollY").ExtractDouble();

  // Send touch-initiated gesture scroll sequence to OOPIF.
  // TODO(wjmaclean): GetViewBounds() is broken for OOPIFs when PSF != 1.f, so
  // we calculate it manually. This will need to be update when GetViewBounds()
  // in RenderWidgetHostViewBase is fixed. See https://crbug.com/928825.
  auto child_bounds = child_view->GetViewBounds();
  gfx::PointF child_upper_left =
      child_view->TransformPointToRootCoordSpaceF(gfx::PointF(0, 0));
  gfx::PointF child_lower_right = child_view->TransformPointToRootCoordSpaceF(
      gfx::PointF(child_bounds.width(), child_bounds.height()));
  gfx::PointF scroll_start_location_in_screen =
      gfx::PointF((child_upper_left.x() + child_lower_right.x()) / 2.f,
                  child_lower_right.y() - 10);
  const float kScrollDelta = 100.f;
  gfx::PointF scroll_end_location_in_screen =
      scroll_start_location_in_screen + gfx::Vector2dF(0, -kScrollDelta);

  // Create touch move sequence with discrete touch moves. Include a brief
  // pause at the end to avoid the scroll flinging.
  std::string actions_template = R"HTML(
      [{
        "source" : "touch",
        "actions" : [
          { "name": "pointerDown", "x": %f, "y": %f},
          { "name": "pointerMove", "x": %f, "y": %f},
          { "name": "pause", "duration": 300 },
          { "name": "pointerUp"}
        ]
      }]
  )HTML";
  std::string touch_move_sequence_json = base::StringPrintf(
      actions_template.c_str(), scroll_start_location_in_screen.x(),
      scroll_start_location_in_screen.y(), scroll_end_location_in_screen.x(),
      scroll_end_location_in_screen.y());
  base::JSONReader json_reader;
  std::unique_ptr<base::Value> touch_params =
      json_reader.ReadToValueDeprecated(touch_move_sequence_json);
  ASSERT_TRUE(touch_params.get()) << json_reader.GetErrorMessage();
  ActionsParser actions_parser(touch_params.get());

  ASSERT_TRUE(actions_parser.ParsePointerActionSequence());
  auto synthetic_scroll_gesture =
      SyntheticGesture::Create(actions_parser.gesture_params());

  {
    auto* child_host = static_cast<RenderWidgetHostImpl*>(
        child->current_frame_host()->GetRenderWidgetHost());
    InputEventAckWaiter ack_waiter(child_host,
                                   blink::WebInputEvent::kGestureScrollEnd);
    host->QueueSyntheticGesture(
        std::move(synthetic_scroll_gesture),
        base::BindOnce([](SyntheticGesture::Result result) {
          EXPECT_EQ(SyntheticGesture::GESTURE_FINISHED, result);
        }));
    ack_waiter.Wait();
  }

  // Verify new scroll position of OOPIF, should match touch sequence delta.
  float expected_scroll_delta = kScrollDelta / final_page_scale;
  float actual_scroll_delta =
      EvalJs(child, "window.scrollY").ExtractDouble() - initial_child_scroll;

  const float kScrollTolerance = 0.2f;
  EXPECT_GT((1.f + kScrollTolerance) * expected_scroll_delta,
            actual_scroll_delta);
  EXPECT_LT((1.f - kScrollTolerance) * expected_scroll_delta,
            actual_scroll_delta);
}

class FeaturePolicyPropagationToAuxiliaryBrowsingContextTest
    : public SitePerProcessFeaturePolicyJavaScriptBrowserTest,
      public testing::WithParamInterface<std::tuple<
          const char* /* Whether or not <iframe> is sandbox or can escape it */,
          bool /* <iframe> same origin? */,
          bool /* opened window same origin? */,
          const char* /* window feature in window.open() */>> {
 protected:
  void SetUpCommandLine(base::CommandLine* command_line) override {
    SitePerProcessFeaturePolicyJavaScriptBrowserTest::SetUpCommandLine(
        command_line);
    feature_list_.InitAndEnableFeature(features::kFeaturePolicyForSandbox);
  }

 private:
  base::test::ScopedFeatureList feature_list_;
};

// This test verifies the correct propagation of FeaturePolicy from an *opener*
// to the opened auxiliary browsing context. This test runs for both cross and
// same origin frames.
IN_PROC_BROWSER_TEST_P(FeaturePolicyPropagationToAuxiliaryBrowsingContextTest,
                       PropagationForDifferentOrigins) {
  EXPECT_TRUE(NavigateToURL(
      shell(), embedded_test_server()->GetURL(
                   "a.com", "/feature_policy_window_open_embedder.html")));
  const GURL same_origin_child = embedded_test_server()->GetURL(
      "a.com", "/feature_policy_window_open_embedded.html");
  const GURL cross_origin_child = embedded_test_server()->GetURL(
      "b.com", "/feature_policy_window_open_embedded.html");
  const GURL cross_origin_window_url =
      embedded_test_server()->GetURL("c.com", "/title1.html");
  const GURL same_origin_window_url = GURL("about:blank");
  const std::string kScriptCheckPolicy =
      "document.featurePolicy.allowsFeature('sync-xhr')";
  // Test parameters
  const std::string iframe_type = std::get<0>(GetParam());
  const std::string iframe_src =
      (std::get<1>(GetParam()) ? same_origin_child : cross_origin_child).spec();
  const std::string window_url =
      (std::get<2>(GetParam()) ? same_origin_window_url
                               : cross_origin_window_url)
          .spec();
  const std::string window_feature = std::get<3>(GetParam());
  SCOPED_TRACE(testing::Message() << " <iframe> Type: " << iframe_type
                                  << " <iframe> Source: " << iframe_src
                                  << " window URL: " << window_url
                                  << " window Feature: " << window_feature);
  // TODO(ekaramad): Modify the test expectation once we resolve the following
  // issues in feature policies:
  //   - "rel='noopener'" might end up resetting the feature policies.
  //   - A new feature to escape feature policies is introduced (similar to the
  //     sandbox version "allow-popups-to-escape-sandbox".
  // For now, only the sandbox-escaping case should be allowed to have a new
  // (default) feature policy state.
  bool expected_feature_state_in_auxiliary_browsing_context =
      (iframe_type == "sandboxed-escaping");
  ShellAddedObserver shell_added_observer;
  ASSERT_TRUE(
      ExecJs(shell(), JsReplace("test($1, $2, $3, $4)", iframe_type, iframe_src,
                                window_url, window_feature)));
  auto* new_shell = shell_added_observer.GetShell();
  while (new_shell->web_contents()->GetLastCommittedURL() != GURL(window_url)) {
    base::RunLoop run_loop;
    base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
        FROM_HERE, run_loop.QuitClosure(), TestTimeouts::tiny_timeout());
    run_loop.Run();
  }
  ASSERT_TRUE(WaitForLoadStop(new_shell->web_contents()));
  ASSERT_EQ(new_shell->web_contents()->GetLastCommittedURL(), window_url);
  EXPECT_EQ(expected_feature_state_in_auxiliary_browsing_context,
            EvalJs(new_shell, kScriptCheckPolicy));
  bool browser_side_feature_state =
      static_cast<RenderFrameHostImpl*>(
          new_shell->web_contents()->GetMainFrame())
          ->feature_policy()
          ->IsFeatureEnabled(blink::mojom::FeaturePolicyFeature::kSyncXHR);
  EXPECT_EQ(expected_feature_state_in_auxiliary_browsing_context,
            browser_side_feature_state);
  new_shell->Close();
}

INSTANTIATE_TEST_SUITE_P(SitePerProcess,
                         FeaturePolicyPropagationToAuxiliaryBrowsingContextTest,
                         testing::Combine(
                             /* iframe_type */
                             testing::ValuesIn({"sandboxed", "notsandboxed",
                                                "sandboxed-escaping"}),
                             /* iframe_same_origin */
                             testing::Bool(),
                             /* window_same_origin */
                             testing::Bool(),
                             /* window feature */
                             testing::ValuesIn({"", "noopener"})));

enum class InnerWebContentsAttachChildFrameOriginType {
  kSameOriginAboutBlank,
  kSameOriginOther,
  kCrossOrigin
};

class InnerWebContentsAttachTest
    : public SitePerProcessBrowserTest,
      public testing::WithParamInterface<
          std::tuple<InnerWebContentsAttachChildFrameOriginType,
                     bool /* original frame has beforeunload handlers */,
                     bool /* user proceeds with attaching */>> {
 public:
  InnerWebContentsAttachTest() {}
  ~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::FromRenderViewHost(web_contents->GetRenderViewHost()),
          true /* always_proceed */, proceed_through_beforeunload);
      RenderFrameHost::PrepareForInnerWebContentsAttachCallback callback =
          base::BindOnce(&PrepareFrameJob::OnPrepare, base::Unretained(this));
      original_render_frame_host->PrepareForInnerWebContentsAttach(
          std::move(callback));
    }
    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;
    RenderFrameHostImpl* new_render_frame_host_ = nullptr;
    base::RunLoop run_loop_;

    DISALLOW_COPY_AND_ASSIGN(PrepareFrameJob);
  };

  void SetUpCommandLine(base::CommandLine* command_line) override {
    SitePerProcessBrowserTest::SetUpCommandLine(command_line);
    feature_list_.InitAndEnableFeature(
        features::kMimeHandlerViewInCrossProcessFrame);
  }

 private:
  base::test::ScopedFeatureList feature_list_;

  DISALLOW_COPY_AND_ASSIGN(InnerWebContentsAttachTest);
};

// 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()->GetFrameTree()->root()->child_at(0);
  NavigateFrameToURL(child_node, child_frame_url);
  if (test_beforeunload) {
    EXPECT_TRUE(ExecJs(child_node,
                       "window.addEventListener('beforeunload', (e) => {"
                       "e.returnValue = ''; return e; });"));
  }
  auto* original_child_frame = child_node->current_frame_host();
  RenderFrameDeletedObserver original_child_frame_observer(
      original_child_frame);
  PrepareFrameJob prepare_job(original_child_frame,
                              proceed_through_beforeunload);
  if (test_beforeunload)
    WaitForAppModalDialog(shell());
  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()));

}  // namespace content
