// Copyright 2014 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 <utility>
#include <vector>

#include "base/bind.h"
#include "base/command_line.h"
#include "base/feature_list.h"
#include "base/files/file_path.h"
#include "base/macros.h"
#include "base/path_service.h"
#include "base/run_loop.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task/post_task.h"
#include "chrome/browser/chrome_content_browser_client.h"
#include "chrome/browser/external_protocol/external_protocol_handler.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/renderer_context_menu/render_view_context_menu_browsertest_util.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/common/chrome_features.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/app_modal/javascript_app_modal_dialog.h"
#include "components/app_modal/native_app_modal_dialog.h"
#include "components/guest_view/browser/guest_view_base.h"
#include "components/guest_view/browser/guest_view_manager_delegate.h"
#include "components/guest_view/browser/test_guest_view_manager.h"
#include "components/spellcheck/spellcheck_buildflags.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/interstitial_page.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/common/content_features.h"
#include "content/public/common/referrer.h"
#include "content/public/common/service_names.mojom.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test_utils.h"
#include "content/public/test/test_navigation_observer.h"
#include "content/public/test/test_utils.h"
#include "extensions/browser/api/extensions_api_client.h"
#include "net/dns/mock_host_resolver.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "third_party/blink/public/platform/web_gesture_event.h"
#include "third_party/blink/public/platform/web_input_event.h"
#include "ui/display/display_switches.h"
#include "ui/events/base_event_utils.h"
#include "ui/gfx/geometry/point.h"
#include "url/gurl.h"

#if BUILDFLAG(ENABLE_SPELLCHECK)
#include "chrome/browser/spellchecker/spellcheck_factory.h"
#include "chrome/common/pref_names.h"
#include "components/prefs/pref_service.h"
#include "components/spellcheck/browser/pref_names.h"
#include "components/spellcheck/common/spellcheck.mojom.h"
#include "components/user_prefs/user_prefs.h"
#include "content/public/browser/browser_context.h"
#include "mojo/public/cpp/bindings/binding_set.h"
#include "services/service_manager/public/cpp/interface_provider.h"
#if BUILDFLAG(HAS_SPELLCHECK_PANEL)
#include "chrome/browser/spellchecker/test/spellcheck_content_browser_client.h"
#include "components/spellcheck/common/spellcheck_panel.mojom.h"
#endif  // BUILDFLAG(HAS_SPELLCHECK_PANEL)
#endif

using app_modal::JavaScriptAppModalDialog;

namespace {

class RedirectObserver : public content::WebContentsObserver {
 public:
  explicit RedirectObserver(content::WebContents* web_contents)
      : WebContentsObserver(web_contents),
        transition_(ui::PageTransition::PAGE_TRANSITION_LINK) {}

  void DidFinishNavigation(
      content::NavigationHandle* navigation_handle) override {
    if (!navigation_handle->HasCommitted())
      return;
    transition_ = navigation_handle->GetPageTransition();
    redirects_ = navigation_handle->GetRedirectChain();
  }

  void WebContentsDestroyed() override {
    // Make sure we don't close the tab while the observer is in scope.
    // See http://crbug.com/314036.
    FAIL() << "WebContents closed during navigation (http://crbug.com/314036).";
  }

  ui::PageTransition transition() const { return transition_; }
  const std::vector<GURL> redirects() const { return redirects_; }

 private:
  ui::PageTransition transition_;
  std::vector<GURL> redirects_;

  DISALLOW_COPY_AND_ASSIGN(RedirectObserver);
};

}  // namespace

class ChromeSitePerProcessTest : public InProcessBrowserTest {
 public:
  ChromeSitePerProcessTest() {}
  ~ChromeSitePerProcessTest() override {}

  void SetUpCommandLine(base::CommandLine* command_line) override {
    content::IsolateAllSitesForTesting(command_line);
  }

  void SetUpOnMainThread() override {
    host_resolver()->AddRule("*", "127.0.0.1");
    ASSERT_TRUE(embedded_test_server()->InitializeAndListen());
    content::SetupCrossSiteRedirector(embedded_test_server());

    // Serve from the root so that flash_object.html can load the swf file.
    // Needed for the PluginWithRemoteTopFrame test.
    base::FilePath test_data_dir;
    CHECK(base::PathService::Get(base::DIR_SOURCE_ROOT, &test_data_dir));
    embedded_test_server()->ServeFilesFromDirectory(test_data_dir);

    // Add content/test/data for cross_site_iframe_factory.html
    embedded_test_server()->ServeFilesFromSourceDirectory("content/test/data");

    embedded_test_server()->StartAcceptingConnections();
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(ChromeSitePerProcessTest);
};

class SitePerProcessHighDPIExpiredCertBrowserTest
    : public ChromeSitePerProcessTest {
 public:
  const double kDeviceScaleFactor = 2.0;

  SitePerProcessHighDPIExpiredCertBrowserTest()
      : https_server_expired_(net::EmbeddedTestServer::TYPE_HTTPS) {
    https_server_expired_.SetSSLConfig(net::EmbeddedTestServer::CERT_EXPIRED);
  }

  net::EmbeddedTestServer* expired_cert_test_server() {
    return &https_server_expired_;
  }

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

  void SetUpOnMainThread() override {
    ChromeSitePerProcessTest::SetUpOnMainThread();
    ASSERT_TRUE(https_server_expired_.Start());
  }

 private:
  net::EmbeddedTestServer https_server_expired_;
};

double GetFrameDeviceScaleFactor(const content::ToRenderFrameHost& adapter) {
  double device_scale_factor;
  const char kGetFrameDeviceScaleFactor[] =
      "window.domAutomationController.send(window.devicePixelRatio);";
  EXPECT_TRUE(ExecuteScriptAndExtractDouble(adapter, kGetFrameDeviceScaleFactor,
                                            &device_scale_factor));
  return device_scale_factor;
}

// Flaky on Windows 10. http://crbug.com/700150
#if defined(OS_WIN)
#define MAYBE_InterstitialLoadsWithCorrectDeviceScaleFactor \
  DISABLED_InterstitialLoadsWithCorrectDeviceScaleFactor
#else
#define MAYBE_InterstitialLoadsWithCorrectDeviceScaleFactor \
  InterstitialLoadsWithCorrectDeviceScaleFactor
#endif
IN_PROC_BROWSER_TEST_F(SitePerProcessHighDPIExpiredCertBrowserTest,
                       MAYBE_InterstitialLoadsWithCorrectDeviceScaleFactor) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)"));
  ui_test_utils::NavigateToURL(browser(), main_url);

  EXPECT_EQ(SitePerProcessHighDPIExpiredCertBrowserTest::kDeviceScaleFactor,
            GetFrameDeviceScaleFactor(
                browser()->tab_strip_model()->GetActiveWebContents()));

  // Navigate to page with expired cert.
  GURL bad_cert_url(
      expired_cert_test_server()->GetURL("c.com", "/title1.html"));
  ui_test_utils::NavigateToURL(browser(), bad_cert_url);
  content::WebContents* active_web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();

  content::RenderFrameHost* interstitial_frame_host;

  if (base::FeatureList::IsEnabled(features::kSSLCommittedInterstitials)) {
    interstitial_frame_host = active_web_contents->GetMainFrame();
  } else {
    WaitForInterstitialAttach(active_web_contents);
    EXPECT_TRUE(active_web_contents->ShowingInterstitialPage());

    // Here we check the device scale factor in use via the interstitial's
    // RenderFrameHost; doing the check directly via the 'active web contents'
    // does not give us the device scale factor for the interstitial.
    interstitial_frame_host =
        active_web_contents->GetInterstitialPage()->GetMainFrame();
  }

  EXPECT_EQ(SitePerProcessHighDPIExpiredCertBrowserTest::kDeviceScaleFactor,
            GetFrameDeviceScaleFactor(interstitial_frame_host));
}

// Verify that browser shutdown path works correctly when there's a
// RenderFrameProxyHost for a child frame.
IN_PROC_BROWSER_TEST_F(ChromeSitePerProcessTest, RenderFrameProxyHostShutdown) {
  GURL main_url(embedded_test_server()->GetURL(
        "a.com",
        "/frame_tree/page_with_two_frames_remote_and_local.html"));
  ui_test_utils::NavigateToURL(browser(), main_url);
}

// Verify that origin replication allows JS access to localStorage, database,
// and FileSystem APIs.  These features involve a check on the
// WebSecurityOrigin of the topmost WebFrame in ContentSettingsObserver, and
// this test ensures this check works when the top frame is remote.
IN_PROC_BROWSER_TEST_F(ChromeSitePerProcessTest,
                       OriginReplicationAllowsAccessToStorage) {
  // Navigate to a page with a same-site iframe.
  GURL main_url(embedded_test_server()->GetURL("a.com", "/iframe.html"));
  ui_test_utils::NavigateToURL(browser(), main_url);

  // Navigate subframe cross-site.
  content::WebContents* active_web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  GURL cross_site_url(embedded_test_server()->GetURL("b.com", "/title2.html"));
  EXPECT_TRUE(NavigateIframeToURL(active_web_contents, "test", cross_site_url));

  // Find the subframe's RenderFrameHost.
  content::RenderFrameHost* frame_host =
      ChildFrameAt(active_web_contents->GetMainFrame(), 0);
  ASSERT_TRUE(frame_host);
  EXPECT_EQ(cross_site_url, frame_host->GetLastCommittedURL());
  EXPECT_TRUE(frame_host->IsCrossProcessSubframe());

  // Check that JS storage APIs can be accessed successfully.
  EXPECT_TRUE(
      content::ExecuteScript(frame_host, "localStorage['foo'] = 'bar'"));
  std::string result;
  EXPECT_TRUE(ExecuteScriptAndExtractString(
      frame_host, "window.domAutomationController.send(localStorage['foo']);",
      &result));
  EXPECT_EQ(result, "bar");
  bool is_object_created = false;
  EXPECT_TRUE(ExecuteScriptAndExtractBool(
      frame_host,
      "window.domAutomationController.send(!!indexedDB.open('testdb', 2));",
      &is_object_created));
  EXPECT_TRUE(is_object_created);
  is_object_created = false;
  EXPECT_TRUE(ExecuteScriptAndExtractBool(
      frame_host,
      "window.domAutomationController.send(!!openDatabase("
      "'foodb', '1.0', 'Test DB', 1024));",
      &is_object_created));
  EXPECT_TRUE(is_object_created);
  EXPECT_TRUE(ExecuteScript(frame_host,
                            "window.webkitRequestFileSystem("
                            "window.TEMPORARY, 1024, function() {});"));
}

