// 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 <algorithm>
#include <list>
#include <memory>
#include <string>
#include <utility>
#include <vector>

#include "base/json/json_reader.h"
#include "base/location.h"
#include "base/memory/ptr_util.h"
#include "base/run_loop.h"
#include "base/scoped_observer.h"
#include "base/single_thread_task_runner.h"
#include "base/stl_util.h"
#include "base/test/test_timeouts.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "components/network_session_configurator/common/network_switches.h"
#include "content/browser/frame_host/cross_process_frame_connector.h"
#include "content/browser/frame_host/frame_tree.h"
#include "content/browser/frame_host/navigation_controller_impl.h"
#include "content/browser/frame_host/navigator.h"
#include "content/browser/frame_host/render_frame_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_view_child_frame.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/common/frame_messages.h"
#include "content/public/browser/back_forward_cache.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/common/url_constants.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test_utils.h"
#include "content/shell/browser/shell.h"
#include "content/test/content_browser_test_utils_internal.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 "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

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

namespace content {

namespace {

void UnloadPrint(FrameTreeNode* node, const char* message) {
  EXPECT_TRUE(
      ExecJs(node, JsReplace("window.onunload = function() { "
                             "  window.domAutomationController.send($1);"
                             "}",
                             message)));
}

}  // namespace

// Tests that there are no crashes if a subframe is detached in its unload
// handler. See https://crbug.com/590054.
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, DetachInUnloadHandler) {
  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();

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

  EXPECT_EQ(1, EvalJs(root->child_at(0), "frames.length;"));

  RenderFrameDeletedObserver deleted_observer(
      root->child_at(0)->child_at(0)->current_frame_host());

  // Add an unload handler to the grandchild that causes it to be synchronously
  // detached, then navigate it.
  EXPECT_TRUE(ExecuteScript(
      root->child_at(0)->child_at(0),
      "window.onunload=function(e){\n"
      "    window.parent.document.getElementById('child-0').remove();\n"
      "};\n"));
  auto script = JsReplace("window.document.getElementById('child-0').src = $1",
                          embedded_test_server()->GetURL(
                              "c.com", "/cross_site_iframe_factory.html?c"));
  EXPECT_TRUE(ExecuteScript(root->child_at(0), script));

  deleted_observer.WaitUntilDeleted();

  EXPECT_EQ(0, EvalJs(root->child_at(0), "frames.length;"));

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

// Tests that trying to navigate in the unload handler doesn't crash the
// browser.
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, NavigateInUnloadHandler) {
  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();

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

  EXPECT_EQ(1,
            EvalJs(root->child_at(0)->current_frame_host(), "frames.length;"));

  // Add an unload handler to B's subframe.
  EXPECT_TRUE(
      ExecuteScript(root->child_at(0)->child_at(0)->current_frame_host(),
                    "window.onunload=function(e){\n"
                    "    window.location = '#navigate';\n"
                    "};\n"));

  // Navigate B's subframe to a cross-site C.
  RenderFrameDeletedObserver deleted_observer(
      root->child_at(0)->child_at(0)->current_frame_host());
  auto script = JsReplace("window.document.getElementById('child-0').src = $1",
                          embedded_test_server()->GetURL(
                              "c.com", "/cross_site_iframe_factory.html"));
  EXPECT_TRUE(ExecuteScript(root->child_at(0)->current_frame_host(), script));

  // Wait until B's subframe RenderFrameHost is destroyed.
  deleted_observer.WaitUntilDeleted();

  // Check that C's subframe is alive and the navigation in the unload handler
  // was ignored.
  EXPECT_EQ(0, EvalJs(root->child_at(0)->child_at(0)->current_frame_host(),
                      "frames.length;"));

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

// Verifies that when navigating an OOPIF to same site and then canceling
// navigation from beforeunload handler popup will not remove the
// RemoteFrameView from OOPIF's owner element in the parent process. This test
// uses OOPIF visibility to make sure RemoteFrameView exists after beforeunload
// is handled.
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
                       CanceledBeforeUnloadShouldNotClearRemoteFrameView) {
  GURL a_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)"));
  EXPECT_TRUE(NavigateToURL(shell(), a_url));

  FrameTreeNode* child_node =
      web_contents()->GetFrameTree()->root()->child_at(0);
  GURL b_url(embedded_test_server()->GetURL(
      "b.com", "/render_frame_host/beforeunload.html"));
  NavigateFrameToURL(child_node, b_url);
  FrameConnectorDelegate* frame_connector_delegate =
      static_cast<RenderWidgetHostViewChildFrame*>(
          child_node->current_frame_host()->GetView())
          ->FrameConnectorForTesting();

  // Need user gesture for 'beforeunload' to fire.
  PrepContentsForBeforeUnloadTest(web_contents());

  // Simulate user choosing to stay on the page after beforeunload fired.
  SetShouldProceedOnBeforeUnload(shell(), true /* proceed */,
                                 false /* success */);

  // First, hide the <iframe>. This goes through RemoteFrameView::Hide() and
  // eventually updates the FrameConnectorDelegate. Also,
  // RemoteFrameView::self_visible_ will be set to false which can only be
  // undone by calling RemoteFrameView::Show. Therefore, potential calls to
  // RemoteFrameView::SetParentVisible(true) would not update the visibility at
  // the browser side.
  ASSERT_TRUE(ExecuteScript(
      web_contents(),
      "document.querySelector('iframe').style.visibility = 'hidden';"));
  while (!frame_connector_delegate->IsHidden()) {
    base::RunLoop run_loop;
    base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
        FROM_HERE, run_loop.QuitClosure(), TestTimeouts::tiny_timeout());
    run_loop.Run();
  }

  // Now we navigate the child to about:blank, but since we do not proceed with
  // the navigation, the OOPIF should stay alive and RemoteFrameView intact.
  ASSERT_TRUE(ExecuteScript(
      web_contents(), "document.querySelector('iframe').src = 'about:blank';"));
  WaitForAppModalDialog(shell());

  // Sanity check: We should still have an OOPIF and hence a RWHVCF.
  ASSERT_TRUE(static_cast<RenderWidgetHostViewBase*>(
                  child_node->current_frame_host()->GetView())
                  ->IsRenderWidgetHostViewChildFrame());

  // Now make the <iframe> visible again. This calls RemoteFrameView::Show()
  // only if the RemoteFrameView is the EmbeddedContentView of the corresponding
  // HTMLFrameOwnerElement.
  ASSERT_TRUE(ExecuteScript(
      web_contents(),
      "document.querySelector('iframe').style.visibility = 'visible';"));
  while (frame_connector_delegate->IsHidden()) {
    base::RunLoop run_loop;
    base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
        FROM_HERE, run_loop.QuitClosure(), TestTimeouts::tiny_timeout());
    run_loop.Run();
  }
}

// Ensure that after a main frame with an OOPIF is navigated cross-site, the
// unload handler in the OOPIF sees correct main frame origin, namely the old
// and not the new origin.  See https://crbug.com/825283.
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
                       ParentOriginDoesNotChangeInUnloadHandler) {
  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();

  // Open a popup on b.com.  The b.com subframe on the main frame will use this
  // in its unload handler.
  GURL b_url(embedded_test_server()->GetURL("b.com", "/title1.html"));
  EXPECT_TRUE(OpenPopup(shell()->web_contents(), b_url, "popup"));

  // Add an unload handler to b.com subframe, which will look up the top
  // frame's origin and send it via domAutomationController.  Unfortunately,
  // the subframe's browser-side state will have been torn down when it runs
  // the unload handler, so to ensure that the message can be received, send it
  // through the popup.
  EXPECT_TRUE(
      ExecuteScript(root->child_at(0),
                    "window.onunload = function(e) {"
                    "  window.open('','popup').domAutomationController.send("
                    "      'top-origin ' + location.ancestorOrigins[0]);"
                    "};"));

  // Navigate the main frame to c.com and wait for the message from the
  // subframe's unload handler.
  GURL c_url(embedded_test_server()->GetURL("c.com", "/title1.html"));
  DOMMessageQueue msg_queue;
  EXPECT_TRUE(NavigateToURL(shell(), c_url));
  std::string message, top_origin;
  while (msg_queue.WaitForMessage(&message)) {
    base::TrimString(message, "\"", &message);
    auto message_parts = base::SplitString(message, " ", base::TRIM_WHITESPACE,
                                           base::SPLIT_WANT_NONEMPTY);
    if (message_parts[0] == "top-origin") {
      top_origin = message_parts[1];
      break;
    }
  }

  // The top frame's origin should be a.com, not c.com.
  EXPECT_EQ(top_origin + "/", main_url.GetOrigin().spec());
}

