// 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
// OnSwapOut, the SwapOut 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,
                       SwapOutACKArrivesPriorToProcessShutdownRequest) {
  GURL start_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
  EXPECT_TRUE(NavigateToURL(shell(), start_url));
  RenderFrameHostImpl* rfh = web_contents()->GetMainFrame();
  rfh->DisableSwapOutTimerForTesting();

  // 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 SwapOut ACK was received (i.e., that we
  // didn't just simulate OnSwappedOut() due to the process erroneously going
  // away before the SwapOut ACK was received, as in https://crbug.com/867274).
  RenderProcessHostWatcher watcher(
      rfh->GetProcess(), RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
  auto swapout_ack_filter = base::MakeRefCounted<ObserveMessageFilter>(
      FrameMsgStart, FrameHostMsg_SwapOut_ACK::ID);
  rfh->GetProcess()->AddFilter(swapout_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(swapout_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 swap out timer on B1.
  root->child_at(0)->current_frame_host()->DisableSwapOutTimerForTesting();

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

  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_SwapoutACK.
  auto swapout_ack_filter_b = base::MakeRefCounted<DropMessageFilter>(
      FrameMsgStart, FrameHostMsg_SwapOut_ACK::ID);
  auto swapout_ack_filter_c = base::MakeRefCounted<DropMessageFilter>(
      FrameMsgStart, FrameHostMsg_SwapOut_ACK::ID);
  rfh_b->GetProcess()->AddFilter(swapout_ack_filter_b.get());
  rfh_c->GetProcess()->AddFilter(swapout_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->DisableSwapOutTimerForTesting();
  rfh_c->DisableSwapOutTimerForTesting();

  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->OnSwapOutACK();
  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 Swapout ACK. They will be called manually.
  auto swapout_ack_filter = base::MakeRefCounted<DropMessageFilter>(
      FrameMsgStart, FrameHostMsg_SwapOut_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(swapout_ack_filter.get());
  a1->GetProcess()->AddFilter(detach_filter_a.get());
  b1->GetProcess()->AddFilter(detach_filter_b.get());

  a1->DisableSwapOutTimerForTesting();
  // 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 SwapOutACK and deletes itself.
  a1->OnSwapOutACK();
  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 Swapout ACK.
  auto swapout_ack_filter = base::MakeRefCounted<DropMessageFilter>(
      FrameMsgStart, FrameHostMsg_SwapOut_ACK::ID);
  auto detach_filter = base::MakeRefCounted<DropMessageFilter>(
      FrameMsgStart, FrameHostMsg_Detach::ID);
  rfh_0->GetProcess()->AddFilter(swapout_ack_filter.get());
  rfh_0->GetProcess()->AddFilter(detach_filter.get());
  rfh_0->DisableSwapOutTimerForTesting();

  // 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->DisableSwapOutTimerForTesting();
  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->DisableSwapOutTimerForTesting();
  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::kUnloadHandler));
  EXPECT_TRUE(ExecJs(B2, "window.onunload = ()=>{};"));
  EXPECT_TRUE(B2->GetSuddenTerminationDisablerState(blink::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 SwapOut/Unload timeout to prevent the previous document from
  // being deleleted before it has finished running B2 unload handler.
  A1->DisableSwapOutTimerForTesting();
  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 SwapOut/Unload timeout to prevent the previous document from
  // being deleleted before it has finished running C3 unload handler.
  A1->DisableSwapOutTimerForTesting();
  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