// Ensure that creating a plugin in a cross-site subframe doesn't crash.  This
// involves querying content settings from the renderer process and using the
// top frame's origin as one of the parameters.  See https://crbug.com/426658.
IN_PROC_BROWSER_TEST_F(ChromeSitePerProcessTest, PluginWithRemoteTopFrame) {
  GURL main_url(
      embedded_test_server()->GetURL("a.com", "/chrome/test/data/iframe.html"));
  ui_test_utils::NavigateToURL(browser(), main_url);

  // Navigate subframe to a page with a Flash object.
  content::WebContents* active_web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  GURL frame_url =
      embedded_test_server()->GetURL("b.com",
                                     "/chrome/test/data/flash_object.html");

  // Ensure the page finishes loading without crashing.
  EXPECT_TRUE(NavigateIframeToURL(active_web_contents, "test", frame_url));
}

// Check that window.focus works for cross-process popups.
IN_PROC_BROWSER_TEST_F(ChromeSitePerProcessTest, PopupWindowFocus) {
  GURL main_url(embedded_test_server()->GetURL("/page_with_focus_events.html"));
  ui_test_utils::NavigateToURL(browser(), main_url);

  // Set window.name on main page.  This will be used to identify the page
  // later when it sends messages from its focus/blur events.
  content::WebContents* web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  EXPECT_TRUE(
      ExecuteScriptWithoutUserGesture(web_contents, "window.name = 'main'"));

  // Open a popup for a cross-site page.
  GURL popup_url =
      embedded_test_server()->GetURL("foo.com", "/page_with_focus_events.html");
  content::TestNavigationObserver popup_observer(nullptr);
  popup_observer.StartWatchingNewWebContents();
  EXPECT_TRUE(ExecuteScript(web_contents,
                            "openPopup('" + popup_url.spec() + "','popup')"));
  popup_observer.Wait();
  ASSERT_EQ(2, browser()->tab_strip_model()->count());
  content::WebContents* popup =
      browser()->tab_strip_model()->GetActiveWebContents();
  EXPECT_EQ(popup_url, popup->GetLastCommittedURL());
  EXPECT_NE(popup, web_contents);

  // Switch focus to the original tab, since opening a popup also focused it.
  web_contents->GetDelegate()->ActivateContents(web_contents);
  EXPECT_EQ(web_contents, browser()->tab_strip_model()->GetActiveWebContents());

  // Focus the popup via window.focus(), this needs user gesture.
  content::DOMMessageQueue queue;
  ExecuteScriptAsync(web_contents, "focusPopup()");

  // Wait for main page to lose focus and for popup to gain focus.  Each event
  // will send a message, and the two messages can arrive in any order.
  std::string status;
  bool main_lost_focus = false;
  bool popup_got_focus = false;
  while (queue.WaitForMessage(&status)) {
    if (status == "\"main-lost-focus\"")
      main_lost_focus = true;
    if (status == "\"popup-got-focus\"")
      popup_got_focus = true;
    if (main_lost_focus && popup_got_focus)
      break;
  }

  // The popup should be focused now.
  EXPECT_EQ(popup, browser()->tab_strip_model()->GetActiveWebContents());
}

// Verify that ctrl-click of an anchor targeting a remote frame works (i.e. that
// it opens the link in a new tab).  See also https://crbug.com/647772.
IN_PROC_BROWSER_TEST_F(ChromeSitePerProcessTest,
                       AnchorCtrlClickWhenTargetIsCrossSite) {
  // Navigate to anchor_targeting_remote_frame.html.
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/frame_tree/anchor_targeting_remote_frame.html"));
  ui_test_utils::NavigateToURL(browser(), main_url);

  // Verify that there is only 1 active tab (with the right contents committed).
  EXPECT_EQ(0, browser()->tab_strip_model()->active_index());
  content::WebContents* main_contents =
      browser()->tab_strip_model()->GetWebContentsAt(0);
  EXPECT_EQ(main_url, main_contents->GetLastCommittedURL());

  // Ctrl-click the anchor/link in the page.
  content::WebContentsAddedObserver new_tab_observer;
#if defined(OS_MACOSX)
  std::string new_tab_click_script = "simulateClick({ metaKey: true });";
#else
  std::string new_tab_click_script = "simulateClick({ ctrlKey: true });";
#endif
  EXPECT_TRUE(ExecuteScript(main_contents, new_tab_click_script));

  // Wait for a new tab to appear (the whole point of this test).
  content::WebContents* new_contents = new_tab_observer.GetWebContents();

  // Verify that the new tab has the right contents and is in the right, new
  // place in the tab strip.
  EXPECT_TRUE(WaitForLoadStop(new_contents));
  EXPECT_EQ(2, browser()->tab_strip_model()->count());
  EXPECT_EQ(new_contents, browser()->tab_strip_model()->GetWebContentsAt(1));
  GURL expected_url(embedded_test_server()->GetURL("c.com", "/title1.html"));
  EXPECT_EQ(expected_url, new_contents->GetLastCommittedURL());
}

namespace {

// This class observes a WebContents for a navigation to an extension scheme to
// finish.
class NavigationToExtensionSchemeObserver
    : public content::WebContentsObserver {
 public:
  explicit NavigationToExtensionSchemeObserver(content::WebContents* contents)
      : content::WebContentsObserver(contents),
        extension_loaded_(contents->GetLastCommittedURL().SchemeIs(
            extensions::kExtensionScheme)) {}

  void Wait() {
    if (extension_loaded_)
      return;
    message_loop_runner_ = new content::MessageLoopRunner();
    message_loop_runner_->Run();
  }

 private:
  void DidFinishNavigation(content::NavigationHandle* handle) override {
    if (!handle->GetURL().SchemeIs(extensions::kExtensionScheme) ||
        !handle->HasCommitted() || handle->IsErrorPage())
      return;
    extension_loaded_ = true;
    message_loop_runner_->Quit();
  }

  bool extension_loaded_;
  scoped_refptr<content::MessageLoopRunner> message_loop_runner_;

  DISALLOW_COPY_AND_ASSIGN(NavigationToExtensionSchemeObserver);
};

}  // namespace

class ChromeSitePerProcessPDFTest : public ChromeSitePerProcessTest {
 public:
  ChromeSitePerProcessPDFTest() : test_guest_view_manager_(nullptr) {}
  ~ChromeSitePerProcessPDFTest() override {}

  void SetUpOnMainThread() override {
    ChromeSitePerProcessTest::SetUpOnMainThread();
    guest_view::GuestViewManager::set_factory_for_testing(&factory_);
    test_guest_view_manager_ = static_cast<guest_view::TestGuestViewManager*>(
        guest_view::GuestViewManager::CreateWithDelegate(
            browser()->profile(),
            extensions::ExtensionsAPIClient::Get()
                ->CreateGuestViewManagerDelegate(browser()->profile())));
  }

 protected:
  guest_view::TestGuestViewManager* test_guest_view_manager() const {
    return test_guest_view_manager_;
  }

  void ResendGestureToEmbedder(const std::string& host_name) {
    content::WebContents* guest_web_contents = SetupGuestWebContents(host_name);
    blink::WebGestureEvent event(blink::WebInputEvent::kGestureScrollUpdate,
                                 blink::WebInputEvent::kNoModifiers,
                                 ui::EventTimeForNow(),
                                 blink::kWebGestureDeviceTouchscreen);
    // This should not crash.
    content::ResendGestureScrollUpdateToEmbedder(guest_web_contents, event);
  }

  void SendSyntheticTapGesture(const std::string& host_name) {
    content::WebContents* guest_web_contents = SetupGuestWebContents(host_name);
    // Observe navigations in guest to find out when navigation to the (PDF)
    // extension commits. It will be used as an indicator that BrowserPlugin
    // has attached.
    NavigationToExtensionSchemeObserver navigation_observer(guest_web_contents);

    // Before sending the mouse clicks, we need to make sure the BrowserPlugin
    // has attached, which happens before navigating the guest to the PDF
    // extension. When attached, the window rects are updated and the context
    // menu position can be properly calculated.
    navigation_observer.Wait();

    // This should not crash
    MaybeSendSyntheticTapGesture(guest_web_contents);
  }

 private:
  content::WebContents* SetupGuestWebContents(const std::string& host_name) {
    // Navigate to a page with an <iframe>.
    GURL main_url(embedded_test_server()->GetURL("a.com", "/iframe.html"));
    ui_test_utils::NavigateToURL(browser(), main_url);

    // Initially, no guests are created.
    EXPECT_EQ(0U, test_guest_view_manager()->num_guests_created());

    // Navigate subframe to a cross-site page with an embedded PDF.
    content::WebContents* active_web_contents =
        browser()->tab_strip_model()->GetActiveWebContents();
    GURL frame_url = embedded_test_server()->GetURL(
        host_name, "/page_with_embedded_pdf.html");

    // Ensure the page finishes loading without crashing.
    EXPECT_TRUE(NavigateIframeToURL(active_web_contents, "test", frame_url));

    // Wait until the guest for PDF is created.
    content::WebContents* guest_web_contents =
        test_guest_view_manager()->WaitForSingleGuestCreated();

    ResetTouchAction(
        guest_view::GuestViewBase::FromWebContents(guest_web_contents)
            ->GetOwnerRenderWidgetHost());
    return guest_web_contents;
  }