// Verify that when the last active frame in a process is going away as part of
// OnUnload, the FrameHostMsg_Unload_ACK is received prior to the process
// starting to shut down, ensuring that any related unload work also happens
// before shutdown. See https://crbug.com/867274 and https://crbug.com/794625.
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
                       UnloadACKArrivesPriorToProcessShutdownRequest) {
  GURL start_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
  EXPECT_TRUE(NavigateToURL(shell(), start_url));
  RenderFrameHostImpl* rfh = web_contents()->GetMainFrame();
  rfh->DisableUnloadTimerForTesting();

  // Navigate cross-site.  Since the current frame is the last active frame in
  // the current process, the process will eventually shut down.  Once the
  // process goes away, ensure that the FrameHostMsg_Unload_ACK was received
  // (i.e., that we didn't just simulate OnUnloaded() due to the process
  // erroneously going away before the FrameHostMsg_Unload_ACK was received, as
  // in https://crbug.com/867274).
  RenderProcessHostWatcher watcher(
      rfh->GetProcess(), RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
  auto unload_ack_filter = base::MakeRefCounted<ObserveMessageFilter>(
      FrameMsgStart, FrameHostMsg_Unload_ACK::ID);
  rfh->GetProcess()->AddFilter(unload_ack_filter.get());
  GURL cross_site_url(embedded_test_server()->GetURL("b.com", "/title1.html"));
  EXPECT_TRUE(NavigateToURLFromRenderer(shell(), cross_site_url));
  watcher.Wait();
  EXPECT_TRUE(unload_ack_filter->has_received_message());
  EXPECT_TRUE(watcher.did_exit_normally());
}

// This is a regression test for https://crbug.com/891423 in which tabs showing
// beforeunload dialogs stalled navigation and triggered the "hung process"
// dialog.
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
                       NoCommitTimeoutWithBeforeUnloadDialog) {
  WebContentsImpl* web_contents =
      static_cast<WebContentsImpl*>(shell()->web_contents());

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

  // Disable the beforeunload hang monitor (otherwise there will be a race
  // between the beforeunload dialog and the beforeunload hang timer) and give
  // the page a gesture to allow dialogs.
  web_contents->GetMainFrame()->DisableBeforeUnloadHangMonitorForTesting();
  web_contents->GetMainFrame()->ExecuteJavaScriptWithUserGestureForTests(
      base::string16());

  // Hang the first contents in a beforeunload dialog.
  BeforeUnloadBlockingDelegate test_delegate(web_contents);
  EXPECT_TRUE(
      ExecJs(web_contents, "window.onbeforeunload=function(e){ return 'x' }"));
  EXPECT_TRUE(ExecJs(web_contents,
                     "setTimeout(function() { window.location.reload() }, 0)"));
  test_delegate.Wait();

  // Attempt to navigate the second tab to a.com.  This will attempt to reuse
  // the hung process.
  base::TimeDelta kTimeout = base::TimeDelta::FromMilliseconds(100);
  NavigationRequest::SetCommitTimeoutForTesting(kTimeout);
  GURL hung_url(embedded_test_server()->GetURL("a.com", "/title3.html"));
  UnresponsiveRendererObserver unresponsive_renderer_observer(new_contents);
  EXPECT_TRUE(
      ExecJs(new_contents, JsReplace("window.location = $1", hung_url)));

  // Verify that we will not be notified about the unresponsive renderer.
  // Before changes in https://crrev.com/c/1089797, the test would get notified
  // and therefore |hung_process| would be non-null.
  RenderProcessHost* hung_process =
      unresponsive_renderer_observer.Wait(kTimeout * 10);
  EXPECT_FALSE(hung_process);

  // Reset the timeout.
  NavigationRequest::SetCommitTimeoutForTesting(base::TimeDelta());
}

// Test that unload handlers in iframes are run, even when the removed subtree
// is complicated with nested iframes in different processes.
//     A1                         A1
//    / \                        / \
//   B1  D  --- Navigate --->   E   D
//  / \
// C1  C2
// |   |
// B2  A2
//     |
//     C3
// TODO(crbug.com/1012185): Flaky timeouts on Linux and Mac.
#if defined(OS_LINUX) || defined(OS_MACOSX)
#define MAYBE_UnloadHandlerSubframes DISABLED_UnloadHandlerSubframes
#else
#define MAYBE_UnloadHandlerSubframes UnloadHandlerSubframes
#endif
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
                       MAYBE_UnloadHandlerSubframes) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b(c(b),c(a(c))),d)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  // Add a unload handler to every frames. It notifies the browser using the
  // DomAutomationController it has been executed.
  FrameTreeNode* root = web_contents()->GetFrameTree()->root();
  UnloadPrint(root, "A1");
  UnloadPrint(root->child_at(0), "B1");
  UnloadPrint(root->child_at(0)->child_at(0), "C1");
  UnloadPrint(root->child_at(0)->child_at(1), "C2");
  UnloadPrint(root->child_at(0)->child_at(0)->child_at(0), "B2");
  UnloadPrint(root->child_at(0)->child_at(1)->child_at(0), "A2");
  UnloadPrint(root->child_at(0)->child_at(1)->child_at(0)->child_at(0), "C3");
  DOMMessageQueue dom_message_queue(
      WebContents::FromRenderFrameHost(web_contents()->GetMainFrame()));

  // Disable the unload timer on B1.
  root->child_at(0)->current_frame_host()->DisableUnloadTimerForTesting();

  // Process B and C are expected to shutdown once every unload handler has
  // run.
  RenderProcessHostWatcher shutdown_B(
      root->child_at(0)->current_frame_host()->GetProcess(),
      RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
  RenderProcessHostWatcher shutdown_C(
      root->child_at(0)->child_at(0)->current_frame_host()->GetProcess(),
      RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);

  // Navigate B to E.
  GURL e_url(embedded_test_server()->GetURL("e.com", "/title1.html"));
  NavigateFrameToURL(root->child_at(0), e_url);

  // Collect unload handler messages.
  std::string message;
  std::vector<std::string> messages;
  for (int i = 0; i < 6; ++i) {
    EXPECT_TRUE(dom_message_queue.WaitForMessage(&message));
    base::TrimString(message, "\"", &message);
    messages.push_back(message);
  }
  EXPECT_FALSE(dom_message_queue.PopMessage(&message));

  // Check every frame in the replaced subtree has executed its unload handler.
  EXPECT_THAT(messages,
              WhenSorted(ElementsAre("A2", "B1", "B2", "C1", "C2", "C3")));

  // In every renderer process, check ancestors have executed their unload
  // handler before their children. This is a slightly less restrictive
  // condition than the specification which requires it to be global instead of
  // per process.
  // https://html.spec.whatwg.org/multipage/browsing-the-web.html#unloading-documents
  //
  // In process B:
  auto B1 = std::find(messages.begin(), messages.end(), "B1");
  auto B2 = std::find(messages.begin(), messages.end(), "B2");
  EXPECT_LT(B1, B2);

  // In process C:
  auto C2 = std::find(messages.begin(), messages.end(), "C2");
  auto C3 = std::find(messages.begin(), messages.end(), "C3");
  EXPECT_LT(C2, C3);

  // Make sure the processes are deleted at some point.
  shutdown_B.Wait();
  shutdown_C.Wait();
}

// Check that unload handlers in iframe don't prevents the main frame to be
// deleted after a timeout.
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, SlowUnloadHandlerInIframe) {
  GURL initial_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)"));
  GURL next_url(embedded_test_server()->GetURL("c.com", "/title1.html"));

  // 1) Navigate on a page with an iframe.
  EXPECT_TRUE(NavigateToURL(shell(), initial_url));

  // 2) Act as if there was an infinite unload handler in B.
  auto filter = base::MakeRefCounted<DropMessageFilter>(
      FrameMsgStart, FrameHostMsg_Detach::ID);
  RenderFrameHost* rfh_b =
      web_contents()->GetFrameTree()->root()->child_at(0)->current_frame_host();
  rfh_b->GetProcess()->AddFilter(filter.get());

  // 3) Navigate and check the old frame is deleted after some time.
  FrameTreeNode* root = web_contents()->GetFrameTree()->root();
  RenderFrameDeletedObserver deleted_observer(root->current_frame_host());
  EXPECT_TRUE(NavigateToURL(shell(), next_url));
  deleted_observer.WaitUntilDeleted();
}

// Navigate from A(B(A(B)) to C. Check the unload handler are executed, executed
// in the right order and the processes for A and B are removed.
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, Unload_ABAB) {
  web_contents()->GetController().GetBackForwardCache().DisableForTesting(
      content::BackForwardCache::TEST_USES_UNLOAD_EVENT);

  GURL initial_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b(a(b)))"));
  GURL next_url(embedded_test_server()->GetURL("c.com", "/title1.html"));

  // 1) Navigate on a page with an iframe.
  EXPECT_TRUE(NavigateToURL(shell(), initial_url));

  // 2) Add unload handler on every frame.
  FrameTreeNode* root = web_contents()->GetFrameTree()->root();
  UnloadPrint(root, "A1");
  UnloadPrint(root->child_at(0), "B1");
  UnloadPrint(root->child_at(0)->child_at(0), "A2");
  UnloadPrint(root->child_at(0)->child_at(0)->child_at(0), "B2");
  root->current_frame_host()->DisableUnloadTimerForTesting();

  DOMMessageQueue dom_message_queue(
      WebContents::FromRenderFrameHost(web_contents()->GetMainFrame()));
  RenderProcessHostWatcher shutdown_A(
      root->current_frame_host()->GetProcess(),
      RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
  RenderProcessHostWatcher shutdown_B(
      root->child_at(0)->current_frame_host()->GetProcess(),
      RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);

  // 3) Navigate cross process.
  EXPECT_TRUE(NavigateToURL(shell(), next_url));

  // 4) Wait for unload handler messages and check they are sent in order.
  std::vector<std::string> messages;
  std::string message;
  for (int i = 0; i < 4; ++i) {
    EXPECT_TRUE(dom_message_queue.WaitForMessage(&message));
    base::TrimString(message, "\"", &message);
    messages.push_back(message);
  }
  EXPECT_FALSE(dom_message_queue.PopMessage(&message));

  EXPECT_THAT(messages, WhenSorted(ElementsAre("A1", "A2", "B1", "B2")));
  auto A1 = std::find(messages.begin(), messages.end(), "A1");
  auto A2 = std::find(messages.begin(), messages.end(), "A2");
  auto B1 = std::find(messages.begin(), messages.end(), "B1");
  auto B2 = std::find(messages.begin(), messages.end(), "B2");
  EXPECT_LT(A1, A2);
  EXPECT_LT(B1, B2);

  // Make sure the processes are deleted at some point.
  shutdown_A.Wait();
  shutdown_B.Wait();
}

// Start with A(B(C)), navigate C to D and then B to E. By emulating a slow
// unload handler in B,C and D, the end result is C is in pending deletion in B
// and B is in pending deletion in A.
//   (1)     (2)     (3)
//|       |       |       |
//|   A   |  A    |   A   |
//|   |   |  |    |    \  |
//|   B   |  B    |  B  E |
//|   |   |   \   |   \   |
//|   C   | C  D  | C  D  |
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, UnloadNestedPendingDeletion) {
  std::string onunload_script = "window.onunload = function(){}";
  GURL url_abc(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b(c))"));
  GURL url_d(embedded_test_server()->GetURL("d.com", "/title1.html"));
  GURL url_e(embedded_test_server()->GetURL("e.com", "/title1.html"));

  // 1) Navigate to a page with an iframe.
  EXPECT_TRUE(NavigateToURL(shell(), url_abc));
  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();
  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_);

  // Act as if there was a slow unload handler on rfh_b and rfh_c.
  // The navigating frames are waiting for FrameHostMsg_Unload_ACK.
  auto unload_ack_filter_b = base::MakeRefCounted<DropMessageFilter>(
      FrameMsgStart, FrameHostMsg_Unload_ACK::ID);
  auto unload_ack_filter_c = base::MakeRefCounted<DropMessageFilter>(
      FrameMsgStart, FrameHostMsg_Unload_ACK::ID);
  rfh_b->GetProcess()->AddFilter(unload_ack_filter_b.get());
  rfh_c->GetProcess()->AddFilter(unload_ack_filter_c.get());
  EXPECT_TRUE(ExecuteScript(rfh_b->frame_tree_node(), onunload_script));
  EXPECT_TRUE(ExecuteScript(rfh_c->frame_tree_node(), onunload_script));
  rfh_b->DisableUnloadTimerForTesting();
  rfh_c->DisableUnloadTimerForTesting();

  RenderFrameDeletedObserver delete_b(rfh_b), delete_c(rfh_c);

  // 2) Navigate rfh_c to D.
  NavigateFrameToURL(rfh_c->frame_tree_node(), url_d);
  EXPECT_EQ(RenderFrameHostImpl::UnloadState::NotRun, rfh_a->unload_state_);
  EXPECT_EQ(RenderFrameHostImpl::UnloadState::NotRun, rfh_b->unload_state_);
  EXPECT_EQ(RenderFrameHostImpl::UnloadState::InProgress, rfh_c->unload_state_);
  RenderFrameHostImpl* rfh_d = rfh_b->child_at(0)->current_frame_host();
  // Set an arbitrarily long timeout to ensure the subframe unload timer doesn't
  // fire before we call OnDetach().
  rfh_d->SetSubframeUnloadTimeoutForTesting(base::TimeDelta::FromSeconds(30));

  RenderFrameDeletedObserver delete_d(rfh_d);

  // Act as if there was a slow unload handler on rfh_d.
  // The non navigating frames are waiting for FrameHostMsg_Detach.
  auto detach_filter = base::MakeRefCounted<DropMessageFilter>(
      FrameMsgStart, FrameHostMsg_Detach::ID);
  rfh_d->GetProcess()->AddFilter(detach_filter.get());
  EXPECT_TRUE(ExecuteScript(rfh_d->frame_tree_node(), onunload_script));

  // 3) Navigate rfh_b to E.
  NavigateFrameToURL(rfh_b->frame_tree_node(), url_e);
  EXPECT_EQ(RenderFrameHostImpl::UnloadState::NotRun, rfh_a->unload_state_);
  EXPECT_EQ(RenderFrameHostImpl::UnloadState::InProgress, rfh_b->unload_state_);
  EXPECT_EQ(RenderFrameHostImpl::UnloadState::InProgress, rfh_c->unload_state_);
  EXPECT_EQ(RenderFrameHostImpl::UnloadState::InProgress, rfh_d->unload_state_);

  // rfh_d completes its unload event. It deletes the frame, including rfh_c.
  EXPECT_FALSE(delete_c.deleted());
  EXPECT_FALSE(delete_d.deleted());
  rfh_d->OnDetach();
  EXPECT_TRUE(delete_c.deleted());
  EXPECT_TRUE(delete_d.deleted());

  // rfh_b completes its unload event.
  EXPECT_FALSE(delete_b.deleted());
  rfh_b->OnUnloadACK();
  EXPECT_TRUE(delete_b.deleted());
}