  guest_view::TestGuestViewManagerFactory factory_;
  guest_view::TestGuestViewManager* test_guest_view_manager_;

  DISALLOW_COPY_AND_ASSIGN(ChromeSitePerProcessPDFTest);
};

// Regression test for https://crbug.com/870536. Ensure that the test doesn't
// crash when a GestureScrollBegin is sent to BrowserPluginGuest, while the
// GestureScrollUpdates are sent to its embedder. For both non-OOPIF and OOPIF
// cases.
IN_PROC_BROWSER_TEST_F(ChromeSitePerProcessPDFTest,
                       ResendGestureToEmbedderOOPIF) {
  ResendGestureToEmbedder("b.com");
}

IN_PROC_BROWSER_TEST_F(ChromeSitePerProcessPDFTest,
                       ResendGestureToEmbedderNonOOPIF) {
  ResendGestureToEmbedder("a.com");
}

// Regression test for https://crbug.com/873211. MaybeSendSyntheticTapGesture
// can be called with no touch action set in TouchActionFilter and results in
// a crash.
IN_PROC_BROWSER_TEST_F(ChromeSitePerProcessPDFTest,
                       SendSyntheticTapGestureOOPIF) {
  SendSyntheticTapGesture("b.com");
}

IN_PROC_BROWSER_TEST_F(ChromeSitePerProcessPDFTest,
                       SendSyntheticTapGestureNonOOPIF) {
  SendSyntheticTapGesture("a.com");
}

// This test verifies that when navigating an OOPIF to a page with <embed>-ed
// PDF, the guest is properly created, and by removing the embedder frame, the
// guest is properly destroyed (https://crbug.com/649856).
IN_PROC_BROWSER_TEST_F(ChromeSitePerProcessPDFTest,
                       EmbeddedPDFInsideCrossOriginFrame) {
  // Navigate to a page with an <iframe>.
  GURL main_url(embedded_test_server()->GetURL("a.com", "/iframe.html"));
  ui_test_utils::NavigateToURL(browser(), main_url);

  // Initially, no guests are created.
  EXPECT_EQ(0U, test_guest_view_manager()->num_guests_created());

  // Navigate subframe to a cross-site page with an embedded PDF.
  content::WebContents* active_web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  GURL frame_url =
      embedded_test_server()->GetURL("b.com", "/page_with_embedded_pdf.html");

  // Ensure the page finishes loading without crashing.
  EXPECT_TRUE(NavigateIframeToURL(active_web_contents, "test", frame_url));

  // Wait until the guest for PDF is created.
  content::WebContents* guest_web_contents =
      test_guest_view_manager()->WaitForSingleGuestCreated();

  // Now detach the frame and observe that the guest is destroyed.
  content::WebContentsDestroyedWatcher observer(guest_web_contents);
  EXPECT_TRUE(ExecuteScript(
      active_web_contents,
      "document.body.removeChild(document.querySelector('iframe'));"));
  observer.Wait();
  EXPECT_EQ(0U, test_guest_view_manager()->GetNumGuestsActive());
}

// A helper class to verify that a "mailto:" external protocol request succeeds.
class MailtoExternalProtocolHandlerDelegate
    : public ExternalProtocolHandler::Delegate {
 public:
  bool has_triggered_external_protocol() {
    return has_triggered_external_protocol_;
  }

  const GURL& external_protocol_url() { return external_protocol_url_; }

  content::WebContents* web_contents() { return web_contents_; }

  void RunExternalProtocolDialog(const GURL& url,
                                 int render_process_host_id,
                                 int routing_id,
                                 ui::PageTransition page_transition,
                                 bool has_user_gesture) override {}

  scoped_refptr<shell_integration::DefaultProtocolClientWorker>
  CreateShellWorker(
      const shell_integration::DefaultWebClientWorkerCallback& callback,
      const std::string& protocol) override {
    return new shell_integration::DefaultProtocolClientWorker(callback,
                                                              protocol);
  }

  ExternalProtocolHandler::BlockState GetBlockState(const std::string& scheme,
                                                    Profile* profile) override {
    return ExternalProtocolHandler::DONT_BLOCK;
  }

  void BlockRequest() override {}

  void LaunchUrlWithoutSecurityCheck(
      const GURL& url,
      content::WebContents* web_contents) override {
    external_protocol_url_ = url;
    web_contents_ = web_contents;
    has_triggered_external_protocol_ = true;
    if (message_loop_runner_)
      message_loop_runner_->Quit();
  }

  void Wait() {
    if (!has_triggered_external_protocol_) {
      message_loop_runner_ = new content::MessageLoopRunner();
      message_loop_runner_->Run();
    }
  }

  void FinishedProcessingCheck() override {}

 private:
  bool has_triggered_external_protocol_ = false;
  GURL external_protocol_url_;
  content::WebContents* web_contents_ = nullptr;
  scoped_refptr<content::MessageLoopRunner> message_loop_runner_;
};

// This test is not run on ChromeOS because it registers a custom handler (see
// ProtocolHandlerRegistry::InstallDefaultsForChromeOS), and handles mailto:
// navigations before getting to external protocol code.
#if defined(OS_CHROMEOS)
#define MAYBE_LaunchExternalProtocolFromSubframe \
  DISABLED_LaunchExternalProtocolFromSubframe
#else
#define MAYBE_LaunchExternalProtocolFromSubframe \
  LaunchExternalProtocolFromSubframe
#endif
// This test verifies that external protocol requests succeed when made from an
// OOPIF (https://crbug.com/668289).
IN_PROC_BROWSER_TEST_F(ChromeSitePerProcessTest,
                       MAYBE_LaunchExternalProtocolFromSubframe) {
  GURL start_url(embedded_test_server()->GetURL("a.com", "/title1.html"));

  ui_test_utils::NavigateToURL(browser(), start_url);

  // Navigate to a page with a cross-site iframe that triggers a mailto:
  // external protocol request.
  // The test did not start by navigating to this URL because that would mask
  // the bug.  Instead, navigating the main frame to another page will cause a
  // cross-process transfer, which will avoid a situation where the OOPIF's
  // swapped-out RenderViewHost and the main frame's active RenderViewHost get
  // the same routing IDs, causing an accidental success.
  GURL mailto_main_frame_url(
      embedded_test_server()->GetURL("b.com", "/iframe.html"));

  ui_test_utils::NavigateToURL(browser(), mailto_main_frame_url);

  MailtoExternalProtocolHandlerDelegate delegate;
  ExternalProtocolHandler::SetDelegateForTesting(&delegate);

  GURL mailto_subframe_url(
      embedded_test_server()->GetURL("c.com", "/page_with_mailto.html"));
  content::WebContents* active_web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  EXPECT_TRUE(
      NavigateIframeToURL(active_web_contents, "test", mailto_subframe_url));

  delegate.Wait();

  EXPECT_TRUE(delegate.has_triggered_external_protocol());
  EXPECT_EQ(delegate.external_protocol_url(), GURL("mailto:mail@example.org"));
  EXPECT_EQ(active_web_contents, delegate.web_contents());
  ExternalProtocolHandler::SetDelegateForTesting(nullptr);
}

// Verify that a popup can be opened after navigating a remote frame.  This has
// to be a chrome/ test to ensure that the popup blocker doesn't block the
// popup.  See https://crbug.com/670770.
IN_PROC_BROWSER_TEST_F(ChromeSitePerProcessTest,
                       NavigateRemoteFrameAndOpenPopup) {
  // Start on a page with an <iframe>.
  GURL main_url(embedded_test_server()->GetURL("a.com", "/iframe.html"));
  ui_test_utils::NavigateToURL(browser(), main_url);

  // Navigate the iframe cross-site.
  content::WebContents* active_web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  GURL frame_url(embedded_test_server()->GetURL("b.com", "/title1.html"));
  EXPECT_TRUE(NavigateIframeToURL(active_web_contents, "test", frame_url));

  // Run a script in the parent frame to (1) navigate iframe to another URL,
  // and (2) open a popup.  Note that ExecuteScript will run this with a user
  // gesture, so both steps should succeed.
  frame_url = embedded_test_server()->GetURL("c.com", "/title1.html");
  content::TestNavigationObserver popup_observer(nullptr);
  popup_observer.StartWatchingNewWebContents();
  bool popup_handle_is_valid = false;
  EXPECT_TRUE(ExecuteScriptAndExtractBool(
      active_web_contents,
      "document.querySelector('iframe').src = '" + frame_url.spec() + "';\n"
      "var w = window.open('about:blank');\n"
      "window.domAutomationController.send(!!w);\n",
      &popup_handle_is_valid));
  popup_observer.Wait();

  // The popup shouldn't be blocked.
  EXPECT_TRUE(popup_handle_is_valid);
  ASSERT_EQ(2, browser()->tab_strip_model()->count());
}

// Ensure that a transferred cross-process navigation does not generate
// DidStopLoading events until the navigation commits.  If it did, then
// ui_test_utils::NavigateToURL would proceed before the URL had committed.
// http://crbug.com/243957.
IN_PROC_BROWSER_TEST_F(ChromeSitePerProcessTest,
                       NoStopDuringTransferUntilCommit) {
  GURL init_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
  ui_test_utils::NavigateToURL(browser(), init_url);

  // Navigate to a same-site page that redirects, causing a transfer.
  content::WebContents* contents =
      browser()->tab_strip_model()->GetActiveWebContents();

  // Create a RedirectObserver that goes away before we close the tab.
  {
    RedirectObserver redirect_observer(contents);
    GURL dest_url(embedded_test_server()->GetURL("b.com", "/title2.html"));
    GURL redirect_url(embedded_test_server()->GetURL(
        "c.com", "/server-redirect?" + dest_url.spec()));
    ui_test_utils::NavigateToURL(browser(), redirect_url);

    // We should immediately see the new committed entry.
    EXPECT_FALSE(contents->GetController().GetPendingEntry());
    EXPECT_EQ(dest_url,
              contents->GetController().GetLastCommittedEntry()->GetURL());

    // We should keep track of the original request URL, redirect chain, and
    // page transition type during a transfer, since these are necessary for
    // history autocomplete to work.
    EXPECT_EQ(redirect_url, contents->GetController()
                                .GetLastCommittedEntry()
                                ->GetOriginalRequestURL());
    EXPECT_EQ(2U, redirect_observer.redirects().size());
    EXPECT_EQ(redirect_url, redirect_observer.redirects().at(0));
    EXPECT_EQ(dest_url, redirect_observer.redirects().at(1));
    EXPECT_TRUE(ui::PageTransitionCoreTypeIs(redirect_observer.transition(),
                                             ui::PAGE_TRANSITION_TYPED));
  }
}

// Tests that a cross-process redirect will only cause the beforeunload
// handler to run once.
IN_PROC_BROWSER_TEST_F(ChromeSitePerProcessTest,
                       SingleBeforeUnloadAfterRedirect) {
  // Navigate to a page with a beforeunload handler.
  GURL url(embedded_test_server()->GetURL("a.com", "/beforeunload.html"));
  ui_test_utils::NavigateToURL(browser(), url);
  content::WebContents* contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  content::PrepContentsForBeforeUnloadTest(contents);

  // Navigate to a URL that redirects to another process and approve the
  // beforeunload dialog that pops up.
  content::TestNavigationObserver nav_observer(contents);
  GURL dest_url(embedded_test_server()->GetURL("b.com", "/title1.html"));
  GURL redirect_url(embedded_test_server()->GetURL(
      "c.com", "/server-redirect?" + dest_url.spec()));
  browser()->OpenURL(content::OpenURLParams(redirect_url, content::Referrer(),
                                            WindowOpenDisposition::CURRENT_TAB,
                                            ui::PAGE_TRANSITION_TYPED, false));
  JavaScriptAppModalDialog* alert = ui_test_utils::WaitForAppModalDialog();
  EXPECT_TRUE(alert->is_before_unload_dialog());
  alert->native_dialog()->AcceptAppModalDialog();
  nav_observer.WaitForNavigationFinished();
}

IN_PROC_BROWSER_TEST_F(ChromeSitePerProcessTest, PrintIgnoredInUnloadHandler) {
  ui_test_utils::NavigateToURL(
      browser(), GURL(embedded_test_server()->GetURL("a.com", "/title1.html")));

  content::WebContents* active_web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();

  // Create 2 iframes and navigate them to b.com.
  EXPECT_TRUE(ExecuteScript(active_web_contents,
                            "var i = document.createElement('iframe'); i.id = "
                            "'child-0'; document.body.appendChild(i);"));
  EXPECT_TRUE(ExecuteScript(active_web_contents,
                            "var i = document.createElement('iframe'); i.id = "
                            "'child-1'; document.body.appendChild(i);"));
  EXPECT_TRUE(NavigateIframeToURL(
      active_web_contents, "child-0",
      GURL(embedded_test_server()->GetURL("b.com", "/title1.html"))));
  EXPECT_TRUE(NavigateIframeToURL(
      active_web_contents, "child-1",
      GURL(embedded_test_server()->GetURL("b.com", "/title1.html"))));

  content::RenderFrameHost* child_0 =
      ChildFrameAt(active_web_contents->GetMainFrame(), 0);
  content::RenderFrameHost* child_1 =
      ChildFrameAt(active_web_contents->GetMainFrame(), 1);

  // Add an unload handler that calls print() to child-0 iframe.
  EXPECT_TRUE(ExecuteScript(
      child_0, "document.body.onunload = function() { print(); }"));

  // Transfer child-0 to a new process hosting c.com.
  EXPECT_TRUE(NavigateIframeToURL(
      active_web_contents, "child-0",
      GURL(embedded_test_server()->GetURL("c.com", "/title1.html"))));

  // Check that b.com's process is still alive.
  bool renderer_alive = false;
  EXPECT_TRUE(ExecuteScriptAndExtractBool(
      child_1, "window.domAutomationController.send(true);", &renderer_alive));
  EXPECT_TRUE(renderer_alive);
}

// Ensure that when a window closes itself via window.close(), its process does
// not get destroyed if there's a pending cross-process navigation in the same
// process from another tab.  See https://crbug.com/799399.
IN_PROC_BROWSER_TEST_F(ChromeSitePerProcessTest,
                       ClosePopupWithPendingNavigationInOpener) {
  // Start on a.com and open a popup to b.com.
  GURL opener_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
  ui_test_utils::NavigateToURL(browser(), opener_url);
  content::WebContents* opener_contents =
      browser()->tab_strip_model()->GetActiveWebContents();

  GURL popup_url(embedded_test_server()->GetURL("b.com", "/title1.html"));
  content::TestNavigationObserver popup_observer(nullptr);
  popup_observer.StartWatchingNewWebContents();
  EXPECT_TRUE(ExecuteScript(opener_contents,
                            "window.open('" + popup_url.spec() + "');"));
  popup_observer.Wait();
  ASSERT_EQ(2, browser()->tab_strip_model()->count());
  content::WebContents* popup_contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  ASSERT_NE(opener_contents, popup_contents);

  // This test technically performs a tab-under navigation. This will be blocked
  // if the tab-under blocking feature is enabled. Simulate clicking the opener
  // here to avoid that behavior.
  content::SimulateMouseClickAt(opener_contents, 0 /* modifiers */,
                                blink::WebMouseEvent::Button::kLeft,
                                gfx::Point(50, 50));

  // From the popup, start a navigation in the opener to b.com, but don't
  // commit.
  GURL b_url(embedded_test_server()->GetURL("b.com", "/title2.html"));
  content::TestNavigationManager manager(opener_contents, b_url);
  EXPECT_TRUE(
      ExecuteScript(popup_contents, "opener.location='" + b_url.spec() + "';"));

  // Close the popup.  This should *not* kill the b.com process, as it still
  // has a pending navigation in the opener window.
  content::RenderProcessHost* b_com_rph =
      popup_contents->GetMainFrame()->GetProcess();
  content::WebContentsDestroyedWatcher destroyed_watcher(popup_contents);
  EXPECT_TRUE(ExecuteScript(popup_contents, "window.close();"));
  destroyed_watcher.Wait();
  EXPECT_TRUE(b_com_rph->IsInitializedAndNotDead());

  // Resume the pending navigation in the original tab and ensure it finishes
  // loading successfully.
  manager.WaitForNavigationFinished();
  EXPECT_EQ(b_url, opener_contents->GetMainFrame()->GetLastCommittedURL());
}

#if BUILDFLAG(ENABLE_SPELLCHECK)
// Class to sniff incoming spellcheck Mojo SpellCheckHost messages.
class MockSpellCheckHost : spellcheck::mojom::SpellCheckHost {
 public:
  explicit MockSpellCheckHost(content::RenderProcessHost* process_host)
      : process_host_(process_host), binding_(this) {}
  ~MockSpellCheckHost() override {}

  content::RenderProcessHost* process_host() const { return process_host_; }

  const base::string16& text() const { return text_; }

  bool HasReceivedText() const { return text_received_; }

  void Wait() {
    if (text_received_)
      return;

    base::RunLoop run_loop;
    quit_ = run_loop.QuitClosure();
    run_loop.Run();
  }

  void WaitUntilTimeout() {
    if (text_received_)
      return;

    auto ui_task_runner = base::CreateSingleThreadTaskRunnerWithTraits(
        {content::BrowserThread::UI});
    ui_task_runner->PostDelayedTask(
        FROM_HERE,
        base::BindOnce(&MockSpellCheckHost::Timeout, base::Unretained(this)),
        base::TimeDelta::FromSeconds(1));

    base::RunLoop run_loop;
    quit_ = run_loop.QuitClosure();
    run_loop.Run();
  }

  void SpellCheckHostRequest(spellcheck::mojom::SpellCheckHostRequest request) {
    EXPECT_FALSE(binding_.is_bound());
    binding_.Bind(std::move(request));
  }

 private:
  void TextReceived(const base::string16& text) {
    text_received_ = true;
    text_ = text;
    binding_.Close();
    if (quit_)
      std::move(quit_).Run();
  }

  void Timeout() {
    if (quit_)
      std::move(quit_).Run();
  }

  // spellcheck::mojom::SpellCheckHost:
  void RequestDictionary() override {}
  void NotifyChecked(const base::string16& word, bool misspelled) override {}

#if !BUILDFLAG(USE_BROWSER_SPELLCHECKER)
  void CallSpellingService(const base::string16& text,
                           CallSpellingServiceCallback callback) override {
    DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
    std::move(callback).Run(true, std::vector<SpellCheckResult>());
    TextReceived(text);
  }
#endif

#if BUILDFLAG(USE_BROWSER_SPELLCHECKER)
  void RequestTextCheck(const base::string16& text,
                        int route_id,
                        RequestTextCheckCallback callback) override {
    DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
    std::move(callback).Run(std::vector<SpellCheckResult>());
    TextReceived(text);
  }