// A set of nested frames A1(B1(A2)) are pending deletion because of a
// navigation. This tests what happens if only A2 has an unload handler.
// If B1 receives FrameHostMsg_OnDetach before A2, it should not destroy itself
// and its children, but rather wait for A2.
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, PartialUnloadHandler) {
  web_contents()->GetController().GetBackForwardCache().DisableForTesting(
      content::BackForwardCache::TEST_USES_UNLOAD_EVENT);

  GURL url_aba(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b(a))"));
  GURL url_c(embedded_test_server()->GetURL("c.com", "/title1.html"));

  // 1) Navigate to A1(B1(A2))
  EXPECT_TRUE(NavigateToURL(shell(), url_aba));

  FrameTreeNode* root = web_contents()->GetFrameTree()->root();
  RenderFrameHostImpl* a1 = root->current_frame_host();
  RenderFrameHostImpl* b1 = a1->child_at(0)->current_frame_host();
  RenderFrameHostImpl* a2 = b1->child_at(0)->current_frame_host();
  RenderFrameDeletedObserver delete_a1(a1);
  RenderFrameDeletedObserver delete_a2(a2);
  RenderFrameDeletedObserver delete_b1(b1);

  // Disable Detach and FrameHostMsg_Unload_ACK. They will be called manually.
  auto unload_ack_filter = base::MakeRefCounted<DropMessageFilter>(
      FrameMsgStart, FrameHostMsg_Unload_ACK::ID);
  auto detach_filter_a = base::MakeRefCounted<DropMessageFilter>(
      FrameMsgStart, FrameHostMsg_Detach::ID);
  auto detach_filter_b = base::MakeRefCounted<DropMessageFilter>(
      FrameMsgStart, FrameHostMsg_Detach::ID);
  a1->GetProcess()->AddFilter(unload_ack_filter.get());
  a1->GetProcess()->AddFilter(detach_filter_a.get());
  b1->GetProcess()->AddFilter(detach_filter_b.get());

  a1->DisableUnloadTimerForTesting();
  // Set an arbitrarily long timeout to ensure the subframe unload timer doesn't
  // fire before we call OnDetach().
  b1->SetSubframeUnloadTimeoutForTesting(base::TimeDelta::FromSeconds(30));

  // Add unload handler on A2, but not on the other frames.
  UnloadPrint(a2->frame_tree_node(), "A2");

  DOMMessageQueue dom_message_queue(
      WebContents::FromRenderFrameHost(web_contents()->GetMainFrame()));

  // 2) Navigate cross process.
  EXPECT_TRUE(NavigateToURL(shell(), url_c));

  // Check that unload handlers are executed.
  std::string message, message_unused;
  EXPECT_TRUE(dom_message_queue.WaitForMessage(&message));
  EXPECT_FALSE(dom_message_queue.PopMessage(&message_unused));
  EXPECT_EQ("\"A2\"", message);

  // No RenderFrameHost are deleted so far.
  EXPECT_FALSE(delete_a1.deleted());
  EXPECT_FALSE(delete_b1.deleted());
  EXPECT_FALSE(delete_a2.deleted());
  EXPECT_EQ(RenderFrameHostImpl::UnloadState::InProgress, a1->unload_state_);
  EXPECT_EQ(RenderFrameHostImpl::UnloadState::Completed, b1->unload_state_);
  EXPECT_EQ(RenderFrameHostImpl::UnloadState::InProgress, a2->unload_state_);

  // 3) B1 receives confirmation it has been deleted. This has no effect,
  //    because it is still waiting on A2 to be deleted.
  b1->OnDetach();
  EXPECT_FALSE(delete_a1.deleted());
  EXPECT_FALSE(delete_b1.deleted());
  EXPECT_FALSE(delete_a2.deleted());
  EXPECT_EQ(RenderFrameHostImpl::UnloadState::InProgress, a1->unload_state_);
  EXPECT_EQ(RenderFrameHostImpl::UnloadState::Completed, b1->unload_state_);
  EXPECT_EQ(RenderFrameHostImpl::UnloadState::InProgress, a2->unload_state_);

  // 4) A2 received confirmation that it has been deleted and destroy B1 and A2.
  a2->OnDetach();
  EXPECT_FALSE(delete_a1.deleted());
  EXPECT_TRUE(delete_b1.deleted());
  EXPECT_TRUE(delete_a2.deleted());
  EXPECT_EQ(RenderFrameHostImpl::UnloadState::InProgress, a1->unload_state_);

  // 5) A1 receives FrameHostMsg_Unload_ACK and deletes itself.
  a1->OnUnloadACK();
  EXPECT_TRUE(delete_a1.deleted());
}

// Test RenderFrameHostImpl::PendingDeletionCheckCompletedOnSubtree.
//
// After a navigation commit, some children with no unload handler may be
// eligible for immediate deletion. Several configurations are tested:
//
// Before navigation commit
//
//              0               |  N  : No unload handler
//   ‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑      | [N] : Unload handler
//  |  |  |  |  |   |     |     |
// [1] 2 [3] 5  7   9     12    |
//        |  |  |  / \   / \    |
//        4 [6] 8 10 11 13 [14] |
//
// After navigation commit (expected)
//
//              0               |  N  : No unload handler
//   ---------------------      | [N] : Unload handler
//  |     |  |            |     |
// [1]   [3] 5            12    |
//           |             \    |
//          [6]            [14] |
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
                       PendingDeletionCheckCompletedOnSubtree) {
  web_contents()->GetController().GetBackForwardCache().DisableForTesting(
      content::BackForwardCache::TEST_USES_UNLOAD_EVENT);

  GURL url_1(embedded_test_server()->GetURL(
      "a.com",
      "/cross_site_iframe_factory.html?a(a,a,a(a),a(a),a(a),a(a,a),a(a,a))"));
  GURL url_2(embedded_test_server()->GetURL("b.com", "/title1.html"));

  // 1) Navigate to 0(1,2,3(4),5(6),7(8),9(10,11),12(13,14));
  EXPECT_TRUE(NavigateToURL(shell(), url_1));

  FrameTreeNode* root = web_contents()->GetFrameTree()->root();
  RenderFrameHostImpl* rfh_0 = root->current_frame_host();
  RenderFrameHostImpl* rfh_1 = rfh_0->child_at(0)->current_frame_host();
  RenderFrameHostImpl* rfh_2 = rfh_0->child_at(1)->current_frame_host();
  RenderFrameHostImpl* rfh_3 = rfh_0->child_at(2)->current_frame_host();
  RenderFrameHostImpl* rfh_4 = rfh_3->child_at(0)->current_frame_host();
  RenderFrameHostImpl* rfh_5 = rfh_0->child_at(3)->current_frame_host();
  RenderFrameHostImpl* rfh_6 = rfh_5->child_at(0)->current_frame_host();
  RenderFrameHostImpl* rfh_7 = rfh_0->child_at(4)->current_frame_host();
  RenderFrameHostImpl* rfh_8 = rfh_7->child_at(0)->current_frame_host();
  RenderFrameHostImpl* rfh_9 = rfh_0->child_at(5)->current_frame_host();
  RenderFrameHostImpl* rfh_10 = rfh_9->child_at(0)->current_frame_host();
  RenderFrameHostImpl* rfh_11 = rfh_9->child_at(1)->current_frame_host();
  RenderFrameHostImpl* rfh_12 = rfh_0->child_at(6)->current_frame_host();
  RenderFrameHostImpl* rfh_13 = rfh_12->child_at(0)->current_frame_host();
  RenderFrameHostImpl* rfh_14 = rfh_12->child_at(1)->current_frame_host();

  RenderFrameDeletedObserver delete_a0(rfh_0), delete_a1(rfh_1),
      delete_a2(rfh_2), delete_a3(rfh_3), delete_a4(rfh_4), delete_a5(rfh_5),
      delete_a6(rfh_6), delete_a7(rfh_7), delete_a8(rfh_8), delete_a9(rfh_9),
      delete_a10(rfh_10), delete_a11(rfh_11), delete_a12(rfh_12),
      delete_a13(rfh_13), delete_a14(rfh_14);

  // Add the unload handlers.
  UnloadPrint(rfh_1->frame_tree_node(), "");
  UnloadPrint(rfh_3->frame_tree_node(), "");
  UnloadPrint(rfh_6->frame_tree_node(), "");
  UnloadPrint(rfh_14->frame_tree_node(), "");

  // Disable Detach and FrameHostMsg_Unload_ACK.
  auto unload_ack_filter = base::MakeRefCounted<DropMessageFilter>(
      FrameMsgStart, FrameHostMsg_Unload_ACK::ID);
  auto detach_filter = base::MakeRefCounted<DropMessageFilter>(
      FrameMsgStart, FrameHostMsg_Detach::ID);
  rfh_0->GetProcess()->AddFilter(unload_ack_filter.get());
  rfh_0->GetProcess()->AddFilter(detach_filter.get());
  rfh_0->DisableUnloadTimerForTesting();

  // 2) Navigate cross process and check the tree. See diagram above.
  EXPECT_TRUE(NavigateToURL(shell(), url_2));

  EXPECT_FALSE(delete_a0.deleted());
  EXPECT_FALSE(delete_a1.deleted());
  EXPECT_TRUE(delete_a2.deleted());
  EXPECT_FALSE(delete_a3.deleted());
  EXPECT_TRUE(delete_a4.deleted());
  EXPECT_FALSE(delete_a5.deleted());
  EXPECT_FALSE(delete_a6.deleted());
  EXPECT_TRUE(delete_a7.deleted());
  EXPECT_TRUE(delete_a8.deleted());
  EXPECT_TRUE(delete_a9.deleted());
  EXPECT_TRUE(delete_a10.deleted());
  EXPECT_TRUE(delete_a11.deleted());
  EXPECT_FALSE(delete_a12.deleted());
  EXPECT_TRUE(delete_a13.deleted());
  EXPECT_FALSE(delete_a14.deleted());
}