  void ToggleSpellCheck(bool, bool) override {}
  void CheckSpelling(const base::string16& word,
                     int,
                     CheckSpellingCallback) override {}
  void FillSuggestionList(const base::string16& word,
                          FillSuggestionListCallback) override {}
#endif

  content::RenderProcessHost* process_host_;
  bool text_received_ = false;
  base::string16 text_;
  mojo::Binding<spellcheck::mojom::SpellCheckHost> binding_;
  base::OnceClosure quit_;

  DISALLOW_COPY_AND_ASSIGN(MockSpellCheckHost);
};

class TestBrowserClientForSpellCheck : public ChromeContentBrowserClient {
 public:
  TestBrowserClientForSpellCheck() = default;

  // ContentBrowserClient overrides.
  void OverrideOnBindInterface(
      const service_manager::BindSourceInfo& remote_info,
      const std::string& name,
      mojo::ScopedMessagePipeHandle* handle) override {
    if (name != spellcheck::mojom::SpellCheckHost::Name_)
      return;

    spellcheck::mojom::SpellCheckHostRequest request(std::move(*handle));

    // Override the default SpellCheckHost interface.
    auto ui_task_runner = base::CreateSingleThreadTaskRunnerWithTraits(
        {content::BrowserThread::UI});
    ui_task_runner->PostTask(
        FROM_HERE,
        base::BindOnce(
            &TestBrowserClientForSpellCheck::BindSpellCheckHostRequest,
            base::Unretained(this), std::move(request), remote_info));
  }

  // Retrieves the registered MockSpellCheckHost for the given
  // RenderProcessHost. It will return nullptr if the RenderProcessHost was
  // initialized while a different instance of ContentBrowserClient was in
  // action.
  MockSpellCheckHost* GetSpellCheckHostForProcess(
      content::RenderProcessHost* process_host) const {
    for (auto& spell_check_host : spell_check_hosts_) {
      if (spell_check_host->process_host() == process_host)
        return spell_check_host.get();
    }
    return nullptr;
  }

  void RunUntilBind() {
    if (spell_check_hosts_.size())
      return;

    base::RunLoop run_loop;
    quit_on_bind_closure_ = run_loop.QuitClosure();
    run_loop.Run();
  }

  void RunUntilBindOrTimeout() {
    if (spell_check_hosts_.size())
      return;

    auto ui_task_runner = base::CreateSingleThreadTaskRunnerWithTraits(
        {content::BrowserThread::UI});
    ui_task_runner->PostDelayedTask(
        FROM_HERE,
        base::BindOnce(&TestBrowserClientForSpellCheck::Timeout,
                       base::Unretained(this)),
        base::TimeDelta::FromSeconds(1));

    base::RunLoop run_loop;
    quit_on_bind_closure_ = run_loop.QuitClosure();
    run_loop.Run();
  }

 private:
  void BindSpellCheckHostRequest(
      spellcheck::mojom::SpellCheckHostRequest request,
      const service_manager::BindSourceInfo& source_info) {
    content::RenderProcessHost* host =
        content::RenderProcessHost::FromRendererInstanceId(
            source_info.identity.instance_id());
    auto spell_check_host = std::make_unique<MockSpellCheckHost>(host);
    spell_check_host->SpellCheckHostRequest(std::move(request));
    spell_check_hosts_.push_back(std::move(spell_check_host));
    if (quit_on_bind_closure_)
      std::move(quit_on_bind_closure_).Run();
  }

  void Timeout() {
    if (quit_on_bind_closure_)
      std::move(quit_on_bind_closure_).Run();
  }

  base::OnceClosure quit_on_bind_closure_;
  std::vector<std::unique_ptr<MockSpellCheckHost>> spell_check_hosts_;

  DISALLOW_COPY_AND_ASSIGN(TestBrowserClientForSpellCheck);
};

// Tests that spelling in out-of-process subframes is checked.
// See crbug.com/638361 for details.
IN_PROC_BROWSER_TEST_F(ChromeSitePerProcessTest, OOPIFSpellCheckTest) {
  TestBrowserClientForSpellCheck browser_client;
  content::ContentBrowserClient* old_browser_client =
      content::SetBrowserClientForTesting(&browser_client);

  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/page_with_contenteditable_in_cross_site_subframe.html"));
  ui_test_utils::NavigateToURL(browser(), main_url);
  browser_client.RunUntilBind();

  content::WebContents* web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  content::RenderFrameHost* cross_site_subframe =
      ChildFrameAt(web_contents->GetMainFrame(), 0);

  MockSpellCheckHost* spell_check_host =
      browser_client.GetSpellCheckHostForProcess(
          cross_site_subframe->GetProcess());
  spell_check_host->Wait();

  EXPECT_EQ(base::ASCIIToUTF16("zz."), spell_check_host->text());

  content::SetBrowserClientForTesting(old_browser_client);
}

// Tests that after disabling spellchecking, spelling in new out-of-process
// subframes is not checked. See crbug.com/789273 for details.
IN_PROC_BROWSER_TEST_F(ChromeSitePerProcessTest, OOPIFDisabledSpellCheckTest) {
  TestBrowserClientForSpellCheck browser_client;
  content::ContentBrowserClient* old_browser_client =
      content::SetBrowserClientForTesting(&browser_client);

  content::BrowserContext* browser_context =
      static_cast<content::BrowserContext*>(browser()->profile());

  // Initiate a SpellcheckService
  SpellcheckServiceFactory::GetForContext(browser_context);

  // Disable spellcheck
  PrefService* prefs = user_prefs::UserPrefs::Get(browser_context);
  prefs->SetBoolean(spellcheck::prefs::kSpellCheckEnable, false);
  base::RunLoop().RunUntilIdle();

  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/page_with_contenteditable_in_cross_site_subframe.html"));
  ui_test_utils::NavigateToURL(browser(), main_url);
  browser_client.RunUntilBindOrTimeout();

  content::WebContents* web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  content::RenderFrameHost* cross_site_subframe =
      ChildFrameAt(web_contents->GetMainFrame(), 0);

  MockSpellCheckHost* spell_check_host =
      browser_client.GetSpellCheckHostForProcess(
          cross_site_subframe->GetProcess());

#if BUILDFLAG(USE_BROWSER_SPELLCHECKER)
  // With browser spellchecker, a SpellCheckHost can still be bound via
  // SpellCheckProvider::FocusedNodeChanged(). However, no spellcheck request
  // should be made.
  EXPECT_TRUE(spell_check_host);
  spell_check_host->WaitUntilTimeout();
  EXPECT_FALSE(spell_check_host->HasReceivedText());
#else
  // Without browser spellchecker, the renderer makes no
  // SpellCheckHostRequest at all, in which case no SpellCheckHost is bound,
  // no spellchecking will be done, and the test succeeds.
  EXPECT_FALSE(spell_check_host);
#endif

  content::SetBrowserClientForTesting(old_browser_client);
  prefs->SetBoolean(spellcheck::prefs::kSpellCheckEnable, true);
}

#if BUILDFLAG(HAS_SPELLCHECK_PANEL)

// Tests that the OSX spell check panel can be opened from an out-of-process
// subframe, crbug.com/712395
IN_PROC_BROWSER_TEST_F(ChromeSitePerProcessTest, OOPIFSpellCheckPanelTest) {
  spellcheck::SpellCheckContentBrowserClient browser_client;
  content::ContentBrowserClient* old_browser_client =
      content::SetBrowserClientForTesting(&browser_client);

  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/page_with_contenteditable_in_cross_site_subframe.html"));
  ui_test_utils::NavigateToURL(browser(), main_url);

  content::WebContents* web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  content::RenderFrameHost* cross_site_subframe =
      ChildFrameAt(web_contents->GetMainFrame(), 0);

  EXPECT_TRUE(cross_site_subframe->IsCrossProcessSubframe());

  spellcheck::mojom::SpellCheckPanelPtr spell_check_panel_client;
  cross_site_subframe->GetRemoteInterfaces()->GetInterface(
      &spell_check_panel_client);
  spell_check_panel_client->ToggleSpellPanel(false);
  browser_client.RunUntilBind();

  spellcheck::SpellCheckMockPanelHost* host =
      browser_client.GetSpellCheckMockPanelHostForProcess(
          cross_site_subframe->GetProcess());
  EXPECT_TRUE(host->SpellingPanelVisible());

  content::SetBrowserClientForTesting(old_browser_client);
}
#endif  // BUILDFLAG(HAS_SPELLCHECK_PANEL)

#endif  // BUILDFLAG(ENABLE_SPELLCHECK)

#if defined(USE_AURA)
// Test that with a desktop/laptop touchscreen, a two finger tap opens a
// context menu in an OOPIF.
IN_PROC_BROWSER_TEST_F(ChromeSitePerProcessTest, TwoFingerTapContextMenu) {
  // Start on a page with an <iframe>.
  GURL main_url(embedded_test_server()->GetURL("a.com", "/iframe.html"));
  ui_test_utils::NavigateToURL(browser(), main_url);

  // Navigate the iframe cross-site.
  content::WebContents* web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  GURL frame_url(embedded_test_server()->GetURL("b.com", "/title1.html"));
  EXPECT_TRUE(NavigateIframeToURL(web_contents, "test", frame_url));

  content::RenderFrameHost* main_frame = web_contents->GetMainFrame();
  content::RenderFrameHost* child_frame = ChildFrameAt(main_frame, 0);
  content::RenderWidgetHostView* child_rwhv = child_frame->GetView();
  content::RenderWidgetHost* child_rwh = child_rwhv->GetRenderWidgetHost();

  ASSERT_TRUE(child_frame->IsCrossProcessSubframe());

  // Send a two finger tap event to the child and wait for the context menu to
  // open.
  ContextMenuWaiter menu_waiter;

  gfx::PointF child_location(1, 1);
  gfx::PointF child_location_in_root =
      child_rwhv->TransformPointToRootCoordSpaceF(child_location);

  blink::WebGestureEvent event(
      blink::WebInputEvent::kGestureTwoFingerTap,
      blink::WebInputEvent::kNoModifiers,
      blink::WebInputEvent::GetStaticTimeStampForTests(),
      blink::kWebGestureDeviceTouchscreen);
  event.SetPositionInWidget(child_location);
  event.SetPositionInScreen(child_location_in_root);
  event.data.two_finger_tap.first_finger_width = 10;
  event.data.two_finger_tap.first_finger_height = 10;

  child_rwh->ForwardGestureEvent(event);

  menu_waiter.WaitForMenuOpenAndClose();
}
#endif  // defined(USE_AURA)