// When an iframe is detached, check that unload handlers execute in all of its
// child frames. Start from A(B(C)) and delete B from A.
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
                       DetachedIframeUnloadHandlerABC) {
  GURL initial_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b(c))"));

  // 1) Navigate to a(b(c))
  EXPECT_TRUE(NavigateToURL(shell(), initial_url));
  FrameTreeNode* root = web_contents()->GetFrameTree()->root();
  RenderFrameHostImpl* rfh_a = root->current_frame_host();
  RenderFrameHostImpl* rfh_b = rfh_a->child_at(0)->current_frame_host();
  RenderFrameHostImpl* rfh_c = rfh_b->child_at(0)->current_frame_host();

  // 2) Add unload handlers on B and C.
  UnloadPrint(rfh_b->frame_tree_node(), "B");
  UnloadPrint(rfh_c->frame_tree_node(), "C");

  DOMMessageQueue dom_message_queue(web_contents());
  RenderProcessHostWatcher shutdown_B(
      rfh_b->GetProcess(), RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
  RenderProcessHostWatcher shutdown_C(
      rfh_c->GetProcess(), RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);

  // 3) Detach B from A.
  ExecuteScriptAsync(root, "document.querySelector('iframe').remove();");

  // 4) Wait for unload handler.
  std::vector<std::string> messages(2);
  EXPECT_TRUE(dom_message_queue.WaitForMessage(&messages[0]));
  EXPECT_TRUE(dom_message_queue.WaitForMessage(&messages[1]));
  std::string unused;
  EXPECT_FALSE(dom_message_queue.PopMessage(&unused));

  std::sort(messages.begin(), messages.end());
  EXPECT_EQ("\"B\"", messages[0]);
  EXPECT_EQ("\"C\"", messages[1]);

  // Make sure the processes are deleted at some point.
  shutdown_B.Wait();
  shutdown_C.Wait();
}

// When an iframe is detached, check that unload handlers execute in all of its
// child frames. Start from A(B1(C(B2))) and delete B1 from A.
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
                       DetachedIframeUnloadHandlerABCB) {
  GURL initial_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b(c(b)))"));

  // 1) Navigate to a(b(c(b)))
  EXPECT_TRUE(NavigateToURL(shell(), initial_url));
  FrameTreeNode* root = web_contents()->GetFrameTree()->root();
  RenderFrameHostImpl* rfh_a = root->current_frame_host();
  RenderFrameHostImpl* rfh_b1 = rfh_a->child_at(0)->current_frame_host();
  RenderFrameHostImpl* rfh_c = rfh_b1->child_at(0)->current_frame_host();
  RenderFrameHostImpl* rfh_b2 = rfh_c->child_at(0)->current_frame_host();

  // 2) Add unload handlers on B1, B2 and C.
  UnloadPrint(rfh_b1->frame_tree_node(), "B1");
  UnloadPrint(rfh_b2->frame_tree_node(), "B2");
  UnloadPrint(rfh_c->frame_tree_node(), "C");

  DOMMessageQueue dom_message_queue(web_contents());
  RenderProcessHostWatcher shutdown_B(
      rfh_b1->GetProcess(), RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
  RenderProcessHostWatcher shutdown_C(
      rfh_c->GetProcess(), RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);

  // 3) Detach B from A.
  ExecuteScriptAsync(root, "document.querySelector('iframe').remove();");

  // 4) Wait for unload handler.
  std::vector<std::string> messages(3);
  EXPECT_TRUE(dom_message_queue.WaitForMessage(&messages[0]));
  EXPECT_TRUE(dom_message_queue.WaitForMessage(&messages[1]));
  EXPECT_TRUE(dom_message_queue.WaitForMessage(&messages[2]));
  std::string unused;
  EXPECT_FALSE(dom_message_queue.PopMessage(&unused));

  std::sort(messages.begin(), messages.end());
  EXPECT_EQ("\"B1\"", messages[0]);
  EXPECT_EQ("\"B2\"", messages[1]);
  EXPECT_EQ("\"C\"", messages[2]);

  // Make sure the processes are deleted at some point.
  shutdown_B.Wait();
  shutdown_C.Wait();
}

// When an iframe is detached, check that unload handlers execute in all of its
// child frames. Start from A1(A2(B)), delete A2 from itself.
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
                       DetachedIframeUnloadHandlerAAB) {
  GURL initial_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(a(b))"));

  // 1) Navigate to a(a(b)).
  EXPECT_TRUE(NavigateToURL(shell(), initial_url));
  FrameTreeNode* root = web_contents()->GetFrameTree()->root();
  RenderFrameHostImpl* rfh_a1 = root->current_frame_host();
  RenderFrameHostImpl* rfh_a2 = rfh_a1->child_at(0)->current_frame_host();
  RenderFrameHostImpl* rfh_b = rfh_a2->child_at(0)->current_frame_host();

  // 2) Add unload handlers on A2 ad B.
  UnloadPrint(rfh_a2->frame_tree_node(), "A2");
  UnloadPrint(rfh_b->frame_tree_node(), "B");

  DOMMessageQueue dom_message_queue(web_contents());
  RenderProcessHostWatcher shutdown_B(
      rfh_b->GetProcess(), RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);

  // 3) A2 detaches itself.
  ExecuteScriptAsync(rfh_a2->frame_tree_node(),
                     "parent.document.querySelector('iframe').remove();");

  // 4) Wait for unload handler.
  std::vector<std::string> messages(2);
  EXPECT_TRUE(dom_message_queue.WaitForMessage(&messages[0]));
  EXPECT_TRUE(dom_message_queue.WaitForMessage(&messages[1]));
  std::string unused;
  EXPECT_FALSE(dom_message_queue.PopMessage(&unused));

  std::sort(messages.begin(), messages.end());
  EXPECT_EQ("\"A2\"", messages[0]);
  EXPECT_EQ("\"B\"", messages[1]);

  // Make sure the process is deleted at some point.
  shutdown_B.Wait();
}

// Tests that running layout from an unload handler inside teardown of the
// RenderWidget (inside WidgetMsg_Close) can succeed.
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
                       RendererInitiatedWindowCloseWithUnload) {
  GURL main_url(embedded_test_server()->GetURL("a.com", "/empty.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

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

  // We will window.open() another URL on the same domain so they share a
  // renderer. This window has an unload handler that forces layout to occur.
  // Then we (in a new stack) close that window causing that layout. If all
  // goes well the window closes. If it goes poorly, the renderer may crash.
  //
  // This path is special because the unload results from window.close() which
  // avoids the user-initiated close path through ViewMsg_ClosePage. In that
  // path the unload handlers are run early, before the actual teardown of
  // the closing RenderWidget.
  GURL open_url = embedded_test_server()->GetURL(
      "a.com", "/unload_handler_force_layout.html");

  // Listen for messages from the window that the test opens, and convert them
  // into the document title, which we can wait on in the main test window.
  EXPECT_TRUE(
      ExecuteScript(root,
                    "window.addEventListener('message', function(event) {\n"
                    "  document.title = event.data;\n"
                    "});"));

  // This performs window.open() and waits for the title of the original
  // document to change to signal that the unload handler has been registered.
  {
    base::string16 title_when_loaded = base::UTF8ToUTF16("loaded");
    TitleWatcher title_watcher(shell()->web_contents(), title_when_loaded);
    EXPECT_TRUE(
        ExecuteScript(root, JsReplace("var w = window.open($1)", open_url)));
    EXPECT_EQ(title_watcher.WaitAndGetTitle(), title_when_loaded);
  }

  // The closes the window and waits for the title of the original document to
  // change again to signal that the unload handler has run.
  {
    base::string16 title_when_done = base::UTF8ToUTF16("unloaded");
    TitleWatcher title_watcher(shell()->web_contents(), title_when_done);
    EXPECT_TRUE(ExecuteScript(root, "w.close()"));
    EXPECT_EQ(title_watcher.WaitAndGetTitle(), title_when_done);
  }
}

// Regression test for https://crbug.com/960006.
//
// 1. Navigate to a1(a2(b3),c4),
// 2. b3 has a slow unload handler.
// 3. a2 navigates same process.
// 4. When the new document is loaded, a message is sent to c4 to check it
//    cannot see b3 anymore, even if b3 is still unloading.
IN_PROC_BROWSER_TEST_F(
    SitePerProcessBrowserTest,
    IsDetachedSubframeObservableDuringUnloadHandlerSameProcess) {
  GURL page_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(a(b),c)"));
  EXPECT_TRUE(NavigateToURL(shell(), page_url));
  RenderFrameHostImpl* node1 =
      static_cast<WebContentsImpl*>(shell()->web_contents())
          ->GetFrameTree()
          ->root()
          ->current_frame_host();
  RenderFrameHostImpl* node2 = node1->child_at(0)->current_frame_host();
  RenderFrameHostImpl* node3 = node2->child_at(0)->current_frame_host();
  RenderFrameHostImpl* node4 = node1->child_at(1)->current_frame_host();
  ASSERT_TRUE(ExecJs(node1, "window.name = 'node1'"));
  ASSERT_TRUE(ExecJs(node2, "window.name = 'node2'"));
  ASSERT_TRUE(ExecJs(node3, "window.name = 'node3'"));
  ASSERT_TRUE(ExecJs(node4, "window.name = 'node4'"));

  // Test sanity check.
  EXPECT_EQ(true, EvalJs(node1, "!!top.node2.node3"));
  EXPECT_EQ(true, EvalJs(node2, "!!top.node2.node3"));
  EXPECT_EQ(true, EvalJs(node3, "!!top.node2.node3"));
  EXPECT_EQ(true, EvalJs(node4, "!!top.node2.node3"));

  // Simulate a long-running unload handler in |node3|.
  auto detach_filter = base::MakeRefCounted<DropMessageFilter>(
      FrameMsgStart, FrameHostMsg_Detach::ID);
  node3->GetProcess()->AddFilter(detach_filter.get());
  node2->DisableUnloadTimerForTesting();
  ASSERT_TRUE(ExecJs(node3, "window.onunload = ()=>{}"));

  // Prepare |node4| to respond to postMessage with a report of whether it can
  // still find |node3|.
  const char* kPostMessageHandlerScript = R"(
      window.postMessageGotData == false;
      window.postMessageCallback = function() {};
      function receiveMessage(event) {
          console.log('node4 - receiveMessage...');

          var can_node3_be_found = false;
          try {
            can_node3_be_found = !!top.node2.node3;
          } catch(e) {
            can_node3_be_found = false;
          }

          window.postMessageGotData = true;
          window.postMessageData = can_node3_be_found;
          window.postMessageCallback(window.postMessageData);
      }
      window.addEventListener("message", receiveMessage, false);
  )";
  ASSERT_TRUE(ExecJs(node4, kPostMessageHandlerScript));

  // Make |node1| navigate |node2| same process and after the navigation
  // succeeds, send a post message to |node4|. We expect that the effects of the
  // commit should be visible to |node4| by the time it receives the posted
  // message.
  const char* kNavigationScript = R"(
      var node2_frame = document.getElementsByTagName('iframe')[0];
      node2_frame.onload = function() {
          console.log('node2_frame.onload ...');
          node4.postMessage('try to find node3', '*');
      };
      node2_frame.src = $1;
  )";
  GURL url = embedded_test_server()->GetURL("a.com", "/title1.html");
  ASSERT_TRUE(ExecJs(node1, JsReplace(kNavigationScript, url)));

  // Check if |node4| has seen |node3| even after |node2| navigation finished
  // (no other frame should see |node3| after the navigation of its parent).
  const char* kPostMessageResultsScript = R"(
      new Promise(function (resolve, reject) {
          if (window.postMessageGotData)
            resolve(window.postMessageData);
          else
            window.postMessageCallback = resolve;
      });
  )";
  EXPECT_EQ(false, EvalJs(node4, kPostMessageResultsScript));
}

// Regression test for https://crbug.com/960006.
//
// 1. Navigate to a1(a2(b3),c4),
// 2. b3 has a slow unload handler.
// 3. a2 navigates cross process.
// 4. When the new document is loaded, a message is sent to c4 to check it
//    cannot see b3 anymore, even if b3 is still unloading.
//
// Note: This test is the same as the above, except it uses a cross-process
// navigation at step 3.
IN_PROC_BROWSER_TEST_F(
    SitePerProcessBrowserTest,
    IsDetachedSubframeObservableDuringUnloadHandlerCrossProcess) {
  GURL page_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(a(b),c)"));
  EXPECT_TRUE(NavigateToURL(shell(), page_url));
  RenderFrameHostImpl* node1 =
      static_cast<WebContentsImpl*>(shell()->web_contents())
          ->GetFrameTree()
          ->root()
          ->current_frame_host();
  RenderFrameHostImpl* node2 = node1->child_at(0)->current_frame_host();
  RenderFrameHostImpl* node3 = node2->child_at(0)->current_frame_host();
  RenderFrameHostImpl* node4 = node1->child_at(1)->current_frame_host();
  ASSERT_TRUE(ExecJs(node1, "window.name = 'node1'"));
  ASSERT_TRUE(ExecJs(node2, "window.name = 'node2'"));
  ASSERT_TRUE(ExecJs(node3, "window.name = 'node3'"));
  ASSERT_TRUE(ExecJs(node4, "window.name = 'node4'"));

  // Test sanity check.
  EXPECT_EQ(true, EvalJs(node1, "!!top.node2.node3"));
  EXPECT_EQ(true, EvalJs(node2, "!!top.node2.node3"));
  EXPECT_EQ(true, EvalJs(node3, "!!top.node2.node3"));
  EXPECT_EQ(true, EvalJs(node4, "!!top.node2.node3"));

  // Add a long-running unload handler to |node3|.
  auto detach_filter = base::MakeRefCounted<DropMessageFilter>(
      FrameMsgStart, FrameHostMsg_Detach::ID);
  node3->GetProcess()->AddFilter(detach_filter.get());
  node2->DisableUnloadTimerForTesting();
  ASSERT_TRUE(ExecJs(node3, "window.onunload = ()=>{}"));

  // Prepare |node4| to respond to postMessage with a report of whether it can
  // still find |node3|.
  const char* kPostMessageHandlerScript = R"(
      window.postMessageGotData == false;
      window.postMessageCallback = function() {};
      function receiveMessage(event) {
          console.log('node4 - receiveMessage...');

          var can_node3_be_found = false;
          try {
            can_node3_be_found = !!top.node2.node3;
          } catch(e) {
            can_node3_be_found = false;
          }

          window.postMessageGotData = true;
          window.postMessageData = can_node3_be_found;
          window.postMessageCallback(window.postMessageData);
      }
      window.addEventListener("message", receiveMessage, false);
  )";
  ASSERT_TRUE(ExecJs(node4, kPostMessageHandlerScript));

  // Make |node1| navigate |node2| cross process and after the navigation
  // succeeds, send a post message to |node4|. We expect that the effects of the
  // commit should be visible to |node4| by the time it receives the posted
  // message.
  const char* kNavigationScript = R"(
      var node2_frame = document.getElementsByTagName('iframe')[0];
      node2_frame.onload = function() {
          console.log('node2_frame.onload ...');
          node4.postMessage('try to find node3', '*');
      };
      node2_frame.src = $1;
  )";
  GURL url = embedded_test_server()->GetURL("d.com", "/title1.html");
  ASSERT_TRUE(ExecJs(node1, JsReplace(kNavigationScript, url)));

  // Check if |node4| has seen |node3| even after |node2| navigation finished
  // (no other frame should see |node3| after the navigation of its parent).
  const char* kPostMessageResultsScript = R"(
      new Promise(function (resolve, reject) {
          if (window.postMessageGotData)
            resolve(window.postMessageData);
          else
            window.postMessageCallback = resolve;
      });
  )";
  EXPECT_EQ(false, EvalJs(node4, kPostMessageResultsScript));
}