// Check that cross-process postMessage preserves user gesture.  When a
// subframe with a user gesture postMessages its parent, the parent should be
// able to open a popup.  This test is in chrome/ so that it exercises the
// popup blocker logic.
IN_PROC_BROWSER_TEST_F(ChromeSitePerProcessTest,
                       CrossProcessPostMessagePreservesUserGesture) {
  // Start on a page with an <iframe>.
  GURL main_url(embedded_test_server()->GetURL("a.com", "/iframe.html"));
  ui_test_utils::NavigateToURL(browser(), main_url);

  // Navigate the iframe cross-site.
  content::WebContents* web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  GURL frame_url(embedded_test_server()->GetURL("b.com", "/title1.html"));
  EXPECT_TRUE(NavigateIframeToURL(web_contents, "test", frame_url));

  // Add a postMessage handler in the top frame.  The handler opens a new
  // popup.
  GURL popup_url(embedded_test_server()->GetURL("a.com", "/title2.html"));
  EXPECT_TRUE(ExecuteScriptWithoutUserGesture(
      web_contents,
      base::StringPrintf("window.addEventListener('message', function() {\n"
                         "  window.w = window.open('%s');\n"
                         "});",
                         popup_url.spec().c_str())));

  // Send a postMessage from the child frame to its parent.  Note that by
  // default ExecuteScript runs with a user gesture, which should be
  // transferred to the parent via postMessage. The parent should open the
  // popup in its message handler, and the popup shouldn't be blocked.
  content::TestNavigationObserver popup_observer(nullptr);
  popup_observer.StartWatchingNewWebContents();
  EXPECT_TRUE(ExecuteScript(ChildFrameAt(web_contents->GetMainFrame(), 0),
                            "parent.postMessage('foo', '*')"));
  popup_observer.Wait();
  ASSERT_EQ(2, browser()->tab_strip_model()->count());

  content::WebContents* popup =
      browser()->tab_strip_model()->GetActiveWebContents();
  EXPECT_EQ(popup_url, popup->GetLastCommittedURL());
  EXPECT_NE(popup, web_contents);

  // Check that the window handle returned from window.open() was valid.
  bool popup_handle_is_valid = false;
  EXPECT_TRUE(ExecuteScriptWithoutUserGestureAndExtractBool(
      web_contents, "window.domAutomationController.send(!!window.w)",
      &popup_handle_is_valid));
  EXPECT_TRUE(popup_handle_is_valid);
}

// Check that when a frame sends two cross-process postMessages while having a
// user gesture, the recipient will only be able to create one popup.  This
// test is in chrome/ so that it exercises the popup blocker logic.
IN_PROC_BROWSER_TEST_F(ChromeSitePerProcessTest,
                       TwoPostMessagesWithSameUserGesture) {
  // Start on a page with an <iframe>.
  GURL main_url(embedded_test_server()->GetURL("a.com", "/iframe.html"));
  ui_test_utils::NavigateToURL(browser(), main_url);

  // Navigate the iframe cross-site.
  content::WebContents* web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  GURL frame_url(embedded_test_server()->GetURL("b.com", "/title1.html"));
  EXPECT_TRUE(NavigateIframeToURL(web_contents, "test", frame_url));
  content::RenderFrameHost* child =
      ChildFrameAt(web_contents->GetMainFrame(), 0);

  // Add a postMessage handler in the root frame.  The handler opens a new popup
  // for a URL constructed using postMessage event data.
  GURL popup_url(embedded_test_server()->GetURL("popup.com", "/"));
  EXPECT_TRUE(ExecuteScriptWithoutUserGesture(
      web_contents, base::StringPrintf(
                        "window.addEventListener('message', function(event) {\n"
                        "  window.w = window.open('%s' + event.data);\n"
                        "});",
                        popup_url.spec().c_str())));

  // Send two postMessages from child frame to parent frame as part of the same
  // user gesture.  Ensure that only one popup can be opened.
  content::TestNavigationObserver popup_observer(nullptr);
  popup_observer.StartWatchingNewWebContents();
  EXPECT_TRUE(ExecuteScript(child,
                            "parent.postMessage('title1.html', '*');\n"
                            "parent.postMessage('title2.html', '*');"));
  popup_observer.Wait();
  EXPECT_EQ(2, browser()->tab_strip_model()->count());

  content::WebContents* popup =
      browser()->tab_strip_model()->GetActiveWebContents();
  EXPECT_EQ(embedded_test_server()->GetURL("popup.com", "/title1.html"),
            popup->GetLastCommittedURL());
  EXPECT_NE(popup, web_contents);

  // Ensure that only one popup can be opened.  The second window.open() call
  // should've failed and stored null into window.w.
  bool popup_handle_is_valid = false;
  EXPECT_TRUE(ExecuteScriptWithoutUserGestureAndExtractBool(
      child, "window.domAutomationController.send(!!window.w)",
      &popup_handle_is_valid));
  EXPECT_FALSE(popup_handle_is_valid);
}

// Check that when a frame sends two postMessages to iframes on different sites
// while having a user gesture, the two recipient processes will only be able
// to create one popup. This test is in chrome/ so that it exercises the popup
// blocker logic.
IN_PROC_BROWSER_TEST_F(ChromeSitePerProcessTest,
                       TwoPostMessagesToDifferentSitesWithSameUserGesture) {
  // Start on a page a.com with two iframes on b.com and c.com.
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b(c))"));
  ui_test_utils::NavigateToURL(browser(), main_url);
  content::WebContents* web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  content::RenderFrameHost* frame_b =
      ChildFrameAt(web_contents->GetMainFrame(), 0);
  content::RenderFrameHost* frame_c = ChildFrameAt(frame_b, 0);

  // Add a postMessage handler in root_frame and frame_b.  The handler opens a
  // new popup for a URL constructed using postMessage event data.
  GURL popup_url(embedded_test_server()->GetURL("popup.com", "/"));
  const std::string script = base::StringPrintf(
      "window.addEventListener('message', function(event) {\n"
      "  window.w = window.open('%s' + event.data);\n"
      "});",
      popup_url.spec().c_str());
  EXPECT_TRUE(ExecuteScriptWithoutUserGesture(web_contents, script));
  EXPECT_TRUE(ExecuteScriptWithoutUserGesture(frame_b, script));

  // Add a popup observer.
  content::TestNavigationObserver popup_observer(nullptr);
  popup_observer.StartWatchingNewWebContents();

  // Send two postMessages from the "leaf" frame to both its ancestors as part
  // of the same user gesture.
  EXPECT_TRUE(ExecuteScript(frame_c,
                            "parent.postMessage('title1.html', '*');\n"
                            "parent.parent.postMessage('title1.html', '*');"));

  // Ensure that only one popup can be opened.  Note that between the two OOPIF
  // processes, there is no ordering guarantee of which one will open the popup
  // first.
  popup_observer.Wait();
  EXPECT_EQ(2, browser()->tab_strip_model()->count());

  content::WebContents* popup =
      browser()->tab_strip_model()->GetActiveWebContents();
  EXPECT_EQ(embedded_test_server()->GetURL("popup.com", "/title1.html"),
            popup->GetLastCommittedURL());
  EXPECT_NE(popup, web_contents);

  // Ensure that only one renderer process has a valid popup handle.
  bool root_frame_handle_is_valid = false;
  bool frame_b_handle_is_valid = false;
  EXPECT_TRUE(ExecuteScriptWithoutUserGestureAndExtractBool(
      web_contents, "window.domAutomationController.send(!!window.w)",
      &root_frame_handle_is_valid));
  EXPECT_TRUE(ExecuteScriptWithoutUserGestureAndExtractBool(
      frame_b, "window.domAutomationController.send(!!window.w)",
      &frame_b_handle_is_valid));
  EXPECT_TRUE(root_frame_handle_is_valid != frame_b_handle_is_valid)
      << "root_frame_handle_is_valid = " << root_frame_handle_is_valid
      << ", frame_b_handle_is_valid = " << frame_b_handle_is_valid;
}