// Regression test. https://crbug.com/963330
// 1. Start from A1(B2,C3)
// 2. B2 is the "focused frame", is deleted and starts unloading.
// 3. C3 commits a new navigation before B2 has completed its unload.
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, FocusedFrameUnload) {
  // 1) Start from A1(B2,C3)
  EXPECT_TRUE(NavigateToURL(
      shell(), embedded_test_server()->GetURL(
                   "a.com", "/cross_site_iframe_factory.html?a(b,c)")));
  RenderFrameHostImpl* A1 = web_contents()->GetMainFrame();
  RenderFrameHostImpl* B2 = A1->child_at(0)->current_frame_host();
  RenderFrameHostImpl* C3 = A1->child_at(1)->current_frame_host();
  FrameTree* frame_tree = A1->frame_tree_node()->frame_tree();

  // 2.1) Make B2 to be the focused frame.
  EXPECT_EQ(A1->frame_tree_node(), frame_tree->GetFocusedFrame());
  EXPECT_TRUE(ExecJs(A1, "document.querySelector('iframe').focus()"));
  EXPECT_EQ(B2->frame_tree_node(), frame_tree->GetFocusedFrame());

  // 2.2 Unload B2. Drop detach message to simulate a long unloading.
  auto filter = base::MakeRefCounted<DropMessageFilter>(
      FrameMsgStart, FrameHostMsg_Detach::ID);
  B2->GetProcess()->AddFilter(filter.get());
  B2->SetSubframeUnloadTimeoutForTesting(base::TimeDelta::FromSeconds(30));

  EXPECT_FALSE(B2->GetSuddenTerminationDisablerState(
      blink::mojom::SuddenTerminationDisablerType::kUnloadHandler));
  EXPECT_TRUE(ExecJs(B2, "window.onunload = ()=>{};"));
  EXPECT_TRUE(B2->GetSuddenTerminationDisablerState(
      blink::mojom::SuddenTerminationDisablerType::kUnloadHandler));

  EXPECT_TRUE(B2->is_active());
  EXPECT_TRUE(ExecJs(A1, "document.querySelector('iframe').remove()"));
  EXPECT_EQ(nullptr, frame_tree->GetFocusedFrame());
  EXPECT_EQ(2u, A1->child_count());
  EXPECT_FALSE(B2->is_active());

  // 3. C3 navigates.
  NavigateFrameToURL(C3->frame_tree_node(),
                     embedded_test_server()->GetURL("d.com", "/title1.html"));
  EXPECT_TRUE(WaitForLoadStop(web_contents()));
  EXPECT_EQ(2u, A1->child_count());
}

// Test the unload timeout is effective.
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, UnloadTimeout) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));
  RenderFrameHostImpl* A1 = web_contents()->GetMainFrame();
  RenderFrameHostImpl* B2 = A1->child_at(0)->current_frame_host();

  // Simulate the iframe being slow to unload by dropping the
  // FrameHostMsg_Detach message sent from B2 to the browser.
  EXPECT_TRUE(ExecJs(B2, "window.onunload = ()=>{};"));
  auto detach_filter = base::MakeRefCounted<DropMessageFilter>(
      FrameMsgStart, FrameHostMsg_Detach::ID);
  B2->GetProcess()->AddFilter(detach_filter.get());

  RenderFrameDeletedObserver delete_B2(B2);
  EXPECT_TRUE(ExecJs(A1, "document.querySelector('iframe').remove()"));
  delete_B2.WaitUntilDeleted();
}

// Test that an unloading child can PostMessage its cross-process parent.
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
                       UnloadPostMessageToParentCrossProcess) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));
  RenderFrameHostImpl* A1 = web_contents()->GetMainFrame();
  RenderFrameHostImpl* B2 = A1->child_at(0)->current_frame_host();
  RenderFrameDeletedObserver delete_B2(B2);
  EXPECT_TRUE(ExecJs(B2, R"(
    window.addEventListener("unload", function() {
      window.parent.postMessage("B2 message", "*");
    });
  )"));
  EXPECT_TRUE(ExecJs(A1, R"(
    window.received_message = "nothing received";
    var received = false;
    window.addEventListener('message', function(event) {
      received_message = event.data;
    });
    document.querySelector('iframe').remove();
  )"));
  delete_B2.WaitUntilDeleted();
  // TODO(https://crbug.com/964950): PostMessage called from an unloading frame
  // must work. A1 must received 'B2 message'. This is not the case here.
  EXPECT_EQ("nothing received", EvalJs(A1, "received_message"));
}

// Test that an unloading child can PostMessage its same-process parent.
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
                       UnloadPostMessageToParentSameProcess) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(a)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));
  RenderFrameHostImpl* A1 = web_contents()->GetMainFrame();
  RenderFrameHostImpl* A2 = A1->child_at(0)->current_frame_host();
  RenderFrameDeletedObserver delete_A1(A2);
  EXPECT_TRUE(ExecJs(A2, R"(
    window.addEventListener("unload", function() {
      window.parent.postMessage("A2 message", "*");
    });
  )"));
  EXPECT_TRUE(ExecJs(A1, R"(
    window.received_message = "nothing received";
    var received = false;
    window.addEventListener('message', function(event) {
      received_message = event.data;
    });
    document.querySelector('iframe').remove();
  )"));
  delete_A1.WaitUntilDeleted();
  EXPECT_EQ("A2 message", EvalJs(A1, "received_message"));
}

// Related to issue https://crbug.com/950625.
//
// 1. Start from A1(B1)
// 2. Navigate A1 to A3, same-process.
// 3. A1 requests the browser to detach B1, but this message is dropped.
// 4. The browser must be resilient and detach B1 when A3 commits.
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
                       SameProcessNavigationResilientToDetachDropped) {
  GURL A1_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)"));
  GURL A3_url(embedded_test_server()->GetURL("a.com", "/title1.html"));

  EXPECT_TRUE(NavigateToURL(shell(), A1_url));
  RenderFrameHostImpl* A1 = web_contents()->GetMainFrame();
  RenderFrameHostImpl* B1 = A1->child_at(0)->current_frame_host();

  auto detach_filter = base::MakeRefCounted<DropMessageFilter>(
      FrameMsgStart, FrameHostMsg_Detach::ID);
  A1->GetProcess()->AddFilter(detach_filter.get());
  RenderFrameDeletedObserver delete_B1(B1);
  shell()->LoadURL(A3_url);
  delete_B1.WaitUntilDeleted();
}

// Some tests need an https server because third-party cookies are used, and
// SameSite=None cookies must be Secure. This is a separate fixture due to
// kIgnoreCertificateErrors flag.
class SitePerProcessSSLBrowserTest : public SitePerProcessBrowserTest {
 protected:
  SitePerProcessSSLBrowserTest()
      : https_server_(net::EmbeddedTestServer::TYPE_HTTPS) {}

  void SetUpCommandLine(base::CommandLine* command_line) override {
    SitePerProcessBrowserTest::SetUpCommandLine(command_line);
    // This is necessary to use https with arbitrary hostnames.
    command_line->AppendSwitch(switches::kIgnoreCertificateErrors);
  }

  void SetUpOnMainThread() override {
    https_server()->AddDefaultHandlers(GetTestDataFilePath());
    ASSERT_TRUE(https_server()->Start());
    SitePerProcessBrowserTest::SetUpOnMainThread();
  }

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

 private:
  net::EmbeddedTestServer https_server_;
};

// Unload handlers should be able to do things that might require for instance
// the RenderFrameHostImpl to stay alive.
// - use console.log (handled via RFHI::DidAddMessageToConsole).
// - use history.replaceState (handled via RFHI::OnUpdateState).
// - use document.cookie
// - use localStorage
//
// Test case:
//  1. Start on A1(B2). B2 has an unload handler.
//  2. Go to A3.
//  3. Go back to A4(B5).
//
// TODO(https://crbug.com/960976): history.replaceState is broken in OOPIFs.
//
// This test is similar to UnloadHandlersArePowerfulGrandChild, but with a
// different frame hierarchy.
IN_PROC_BROWSER_TEST_F(SitePerProcessSSLBrowserTest,
                       UnloadHandlersArePowerful) {
  // Navigate to a page hosting a cross-origin frame.
  GURL url =
      https_server()->GetURL("a.com", "/cross_site_iframe_factory.html?a(b)");
  EXPECT_TRUE(NavigateToURL(shell(), url));

  RenderFrameHostImpl* A1 = web_contents()->GetMainFrame();
  RenderFrameHostImpl* B2 = A1->child_at(0)->current_frame_host();

  // Increase Unload timeout to prevent the previous document from
  // being deleleted before it has finished running B2 unload handler.
  A1->DisableUnloadTimerForTesting();
  B2->SetSubframeUnloadTimeoutForTesting(base::TimeDelta::FromSeconds(30));

  // Add an unload handler to the subframe and try in that handler to preserve
  // state that we will try to recover later.
  ASSERT_TRUE(ExecJs(B2, R"(
    window.addEventListener("unload", function() {
      // Waiting for 100ms, to give more time for browser-side things to go bad
      // and delete RenderFrameHostImpl prematurely.
      var start = (new Date()).getTime();
      do {
        curr = (new Date()).getTime();
      } while (start + 100 > curr);

      // Test that various RFHI-dependent things work fine in an unload handler.
      stateObj = { "history_test_key": "history_test_value" }
      history.replaceState(stateObj, 'title', window.location.href);
      console.log('console.log() sent');

      // As a sanity check, test that RFHI-independent things also work fine.
      localStorage.localstorage_test_key = 'localstorage_test_value';
      document.cookie = 'cookie_test_key=' +
                        'cookie_test_value; SameSite=none; Secure';
    });
  )"));

  // Navigate A1(B2) to A3.
  {
    // Prepare observers.
    ConsoleObserverDelegate console(web_contents(), "console.log() sent");
    web_contents()->SetDelegate(&console);
    RenderFrameDeletedObserver B2_deleted(B2);

    // Navigate
    GURL away_url(https_server()->GetURL("a.com", "/title1.html"));
    ASSERT_TRUE(ExecJs(A1, JsReplace("location = $1", away_url)));

    // Observers must be reached.
    B2_deleted.WaitUntilDeleted();
    console.Wait();
  }

  // Navigate back from A3 to A4(B5).
  web_contents()->GetController().GoBack();
  EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));

  RenderFrameHostImpl* A4 = web_contents()->GetMainFrame();
  RenderFrameHostImpl* B5 = A4->child_at(0)->current_frame_host();

  // Verify that we can recover the data that should have been persisted by the
  // unload handler.
  EXPECT_EQ("localstorage_test_value",
            EvalJs(B5, "localStorage.localstorage_test_key"));
  EXPECT_EQ("cookie_test_key=cookie_test_value", EvalJs(B5, "document.cookie"));

  // TODO(lukasza): https://crbug.com/960976: Make the verification below
  // unconditional, once the bug is fixed.
  if (!AreAllSitesIsolatedForTesting()) {
    EXPECT_EQ("history_test_value",
              EvalJs(B5, "history.state.history_test_key"));
  }
}

// Unload handlers should be able to do things that might require for instance
// the RenderFrameHostImpl to stay alive.
// - use console.log (handled via RFHI::DidAddMessageToConsole).
// - use history.replaceState (handled via RFHI::OnUpdateState).
// - use document.cookie
// - use localStorage
//
// Test case:
//  1. Start on A1(B2(C3)). C3 has an unload handler.
//  2. Go to A4.
//  3. Go back to A5(B6(C7)).
//
// TODO(https://crbug.com/960976): history.replaceState is broken in OOPIFs.
//
// This test is similar to UnloadHandlersArePowerful, but with a different frame
// hierarchy.
IN_PROC_BROWSER_TEST_F(SitePerProcessSSLBrowserTest,
                       UnloadHandlersArePowerfulGrandChild) {
  // Navigate to a page hosting a cross-origin frame.
  GURL url = https_server()->GetURL("a.com",
                                    "/cross_site_iframe_factory.html?a(b(c))");
  EXPECT_TRUE(NavigateToURL(shell(), url));

  RenderFrameHostImpl* A1 = web_contents()->GetMainFrame();
  RenderFrameHostImpl* B2 = A1->child_at(0)->current_frame_host();
  RenderFrameHostImpl* C3 = B2->child_at(0)->current_frame_host();

  // Increase Unload timeout to prevent the previous document from
  // being deleleted before it has finished running C3 unload handler.
  A1->DisableUnloadTimerForTesting();
  B2->SetSubframeUnloadTimeoutForTesting(base::TimeDelta::FromSeconds(30));
  C3->SetSubframeUnloadTimeoutForTesting(base::TimeDelta::FromSeconds(30));

  // Add an unload handler to the subframe and try in that handler to preserve
  // state that we will try to recover later.
  ASSERT_TRUE(ExecJs(C3, R"(
    window.addEventListener("unload", function() {
      // Waiting for 100ms, to give more time for browser-side things to go bad
      // and delete RenderFrameHostImpl prematurely.
      var start = (new Date()).getTime();
      do {
        curr = (new Date()).getTime();
      } while (start + 100 > curr);

      // Test that various RFHI-dependent things work fine in an unload handler.
      stateObj = { "history_test_key": "history_test_value" }
      history.replaceState(stateObj, 'title', window.location.href);
      console.log('console.log() sent');

      // As a sanity check, test that RFHI-independent things also work fine.
      localStorage.localstorage_test_key = 'localstorage_test_value';
      document.cookie = 'cookie_test_key=' +
                        'cookie_test_value; SameSite=none; Secure';
    });
  )"));

  // Navigate A1(B2(C3) to A4.
  {
    // Prepare observers.
    ConsoleObserverDelegate console(web_contents(), "console.log() sent");
    web_contents()->SetDelegate(&console);
    RenderFrameDeletedObserver B2_deleted(B2);
    RenderFrameDeletedObserver C3_deleted(C3);

    // Navigate
    GURL away_url(https_server()->GetURL("a.com", "/title1.html"));
    ASSERT_TRUE(ExecJs(A1, JsReplace("location = $1", away_url)));

    // Observers must be reached.
    B2_deleted.WaitUntilDeleted();
    C3_deleted.WaitUntilDeleted();
    console.Wait();
  }

  // Navigate back from A4 to A5(B6(C7))
  web_contents()->GetController().GoBack();
  EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));

  RenderFrameHostImpl* A5 = web_contents()->GetMainFrame();
  RenderFrameHostImpl* B6 = A5->child_at(0)->current_frame_host();
  RenderFrameHostImpl* C7 = B6->child_at(0)->current_frame_host();

  // Verify that we can recover the data that should have been persisted by the
  // unload handler.
  EXPECT_EQ("localstorage_test_value",
            EvalJs(C7, "localStorage.localstorage_test_key"));
  EXPECT_EQ("cookie_test_key=cookie_test_value", EvalJs(C7, "document.cookie"));

  // TODO(lukasza): https://crbug.com/960976: Make the verification below
  // unconditional, once the bug is fixed.
  if (!AreAllSitesIsolatedForTesting()) {
    EXPECT_EQ("history_test_value",
              EvalJs(C7, "history.state.history_test_key"));
  }
}

}  // namespace content