// Check that when a frame sends a cross-process postMessage to a second frame
// while having a user gesture, and then the second frame sends another
// cross-process postMessage to a third frame, the second and third frames can
// only create one popup between the two of them. This test is in chrome/ so
// that it exercises the popup blocker logic.
IN_PROC_BROWSER_TEST_F(ChromeSitePerProcessTest,
                       PostMessageSendsSecondPostMessageWithUserGesture) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b(c))"));
  ui_test_utils::NavigateToURL(browser(), main_url);

  content::WebContents* web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  content::RenderFrameHost* child =
      ChildFrameAt(web_contents->GetMainFrame(), 0);
  content::RenderFrameHost* grandchild = ChildFrameAt(child, 0);
  ASSERT_TRUE(child->IsCrossProcessSubframe());
  ASSERT_TRUE(grandchild->IsCrossProcessSubframe());
  ASSERT_NE(child->GetProcess(), web_contents->GetMainFrame()->GetProcess());
  ASSERT_NE(grandchild->GetProcess(), child->GetProcess());
  ASSERT_NE(grandchild->GetProcess(),
            web_contents->GetMainFrame()->GetProcess());

  // Add a postMessage handler to middle frame to send another postMessage to
  // top frame and then immediately attempt window.open().
  GURL popup1_url(embedded_test_server()->GetURL("popup.com", "/title1.html"));
  EXPECT_TRUE(ExecuteScriptWithoutUserGesture(
      child,
      base::StringPrintf("window.addEventListener('message', function() {\n"
                         "  parent.postMessage('foo', '*');\n"
                         "  window.w = window.open('%s');\n"
                         "});",
                         popup1_url.spec().c_str())));

  // Add a postMessage handler to top frame to attempt a window.open().
  GURL popup2_url(embedded_test_server()->GetURL("popup.com", "/title2.html"));
  EXPECT_TRUE(ExecuteScriptWithoutUserGesture(
      web_contents,
      base::StringPrintf("window.addEventListener('message', function() {\n"
                         "  window.w = window.open('%s');\n"
                         "});",
                         popup2_url.spec().c_str())));

  // Send a postMessage from bottom frame to middle frame as part of the same
  // user gesture.  Ensure that only one popup can be opened.
  content::TestNavigationObserver popup_observer(nullptr);
  popup_observer.StartWatchingNewWebContents();
  EXPECT_TRUE(ExecuteScript(grandchild, "parent.postMessage('foo', '*');"));
  popup_observer.Wait();

  content::WebContents* popup =
      browser()->tab_strip_model()->GetActiveWebContents();
  EXPECT_EQ(popup1_url, popup->GetLastCommittedURL());
  EXPECT_NE(popup, web_contents);

  // Ensure that only one popup can be opened.  The second window.open() call at
  // top frame should fail, storing null into window.w.
  bool popup_handle_is_valid = false;
  EXPECT_TRUE(ExecuteScriptWithoutUserGestureAndExtractBool(
      web_contents, "window.domAutomationController.send(!!window.w)",
      &popup_handle_is_valid));
  EXPECT_FALSE(popup_handle_is_valid);
  EXPECT_EQ(2, browser()->tab_strip_model()->count());
}

// Test that when a frame sends a cross-process postMessage and then requests a
// window.open(), and the message recipient also requests a window.open(), only
// one popup will be opened.
IN_PROC_BROWSER_TEST_F(ChromeSitePerProcessTest,
                       PostMessageSenderAndReceiverRaceToCreatePopup) {
  // TODO(alexmos, mustaq): This test will not work until either (1) browser
  // process starts tracking and coordinating user gestures (see
  // http://crbug.com/161068), or (2) UserActivation v2 ships and supports
  // OOPIFs (see https://crbug.com/696617 and https://crbug.com/780556).
  if (!base::FeatureList::IsEnabled(features::kUserActivationV2))
    return;

  // Start on a page with an <iframe>.
  GURL main_url(embedded_test_server()->GetURL("a.com", "/iframe.html"));
  ui_test_utils::NavigateToURL(browser(), main_url);

  // Navigate the iframe cross-site.
  content::WebContents* web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  GURL frame_url(embedded_test_server()->GetURL("b.com", "/title1.html"));
  EXPECT_TRUE(NavigateIframeToURL(web_contents, "test", frame_url));
  content::RenderFrameHost* child =
      ChildFrameAt(web_contents->GetMainFrame(), 0);

  // Add a postMessage handler in the root frame.  The handler opens a new popup
  // for a URL constructed using postMessage event data.
  GURL popup_url(embedded_test_server()->GetURL("popup.com", "/title1.html"));
  EXPECT_TRUE(ExecuteScriptWithoutUserGesture(
      web_contents,
      base::StringPrintf("window.addEventListener('message', function() {\n"
                         "  window.w = window.open('%s');\n"
                         "});",
                         popup_url.spec().c_str())));

  // Send a postMessage from child frame to parent frame and then immediately
  // consume the user gesture with window.open().
  content::TestNavigationObserver popup_observer(nullptr);
  popup_observer.StartWatchingNewWebContents();
  EXPECT_TRUE(ExecuteScript(
      child, base::StringPrintf(
                 "parent.postMessage('foo', '*');\n"
                 "window.setTimeout(\"window.w = window.open('%s')\", 0);",
                 popup_url.spec().c_str())));
  popup_observer.Wait();

  content::WebContents* popup =
      browser()->tab_strip_model()->GetActiveWebContents();
  EXPECT_EQ(popup_url, popup->GetLastCommittedURL());
  EXPECT_NE(popup, web_contents);

  // Ensure that only one popup was opened, from either the parent or the child
  // frame, but not both.
  bool parent_popup_handle_is_valid = false;
  EXPECT_TRUE(ExecuteScriptWithoutUserGestureAndExtractBool(
      web_contents, "window.domAutomationController.send(!!window.w)",
      &parent_popup_handle_is_valid));
  bool child_popup_handle_is_valid = false;
  EXPECT_TRUE(ExecuteScriptWithoutUserGestureAndExtractBool(
      child, "window.domAutomationController.send(!!window.w)",
      &child_popup_handle_is_valid));
  EXPECT_NE(parent_popup_handle_is_valid, child_popup_handle_is_valid)
      << " parent_popup_handle_is_valid=" << parent_popup_handle_is_valid
      << " child_popup_handle_is_valid=" << child_popup_handle_is_valid;

  ASSERT_EQ(2, browser()->tab_strip_model()->count());
}

// Test that an activation is visible to the ancestors of the activated frame
// and not to the descendants.
IN_PROC_BROWSER_TEST_F(ChromeSitePerProcessTest,
                       UserActivationVisibilityInAncestorFrame) {
  if (!base::FeatureList::IsEnabled(features::kUserActivationV2))
    return;

  // Start on a page a.com with two iframes on b.com and c.com.
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b(c))"));
  ui_test_utils::NavigateToURL(browser(), main_url);
  content::WebContents* web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  content::RenderFrameHost* frame_b =
      ChildFrameAt(web_contents->GetMainFrame(), 0);
  content::RenderFrameHost* frame_c = ChildFrameAt(frame_b, 0);

  // Activate frame_b by executing a dummy script.
  const std::string no_op_script = "// No-op script";
  EXPECT_TRUE(ExecuteScript(frame_b, no_op_script));

  // Add a popup observer.
  content::TestNavigationObserver popup_observer(nullptr);
  popup_observer.StartWatchingNewWebContents();

  // Try opening popups from frame_c and root frame.
  GURL popup_url(embedded_test_server()->GetURL("popup.com", "/"));
  EXPECT_TRUE(ExecuteScriptWithoutUserGesture(
      frame_c,
      base::StringPrintf("window.w = window.open('%s' + 'title1.html');",
                         popup_url.spec().c_str())));
  EXPECT_TRUE(ExecuteScriptWithoutUserGesture(
      web_contents,
      base::StringPrintf("window.w = window.open('%s' + 'title2.html');",
                         popup_url.spec().c_str())));

  // Wait and check that only one popup has opened.
  popup_observer.Wait();
  EXPECT_EQ(2, browser()->tab_strip_model()->count());

  content::WebContents* popup =
      browser()->tab_strip_model()->GetActiveWebContents();
  EXPECT_EQ(embedded_test_server()->GetURL("popup.com", "/title2.html"),
            popup->GetLastCommittedURL());
  EXPECT_NE(popup, web_contents);

  // Confirm that only the root_frame opened the popup.
  bool root_frame_popup_opened = false;
  EXPECT_TRUE(ExecuteScriptWithoutUserGestureAndExtractBool(
      web_contents, "window.domAutomationController.send(!!window.w);",
      &root_frame_popup_opened));
  EXPECT_TRUE(root_frame_popup_opened);

  bool frame_c_popup_opened = false;
  EXPECT_TRUE(ExecuteScriptWithoutUserGestureAndExtractBool(
      frame_c, "window.domAutomationController.send(!!window.w);",
      &frame_c_popup_opened));

  EXPECT_FALSE(frame_c_popup_opened);
}

// Test that when an activation is consumed, no frames in the frame tree can
// consume it again.
IN_PROC_BROWSER_TEST_F(ChromeSitePerProcessTest,
                       UserActivationConsumptionAcrossFrames) {
  if (!base::FeatureList::IsEnabled(features::kUserActivationV2))
    return;

  // Start on a page a.com with two iframes on b.com and c.com.
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b,c)"));
  ui_test_utils::NavigateToURL(browser(), main_url);
  content::WebContents* web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  content::RenderFrameHost* frame_b =
      ChildFrameAt(web_contents->GetMainFrame(), 0);
  content::RenderFrameHost* frame_c =
      ChildFrameAt(web_contents->GetMainFrame(), 1);

  // Activate frame_b and frame_c by executing dummy scripts.
  const std::string no_op_script = "// No-op script";
  EXPECT_TRUE(ExecuteScript(frame_b, no_op_script));
  EXPECT_TRUE(ExecuteScript(frame_c, no_op_script));

  // Add a popup observer.
  content::TestNavigationObserver popup_observer(nullptr);
  popup_observer.StartWatchingNewWebContents();

  // Try opening popups from all three frames.
  GURL popup_url(embedded_test_server()->GetURL("popup.com", "/"));
  EXPECT_TRUE(ExecuteScriptWithoutUserGesture(
      frame_b,
      base::StringPrintf("window.w = window.open('%s' + 'title1.html');",
                         popup_url.spec().c_str())));
  EXPECT_TRUE(ExecuteScriptWithoutUserGesture(
      frame_c,
      base::StringPrintf("window.w = window.open('%s' + 'title2.html');",
                         popup_url.spec().c_str())));
  EXPECT_TRUE(ExecuteScriptWithoutUserGesture(
      web_contents,
      base::StringPrintf("window.w = window.open('%s' + 'title3.html');",
                         popup_url.spec().c_str())));

  // Wait and check that only one popup has opened.
  popup_observer.Wait();
  EXPECT_EQ(2, browser()->tab_strip_model()->count());

  content::WebContents* popup =
      browser()->tab_strip_model()->GetActiveWebContents();
  EXPECT_EQ(embedded_test_server()->GetURL("popup.com", "/title1.html"),
            popup->GetLastCommittedURL());
  EXPECT_NE(popup, web_contents);

  // Confirm that only frame_b opened the popup.
  bool root_frame_popup_opened = false;
  EXPECT_TRUE(ExecuteScriptWithoutUserGestureAndExtractBool(
      web_contents, "window.domAutomationController.send(!!window.w);",
      &root_frame_popup_opened));
  EXPECT_FALSE(root_frame_popup_opened);

  bool frame_b_popup_opened = false;
  EXPECT_TRUE(ExecuteScriptWithoutUserGestureAndExtractBool(
      frame_b, "window.domAutomationController.send(!!window.w);",
      &frame_b_popup_opened));
  EXPECT_TRUE(frame_b_popup_opened);

  bool frame_c_popup_opened = false;
  EXPECT_TRUE(ExecuteScriptWithoutUserGestureAndExtractBool(
      frame_c, "window.domAutomationController.send(!!window.w);",
      &frame_c_popup_opened));
  EXPECT_FALSE(frame_c_popup_opened);
}

// Tests that a cross-site iframe runs its beforeunload handler when closing a
// tab.  See https://crbug.com/853021.
IN_PROC_BROWSER_TEST_F(ChromeSitePerProcessTest,
                       TabCloseWithCrossSiteBeforeUnloadIframe) {
  TabStripModel* tab_strip_model = browser()->tab_strip_model();
  content::WebContents* first_web_contents =
      tab_strip_model->GetActiveWebContents();

  // Add a second tab and load a page with an iframe.
  GURL main_url(embedded_test_server()->GetURL("a.com", "/iframe.html"));
  ui_test_utils::NavigateToURLWithDisposition(
      browser(), main_url, WindowOpenDisposition::NEW_FOREGROUND_TAB,
      ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
  content::WebContents* second_web_contents =
      tab_strip_model->GetActiveWebContents();
  EXPECT_NE(first_web_contents, second_web_contents);

  // Navigate iframe cross-site.
  GURL frame_url(embedded_test_server()->GetURL("b.com", "/title1.html"));
  EXPECT_TRUE(NavigateIframeToURL(second_web_contents, "test", frame_url));

  // Install a dialog-showing beforeunload handler in the iframe.
  content::RenderFrameHost* child =
      ChildFrameAt(second_web_contents->GetMainFrame(), 0);
  EXPECT_TRUE(
      ExecuteScript(child, "window.onbeforeunload = () => { return 'x' };"));
  content::PrepContentsForBeforeUnloadTest(second_web_contents);

  // Close the second tab.  This should return false to indicate that we're
  // waiting for the beforeunload dialog.
  EXPECT_FALSE(
      tab_strip_model->CloseWebContentsAt(tab_strip_model->active_index(), 0));

  // Cancel the dialog and make sure the tab stays alive.
  auto* dialog = ui_test_utils::WaitForAppModalDialog();
  dialog->native_dialog()->CancelAppModalDialog();
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(second_web_contents, tab_strip_model->GetActiveWebContents());
  EXPECT_EQ(2, browser()->tab_strip_model()->count());

  // Try closing the tab again.
  EXPECT_FALSE(
      tab_strip_model->CloseWebContentsAt(tab_strip_model->active_index(), 0));

  // Accept the dialog and wait for tab close to complete.
  content::WebContentsDestroyedWatcher destroyed_watcher(second_web_contents);
  dialog = ui_test_utils::WaitForAppModalDialog();
  dialog->native_dialog()->AcceptAppModalDialog();
  destroyed_watcher.Wait();
  EXPECT_EQ(first_web_contents, tab_strip_model->GetActiveWebContents());
}

// Test that there's no crash in the following scenario:
// 1. a page opens a cross-site popup, where the popup has a cross-site iframe
//    with a beforeunload handler.
// 2. The user tries to close the popup, triggering beforeunload.
// 3. While waiting for the subframe's beforeunload, the original page closes
//    the popup via window.close().
// See https://crbug.com/866382.
IN_PROC_BROWSER_TEST_F(ChromeSitePerProcessTest,
                       CrossProcessWindowCloseWithBeforeUnloadIframe) {
  GURL main_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
  ui_test_utils::NavigateToURL(browser(), main_url);

  TabStripModel* tab_strip_model = browser()->tab_strip_model();
  content::WebContents* first_web_contents =
      tab_strip_model->GetActiveWebContents();

  // Open a cross-site popup from the first page.
  content::TestNavigationObserver popup_observer(nullptr);
  popup_observer.StartWatchingNewWebContents();
  GURL popup_url(embedded_test_server()->GetURL("b.com", "/iframe.html"));
  EXPECT_TRUE(ExecuteScript(first_web_contents,
                            base::StringPrintf("window.w = window.open('%s');",
                                               popup_url.spec().c_str())));
  popup_observer.Wait();
  EXPECT_EQ(2, browser()->tab_strip_model()->count());

  content::WebContents* second_web_contents =
      tab_strip_model->GetActiveWebContents();
  EXPECT_NE(first_web_contents, second_web_contents);

  // Navigate popup iframe cross-site.
  GURL frame_url(embedded_test_server()->GetURL("c.com", "/title1.html"));
  EXPECT_TRUE(NavigateIframeToURL(second_web_contents, "test", frame_url));

  // Install a dialog-showing beforeunload handler in the iframe.
  content::RenderFrameHost* child =
      ChildFrameAt(second_web_contents->GetMainFrame(), 0);
  EXPECT_TRUE(
      ExecuteScript(child, "window.onbeforeunload = () => { return 'x' };"));
  content::PrepContentsForBeforeUnloadTest(second_web_contents);

  // Close the second tab.  This should return false to indicate that we're
  // waiting for the beforeunload dialog.
  EXPECT_FALSE(
      tab_strip_model->CloseWebContentsAt(tab_strip_model->active_index(), 0));

  // From the first tab, execute window.close() on the popup and wait for the
  // second WebContents to be destroyed.
  content::WebContentsDestroyedWatcher destroyed_watcher(second_web_contents);
  EXPECT_TRUE(ExecuteScript(first_web_contents, "w.close()"));
  destroyed_watcher.Wait();
  EXPECT_EQ(first_web_contents, tab_strip_model->GetActiveWebContents());
}

// Test that there's no crash in the following scenario:
// 1. a page opens a cross-site popup, where the popup has two cross-site
//    iframes, with second having a beforeunload handler.
// 2. The user tries to close the popup, triggering beforeunload.
// 3. While waiting for second subframe's beforeunload, the original page
//    closes the popup via window.close().
// See https://crbug.com/866382.  This is a variant of the test above, but
// with two iframes, which used to trigger a different crash.
IN_PROC_BROWSER_TEST_F(ChromeSitePerProcessTest,
                       CrossProcessWindowCloseWithTwoBeforeUnloadIframes) {
  GURL main_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
  ui_test_utils::NavigateToURL(browser(), main_url);

  TabStripModel* tab_strip_model = browser()->tab_strip_model();
  content::WebContents* first_web_contents =
      tab_strip_model->GetActiveWebContents();

  // Open a cross-site popup from the first page.
  content::TestNavigationObserver popup_observer(nullptr);
  popup_observer.StartWatchingNewWebContents();
  GURL popup_url(
      embedded_test_server()->GetURL("b.com", "/two_iframes_blank.html"));
  EXPECT_TRUE(ExecuteScript(first_web_contents,
                            base::StringPrintf("window.w = window.open('%s');",
                                               popup_url.spec().c_str())));
  popup_observer.Wait();
  EXPECT_EQ(2, browser()->tab_strip_model()->count());

  content::WebContents* second_web_contents =
      tab_strip_model->GetActiveWebContents();
  EXPECT_NE(first_web_contents, second_web_contents);

  // Navigate both popup iframes cross-site.
  GURL frame_url(embedded_test_server()->GetURL("c.com", "/title1.html"));
  EXPECT_TRUE(NavigateIframeToURL(second_web_contents, "iframe1", frame_url));
  EXPECT_TRUE(NavigateIframeToURL(second_web_contents, "iframe2", frame_url));

  // Install a dialog-showing beforeunload handler in the second iframe.
  content::RenderFrameHost* child =
      ChildFrameAt(second_web_contents->GetMainFrame(), 1);
  EXPECT_TRUE(
      ExecuteScript(child, "window.onbeforeunload = () => { return 'x' };"));
  content::PrepContentsForBeforeUnloadTest(second_web_contents);

  // Close the second tab.  This should return false to indicate that we're
  // waiting for the beforeunload dialog.
  EXPECT_FALSE(
      tab_strip_model->CloseWebContentsAt(tab_strip_model->active_index(), 0));

  // From the first tab, execute window.close() on the popup and wait for the
  // second WebContents to be destroyed.
  content::WebContentsDestroyedWatcher destroyed_watcher(second_web_contents);
  EXPECT_TRUE(ExecuteScript(first_web_contents, "w.close()"));
  destroyed_watcher.Wait();
  EXPECT_EQ(first_web_contents, tab_strip_model->GetActiveWebContents());
}
