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

#include "base/bind.h"
#include "base/files/file_util.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/memory/ref_counted.h"
#include "base/optional.h"
#include "base/path_service.h"
#include "base/run_loop.h"
#include "base/strings/pattern.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/scoped_feature_list.h"
#include "base/threading/thread_restrictions.h"
#include "base/time/time.h"
#include "base/values.h"
#include "build/build_config.h"
#include "components/url_formatter/url_formatter.h"
#include "content/browser/frame_host/frame_tree.h"
#include "content/browser/frame_host/navigation_entry_impl.h"
#include "content/browser/loader/resource_dispatcher_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_input_event_router.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/browser/web_contents/web_contents_view.h"
#include "content/common/frame_messages.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/file_select_listener.h"
#include "content/public/browser/invalidate_type.h"
#include "content/public/browser/javascript_dialog_manager.h"
#include "content/public/browser/load_notification_details.h"
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/notification_details.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_types.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/browser/site_isolation_policy.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_delegate.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/common/content_client.h"
#include "content/public/common/content_paths.h"
#include "content/public/common/url_constants.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_utils.h"
#include "content/public/test/no_renderer_crashes_assertion.h"
#include "content/public/test/test_navigation_observer.h"
#include "content/public/test/test_utils.h"
#include "content/public/test/url_loader_interceptor.h"
#include "content/shell/browser/shell.h"
#include "content/test/content_browser_test_utils_internal.h"
#include "content/test/test_content_browser_client.h"
#include "net/base/features.h"
#include "net/base/ip_endpoint.h"
#include "net/base/network_isolation_key.h"
#include "net/dns/mock_host_resolver.h"
#include "net/test/embedded_test_server/controllable_http_response.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "services/network/public/cpp/features.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "url/gurl.h"

namespace content {

#define SCOPE_TRACED(statement) \
  {                             \
    SCOPED_TRACE(#statement);   \
    statement;                  \
  }

void ResizeWebContentsView(Shell* shell, const gfx::Size& size,
                           bool set_start_page) {
  // Shell::SizeTo is not implemented on Aura; WebContentsView::SizeContents
  // works on Win and ChromeOS but not Linux - we need to resize the shell
  // window on Linux because if we don't, the next layout of the unchanged shell
  // window will resize WebContentsView back to the previous size.
  // SizeContents is a hack and should not be relied on.
#if defined(OS_MACOSX)
  shell->SizeTo(size);
  // If |set_start_page| is true, start with blank page to make sure resize
  // takes effect.
  if (set_start_page)
    NavigateToURL(shell, GURL("about://blank"));
#else
  static_cast<WebContentsImpl*>(shell->web_contents())->GetView()->
      SizeContents(size);
#endif  // defined(OS_MACOSX)
}

// Class to test that OverrideWebkitPrefs has been called for all relevant
// RenderViewHosts.
class NotifyPreferencesChangedTestContentBrowserClient
    : public TestContentBrowserClient {
 public:
  NotifyPreferencesChangedTestContentBrowserClient() = default;

  void OverrideWebkitPrefs(RenderViewHost* render_view_host,
                           WebPreferences* prefs) override {
    override_webkit_prefs_rvh_set_.insert(render_view_host);
  }

  const std::unordered_set<RenderViewHost*>& override_webkit_prefs_rvh_set() {
    return override_webkit_prefs_rvh_set_;
  }

 private:
  std::unordered_set<RenderViewHost*> override_webkit_prefs_rvh_set_;

  DISALLOW_COPY_AND_ASSIGN(NotifyPreferencesChangedTestContentBrowserClient);
};

class WebContentsImplBrowserTest : public ContentBrowserTest {
 public:
  WebContentsImplBrowserTest() {}
  void SetUp() override {
    RenderWidgetHostImpl::DisableResizeAckCheckForTesting();
    ContentBrowserTest::SetUp();
  }

  void SetUpOnMainThread() override {
    // Setup the server to allow serving separate sites, so we can perform
    // cross-process navigation.
    host_resolver()->AddRule("*", "127.0.0.1");
  }

  bool IsInFullscreen() {
    WebContentsImpl* web_contents =
        static_cast<WebContentsImpl*>(shell()->web_contents());
    return web_contents->current_fullscreen_frame_;
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(WebContentsImplBrowserTest);
};

// Keeps track of data from LoadNotificationDetails so we can later verify that
// they are correct, after the LoadNotificationDetails object is deleted.
class LoadStopNotificationObserver : public WindowedNotificationObserver {
 public:
  explicit LoadStopNotificationObserver(NavigationController* controller)
      : WindowedNotificationObserver(NOTIFICATION_LOAD_STOP,
                                     Source<NavigationController>(controller)),
        session_index_(-1),
        controller_(nullptr) {}
  void Observe(int type,
               const NotificationSource& source,
               const NotificationDetails& details) override {
    if (type == NOTIFICATION_LOAD_STOP) {
      const Details<LoadNotificationDetails> load_details(details);
      url_ = load_details->url;
      session_index_ = load_details->session_index;
      controller_ = load_details->controller;
    }
    WindowedNotificationObserver::Observe(type, source, details);
  }

  GURL url_;
  int session_index_;
  NavigationController* controller_;
};

// Starts a new navigation as soon as the current one commits, but does not
// wait for it to complete.  This allows us to observe DidStopLoading while
// a pending entry is present.
class NavigateOnCommitObserver : public WebContentsObserver {
 public:
  NavigateOnCommitObserver(Shell* shell, GURL url)
      : WebContentsObserver(shell->web_contents()),
        shell_(shell),
        url_(url),
        done_(false) {
  }

  // WebContentsObserver:
  void NavigationEntryCommitted(
      const LoadCommittedDetails& load_details) override {
    if (!done_) {
      done_ = true;
      shell_->LoadURL(url_);

      // There should be a pending entry.
      CHECK(shell_->web_contents()->GetController().GetPendingEntry());

      // Now that there is a pending entry, stop the load.
      shell_->Stop();
    }
  }

  Shell* shell_;
  GURL url_;
  bool done_;
};

class RenderViewSizeDelegate : public WebContentsDelegate {
 public:
  void set_size_insets(const gfx::Size& size_insets) {
    size_insets_ = size_insets;
  }

  // WebContentsDelegate:
  gfx::Size GetSizeForNewRenderView(WebContents* web_contents) const override {
    gfx::Size size(web_contents->GetContainerBounds().size());
    size.Enlarge(size_insets_.width(), size_insets_.height());
    return size;
  }

 private:
  gfx::Size size_insets_;
};

class RenderViewSizeObserver : public WebContentsObserver {
 public:
  RenderViewSizeObserver(Shell* shell, const gfx::Size& wcv_new_size)
      : WebContentsObserver(shell->web_contents()),
        shell_(shell),
        wcv_new_size_(wcv_new_size) {
  }

  // WebContentsObserver:
  void RenderFrameCreated(RenderFrameHost* rfh) override {
    if (!rfh->GetParent())
      rwhv_create_size_ = rfh->GetView()->GetViewBounds().size();
  }

  void DidStartNavigation(NavigationHandle* navigation_handle) override {
    ResizeWebContentsView(shell_, wcv_new_size_, false);
  }

  gfx::Size rwhv_create_size() const { return rwhv_create_size_; }

 private:
  Shell* shell_;  // Weak ptr.
  gfx::Size wcv_new_size_;
  gfx::Size rwhv_create_size_;
};

class LoadingStateChangedDelegate : public WebContentsDelegate {
 public:
  LoadingStateChangedDelegate()
      : loadingStateChangedCount_(0)
      , loadingStateToDifferentDocumentCount_(0) {
  }

  // WebContentsDelegate:
  void LoadingStateChanged(WebContents* contents,
                           bool to_different_document) override {
      loadingStateChangedCount_++;
      if (to_different_document)
        loadingStateToDifferentDocumentCount_++;
  }

  int loadingStateChangedCount() const { return loadingStateChangedCount_; }
  int loadingStateToDifferentDocumentCount() const {
    return loadingStateToDifferentDocumentCount_;
  }

 private:
  int loadingStateChangedCount_;
  int loadingStateToDifferentDocumentCount_;
};

// Test that DidStopLoading includes the correct URL in the details.
IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, DidStopLoadingDetails) {
  ASSERT_TRUE(embedded_test_server()->Start());

  LoadStopNotificationObserver load_observer(
      &shell()->web_contents()->GetController());
  NavigateToURL(shell(), embedded_test_server()->GetURL("/title1.html"));
  load_observer.Wait();

  EXPECT_EQ("/title1.html", load_observer.url_.path());
  EXPECT_EQ(0, load_observer.session_index_);
  EXPECT_EQ(&shell()->web_contents()->GetController(),
            load_observer.controller_);
}

// Test that DidStopLoading includes the correct URL in the details when a
// pending entry is present.
IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
                       DidStopLoadingDetailsWithPending) {
  ASSERT_TRUE(embedded_test_server()->Start());
  // TODO(clamy): Add a cross-process navigation case as well once
  // crbug.com/581024 is fixed.
  GURL url1 = embedded_test_server()->GetURL("/title1.html");
  GURL url2 = embedded_test_server()->GetURL("/title2.html");

  // Listen for the first load to stop.
  LoadStopNotificationObserver load_observer(
      &shell()->web_contents()->GetController());
  // Start a new pending navigation as soon as the first load commits.
  // We will hear a DidStopLoading from the first load as the new load
  // is started.
  NavigateOnCommitObserver commit_observer(shell(), url2);
  NavigateToURL(shell(), url1);
  load_observer.Wait();

  EXPECT_EQ(url1, load_observer.url_);
  EXPECT_EQ(0, load_observer.session_index_);
  EXPECT_EQ(&shell()->web_contents()->GetController(),
            load_observer.controller_);
}

namespace {

// Class that waits for a particular load to finish in any frame.  This happens
// after the commit event.
class LoadFinishedWaiter : public WebContentsObserver {
 public:
  LoadFinishedWaiter(WebContents* web_contents, const GURL& expected_url)
      : WebContentsObserver(web_contents),
        expected_url_(expected_url),
        run_loop_(new base::RunLoop()) {
    EXPECT_TRUE(web_contents != nullptr);
  }

  void Wait() { run_loop_->Run(); }

 private:
  void DidFinishLoad(RenderFrameHost* render_frame_host,
                     const GURL& url) override {
    if (url == expected_url_)
      run_loop_->Quit();
  }

  GURL expected_url_;
  std::unique_ptr<base::RunLoop> run_loop_;
};

}  // namespace

// Ensure that cross-site subframes always notify their parents when they finish
// loading, so that the page eventually reaches DidStopLoading.  There was a bug
// where an OOPIF would not notify its parent if (1) it finished loading, but
// (2) later added a subframe that kept the main frame in the loading state, and
// (3) all subframes then finished loading.
// Note that this test makes sense to run with and without OOPIFs.
// See https://crbug.com/822013#c12.
IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
                       DidStopLoadingWithNestedFrames) {
  ASSERT_TRUE(embedded_test_server()->Start());
  WebContentsImpl* web_contents =
      static_cast<WebContentsImpl*>(shell()->web_contents());

  // Navigate to an A(B, C) page where B is slow to load.  Wait for C to reach
  // load stop.  A will still be loading due to B.
  GURL url_a = embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b,c)");
  GURL url_b = embedded_test_server()->GetURL(
      "b.com", "/cross_site_iframe_factory.html?b()");
  GURL url_c = embedded_test_server()->GetURL(
      "c.com", "/cross_site_iframe_factory.html?c()");
  TestNavigationManager delayer_b(web_contents, url_b);
  LoadFinishedWaiter load_waiter_c(web_contents, url_c);
  shell()->LoadURL(url_a);
  EXPECT_TRUE(delayer_b.WaitForRequestStart());
  load_waiter_c.Wait();
  EXPECT_TRUE(web_contents->IsLoading());

  // At this point, C has finished loading and B is stalled.  Add a slow D frame
  // within C.
  GURL url_d = embedded_test_server()->GetURL("d.com", "/title1.html");
  FrameTreeNode* subframe_c = web_contents->GetFrameTree()->root()->child_at(1);
  EXPECT_EQ(url_c, subframe_c->current_url());
  TestNavigationManager delayer_d(web_contents, url_d);
  const std::string add_d_script = base::StringPrintf(
      "var f = document.createElement('iframe');"
      "f.src='%s';"
      "document.body.appendChild(f);",
      url_d.spec().c_str());
  EXPECT_TRUE(content::ExecuteScript(subframe_c, add_d_script));
  EXPECT_TRUE(delayer_d.WaitForRequestStart());
  EXPECT_TRUE(web_contents->IsLoading());

  // Let B finish and wait for another load stop.  A will still be loading due
  // to D.
  LoadFinishedWaiter load_waiter_b(web_contents, url_b);
  delayer_b.WaitForNavigationFinished();
  load_waiter_b.Wait();
  EXPECT_TRUE(web_contents->IsLoading());

  // Let D finish.  We should get a load stop in the main frame.
  LoadFinishedWaiter load_waiter_d(web_contents, url_d);
  delayer_d.WaitForNavigationFinished();
  load_waiter_d.Wait();
  EXPECT_TRUE(WaitForLoadStop(web_contents));
  EXPECT_FALSE(web_contents->IsLoading());
}

// Test that a renderer-initiated navigation to an invalid URL does not leave
// around a pending entry that could be used in a URL spoof.  We test this in
// a browser test because our unit test framework incorrectly calls
// DidStartProvisionalLoadForFrame for in-page navigations.
// See http://crbug.com/280512.
IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
                       ClearNonVisiblePendingOnFail) {
  ASSERT_TRUE(embedded_test_server()->Start());

  NavigateToURL(shell(), embedded_test_server()->GetURL("/title1.html"));

  // Navigate to an invalid URL and make sure it doesn't leave a pending entry.
  LoadStopNotificationObserver load_observer1(
      &shell()->web_contents()->GetController());
  ASSERT_TRUE(
      ExecuteScript(shell(), "window.location.href=\"nonexistent:12121\";"));
  load_observer1.Wait();
  EXPECT_FALSE(shell()->web_contents()->GetController().GetPendingEntry());

  LoadStopNotificationObserver load_observer2(
      &shell()->web_contents()->GetController());
  ASSERT_TRUE(ExecuteScript(shell(), "window.location.href=\"#foo\";"));
  load_observer2.Wait();
  EXPECT_EQ(embedded_test_server()->GetURL("/title1.html#foo"),
            shell()->web_contents()->GetVisibleURL());
}

// Crashes under ThreadSanitizer, http://crbug.com/356758.
#if defined(OS_WIN) || defined(OS_ANDROID) \
    || defined(THREAD_SANITIZER)
#define MAYBE_GetSizeForNewRenderView DISABLED_GetSizeForNewRenderView
#else
#define MAYBE_GetSizeForNewRenderView DISABLED_GetSizeForNewRenderView
#endif
// Test that RenderViewHost is created and updated at the size specified by
// WebContentsDelegate::GetSizeForNewRenderView().
IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
                       MAYBE_GetSizeForNewRenderView) {
  ASSERT_TRUE(embedded_test_server()->Start());
  // Create a new server with a different site.
  net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS);
  https_server.ServeFilesFromSourceDirectory(GetTestDataFilePath());
  ASSERT_TRUE(https_server.Start());

  std::unique_ptr<RenderViewSizeDelegate> delegate(
      new RenderViewSizeDelegate());
  shell()->web_contents()->SetDelegate(delegate.get());
  ASSERT_TRUE(shell()->web_contents()->GetDelegate() == delegate.get());

  // When no size is set, RenderWidgetHostView adopts the size of
  // WebContentsView.
  NavigateToURL(shell(), embedded_test_server()->GetURL("/title2.html"));
  EXPECT_EQ(shell()->web_contents()->GetContainerBounds().size(),
            shell()->web_contents()->GetRenderWidgetHostView()->GetViewBounds().
                size());

  // When a size is set, RenderWidgetHostView and WebContentsView honor this
  // size.
  gfx::Size size(300, 300);
  gfx::Size size_insets(10, 15);
  ResizeWebContentsView(shell(), size, true);
  delegate->set_size_insets(size_insets);
  NavigateToURL(shell(), https_server.GetURL("/"));
  size.Enlarge(size_insets.width(), size_insets.height());
  EXPECT_EQ(size,
            shell()->web_contents()->GetRenderWidgetHostView()->GetViewBounds().
                size());
  // The web_contents size is set by the embedder, and should not depend on the
  // rwhv size. The behavior is correct on OSX, but incorrect on other
  // platforms.
  gfx::Size exp_wcv_size(300, 300);
#if !defined(OS_MACOSX)
  exp_wcv_size.Enlarge(size_insets.width(), size_insets.height());
#endif

  EXPECT_EQ(exp_wcv_size,
            shell()->web_contents()->GetContainerBounds().size());

  // If WebContentsView is resized after RenderWidgetHostView is created but
  // before pending navigation entry is committed, both RenderWidgetHostView and
  // WebContentsView use the new size of WebContentsView.
  gfx::Size init_size(200, 200);
  gfx::Size new_size(100, 100);
  size_insets = gfx::Size(20, 30);
  ResizeWebContentsView(shell(), init_size, true);
  delegate->set_size_insets(size_insets);
  RenderViewSizeObserver observer(shell(), new_size);
  NavigateToURL(shell(), embedded_test_server()->GetURL("/title1.html"));
  // RenderWidgetHostView is created at specified size.
  init_size.Enlarge(size_insets.width(), size_insets.height());
  EXPECT_EQ(init_size, observer.rwhv_create_size());

// Once again, the behavior is correct on OSX. The embedder explicitly sets
// the size to (100,100) during navigation. Both the wcv and the rwhv should
// take on that size.
#if !defined(OS_MACOSX)
  new_size.Enlarge(size_insets.width(), size_insets.height());
#endif
  gfx::Size actual_size = shell()->web_contents()->GetRenderWidgetHostView()->
      GetViewBounds().size();

  EXPECT_EQ(new_size, actual_size);
  EXPECT_EQ(new_size, shell()->web_contents()->GetContainerBounds().size());
}

IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, SetTitleOnUnload) {
  GURL url(
      "data:text/html,"
      "<title>A</title>"
      "<body onunload=\"document.title = 'B'\"></body>");
  NavigateToURL(shell(), url);
  ASSERT_EQ(1, shell()->web_contents()->GetController().GetEntryCount());
  NavigationEntryImpl* entry1 = NavigationEntryImpl::FromNavigationEntry(
      shell()->web_contents()->GetController().GetLastCommittedEntry());
  SiteInstance* site_instance1 = entry1->site_instance();
  EXPECT_EQ(base::ASCIIToUTF16("A"), entry1->GetTitle());

  // Force a process switch by going to a privileged page.
  GURL web_ui_page(std::string(kChromeUIScheme) + "://" +
                   std::string(kChromeUIGpuHost));
  NavigateToURL(shell(), web_ui_page);
  NavigationEntryImpl* entry2 = NavigationEntryImpl::FromNavigationEntry(
      shell()->web_contents()->GetController().GetLastCommittedEntry());
  SiteInstance* site_instance2 = entry2->site_instance();
  EXPECT_NE(site_instance1, site_instance2);

  EXPECT_EQ(2, shell()->web_contents()->GetController().GetEntryCount());
  EXPECT_EQ(base::ASCIIToUTF16("B"), entry1->GetTitle());
}

IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, OpenURLSubframe) {
  // Navigate to a page with frames and grab a subframe's FrameTreeNode ID.
  ASSERT_TRUE(embedded_test_server()->Start());
  NavigateToURL(shell(),
                embedded_test_server()->GetURL("/frame_tree/top.html"));
  WebContentsImpl* wc = static_cast<WebContentsImpl*>(shell()->web_contents());
  FrameTreeNode* root = wc->GetFrameTree()->root();
  ASSERT_EQ(3UL, root->child_count());
  int frame_tree_node_id = root->child_at(0)->frame_tree_node_id();
  EXPECT_NE(-1, frame_tree_node_id);

  // Navigate with the subframe's FrameTreeNode ID.
  const GURL url(embedded_test_server()->GetURL("/title1.html"));
  OpenURLParams params(url, Referrer(), frame_tree_node_id,
                       WindowOpenDisposition::CURRENT_TAB,
                       ui::PAGE_TRANSITION_LINK, true);
  params.initiator_origin = wc->GetMainFrame()->GetLastCommittedOrigin();
  shell()->web_contents()->OpenURL(params);

  // Make sure the NavigationEntry ends up with the FrameTreeNode ID.
  NavigationController* controller = &shell()->web_contents()->GetController();
  EXPECT_TRUE(controller->GetPendingEntry());
  EXPECT_EQ(frame_tree_node_id,
            NavigationEntryImpl::FromNavigationEntry(
                controller->GetPendingEntry())->frame_tree_node_id());
}

IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
                       AppendingFrameInWebUIDoesNotCrash) {
  const GURL kWebUIUrl(GetWebUIURL("tracing"));
  const char kJSCodeForAppendingFrame[] =
      "document.body.appendChild(document.createElement('iframe'));";

  NavigateToURL(shell(), kWebUIUrl);

  EXPECT_TRUE(content::ExecuteScript(shell(), kJSCodeForAppendingFrame));
}

// Observer class to track the creation of RenderFrameHost objects. It is used
// in subsequent tests.
class RenderFrameCreatedObserver : public WebContentsObserver {
 public:
  explicit RenderFrameCreatedObserver(Shell* shell)
      : WebContentsObserver(shell->web_contents()), last_rfh_(nullptr) {}

  void RenderFrameCreated(RenderFrameHost* render_frame_host) override {
    last_rfh_ = render_frame_host;
  }

  RenderFrameHost* last_rfh() const { return last_rfh_; }

 private:
  RenderFrameHost* last_rfh_;

  DISALLOW_COPY_AND_ASSIGN(RenderFrameCreatedObserver);
};

// Test that creation of new RenderFrameHost objects sends the correct object
// to the WebContentObservers. See http://crbug.com/347339.
IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
                       RenderFrameCreatedCorrectProcessForObservers) {
  static const char kFooCom[] = "foo.com";
  GURL::Replacements replace_host;
  net::HostPortPair foo_host_port;
  GURL cross_site_url;

  ASSERT_TRUE(embedded_test_server()->Start());

  foo_host_port = embedded_test_server()->host_port_pair();
  foo_host_port.set_host(kFooCom);

  GURL initial_url(embedded_test_server()->GetURL("/title1.html"));

  cross_site_url = embedded_test_server()->GetURL("/title2.html");
  replace_host.SetHostStr(kFooCom);
  cross_site_url = cross_site_url.ReplaceComponents(replace_host);

  // Navigate to the initial URL and capture the RenderFrameHost for later
  // comparison.
  NavigateToURL(shell(), initial_url);
  RenderFrameHost* orig_rfh = shell()->web_contents()->GetMainFrame();

  // Install the observer and navigate cross-site.
  RenderFrameCreatedObserver observer(shell());
  NavigateToURL(shell(), cross_site_url);

  // The observer should've seen a RenderFrameCreated call for the new frame
  // and not the old one.
  EXPECT_NE(observer.last_rfh(), orig_rfh);
  EXPECT_EQ(observer.last_rfh(), shell()->web_contents()->GetMainFrame());
}

IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
                       LoadingStateChangedForSameDocumentNavigation) {
  ASSERT_TRUE(embedded_test_server()->Start());
  std::unique_ptr<LoadingStateChangedDelegate> delegate(
      new LoadingStateChangedDelegate());
  shell()->web_contents()->SetDelegate(delegate.get());

  LoadStopNotificationObserver load_observer(
      &shell()->web_contents()->GetController());
  TitleWatcher title_watcher(shell()->web_contents(),
                             base::ASCIIToUTF16("pushState"));
  NavigateToURL(shell(), embedded_test_server()->GetURL("/push_state.html"));
  load_observer.Wait();
  base::string16 title = title_watcher.WaitAndGetTitle();
  ASSERT_EQ(title, base::ASCIIToUTF16("pushState"));

  // LoadingStateChanged should be called 5 times: start and stop for the
  // initial load of push_state.html, once for the switch from
  // IsWaitingForResponse() to !IsWaitingForResponse(), and start and stop for
  // the "navigation" triggered by history.pushState(). However, the start
  // notification for the history.pushState() navigation should set
  // to_different_document to false.
  EXPECT_EQ("pushState", shell()->web_contents()->GetLastCommittedURL().ref());
  EXPECT_EQ(5, delegate->loadingStateChangedCount());
  EXPECT_EQ(4, delegate->loadingStateToDifferentDocumentCount());
}

IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
                       RenderViewCreatedForChildWindow) {
  ASSERT_TRUE(embedded_test_server()->Start());

  NavigateToURL(shell(),
                embedded_test_server()->GetURL("/title1.html"));

  WebContentsAddedObserver new_web_contents_observer;
  ASSERT_TRUE(ExecuteScript(shell(),
                            "var a = document.createElement('a');"
                            "a.href='./title2.html';"
                            "a.target = '_blank';"
                            "document.body.appendChild(a);"
                            "a.click();"));
  WebContents* new_web_contents = new_web_contents_observer.GetWebContents();
  WaitForLoadStop(new_web_contents);
  EXPECT_TRUE(new_web_contents_observer.RenderViewCreatedCalled());
}

// Observer class to track resource loads.
class ResourceLoadObserver : public WebContentsObserver {
 public:
  explicit ResourceLoadObserver(Shell* shell)
      : WebContentsObserver(shell->web_contents()) {}

  const std::vector<mojom::ResourceLoadInfoPtr>& resource_load_infos() const {
    return resource_load_infos_;
  }

  const std::vector<bool>& resource_is_associated_with_main_frame() const {
    return resource_is_associated_with_main_frame_;
  }

  const std::vector<GURL>& memory_cached_loaded_urls() const {
    return memory_cached_loaded_urls_;
  }

  // Use this method with the SCOPED_TRACE macro, so it shows the caller context
  // if it fails.
  void CheckResourceLoaded(
      const GURL& url,
      const GURL& referrer,
      const std::string& load_method,
      content::ResourceType resource_type,
      const base::FilePath::StringPieceType& served_file_name,
      const std::string& mime_type,
      const std::string& ip_address,
      bool was_cached,
      bool first_network_request,
      const base::TimeTicks& before_request,
      const base::TimeTicks& after_request) {
    bool resource_load_info_found = false;
    for (const auto& resource_load_info : resource_load_infos_) {
      if (resource_load_info->url != url)
        continue;

      resource_load_info_found = true;
      int64_t file_size = -1;
      if (!served_file_name.empty()) {
        base::ScopedAllowBlockingForTesting allow_blocking;
        base::FilePath test_dir;
        ASSERT_TRUE(base::PathService::Get(content::DIR_TEST_DATA, &test_dir));
        base::FilePath served_file = test_dir.Append(served_file_name);
        ASSERT_TRUE(GetFileSize(served_file, &file_size));
      }
      EXPECT_EQ(referrer, resource_load_info->referrer);
      EXPECT_EQ(load_method, resource_load_info->method);
      EXPECT_EQ(resource_type, resource_load_info->resource_type);
      if (!first_network_request)
        EXPECT_GT(resource_load_info->request_id, 0);
      EXPECT_EQ(mime_type, resource_load_info->mime_type);
      ASSERT_TRUE(resource_load_info->network_info->remote_endpoint);
      EXPECT_EQ(ip_address, resource_load_info->network_info->remote_endpoint
                                ->ToStringWithoutPort());
      EXPECT_EQ(was_cached, resource_load_info->was_cached);
      // Simple sanity check of the load timing info.
      auto CheckTime = [before_request, after_request](auto actual) {
        EXPECT_LE(before_request, actual);
        EXPECT_GT(after_request, actual);
      };
      const net::LoadTimingInfo& timing = resource_load_info->load_timing_info;
      CheckTime(timing.request_start);
      CheckTime(timing.receive_headers_end);
      CheckTime(timing.send_start);
      CheckTime(timing.send_end);
      if (!was_cached) {
        CheckTime(timing.connect_timing.dns_start);
        CheckTime(timing.connect_timing.dns_end);
        CheckTime(timing.connect_timing.connect_start);
        CheckTime(timing.connect_timing.connect_end);
      }
      if (file_size != -1) {
        EXPECT_EQ(file_size, resource_load_info->raw_body_bytes);
        EXPECT_LT(file_size, resource_load_info->total_received_bytes);
      }
    }
    EXPECT_TRUE(resource_load_info_found);
  }

  // Returns the resource with the given url if found, otherwise nullptr.
  mojom::ResourceLoadInfoPtr* FindResource(const GURL& url) {
    for (auto& resource : resource_load_infos_) {
      if (resource->url == url)
        return &resource;
    }
    return nullptr;
  }

  void Reset() {
    resource_load_infos_.clear();
    memory_cached_loaded_urls_.clear();
    resource_is_associated_with_main_frame_.clear();
  }

  void WaitForResourceCompletion(const GURL& url) {
    // If we've already seen the resource, return immediately.
    for (const auto& load_info : resource_load_infos_) {
      if (load_info->url == url)
        return;
    }

    // Otherwise wait for it.
    base::RunLoop loop;
    waiting_url_ = url;
    waiting_callback_ = loop.QuitClosure();
    loop.Run();
  }

 private:
  // WebContentsObserver implementation:
  void ResourceLoadComplete(
      content::RenderFrameHost* render_frame_host,
      const GlobalRequestID& request_id,
      const mojom::ResourceLoadInfo& resource_load_info) override {
    EXPECT_NE(nullptr, render_frame_host);
    resource_load_infos_.push_back(resource_load_info.Clone());
    resource_is_associated_with_main_frame_.push_back(
        render_frame_host->GetParent() == nullptr);

    // Have we been waiting for this resource? If so, run the callback.
    if (waiting_url_.is_valid() && resource_load_info.url == waiting_url_) {
      waiting_url_ = GURL();
      std::move(waiting_callback_).Run();
    }
  }

  void DidLoadResourceFromMemoryCache(const GURL& url,
                                      const std::string& mime_type,
                                      ResourceType resource_type) override {
    memory_cached_loaded_urls_.push_back(url);
  }

  std::vector<GURL> memory_cached_loaded_urls_;
  std::vector<mojom::ResourceLoadInfoPtr> resource_load_infos_;
  std::vector<bool> resource_is_associated_with_main_frame_;
  GURL waiting_url_;
  base::OnceClosure waiting_callback_;

  DISALLOW_COPY_AND_ASSIGN(ResourceLoadObserver);
};

IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, ResourceLoadComplete) {
  ResourceLoadObserver observer(shell());
  ASSERT_TRUE(embedded_test_server()->Start());
  // Load a page with an image and an image.
  GURL page_url(embedded_test_server()->GetURL("/page_with_iframe.html"));
  base::TimeTicks before = base::TimeTicks::Now();
  NavigateToURL(shell(), page_url);
  base::TimeTicks after = base::TimeTicks::Now();
  ASSERT_EQ(3U, observer.resource_load_infos().size());
  SCOPE_TRACED(observer.CheckResourceLoaded(
      page_url, /*referrer=*/GURL(), "GET", content::ResourceType::kMainFrame,
      FILE_PATH_LITERAL("page_with_iframe.html"), "text/html", "127.0.0.1",
      /*was_cached=*/false, /*first_network_request=*/true, before, after));
  SCOPE_TRACED(observer.CheckResourceLoaded(
      embedded_test_server()->GetURL("/image.jpg"),
      /*referrer=*/page_url, "GET", content::ResourceType::kImage,
      FILE_PATH_LITERAL("image.jpg"), "image/jpeg", "127.0.0.1",
      /*was_cached=*/false, /*first_network_request=*/false, before, after));
  SCOPE_TRACED(observer.CheckResourceLoaded(
      embedded_test_server()->GetURL("/title1.html"),
      /*referrer=*/page_url, "GET", content::ResourceType::kSubFrame,
      FILE_PATH_LITERAL("title1.html"), "text/html", "127.0.0.1",
      /*was_cached=*/false, /*first_network_request=*/false, before, after));
}

// Same as WebContentsImplBrowserTest.ResourceLoadComplete but with resources
// retrieved from the network cache.
IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
                       ResourceLoadCompleteFromNetworkCache) {
  ResourceLoadObserver observer(shell());
  ASSERT_TRUE(embedded_test_server()->Start());
  GURL page_url(
      embedded_test_server()->GetURL("/page_with_cached_subresource.html"));
  base::TimeTicks before = base::TimeTicks::Now();
  NavigateToURL(shell(), page_url);
  base::TimeTicks after = base::TimeTicks::Now();

  GURL resource_url = embedded_test_server()->GetURL("/cachetime");
  ASSERT_EQ(2U, observer.resource_load_infos().size());
  SCOPE_TRACED(observer.CheckResourceLoaded(
      page_url, /*referrer=*/GURL(), "GET", content::ResourceType::kMainFrame,
      /*served_file_name=*/FILE_PATH_LITERAL(""), "text/html", "127.0.0.1",
      /*was_cached=*/false,
      /*first_network_request=*/true, before, after));

  SCOPE_TRACED(observer.CheckResourceLoaded(
      resource_url, /*referrer=*/page_url, "GET",
      content::ResourceType::kScript,
      /*served_file_name=*/FILE_PATH_LITERAL(""), "text/html", "127.0.0.1",
      /*was_cached=*/false, /*first_network_request=*/false, before, after));
  EXPECT_TRUE(
      observer.resource_load_infos()[1]->network_info->network_accessed);
  EXPECT_TRUE(observer.memory_cached_loaded_urls().empty());
  observer.Reset();

  // Loading again should serve the request out of the in-memory cache.
  before = base::TimeTicks::Now();
  NavigateToURL(shell(), page_url);
  after = base::TimeTicks::Now();
  ASSERT_EQ(1U, observer.resource_load_infos().size());
  SCOPE_TRACED(observer.CheckResourceLoaded(
      page_url, /*referrer=*/GURL(), "GET", content::ResourceType::kMainFrame,
      /*served_file_name=*/FILE_PATH_LITERAL(""), "text/html", "127.0.0.1",
      /*was_cached=*/false, /*first_network_request=*/false, before, after));
  ASSERT_EQ(1U, observer.memory_cached_loaded_urls().size());
  EXPECT_EQ(resource_url, observer.memory_cached_loaded_urls()[0]);
  observer.Reset();

  // Kill the renderer process so when the navigate again, it will be a fresh
  // renderer with an empty in-memory cache.
  ScopedAllowRendererCrashes scoped_allow_renderer_crashes;
  NavigateToURL(shell(), GetWebUIURL("crash"));

  // Reload that URL, the subresource should be served from the network cache.
  before = base::TimeTicks::Now();
  NavigateToURL(shell(), page_url);
  after = base::TimeTicks::Now();
  ASSERT_EQ(2U, observer.resource_load_infos().size());
  SCOPE_TRACED(observer.CheckResourceLoaded(
      page_url, /*referrer=*/GURL(), "GET", content::ResourceType::kMainFrame,
      /*served_file_name=*/FILE_PATH_LITERAL(""), "text/html", "127.0.0.1",
      /*was_cached=*/false, /*first_network_request=*/true, before, after));
  SCOPE_TRACED(observer.CheckResourceLoaded(
      resource_url, /*referrer=*/page_url, "GET",
      content::ResourceType::kScript,
      /*served_file_name=*/FILE_PATH_LITERAL(""), "text/html", "127.0.0.1",
      /*was_cached=*/true, /*first_network_request=*/false, before, after));
  EXPECT_TRUE(observer.memory_cached_loaded_urls().empty());
  EXPECT_FALSE(
      observer.resource_load_infos()[1]->network_info->network_accessed);
}

class WebContentsSplitCacheBrowserTest : public WebContentsImplBrowserTest {
 public:
  enum class Context { kMainFrame, kSameOriginFrame, kCrossOriginFrame };
  WebContentsSplitCacheBrowserTest() {}

  // WebContentsImplBrowserTest:
  void SetUpOnMainThread() override {
    WebContentsImplBrowserTest::SetUpOnMainThread();

    embedded_test_server()->RegisterRequestHandler(base::BindRepeating(
        &WebContentsSplitCacheBrowserTest::CachedScriptHandler,
        base::Unretained(this)));
    ASSERT_TRUE(embedded_test_server()->Start());
  }

  std::unique_ptr<net::test_server::HttpResponse> CachedScriptHandler(
      const net::test_server::HttpRequest& request) {
    GURL absolute_url = embedded_test_server()->GetURL(request.relative_url);

    // Return a page that redirects to d.com/title1.html.
    if (absolute_url.path() == "/redirect_to_d") {
      auto http_response =
          std::make_unique<net::test_server::BasicHttpResponse>();
      http_response->set_code(net::HTTP_SEE_OTHER);
      http_response->AddCustomHeader(
          "Location",
          embedded_test_server()->GetURL("d.com", "/title1.html").spec());
      return http_response;
    }

    // Return valid cacheable script.
    if (absolute_url.path() == "/script") {
      auto http_response =
          std::make_unique<net::test_server::BasicHttpResponse>();
      http_response->set_code(net::HTTP_OK);
      http_response->set_content("console.log(\"Hello World\");");
      http_response->set_content_type("application/javascript");
      http_response->AddCustomHeader("Cache-Control", "max-age=1000");
      return http_response;
    }

    // A basic worker that loads 3p.com/script
    if (absolute_url.path() == "/worker.js") {
      auto http_response =
          std::make_unique<net::test_server::BasicHttpResponse>();
      http_response->set_code(net::HTTP_OK);

      GURL resource = GenURL("3p.com", "/script");
      std::string content =
          base::StringPrintf("importScripts('%s');", resource.spec().c_str());

      http_response->set_content(content);
      http_response->set_content_type("application/javascript");
      return http_response;
    }

    // A worker that loads a nested /worker.js on an origin provided as a query
    // param.
    if (absolute_url.path() == "/embedding_worker.js") {
      auto http_response =
          std::make_unique<net::test_server::BasicHttpResponse>();
      http_response->set_code(net::HTTP_OK);

      GURL resource =
          GenURL(base::StringPrintf("%s.com", absolute_url.query().c_str()),
                 "/worker.js");

      const char kLoadWorkerScript[] = "let w = new Worker('%s');";
      std::string content =
          base::StringPrintf(kLoadWorkerScript, resource.spec().c_str());

      http_response->set_content(content);
      http_response->set_content_type("application/javascript");
      return http_response;
    }

    return std::unique_ptr<net::test_server::HttpResponse>();
  }

 protected:
  // Terminates the renderer to clear the in-memory cache.
  void TerminateRenderer() {
    RenderProcessHost* process =
        shell()->web_contents()->GetMainFrame()->GetProcess();
    RenderProcessHostWatcher process_watcher(
        process, RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
    ScopedAllowRendererCrashes scoped_allow_renderer_crashes;
    NavigateToURL(shell(), GetWebUIURL("crash"));
    process_watcher.Wait();
  }

  bool TestResourceLoadFromDedicatedWorker(const GURL& url,
                                           const GURL& worker) {
    TerminateRenderer();

    // Observe network requests.
    ResourceLoadObserver observer(shell());

    NavigateToURL(shell(), url);

    const char kLoadWorkerScript[] = "let w = new Worker('%s');";
    std::string create_worker_script =
        base::StringPrintf(kLoadWorkerScript, worker.spec().c_str());

    EXPECT_TRUE(ExecuteScript(shell(), create_worker_script));

    GURL resource = GenURL("3p.com", "/script");
    observer.WaitForResourceCompletion(resource);
    return (*observer.FindResource(resource))->was_cached;
  }

  // Loads 3p.com/script on page |url|, optionally from |sub_frame| if it's
  // valid and return if the script was cached or not.
  bool TestResourceLoad(const GURL& url, const GURL& sub_frame) {
    TerminateRenderer();

    // Observe network requests.
    ResourceLoadObserver observer(shell());

    NavigateToURL(shell(), url);

    RenderFrameHost* host_to_load_resource =
        shell()->web_contents()->GetMainFrame();
    RenderFrameHostImpl* main_frame =
        static_cast<RenderFrameHostImpl*>(host_to_load_resource);

    // If there is supposed to be a sub-frame, create it.
    if (sub_frame.is_valid()) {
      const char kLoadIframeScript[] =
          "var iframe = document.createElement('iframe');"
          "iframe.src='%s';"
          "document.body.appendChild(iframe);";
      std::string create_iframe_script =
          base::StringPrintf(kLoadIframeScript, sub_frame.spec().c_str());
      EXPECT_TRUE(ExecuteScript(shell(), create_iframe_script));
      EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));

      host_to_load_resource =
          static_cast<WebContentsImpl*>(shell()->web_contents())
              ->GetFrameTree()
              ->root()
              ->child_at(0)
              ->current_frame_host();
    }

    const char kLoadResourceScript[] = R"(
    var script = document.createElement("script");
    script.src = '%s';
    document.body.appendChild(script);
  )";
    GURL resource = GenURL("3p.com", "/script");
    std::string loader_script =
        base::StringPrintf(kLoadResourceScript, resource.spec().c_str());

    EXPECT_TRUE(ExecuteScript(host_to_load_resource, loader_script));
    observer.WaitForResourceCompletion(resource);

    // Test the network isolation key.
    RenderFrameHostImpl* frame_host =
        static_cast<RenderFrameHostImpl*>(host_to_load_resource);
    url::Origin top_frame_origin =
        main_frame->frame_tree_node()->current_origin();

    if (!top_frame_origin.opaque()) {
      EXPECT_EQ(net::NetworkIsolationKey(top_frame_origin),
                frame_host->network_isolation_key_);
    }

    return (*observer.FindResource(resource))->was_cached;
  }

  GURL GenURL(const std::string& host, const std::string& path) {
    return embedded_test_server()->GetURL(host, path);
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(WebContentsSplitCacheBrowserTest);
};

class WebContentsSplitCacheBrowserTestEnabled
    : public WebContentsSplitCacheBrowserTest {
 public:
  WebContentsSplitCacheBrowserTestEnabled() {
    feature_list.InitAndEnableFeature(
        net::features::kSplitCacheByTopFrameOrigin);
  }

 private:
  base::test::ScopedFeatureList feature_list;
};

class WebContentsSplitCacheBrowserTestDisabled
    : public WebContentsSplitCacheBrowserTest {
 public:
  WebContentsSplitCacheBrowserTestDisabled() {
    feature_list.InitAndDisableFeature(
        net::features::kSplitCacheByTopFrameOrigin);
  }

 private:
  base::test::ScopedFeatureList feature_list;
};

IN_PROC_BROWSER_TEST_F(WebContentsSplitCacheBrowserTestEnabled, SplitCache) {
  // Load a cacheable resource for the first time, and it's not cached.
  EXPECT_FALSE(TestResourceLoad(GenURL("a.com", "/title1.html"), GURL()));

  // The second time, it's cached.
  EXPECT_TRUE(TestResourceLoad(GenURL("a.com", "/title1.html"), GURL()));

  // Now load it from a different site, and the resource isn't cached because
  // the top frame origin is different.
  EXPECT_FALSE(TestResourceLoad(GenURL("b.com", "/title1.html"), GURL()));

  // Now load it from 3p.com, which is same-site to the cacheable
  // resource. Still not supposed to be cached.
  EXPECT_FALSE(TestResourceLoad(GenURL("3p.com", "/title1.html"), GURL()));

  // Load it from a a.com/redirect_to_d which redirects to d.com/title1.html and
  // the resource shouldn't be cached because now we're on d.com.
  EXPECT_FALSE(TestResourceLoad(GenURL("a.com", "/redirect_to_d"), GURL()));

  // Load the resource from a same-origin iframe on a page where it's already
  // cached. It should still be cached.
  EXPECT_TRUE(TestResourceLoad(GenURL("a.com", "/title1.html"),
                               GenURL("a.com", "/title1.html")));

  // Load the resource from a cross-origin iframe on a page where it's already
  // cached. It should still be cached.
  EXPECT_TRUE(TestResourceLoad(GenURL("a.com", "/title1.html"),
                               GenURL("d.com", "/title1.html")));

  // Load the resource from a same-origin iframe on a page where it's not
  // cached. It should not be cached.
  EXPECT_FALSE(TestResourceLoad(GenURL("e.com", "/title1.html"),
                                GenURL("e.com", "/title1.html")));

  // Load the resource from a cross-origin iframe where the iframe's origin has
  // seen the object before but the top frame hasn't. It should not be cached.
  EXPECT_FALSE(TestResourceLoad(GenURL("f.com", "/title1.html"),
                                GenURL("a.com", "/title1.html")));

  // Load the resource from a data url which has an opaque origin. It shouldn't
  // be cached.
  GURL data_url("data:text/html,<body>Hello World</body>");
  EXPECT_FALSE(TestResourceLoad(data_url, GURL()));

  // Load the same resource from the same data url, it shouldn't be cached
  // because the origin should be unique.
  EXPECT_FALSE(TestResourceLoad(data_url, GURL()));

  // Load the resource from a document that points to about:blank.
  GURL blank_url("about:blank");
  EXPECT_FALSE(TestResourceLoad(blank_url, GURL()));

  // Load the same resource from about:blank url again, it shouldn't be cached
  // because the origin is unique. TODO(crbug.com/888079) will change this
  // behavior and about:blank main frame pages will inherit the origin of the
  // page that opened it.
  EXPECT_FALSE(TestResourceLoad(blank_url, GURL()));

  // TODO(crbug.com/950069): Add tests for about:blank, about:srcdoc subframes
  // when the cache key also starts using subframe origin.
}

IN_PROC_BROWSER_TEST_F(WebContentsSplitCacheBrowserTestDisabled,
                       NonSplitCache) {
  // Load a cacheable resource for the first time, and it's not cached.
  EXPECT_FALSE(TestResourceLoad(GenURL("a.com", "/title1.html"), GURL()));

  // The second time, it's cached.
  EXPECT_TRUE(TestResourceLoad(GenURL("a.com", "/title1.html"), GURL()));

  // Now load it from a different site, and the resource is cached.
  EXPECT_TRUE(TestResourceLoad(GenURL("b.com", "/title1.html"), GURL()));

  // Load it from a cross-origin iframe, and it's still cached.
  EXPECT_TRUE(TestResourceLoad(GenURL("b.com", "/title1.html"),
                               GenURL("c.com", "/title1.html")));
}

IN_PROC_BROWSER_TEST_F(WebContentsSplitCacheBrowserTestEnabled,
                       SplitCacheDedicatedWorkers) {
  // Load 3p.com/script from a.com's worker. The first time it's loaded from the
  // network and the second it's cached.
  EXPECT_FALSE(TestResourceLoadFromDedicatedWorker(
      GenURL("a.com", "/title1.html"), GenURL("a.com", "/worker.js")));
  EXPECT_TRUE(TestResourceLoadFromDedicatedWorker(
      GenURL("a.com", "/title1.html"), GenURL("a.com", "/worker.js")));

  // Load 3p.com/script from a worker with a new top frame origin. Due to split
  // caching it's a cache miss.
  EXPECT_FALSE(TestResourceLoadFromDedicatedWorker(
      GenURL("b.com", "/title1.html"), GenURL("b.com", "/worker.js")));
  EXPECT_TRUE(TestResourceLoadFromDedicatedWorker(
      GenURL("b.com", "/title1.html"), GenURL("b.com", "/worker.js")));

  // Load 3p.com/script from a nested worker with a new top-frame origin. Due to
  // split caching it's a cache miss.
  EXPECT_FALSE(TestResourceLoadFromDedicatedWorker(
      GenURL("c.com", "/title1.html"),
      GenURL("c.com", "/embedding_worker.js?c")));
  EXPECT_TRUE(TestResourceLoadFromDedicatedWorker(
      GenURL("c.com", "/title1.html"),
      GenURL("c.com", "/embedding_worker.js?c")));
}

IN_PROC_BROWSER_TEST_F(WebContentsSplitCacheBrowserTestDisabled,
                       SplitCacheDedicatedWorkers) {
  // Load 3p.com/script from a.com's worker. The first time it's loaded from the
  // network and the second it's cached.
  EXPECT_FALSE(TestResourceLoadFromDedicatedWorker(
      GenURL("a.com", "/title1.html"), GenURL("a.com", "/worker.js")));
  EXPECT_TRUE(TestResourceLoadFromDedicatedWorker(
      GenURL("a.com", "/title1.html"), GenURL("a.com", "/worker.js")));

  // Load 3p.com/script from b.com's worker. The cache isn't split by top frame
  // origin so the resource is already cached.
  EXPECT_TRUE(TestResourceLoadFromDedicatedWorker(
      GenURL("b.com", "/title1.html"), GenURL("b.com", "/worker.js")));

  // Load 3p.com/script from a nested worker with a new top-frame origin. The
  // cache isn't split by top frame origin so the resource is already cached.
  EXPECT_TRUE(TestResourceLoadFromDedicatedWorker(
      GenURL("c.com", "/title1.html"),
      GenURL("c.com", "/embedding_worker.js?c")));
}

IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
                       ResourceLoadCompleteFromLocalResource) {
  ResourceLoadObserver observer(shell());
  ASSERT_TRUE(embedded_test_server()->Start());
  NavigateToURL(shell(),
                GURL(embedded_test_server()->GetURL("/page_with_image.html")));
  ASSERT_EQ(2U, observer.resource_load_infos().size());
  EXPECT_TRUE(
      observer.resource_load_infos()[0]->network_info->network_accessed);
  EXPECT_TRUE(
      observer.resource_load_infos()[1]->network_info->network_accessed);
  observer.Reset();

  NavigateToURL(shell(), GetWebUIURL("gpu"));
  ASSERT_LE(1U, observer.resource_load_infos().size());
  for (const mojom::ResourceLoadInfoPtr& resource_load_info :
       observer.resource_load_infos()) {
    EXPECT_FALSE(resource_load_info->network_info->network_accessed);
  }
}

IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
                       ResourceLoadCompleteWithRedirect) {
  ResourceLoadObserver observer(shell());
  ASSERT_TRUE(embedded_test_server()->Start());

  GURL page_destination_url(
      embedded_test_server()->GetURL("/page_with_image_redirect.html"));
  GURL page_original_url(embedded_test_server()->GetURL(
      "/server-redirect?" + page_destination_url.spec()));
  NavigateToURL(shell(), page_original_url);

  ASSERT_EQ(2U, observer.resource_load_infos().size());
  const mojom::ResourceLoadInfoPtr& page_load_info =
      observer.resource_load_infos()[0];
  EXPECT_EQ(page_destination_url, page_load_info->url);
  EXPECT_EQ(page_original_url, page_load_info->original_url);

  GURL image_destination_url(embedded_test_server()->GetURL("/blank.jpg"));
  GURL image_original_url(
      embedded_test_server()->GetURL("/server-redirect?blank.jpg"));
  const mojom::ResourceLoadInfoPtr& image_load_info =
      observer.resource_load_infos()[1];
  EXPECT_EQ(image_destination_url, image_load_info->url);
  EXPECT_EQ(image_original_url, image_load_info->original_url);
}

IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
                       ResourceLoadCompleteNetError) {
  ResourceLoadObserver observer(shell());
  ASSERT_TRUE(embedded_test_server()->Start());

  GURL page_url(embedded_test_server()->GetURL("/page_with_image.html"));
  GURL image_url(embedded_test_server()->GetURL("/blank.jpg"));

  // Load the page without errors.
  NavigateToURL(shell(), page_url);
  ASSERT_EQ(2U, observer.resource_load_infos().size());
  EXPECT_EQ(net::OK, observer.resource_load_infos()[0]->net_error);
  EXPECT_EQ(net::OK, observer.resource_load_infos()[1]->net_error);
  observer.Reset();

  // Load the page and simulate a network error.
  content::URLLoaderInterceptor url_interceptor(base::BindRepeating(
      [](const GURL& url,
         content::URLLoaderInterceptor::RequestParams* params) {
        if (params->url_request.url != url)
          return false;
        network::URLLoaderCompletionStatus status;
        status.error_code = net::ERR_ADDRESS_UNREACHABLE;
        params->client->OnComplete(status);
        return true;
      },
      image_url));
  NavigateToURL(shell(), page_url);
  ASSERT_EQ(2U, observer.resource_load_infos().size());
  EXPECT_EQ(net::OK, observer.resource_load_infos()[0]->net_error);
  EXPECT_EQ(net::ERR_ADDRESS_UNREACHABLE,
            observer.resource_load_infos()[1]->net_error);
}

IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
                       ResourceLoadCompleteAlwaysAccessNetwork) {
  ResourceLoadObserver observer(shell());
  ASSERT_TRUE(embedded_test_server()->Start());

  GURL cacheable_url(embedded_test_server()->GetURL("/set-header"));
  NavigateToURL(shell(), cacheable_url);
  ASSERT_EQ(1U, observer.resource_load_infos().size());
  EXPECT_FALSE(
      observer.resource_load_infos()[0]->network_info->always_access_network);
  observer.Reset();

  std::array<std::string, 3> headers = {
      "cache-control: no-cache", "cache-control: no-store", "pragma: no-cache"};
  for (const std::string& header : headers) {
    GURL no_cache_url(embedded_test_server()->GetURL("/set-header?" + header));
    NavigateToURL(shell(), no_cache_url);
    ASSERT_EQ(1U, observer.resource_load_infos().size());
    EXPECT_TRUE(
        observer.resource_load_infos()[0]->network_info->always_access_network);
    observer.Reset();
  }
}

IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
                       ResourceLoadCompleteWithRedirects) {
  ResourceLoadObserver observer(shell());
  ASSERT_TRUE(embedded_test_server()->Start());

  GURL target_url(embedded_test_server()->GetURL("/title1.html"));
  GURL intermediate_url(
      embedded_test_server()->GetURL("/server-redirect?" + target_url.spec()));
  GURL start_url(embedded_test_server()->GetURL("/server-redirect?" +
                                                intermediate_url.spec()));

  NavigateToURL(shell(), start_url);

  ASSERT_EQ(1U, observer.resource_load_infos().size());
  EXPECT_EQ(target_url, observer.resource_load_infos()[0]->url);

  ASSERT_EQ(2U, observer.resource_load_infos()[0]->redirect_info_chain.size());
  EXPECT_EQ(intermediate_url,
            observer.resource_load_infos()[0]->redirect_info_chain[0]->url);
  EXPECT_TRUE(observer.resource_load_infos()[0]
                  ->redirect_info_chain[0]
                  ->network_info->network_accessed);
  EXPECT_FALSE(observer.resource_load_infos()[0]
                   ->redirect_info_chain[0]
                   ->network_info->always_access_network);
  EXPECT_EQ(target_url,
            observer.resource_load_infos()[0]->redirect_info_chain[1]->url);
  EXPECT_TRUE(observer.resource_load_infos()[0]
                  ->redirect_info_chain[1]
                  ->network_info->network_accessed);
  EXPECT_FALSE(observer.resource_load_infos()[0]
                   ->redirect_info_chain[1]
                   ->network_info->always_access_network);
}

IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
                       ResourceLoadCompleteIsMainFrame) {
  ResourceLoadObserver observer(shell());
  ASSERT_TRUE(embedded_test_server()->Start());

  GURL url(embedded_test_server()->GetURL("/page_with_image.html"));
  NavigateToURL(shell(), url);
  ASSERT_EQ(2U, observer.resource_load_infos().size());
  EXPECT_EQ(url, observer.resource_load_infos()[0]->url);
  EXPECT_TRUE(observer.resource_is_associated_with_main_frame()[0]);
  EXPECT_TRUE(observer.resource_is_associated_with_main_frame()[1]);
  observer.Reset();

  // Load that same page inside an iframe.
  GURL data_url("data:text/html,<iframe src='" + url.spec() + "'></iframe>");
  NavigateToURL(shell(), data_url);
  ASSERT_EQ(3U, observer.resource_load_infos().size());
  EXPECT_EQ(data_url, observer.resource_load_infos()[0]->url);
  EXPECT_EQ(url, observer.resource_load_infos()[1]->url);
  EXPECT_TRUE(observer.resource_is_associated_with_main_frame()[0]);
  EXPECT_FALSE(observer.resource_is_associated_with_main_frame()[1]);
  EXPECT_FALSE(observer.resource_is_associated_with_main_frame()[2]);
}

struct LoadProgressDelegateAndObserver : public WebContentsDelegate,
                                         public WebContentsObserver {
  explicit LoadProgressDelegateAndObserver(Shell* shell)
      : WebContentsObserver(shell->web_contents()),
        did_start_loading(false),
        did_stop_loading(false) {
    web_contents()->SetDelegate(this);
  }

  // WebContentsDelegate:
  void LoadProgressChanged(WebContents* source, double progress) override {
    EXPECT_TRUE(did_start_loading);
    EXPECT_FALSE(did_stop_loading);
    progresses.push_back(progress);
  }

  // WebContentsObserver:
  void DidStartLoading() override {
    EXPECT_FALSE(did_start_loading);
    EXPECT_EQ(0U, progresses.size());
    EXPECT_FALSE(did_stop_loading);
    did_start_loading = true;
  }

  void DidStopLoading() override {
    EXPECT_TRUE(did_start_loading);
    EXPECT_GE(progresses.size(), 1U);
    EXPECT_FALSE(did_stop_loading);
    did_stop_loading = true;
  }

  bool did_start_loading;
  std::vector<double> progresses;
  bool did_stop_loading;
};

IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, LoadProgress) {
  ASSERT_TRUE(embedded_test_server()->Start());
  std::unique_ptr<LoadProgressDelegateAndObserver> delegate(
      new LoadProgressDelegateAndObserver(shell()));

  NavigateToURL(shell(), embedded_test_server()->GetURL("/title1.html"));

  const std::vector<double>& progresses = delegate->progresses;
  // All updates should be in order ...
  if (std::adjacent_find(progresses.begin(),
                         progresses.end(),
                         std::greater<double>()) != progresses.end()) {
    ADD_FAILURE() << "Progress values should be in order: "
                  << ::testing::PrintToString(progresses);
  }

  // ... and the last one should be 1.0, meaning complete.
  ASSERT_GE(progresses.size(), 1U)
      << "There should be at least one progress update";
  EXPECT_EQ(1.0, *progresses.rbegin());
}

IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, LoadProgressWithFrames) {
  ASSERT_TRUE(embedded_test_server()->Start());
  std::unique_ptr<LoadProgressDelegateAndObserver> delegate(
      new LoadProgressDelegateAndObserver(shell()));

  NavigateToURL(shell(),
                embedded_test_server()->GetURL("/frame_tree/top.html"));

  const std::vector<double>& progresses = delegate->progresses;
  // All updates should be in order ...
  if (std::adjacent_find(progresses.begin(),
                         progresses.end(),
                         std::greater<double>()) != progresses.end()) {
    ADD_FAILURE() << "Progress values should be in order: "
                  << ::testing::PrintToString(progresses);
  }

  // ... and the last one should be 1.0, meaning complete.
  ASSERT_GE(progresses.size(), 1U)
      << "There should be at least one progress update";
  EXPECT_EQ(1.0, *progresses.rbegin());
}

// Ensure that a new navigation that interrupts a pending one will still fire
// a DidStopLoading.  See http://crbug.com/429399.
IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
                       LoadProgressAfterInterruptedNav) {
  ASSERT_TRUE(embedded_test_server()->Start());

  // Start at a real page.
  NavigateToURL(shell(), embedded_test_server()->GetURL("/title1.html"));

  // Simulate a navigation that has not completed.
  const GURL kURL2 = embedded_test_server()->GetURL("/title2.html");
  TestNavigationManager navigation(shell()->web_contents(), kURL2);
  std::unique_ptr<LoadProgressDelegateAndObserver> delegate(
      new LoadProgressDelegateAndObserver(shell()));
  shell()->LoadURL(kURL2);
  EXPECT_TRUE(navigation.WaitForResponse());
  EXPECT_TRUE(delegate->did_start_loading);
  EXPECT_FALSE(delegate->did_stop_loading);

  // Also simulate a DidChangeLoadProgress, but not a DidStopLoading.
  RenderFrameHostImpl* main_frame = static_cast<RenderFrameHostImpl*>(
      shell()->web_contents()->GetMainFrame());
  FrameHostMsg_DidChangeLoadProgress progress_msg(main_frame->GetRoutingID(),
                                                  1.0);
  main_frame->OnMessageReceived(progress_msg);
  EXPECT_TRUE(delegate->did_start_loading);
  EXPECT_FALSE(delegate->did_stop_loading);

  // Now interrupt with a new cross-process navigation.
  TestNavigationObserver tab_observer(shell()->web_contents(), 1);
  GURL url(embedded_test_server()->GetURL("foo.com", "/title2.html"));
  shell()->LoadURL(url);
  tab_observer.Wait();
  EXPECT_EQ(url, shell()->web_contents()->GetLastCommittedURL());

  // We should have gotten to DidStopLoading.
  EXPECT_TRUE(delegate->did_stop_loading);
}

struct FirstVisuallyNonEmptyPaintObserver : public WebContentsObserver {
  explicit FirstVisuallyNonEmptyPaintObserver(Shell* shell)
      : WebContentsObserver(shell->web_contents()),
        did_fist_visually_non_empty_paint_(false) {}

  void DidFirstVisuallyNonEmptyPaint() override {
    did_fist_visually_non_empty_paint_ = true;
    on_did_first_visually_non_empty_paint_.Run();
  }

  void WaitForDidFirstVisuallyNonEmptyPaint() {
    if (did_fist_visually_non_empty_paint_)
      return;
    base::RunLoop run_loop;
    on_did_first_visually_non_empty_paint_ = run_loop.QuitClosure();
    run_loop.Run();
  }

  base::Closure on_did_first_visually_non_empty_paint_;
  bool did_fist_visually_non_empty_paint_;
};

// See: http://crbug.com/395664
#if defined(OS_ANDROID)
#define MAYBE_FirstVisuallyNonEmptyPaint DISABLED_FirstVisuallyNonEmptyPaint
#else
// http://crbug.com/398471
#define MAYBE_FirstVisuallyNonEmptyPaint DISABLED_FirstVisuallyNonEmptyPaint
#endif
IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
                       MAYBE_FirstVisuallyNonEmptyPaint) {
  ASSERT_TRUE(embedded_test_server()->Start());
  std::unique_ptr<FirstVisuallyNonEmptyPaintObserver> observer(
      new FirstVisuallyNonEmptyPaintObserver(shell()));

  NavigateToURL(shell(), embedded_test_server()->GetURL("/title1.html"));

  observer->WaitForDidFirstVisuallyNonEmptyPaint();
  ASSERT_TRUE(observer->did_fist_visually_non_empty_paint_);
}

namespace {

class WebDisplayModeDelegate : public WebContentsDelegate {
 public:
  explicit WebDisplayModeDelegate(blink::WebDisplayMode mode) : mode_(mode) { }
  ~WebDisplayModeDelegate() override { }

  blink::WebDisplayMode GetDisplayMode(
      const WebContents* source) const override { return mode_; }
  void set_mode(blink::WebDisplayMode mode) { mode_ = mode; }
 private:
  blink::WebDisplayMode mode_;

  DISALLOW_COPY_AND_ASSIGN(WebDisplayModeDelegate);
};

}  // namespace

IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, ChangeDisplayMode) {
  ASSERT_TRUE(embedded_test_server()->Start());
  WebDisplayModeDelegate delegate(blink::kWebDisplayModeMinimalUi);
  shell()->web_contents()->SetDelegate(&delegate);

  NavigateToURL(shell(), GURL("about://blank"));

  ASSERT_TRUE(ExecuteScript(shell(),
                            "document.title = "
                            " window.matchMedia('(display-mode:"
                            " minimal-ui)').matches"));
  EXPECT_EQ(base::ASCIIToUTF16("true"), shell()->web_contents()->GetTitle());

  delegate.set_mode(blink::kWebDisplayModeFullscreen);
  // Simulate widget is entering fullscreen (changing size is enough).
  shell()
      ->web_contents()
      ->GetRenderViewHost()
      ->GetWidget()
      ->SynchronizeVisualProperties();

  ASSERT_TRUE(ExecuteScript(shell(),
                            "document.title = "
                            " window.matchMedia('(display-mode:"
                            " fullscreen)').matches"));
  EXPECT_EQ(base::ASCIIToUTF16("true"), shell()->web_contents()->GetTitle());
}

// Observer class used to verify that WebContentsObservers are notified
// when the page scale factor changes.
// See WebContentsImplBrowserTest.ChangePageScale.
class MockPageScaleObserver : public WebContentsObserver {
 public:
  explicit MockPageScaleObserver(Shell* shell)
      : WebContentsObserver(shell->web_contents()),
        got_page_scale_update_(false) {
    // Once OnPageScaleFactorChanged is called, quit the run loop.
    ON_CALL(*this, OnPageScaleFactorChanged(::testing::_)).WillByDefault(
        ::testing::InvokeWithoutArgs(
            this, &MockPageScaleObserver::GotPageScaleUpdate));
  }

  MOCK_METHOD1(OnPageScaleFactorChanged, void(float page_scale_factor));

  void WaitForPageScaleUpdate() {
    if (!got_page_scale_update_) {
      base::RunLoop run_loop;
      on_page_scale_update_ = run_loop.QuitClosure();
      run_loop.Run();
    }
    got_page_scale_update_ = false;
  }

 private:
  void GotPageScaleUpdate() {
    got_page_scale_update_ = true;
    on_page_scale_update_.Run();
  }

  base::Closure on_page_scale_update_;
  bool got_page_scale_update_;
};

// When the page scale factor is set in the renderer it should send
// a notification to the browser so that WebContentsObservers are notified.
IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, ChangePageScale) {
  ASSERT_TRUE(embedded_test_server()->Start());
  NavigateToURL(shell(), embedded_test_server()->GetURL("/title1.html"));

  MockPageScaleObserver observer(shell());
  ::testing::InSequence expect_call_sequence;

  shell()->web_contents()->SetPageScale(1.5);
  EXPECT_CALL(observer, OnPageScaleFactorChanged(::testing::FloatEq(1.5)));
  observer.WaitForPageScaleUpdate();

  // Navigate to reset the page scale factor.
  shell()->LoadURL(embedded_test_server()->GetURL("/title2.html"));
  EXPECT_CALL(observer, OnPageScaleFactorChanged(::testing::_));
  observer.WaitForPageScaleUpdate();
}

// Test that a direct navigation to a view-source URL works.
IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, ViewSourceDirectNavigation) {
  ASSERT_TRUE(embedded_test_server()->Start());
  const GURL kUrl(embedded_test_server()->GetURL("/simple_page.html"));
  const GURL kViewSourceURL(kViewSourceScheme + std::string(":") + kUrl.spec());
  NavigateToURL(shell(), kViewSourceURL);
  // Displayed view-source URLs don't include the scheme of the effective URL if
  // the effective URL is HTTP. (e.g. view-source:example.com is displayed
  // instead of view-source:http://example.com).
  EXPECT_EQ(base::ASCIIToUTF16(std::string("view-source:") + kUrl.host() + ":" +
                               kUrl.port() + kUrl.path()),
            shell()->web_contents()->GetTitle());
  EXPECT_TRUE(shell()
                  ->web_contents()
                  ->GetController()
                  .GetLastCommittedEntry()
                  ->IsViewSourceMode());
}

// Test that window.open to a view-source URL is blocked.
IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
                       ViewSourceWindowOpen_ShouldBeBlocked) {
  ASSERT_TRUE(embedded_test_server()->Start());
  const GURL kUrl(embedded_test_server()->GetURL("/simple_page.html"));
  const GURL kViewSourceURL(kViewSourceScheme + std::string(":") + kUrl.spec());
  NavigateToURL(shell(), kUrl);

  ShellAddedObserver new_shell_observer;
  EXPECT_TRUE(ExecuteScript(shell()->web_contents(),
                            "window.open('" + kViewSourceURL.spec() + "');"));
  Shell* new_shell = new_shell_observer.GetShell();
  WaitForLoadStop(new_shell->web_contents());
  EXPECT_TRUE(new_shell->web_contents()->GetURL().spec().empty());
  // No navigation should commit.
  EXPECT_FALSE(
      new_shell->web_contents()->GetController().GetLastCommittedEntry());
}

// Test that a content initiated navigation to a view-source URL is blocked.
IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
                       ViewSourceRedirect_ShouldBeBlocked) {
  ASSERT_TRUE(embedded_test_server()->Start());
  const GURL kUrl(embedded_test_server()->GetURL("/simple_page.html"));
  const GURL kViewSourceURL(kViewSourceScheme + std::string(":") + kUrl.spec());
  NavigateToURL(shell(), kUrl);

  std::unique_ptr<ConsoleObserverDelegate> console_delegate(
      new ConsoleObserverDelegate(
          shell()->web_contents(),
          "Not allowed to load local resource: view-source:*"));
  shell()->web_contents()->SetDelegate(console_delegate.get());

  EXPECT_TRUE(
      ExecuteScript(shell()->web_contents(),
                    "window.location = '" + kViewSourceURL.spec() + "';"));
  console_delegate->Wait();
  // Original page shouldn't navigate away.
  EXPECT_EQ(kUrl, shell()->web_contents()->GetURL());
  EXPECT_FALSE(shell()
                   ->web_contents()
                   ->GetController()
                   .GetLastCommittedEntry()
                   ->IsViewSourceMode());
}

// Test that view source mode for a webui page can be opened.
IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, ViewSourceWebUI) {
  const std::string kUrl = "view-source:" + GetWebUIURLString(kChromeUIGpuHost);
  const GURL kGURL(kUrl);
  NavigateToURL(shell(), kGURL);
  EXPECT_EQ(base::ASCIIToUTF16(kUrl), shell()->web_contents()->GetTitle());
  EXPECT_TRUE(shell()
                  ->web_contents()
                  ->GetController()
                  .GetLastCommittedEntry()
                  ->IsViewSourceMode());
}

IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, NewNamedWindow) {
  ASSERT_TRUE(embedded_test_server()->Start());

  GURL url = embedded_test_server()->GetURL("/click-noreferrer-links.html");
  EXPECT_TRUE(NavigateToURL(shell(), url));

  {
    ShellAddedObserver new_shell_observer;

    // Open a new, named window.
    EXPECT_TRUE(
        ExecuteScript(shell(), "window.open('about:blank','new_window');"));

    Shell* new_shell = new_shell_observer.GetShell();
    WaitForLoadStop(new_shell->web_contents());

    EXPECT_EQ("new_window",
              static_cast<WebContentsImpl*>(new_shell->web_contents())
                  ->GetFrameTree()->root()->frame_name());

    bool success = false;
    EXPECT_TRUE(ExecuteScriptAndExtractBool(
        new_shell,
        "window.domAutomationController.send(window.name == 'new_window');",
        &success));
    EXPECT_TRUE(success);
  }

  {
    ShellAddedObserver new_shell_observer;

    // Test clicking a target=foo link.
    bool success = false;
    EXPECT_TRUE(ExecuteScriptAndExtractBool(
        shell(),
        "window.domAutomationController.send(clickSameSiteTargetedLink());",
        &success));
    EXPECT_TRUE(success);

    Shell* new_shell = new_shell_observer.GetShell();
    WaitForLoadStop(new_shell->web_contents());

    EXPECT_EQ("foo",
              static_cast<WebContentsImpl*>(new_shell->web_contents())
                  ->GetFrameTree()->root()->frame_name());
  }
}

// Test that HasOriginalOpener() tracks provenance through closed WebContentses.
IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
                       HasOriginalOpenerTracksThroughClosedWebContents) {
  const GURL blank_url = GURL("about:blank");

  Shell* shell1 = shell();
  EXPECT_TRUE(NavigateToURL(shell1, blank_url));

  Shell* shell2 = OpenPopup(shell1, blank_url, "window2");
  Shell* shell3 = OpenPopup(shell2, blank_url, "window3");

  EXPECT_EQ(shell2->web_contents(),
            WebContents::FromRenderFrameHost(
                shell3->web_contents()->GetOriginalOpener()));
  EXPECT_EQ(shell1->web_contents(),
            WebContents::FromRenderFrameHost(
                shell2->web_contents()->GetOriginalOpener()));

  shell2->Close();

  EXPECT_EQ(shell1->web_contents(),
            WebContents::FromRenderFrameHost(
                shell3->web_contents()->GetOriginalOpener()));
}

// TODO(clamy): Make the test work on Windows and on Mac. On Mac and Windows,
// there seem to be an issue with the ShellJavascriptDialogManager.
// Flaky on all platforms: https://crbug.com/655628
// Test that if a BeforeUnload dialog is destroyed due to the commit of a
// cross-site navigation, it will not reset the loading state.
IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
                       DISABLED_NoResetOnBeforeUnloadCanceledOnCommit) {
  ASSERT_TRUE(embedded_test_server()->Start());
  const GURL kStartURL(
      embedded_test_server()->GetURL("/hang_before_unload.html"));
  const GURL kCrossSiteURL(
      embedded_test_server()->GetURL("bar.com", "/title1.html"));

  // Navigate to a first web page with a BeforeUnload event listener.
  EXPECT_TRUE(NavigateToURL(shell(), kStartURL));

  // Start a cross-site navigation that will not commit for the moment.
  TestNavigationManager cross_site_delayer(shell()->web_contents(),
                                           kCrossSiteURL);
  shell()->LoadURL(kCrossSiteURL);
  EXPECT_TRUE(cross_site_delayer.WaitForRequestStart());

  // Click on a link in the page. This will show the BeforeUnload dialog.
  // Ensure the dialog is not dismissed, which will cause it to still be
  // present when the cross-site navigation later commits.
  // Note: the javascript function executed will not do the link click but
  // schedule it for afterwards. Since the BeforeUnload event is synchronous,
  // clicking on the link right away would cause the ExecuteScript to never
  // return.
  SetShouldProceedOnBeforeUnload(shell(), false, false);
  EXPECT_TRUE(ExecuteScript(shell(), "clickLinkSoon()"));
  WaitForAppModalDialog(shell());

  // Have the cross-site navigation commit. The main RenderFrameHost should
  // still be loading after that.
  cross_site_delayer.WaitForNavigationFinished();
  EXPECT_TRUE(shell()->web_contents()->IsLoading());
}

namespace {
void NavigateToDataURLAndCheckForTerminationDisabler(
    Shell* shell,
    const std::string& html,
    bool expect_onunload,
    bool expect_onbeforeunload) {
  NavigateToURL(shell, GURL("data:text/html," + html));
  RenderFrameHostImpl* rfh =
      static_cast<RenderFrameHostImpl*>(shell->web_contents()->GetMainFrame());
  EXPECT_EQ(expect_onunload || expect_onbeforeunload,
            shell->web_contents()->NeedToFireBeforeUnload());
  EXPECT_EQ(expect_onunload,
            rfh->GetSuddenTerminationDisablerState(blink::kUnloadHandler));
  EXPECT_EQ(expect_onbeforeunload, rfh->GetSuddenTerminationDisablerState(
                                       blink::kBeforeUnloadHandler));
}
}  // namespace

IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
                       SuddenTerminationDisablerNone) {
  const std::string NO_HANDLERS_HTML = "<html><body>foo</body></html>";
  NavigateToDataURLAndCheckForTerminationDisabler(shell(), NO_HANDLERS_HTML,
                                                  false, false);
}

IN_PROC_BROWSER_TEST_F(
    WebContentsImplBrowserTest,
    SuddenTerminationDisablerNoneProcessTerminationDisallowed) {
  const std::string NO_HANDLERS_HTML = "<html><body>foo</body></html>";
  // The WebContents termination disabler should be independent of the
  // RenderProcessHost termination disabler, as process termination can depend
  // on more than the presence of a beforeunload/unload handler.
  shell()
      ->web_contents()
      ->GetMainFrame()
      ->GetProcess()
      ->SetSuddenTerminationAllowed(false);
  NavigateToDataURLAndCheckForTerminationDisabler(shell(), NO_HANDLERS_HTML,
                                                  false, false);
}

IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
                       SuddenTerminationDisablerOnUnload) {
  const std::string UNLOAD_HTML =
      "<html><body><script>window.onunload=function(e) {}</script>"
      "</body></html>";
  NavigateToDataURLAndCheckForTerminationDisabler(shell(), UNLOAD_HTML, true,
                                                  false);
}

IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
                       SuddenTerminationDisablerOnBeforeUnload) {
  const std::string BEFORE_UNLOAD_HTML =
      "<html><body><script>window.onbeforeunload=function(e) {}</script>"
      "</body></html>";
  NavigateToDataURLAndCheckForTerminationDisabler(shell(), BEFORE_UNLOAD_HTML,
                                                  false, true);
}

IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
                       SuddenTerminationDisablerOnUnloadAndBeforeUnload) {
  const std::string UNLOAD_AND_BEFORE_UNLOAD_HTML =
      "<html><body><script>window.onunload=function(e) {};"
      "window.onbeforeunload=function(e) {}</script>"
      "</body></html>";
  NavigateToDataURLAndCheckForTerminationDisabler(
      shell(), UNLOAD_AND_BEFORE_UNLOAD_HTML, true, true);
}

class TestWCDelegateForDialogsAndFullscreen : public JavaScriptDialogManager,
                                              public WebContentsDelegate {
 public:
  explicit TestWCDelegateForDialogsAndFullscreen(WebContentsImpl* web_contents)
      : web_contents_(web_contents) {
    old_delegate_ = web_contents_->GetDelegate();
    web_contents_->SetDelegate(this);
  }
  ~TestWCDelegateForDialogsAndFullscreen() override {
    web_contents_->SetJavaScriptDialogManagerForTesting(nullptr);
    web_contents_->SetDelegate(old_delegate_);
  }

  void WillWaitForDialog() { waiting_for_ = kDialog; }
  void WillWaitForNewContents() { waiting_for_ = kNewContents; }
  void WillWaitForFullscreenExit() { waiting_for_ = kFullscreenExit; }

  void Wait() {
    run_loop_->Run();
    run_loop_ = std::make_unique<base::RunLoop>();
  }

  std::string last_message() { return last_message_; }

  // WebContentsDelegate

  JavaScriptDialogManager* GetJavaScriptDialogManager(
      WebContents* source) override {
    return this;
  }

  void EnterFullscreenModeForTab(
      WebContents* web_contents,
      const GURL& origin,
      const blink::WebFullscreenOptions& options) override {
    is_fullscreen_ = true;
  }

  void ExitFullscreenModeForTab(WebContents*) override {
    is_fullscreen_ = false;

    if (waiting_for_ == kFullscreenExit) {
      waiting_for_ = kNothing;
      run_loop_->Quit();
    }
  }

  bool IsFullscreenForTabOrPending(
      const WebContents* web_contents) const override {
    return is_fullscreen_;
  }

  void AddNewContents(WebContents* source,
                      std::unique_ptr<WebContents> new_contents,
                      WindowOpenDisposition disposition,
                      const gfx::Rect& initial_rect,
                      bool user_gesture,
                      bool* was_blocked) override {
    popup_ = std::move(new_contents);

    if (waiting_for_ == kNewContents) {
      waiting_for_ = kNothing;
      run_loop_->Quit();
    }
  }

  // JavaScriptDialogManager

  void RunJavaScriptDialog(WebContents* web_contents,
                           RenderFrameHost* render_frame_host,
                           JavaScriptDialogType dialog_type,
                           const base::string16& message_text,
                           const base::string16& default_prompt_text,
                           DialogClosedCallback callback,
                           bool* did_suppress_message) override {
    last_message_ = base::UTF16ToUTF8(message_text);
    *did_suppress_message = true;

    if (waiting_for_ == kDialog) {
      waiting_for_ = kNothing;
      run_loop_->Quit();
    }
  }

  void RunBeforeUnloadDialog(WebContents* web_contents,
                             RenderFrameHost* render_frame_host,
                             bool is_reload,
                             DialogClosedCallback callback) override {
    std::move(callback).Run(true, base::string16());

    if (waiting_for_ == kDialog) {
      waiting_for_ = kNothing;
      run_loop_->Quit();
    }
  }

  bool HandleJavaScriptDialog(WebContents* web_contents,
                              bool accept,
                              const base::string16* prompt_override) override {
    return true;
  }

  void CancelDialogs(WebContents* web_contents,
                     bool reset_state) override {}

 private:
  WebContentsImpl* web_contents_;
  WebContentsDelegate* old_delegate_;

  enum {
    kNothing,
    kDialog,
    kNewContents,
    kFullscreenExit
  } waiting_for_ = kNothing;

  std::string last_message_;

  bool is_fullscreen_ = false;

  std::unique_ptr<WebContents> popup_;

  std::unique_ptr<base::RunLoop> run_loop_ = std::make_unique<base::RunLoop>();

  DISALLOW_COPY_AND_ASSIGN(TestWCDelegateForDialogsAndFullscreen);
};

class MockFileSelectListener : public FileSelectListener {
 public:
  MockFileSelectListener() {}
  void FileSelected(std::vector<blink::mojom::FileChooserFileInfoPtr> files,
                    const base::FilePath& base_dir,
                    blink::mojom::FileChooserParams::Mode mode) override {}
  void FileSelectionCanceled() override {}
};

IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
                       JavaScriptDialogsInMainAndSubframes) {
  WebContentsImpl* wc = static_cast<WebContentsImpl*>(shell()->web_contents());
  TestWCDelegateForDialogsAndFullscreen test_delegate(wc);

  ASSERT_TRUE(embedded_test_server()->Start());

  NavigateToURL(shell(),
                embedded_test_server()->GetURL("a.com", "/title1.html"));
  EXPECT_TRUE(WaitForLoadStop(wc));

  FrameTreeNode* root = wc->GetFrameTree()->root();
  ASSERT_EQ(0U, root->child_count());

  std::string script =
      "var iframe = document.createElement('iframe');"
      "document.body.appendChild(iframe);";
  EXPECT_TRUE(content::ExecuteScript(root->current_frame_host(), script));
  EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));

  ASSERT_EQ(1U, root->child_count());
  FrameTreeNode* frame = root->child_at(0);
  ASSERT_NE(nullptr, frame);

  url::Replacements<char> clear_port;
  clear_port.ClearPort();

  // A dialog from the main frame.
  std::string alert_location = "alert(document.location)";
  test_delegate.WillWaitForDialog();
  EXPECT_TRUE(
      content::ExecuteScript(root->current_frame_host(), alert_location));
  test_delegate.Wait();
  EXPECT_EQ(GURL("http://a.com/title1.html"),
            GURL(test_delegate.last_message()).ReplaceComponents(clear_port));

  // A dialog from the subframe.
  test_delegate.WillWaitForDialog();
  EXPECT_TRUE(
      content::ExecuteScript(frame->current_frame_host(), alert_location));
  test_delegate.Wait();
  EXPECT_EQ("about:blank", test_delegate.last_message());

  // Navigate the subframe cross-site.
  NavigateFrameToURL(frame,
                     embedded_test_server()->GetURL("b.com", "/title2.html"));
  EXPECT_TRUE(WaitForLoadStop(wc));

  // A dialog from the subframe.
  test_delegate.WillWaitForDialog();
  EXPECT_TRUE(
      content::ExecuteScript(frame->current_frame_host(), alert_location));
  test_delegate.Wait();
  EXPECT_EQ(GURL("http://b.com/title2.html"),
            GURL(test_delegate.last_message()).ReplaceComponents(clear_port));

  // A dialog from the main frame.
  test_delegate.WillWaitForDialog();
  EXPECT_TRUE(
      content::ExecuteScript(root->current_frame_host(), alert_location));
  test_delegate.Wait();
  EXPECT_EQ(GURL("http://a.com/title1.html"),
            GURL(test_delegate.last_message()).ReplaceComponents(clear_port));

  // Navigate the top frame cross-site; ensure that dialogs work.
  NavigateToURL(shell(),
                embedded_test_server()->GetURL("c.com", "/title3.html"));
  EXPECT_TRUE(WaitForLoadStop(wc));
  test_delegate.WillWaitForDialog();
  EXPECT_TRUE(
      content::ExecuteScript(root->current_frame_host(), alert_location));
  test_delegate.Wait();
  EXPECT_EQ(GURL("http://c.com/title3.html"),
            GURL(test_delegate.last_message()).ReplaceComponents(clear_port));

  // Navigate back; ensure that dialogs work.
  wc->GetController().GoBack();
  EXPECT_TRUE(WaitForLoadStop(wc));
  test_delegate.WillWaitForDialog();
  EXPECT_TRUE(
      content::ExecuteScript(root->current_frame_host(), alert_location));
  test_delegate.Wait();
  EXPECT_EQ(GURL("http://a.com/title1.html"),
            GURL(test_delegate.last_message()).ReplaceComponents(clear_port));
}

IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
                       JavaScriptDialogsNormalizeText) {
  WebContentsImpl* wc = static_cast<WebContentsImpl*>(shell()->web_contents());
  TestWCDelegateForDialogsAndFullscreen test_delegate(wc);

  GURL url("about:blank");
  EXPECT_TRUE(NavigateToURL(shell(), url));

  // A dialog with mixed linebreaks.
  std::string alert = "alert('1\\r2\\r\\n3\\n4')";
  test_delegate.WillWaitForDialog();
  EXPECT_TRUE(content::ExecuteScript(wc, alert));
  test_delegate.Wait();
  EXPECT_EQ("1\n2\n3\n4", test_delegate.last_message());
}

IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
                       CreateWebContentsWithRendererProcess) {
  ASSERT_TRUE(embedded_test_server()->Start());
  WebContents* base_web_contents = shell()->web_contents();
  ASSERT_TRUE(base_web_contents);

  WebContents::CreateParams create_params(
      base_web_contents->GetBrowserContext());
  create_params.desired_renderer_state =
      WebContents::CreateParams::kInitializeAndWarmupRendererProcess;
  create_params.initial_size =
      base_web_contents->GetContainerBounds().size();
  std::unique_ptr<WebContents> web_contents(WebContents::Create(create_params));
  ASSERT_TRUE(web_contents);

  // There is no navigation (to about:blank or something like that).
  EXPECT_FALSE(web_contents->IsLoading());

  // The WebContents have an associated main frame and a renderer process that
  // has either already launched (or is in the process of being launched).
  ASSERT_TRUE(web_contents->GetMainFrame());
  EXPECT_TRUE(web_contents->GetMainFrame()->IsRenderFrameLive());
  EXPECT_TRUE(web_contents->GetController().IsInitialBlankNavigation());
  RenderProcessHost* process = web_contents->GetMainFrame()->GetProcess();
  int renderer_id = process->GetID();
  ASSERT_TRUE(process);
  EXPECT_TRUE(process->IsInitializedAndNotDead());

  // Navigate the WebContents.
  GURL url(embedded_test_server()->GetURL("c.com", "/title3.html"));
  TestNavigationObserver same_tab_observer(web_contents.get());
  NavigationController::LoadURLParams params(url);
  params.transition_type = ui::PageTransitionFromInt(
      ui::PAGE_TRANSITION_TYPED | ui::PAGE_TRANSITION_FROM_ADDRESS_BAR);
  web_contents->GetController().LoadURLWithParams(params);
  same_tab_observer.Wait();
  EXPECT_TRUE(same_tab_observer.last_navigation_succeeded());

  // Check that pre-warmed process is used.
  EXPECT_EQ(process, web_contents->GetMainFrame()->GetProcess());
  EXPECT_EQ(renderer_id, web_contents->GetMainFrame()->GetProcess()->GetID());
  EXPECT_EQ(1, web_contents->GetController().GetEntryCount());
  NavigationEntry* entry =
      web_contents->GetController().GetLastCommittedEntry();
  ASSERT_TRUE(entry);
  EXPECT_EQ(url, entry->GetURL());
}

// Regression test for https://crbug.com/840409.
IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
                       CreateWebContentsWithoutRendererProcess) {
  ASSERT_TRUE(embedded_test_server()->Start());
  WebContents* base_web_contents = shell()->web_contents();
  ASSERT_TRUE(base_web_contents);

  for (int i = 1; i <= 2; i++) {
    SCOPED_TRACE(testing::Message() << "Iteration #" << i);

    WebContents::CreateParams create_params(
        base_web_contents->GetBrowserContext());
    create_params.desired_renderer_state =
        WebContents::CreateParams::kNoRendererProcess;
    create_params.initial_size = base_web_contents->GetContainerBounds().size();
    std::unique_ptr<WebContents> web_contents(
        WebContents::Create(create_params));
    ASSERT_TRUE(web_contents);
    base::RunLoop().RunUntilIdle();

    // There is no navigation (to about:blank or something like that) yet.
    EXPECT_FALSE(web_contents->IsLoading());

    // The WebContents have an associated main frame and a RenderProcessHost
    // object, but no actual OS process has been launched yet.
    ASSERT_TRUE(web_contents->GetMainFrame());
    EXPECT_FALSE(web_contents->GetMainFrame()->IsRenderFrameLive());
    EXPECT_TRUE(web_contents->GetController().IsInitialBlankNavigation());
    RenderProcessHost* process = web_contents->GetMainFrame()->GetProcess();
    int renderer_id = process->GetID();
    ASSERT_TRUE(process);
    EXPECT_FALSE(process->IsInitializedAndNotDead());
    EXPECT_EQ(base::kNullProcessHandle, process->GetProcess().Handle());

    // Navigate the WebContents.
    GURL url(embedded_test_server()->GetURL("c.com", "/title3.html"));
    TestNavigationObserver same_tab_observer(web_contents.get());
    NavigationController::LoadURLParams params(url);
    params.transition_type = ui::PageTransitionFromInt(
        ui::PAGE_TRANSITION_TYPED | ui::PAGE_TRANSITION_FROM_ADDRESS_BAR);
    web_contents->GetController().LoadURLWithParams(params);
    same_tab_observer.Wait();
    EXPECT_TRUE(same_tab_observer.last_navigation_succeeded());

    // The process should be launched now.
    EXPECT_TRUE(process->IsInitializedAndNotDead());
    EXPECT_NE(base::kNullProcessHandle, process->GetProcess().Handle());

    // Check that the RenderProcessHost and its ID didn't change.
    EXPECT_EQ(process, web_contents->GetMainFrame()->GetProcess());
    EXPECT_EQ(renderer_id, web_contents->GetMainFrame()->GetProcess()->GetID());

    // Verify that the navigation succeeded.
    EXPECT_EQ(1, web_contents->GetController().GetEntryCount());
    NavigationEntry* entry =
        web_contents->GetController().GetLastCommittedEntry();
    ASSERT_TRUE(entry);
    EXPECT_EQ(url, entry->GetURL());
  }
}

IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
                       NavigatingToWebUIDoesNotUsePreWarmedProcess) {
  GURL web_ui_url(std::string(kChromeUIScheme) + "://" +
                  std::string(kChromeUIGpuHost));
  ASSERT_TRUE(embedded_test_server()->Start());
  WebContents* base_web_contents = shell()->web_contents();
  ASSERT_TRUE(base_web_contents);

  WebContents::CreateParams create_params(
      base_web_contents->GetBrowserContext());
  create_params.desired_renderer_state =
      WebContents::CreateParams::kInitializeAndWarmupRendererProcess;
  create_params.initial_size =
      base_web_contents->GetContainerBounds().size();
  std::unique_ptr<WebContents> web_contents(WebContents::Create(create_params));
  ASSERT_TRUE(web_contents);

  // There is no navigation (to about:blank or something like that).
  EXPECT_FALSE(web_contents->IsLoading());

  ASSERT_TRUE(web_contents->GetMainFrame());
  EXPECT_TRUE(web_contents->GetMainFrame()->IsRenderFrameLive());
  EXPECT_TRUE(web_contents->GetController().IsInitialBlankNavigation());
  int renderer_id = web_contents->GetMainFrame()->GetProcess()->GetID();

  TestNavigationObserver same_tab_observer(web_contents.get(), 1);
  NavigationController::LoadURLParams params(web_ui_url);
  params.transition_type = ui::PageTransitionFromInt(
      ui::PAGE_TRANSITION_TYPED | ui::PAGE_TRANSITION_FROM_ADDRESS_BAR);
  web_contents->GetController().LoadURLWithParams(params);
  same_tab_observer.Wait();

  // Check that pre-warmed process isn't used.
  EXPECT_NE(renderer_id, web_contents->GetMainFrame()->GetProcess()->GetID());
  EXPECT_EQ(1, web_contents->GetController().GetEntryCount());
  NavigationEntry* entry =
      web_contents->GetController().GetLastCommittedEntry();
  ASSERT_TRUE(entry);
  EXPECT_EQ(web_ui_url, entry->GetURL());
}

namespace {

class DownloadImageObserver {
 public:
  MOCK_METHOD5(OnFinishDownloadImage, void(
      int id,
      int status_code,
      const GURL& image_url,
      const std::vector<SkBitmap>& bitmap,
      const std::vector<gfx::Size>& sizes));
  ~DownloadImageObserver() = default;
};

void DownloadImageTestInternal(Shell* shell,
                               const GURL& image_url,
                               int expected_http_status,
                               int expected_number_of_images) {
  using ::testing::_;
  using ::testing::InvokeWithoutArgs;
  using ::testing::SizeIs;

  // Set up everything.
  DownloadImageObserver download_image_observer;
  scoped_refptr<MessageLoopRunner> loop_runner =
      new MessageLoopRunner();

  // Set up expectation and stub.
  EXPECT_CALL(download_image_observer,
              OnFinishDownloadImage(_, expected_http_status, _,
                                    SizeIs(expected_number_of_images), _));
  ON_CALL(download_image_observer, OnFinishDownloadImage(_, _, _, _, _))
      .WillByDefault(
          InvokeWithoutArgs(loop_runner.get(), &MessageLoopRunner::Quit));

  shell->LoadURL(GURL("about:blank"));
  shell->web_contents()->DownloadImage(
      image_url, false, 1024, false,
      base::BindOnce(&DownloadImageObserver::OnFinishDownloadImage,
                     base::Unretained(&download_image_observer)));

  // Wait for response.
  loop_runner->Run();
}

void ExpectNoValidImageCallback(const base::Closure& quit_closure,
                                int id,
                                int status_code,
                                const GURL& image_url,
                                const std::vector<SkBitmap>& bitmap,
                                const std::vector<gfx::Size>& sizes) {
  EXPECT_EQ(200, status_code);
  EXPECT_TRUE(bitmap.empty());
  EXPECT_TRUE(sizes.empty());
  quit_closure.Run();
}

}  // anonymous namespace

IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
                       DownloadImage_HttpImage) {
  ASSERT_TRUE(embedded_test_server()->Start());
  const GURL kImageUrl = embedded_test_server()->GetURL("/single_face.jpg");
  DownloadImageTestInternal(shell(), kImageUrl, 200, 1);
}

IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
                       DownloadImage_Deny_FileImage) {
  ASSERT_TRUE(embedded_test_server()->Start());
  shell()->LoadURL(embedded_test_server()->GetURL("/simple_page.html"));

  const GURL kImageUrl = GetTestUrl("", "single_face.jpg");
  DownloadImageTestInternal(shell(), kImageUrl, 0, 0);
}

IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
                       DownloadImage_Allow_FileImage) {
  shell()->LoadURL(GetTestUrl("", "simple_page.html"));

  const GURL kImageUrl =
      GetTestUrl("", "image.jpg");
  DownloadImageTestInternal(shell(), kImageUrl, 0, 0);
}

IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, DownloadImage_NoValidImage) {
  ASSERT_TRUE(embedded_test_server()->Start());
  const GURL kImageUrl = embedded_test_server()->GetURL("/invalid.ico");
  shell()->LoadURL(GURL("about:blank"));
  base::RunLoop run_loop;
  shell()->web_contents()->DownloadImage(
      kImageUrl, false, 2, false,
      base::BindOnce(&ExpectNoValidImageCallback, run_loop.QuitClosure()));

  run_loop.Run();
}

IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, DownloadImage_DataImage) {
  const GURL kImageUrl = GURL(
      "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHE"
      "lEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==");
  DownloadImageTestInternal(shell(), kImageUrl, 0, 1);
}

IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
                       DownloadImage_InvalidDataImage) {
  const GURL kImageUrl = GURL("data:image/png;invalid");
  DownloadImageTestInternal(shell(), kImageUrl, 0, 0);
}

class MouseLockDelegate : public WebContentsDelegate {
 public:
  // WebContentsDelegate:
  void RequestToLockMouse(WebContents* web_contents,
                          bool user_gesture,
                          bool last_unlocked_by_target) override {
    request_to_lock_mouse_called_ = true;
  }
  bool request_to_lock_mouse_called_ = false;
};

// TODO(crbug.com/898641): This test is flaky.
IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
                       DISABLED_RenderWidgetDeletedWhileMouseLockPending) {
  ASSERT_TRUE(embedded_test_server()->Start());

  std::unique_ptr<MouseLockDelegate> delegate(new MouseLockDelegate());
  shell()->web_contents()->SetDelegate(delegate.get());
  ASSERT_TRUE(shell()->web_contents()->GetDelegate() == delegate.get());

  NavigateToURL(shell(),
                embedded_test_server()->GetURL("a.com", "/title1.html"));

  // Try to request pointer lock. WebContentsDelegate should get a notification.
  ASSERT_TRUE(ExecuteScript(shell(),
                            "window.domAutomationController.send(document.body."
                            "requestPointerLock());"));
  EXPECT_TRUE(delegate.get()->request_to_lock_mouse_called_);

  // Make sure that the renderer didn't get the pointer lock, since the
  // WebContentsDelegate didn't approve the notification.
  bool locked = false;
  ASSERT_TRUE(ExecuteScriptAndExtractBool(shell(),
                                          "window.domAutomationController.send("
                                          "document.pointerLockElement == "
                                          "null);",
                                          &locked));
  EXPECT_TRUE(locked);

  // Try to request the pointer lock again. Since there's a pending request in
  // WebContentsDelelgate, the WebContents shouldn't ask again.
  delegate.get()->request_to_lock_mouse_called_ = false;
  ASSERT_TRUE(ExecuteScript(shell(),
                            "window.domAutomationController.send(document.body."
                            "requestPointerLock());"));
  EXPECT_FALSE(delegate.get()->request_to_lock_mouse_called_);

  // Force a cross-process navigation so that the RenderWidgetHost is deleted.
  NavigateToURL(shell(),
                embedded_test_server()->GetURL("b.com", "/title1.html"));

  // Make sure the WebContents cleaned up the previous pending request. A new
  // request should be forwarded to the WebContentsDelegate.
  delegate.get()->request_to_lock_mouse_called_ = false;
  ASSERT_TRUE(ExecuteScript(shell(),
                            "window.domAutomationController.send(document.body."
                            "requestPointerLock());"));
  EXPECT_TRUE(delegate.get()->request_to_lock_mouse_called_);
}

// Checks that user agent override string is only used when it's overridden.
IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, UserAgentOverride) {
  ASSERT_TRUE(embedded_test_server()->Start());
  const std::string kHeaderPath =
      std::string("/echoheader?") + net::HttpRequestHeaders::kUserAgent;
  const GURL kUrl(embedded_test_server()->GetURL(kHeaderPath));
  const std::string kUserAgentOverride = "foo";

  NavigateToURL(shell(), kUrl);
  std::string header_value;
  EXPECT_TRUE(ExecuteScriptAndExtractString(
      shell()->web_contents(),
      "window.domAutomationController.send(document.body.textContent);",
      &header_value));
  EXPECT_NE(kUserAgentOverride, header_value);

  shell()->web_contents()->SetUserAgentOverride("foo", false);
  NavigateToURL(shell(), kUrl);
  EXPECT_TRUE(ExecuteScriptAndExtractString(
      shell()->web_contents(),
      "window.domAutomationController.send(document.body.textContent);",
      &header_value));
  EXPECT_NE(kUserAgentOverride, header_value);

  shell()
      ->web_contents()
      ->GetController()
      .GetLastCommittedEntry()
      ->SetIsOverridingUserAgent(true);
  TestNavigationObserver tab_observer(shell()->web_contents(), 1);
  shell()->web_contents()->GetController().Reload(ReloadType::NORMAL, false);
  tab_observer.Wait();
  EXPECT_TRUE(ExecuteScriptAndExtractString(
      shell()->web_contents(),
      "window.domAutomationController.send(document.body.textContent);",
      &header_value));
  EXPECT_EQ(kUserAgentOverride, header_value);
}

IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
                       DialogsFromJavaScriptEndFullscreen) {
  WebContentsImpl* wc = static_cast<WebContentsImpl*>(shell()->web_contents());
  TestWCDelegateForDialogsAndFullscreen test_delegate(wc);

  GURL url("about:blank");
  EXPECT_TRUE(NavigateToURL(shell(), url));

  // alert
  wc->EnterFullscreenMode(url, blink::WebFullscreenOptions());
  EXPECT_TRUE(wc->IsFullscreenForCurrentTab());
  std::string script = "alert('hi')";
  test_delegate.WillWaitForDialog();
  EXPECT_TRUE(content::ExecuteScript(wc, script));
  test_delegate.Wait();
  EXPECT_FALSE(wc->IsFullscreenForCurrentTab());

  // confirm
  wc->EnterFullscreenMode(url, blink::WebFullscreenOptions());
  EXPECT_TRUE(wc->IsFullscreenForCurrentTab());
  script = "confirm('hi')";
  test_delegate.WillWaitForDialog();
  EXPECT_TRUE(content::ExecuteScript(wc, script));
  test_delegate.Wait();
  EXPECT_FALSE(wc->IsFullscreenForCurrentTab());

  // prompt
  wc->EnterFullscreenMode(url, blink::WebFullscreenOptions());
  EXPECT_TRUE(wc->IsFullscreenForCurrentTab());
  script = "prompt('hi')";
  test_delegate.WillWaitForDialog();
  EXPECT_TRUE(content::ExecuteScript(wc, script));
  test_delegate.Wait();
  EXPECT_FALSE(wc->IsFullscreenForCurrentTab());

  // beforeunload
  wc->EnterFullscreenMode(url, blink::WebFullscreenOptions());
  EXPECT_TRUE(wc->IsFullscreenForCurrentTab());
  // Disable the 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.
  wc->GetMainFrame()->DisableBeforeUnloadHangMonitorForTesting();
  wc->GetMainFrame()->ExecuteJavaScriptWithUserGestureForTests(
      base::string16());
  script = "window.onbeforeunload=function(e){ return 'x' };";
  EXPECT_TRUE(content::ExecuteScript(wc, script));
  test_delegate.WillWaitForDialog();
  EXPECT_TRUE(NavigateToURL(shell(), url));
  test_delegate.Wait();
  EXPECT_FALSE(wc->IsFullscreenForCurrentTab());
}

IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
                       DialogsFromJavaScriptEndFullscreenEvenInInnerWC) {
  WebContentsImpl* top_contents =
      static_cast<WebContentsImpl*>(shell()->web_contents());
  TestWCDelegateForDialogsAndFullscreen top_test_delegate(top_contents);

  GURL url("about:blank");
  EXPECT_TRUE(NavigateToURL(shell(), url));

  FrameTreeNode* root = top_contents->GetFrameTree()->root();
  ASSERT_EQ(0U, root->child_count());

  std::string script =
      "var iframe = document.createElement('iframe');"
      "document.body.appendChild(iframe);";
  EXPECT_TRUE(content::ExecuteScript(root->current_frame_host(), script));
  EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));

  ASSERT_EQ(1U, root->child_count());
  RenderFrameHost* frame = root->child_at(0)->current_frame_host();
  ASSERT_NE(nullptr, frame);

  WebContentsImpl* inner_contents =
      static_cast<WebContentsImpl*>(CreateAndAttachInnerContents(frame));
  TestWCDelegateForDialogsAndFullscreen inner_test_delegate(inner_contents);

  // A dialog from the inner WebContents should make the outer contents lose
  // fullscreen.
  top_contents->EnterFullscreenMode(url, blink::WebFullscreenOptions());
  EXPECT_TRUE(top_contents->IsFullscreenForCurrentTab());
  script = "alert('hi')";
  inner_test_delegate.WillWaitForDialog();
  EXPECT_TRUE(content::ExecuteScript(inner_contents, script));
  inner_test_delegate.Wait();
  EXPECT_FALSE(top_contents->IsFullscreenForCurrentTab());
}

IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, FileChooserEndsFullscreen) {
  WebContentsImpl* wc = static_cast<WebContentsImpl*>(shell()->web_contents());
  TestWCDelegateForDialogsAndFullscreen test_delegate(wc);

  GURL url("about:blank");
  EXPECT_TRUE(NavigateToURL(shell(), url));

  wc->EnterFullscreenMode(url, blink::WebFullscreenOptions());
  EXPECT_TRUE(wc->IsFullscreenForCurrentTab());
  wc->RunFileChooser(wc->GetMainFrame(),
                     std::make_unique<MockFileSelectListener>(),
                     blink::mojom::FileChooserParams());
  EXPECT_FALSE(wc->IsFullscreenForCurrentTab());
}

IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
                       PopupsFromJavaScriptEndFullscreen) {
  WebContentsImpl* wc = static_cast<WebContentsImpl*>(shell()->web_contents());
  TestWCDelegateForDialogsAndFullscreen test_delegate(wc);

  GURL url("about:blank");
  EXPECT_TRUE(NavigateToURL(shell(), url));

  // popup
  wc->EnterFullscreenMode(url, blink::WebFullscreenOptions());
  EXPECT_TRUE(wc->IsFullscreenForCurrentTab());
  std::string script = "window.open('', '', 'width=200,height=100')";
  test_delegate.WillWaitForNewContents();
  EXPECT_TRUE(content::ExecuteScript(wc, script));
  test_delegate.Wait();
  EXPECT_FALSE(wc->IsFullscreenForCurrentTab());
}

IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
                       FocusFromJavaScriptEndsFullscreen) {
  WebContentsImpl* wc = static_cast<WebContentsImpl*>(shell()->web_contents());
  TestWCDelegateForDialogsAndFullscreen test_delegate(wc);

  GURL url("about:blank");
  EXPECT_TRUE(NavigateToURL(shell(), url));

  // Make a popup.
  std::string script =
      "window.FocusFromJavaScriptEndsFullscreen = "
      "window.open('', '', 'width=200,height=100')";
  test_delegate.WillWaitForNewContents();
  EXPECT_TRUE(content::ExecuteScript(wc, script));
  test_delegate.Wait();

  // Put the main contents into fullscreen ...
  wc->EnterFullscreenMode(url, blink::WebFullscreenOptions());
  EXPECT_TRUE(wc->IsFullscreenForCurrentTab());

  // ... and ensure that a call to window.focus() from it causes loss of
  // ... fullscreen.
  script = "window.FocusFromJavaScriptEndsFullscreen.focus()";
  test_delegate.WillWaitForFullscreenExit();
  EXPECT_TRUE(content::ExecuteScript(wc, script));
  test_delegate.Wait();
  EXPECT_FALSE(wc->IsFullscreenForCurrentTab());
}

IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
                       FrameDetachInCopyDoesNotCrash) {
  ASSERT_TRUE(embedded_test_server()->Start());
  EXPECT_TRUE(NavigateToURL(
      shell(),
      embedded_test_server()->GetURL("a.com", "/detach_frame_in_copy.html")));

  WebContentsImpl* web_contents =
      static_cast<WebContentsImpl*>(shell()->web_contents());
  // Focus the child frame before sending it a copy command: the child frame
  // will detach itself upon getting a 'copy' event.
  ASSERT_TRUE(ExecuteScript(web_contents, "window[0].focus();"));
  FrameTree* frame_tree = web_contents->GetFrameTree();
  FrameTreeNode* root = frame_tree->root();
  ASSERT_EQ(root->child_at(0), frame_tree->GetFocusedFrame());
  shell()->web_contents()->Copy();

  TitleWatcher title_watcher(web_contents, base::ASCIIToUTF16("done"));
  base::string16 title = title_watcher.WaitAndGetTitle();
  ASSERT_EQ(title, base::ASCIIToUTF16("done"));
}

class UpdateTargetURLWaiter : public WebContentsDelegate {
 public:
  explicit UpdateTargetURLWaiter(WebContents* web_contents) {
    web_contents->SetDelegate(this);
  }

  const GURL& WaitForUpdatedTargetURL() {
    if (updated_target_url_.has_value())
      return updated_target_url_.value();

    runner_ = new MessageLoopRunner();
    runner_->Run();
    return updated_target_url_.value();
  }

 private:
  void UpdateTargetURL(WebContents* source, const GURL& url) override {
    updated_target_url_ = url;
    if (runner_.get())
      runner_->QuitClosure().Run();
  }

  base::Optional<GURL> updated_target_url_;
  scoped_refptr<MessageLoopRunner> runner_;

  DISALLOW_COPY_AND_ASSIGN(UpdateTargetURLWaiter);
};

// Verifies that focusing a link in a cross-site frame will correctly tell
// WebContentsDelegate to show a link status bubble.  This is a regression test
// for https://crbug.com/807776.
IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, UpdateTargetURL) {
  // Navigate to a test page.
  ASSERT_TRUE(embedded_test_server()->Start());
  WebContentsImpl* web_contents =
      static_cast<WebContentsImpl*>(shell()->web_contents());
  GURL url = embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)");
  EXPECT_TRUE(NavigateToURL(shell(), url));
  FrameTreeNode* subframe = web_contents->GetFrameTree()->root()->child_at(0);
  GURL subframe_url =
      embedded_test_server()->GetURL("b.com", "/simple_links.html");
  NavigateFrameToURL(subframe, subframe_url);

  // Focusing the link should fire the UpdateTargetURL notification.
  UpdateTargetURLWaiter target_url_waiter(web_contents);
  EXPECT_TRUE(ExecuteScript(
      subframe, "document.getElementById('cross_site_link').focus();"));
  EXPECT_EQ(GURL("http://foo.com/title2.html"),
            target_url_waiter.WaitForUpdatedTargetURL());
}

namespace {

class LoadStateWaiter : public WebContentsDelegate {
 public:
  explicit LoadStateWaiter(content::WebContents* contents)
      : web_contents_(contents) {
    contents->SetDelegate(this);
  }
  ~LoadStateWaiter() override = default;

  // Waits until the WebContents changes its LoadStateHost to |host|.
  void Wait(net::LoadState load_state, const base::string16& host) {
    waiting_host_ = host;
    waiting_state_ = load_state;
    if (!LoadStateMatches(web_contents_)) {
      base::RunLoop run_loop;
      quit_closure_ = run_loop.QuitClosure();
      run_loop.Run();
      DCHECK(LoadStateMatches(web_contents_));
    }
  }

  // WebContentsDelegate:
  void NavigationStateChanged(WebContents* source,
                              InvalidateTypes changed_flags) override {
    if (!quit_closure_)
      return;
    if (!(changed_flags & INVALIDATE_TYPE_LOAD))
      return;
    if (LoadStateMatches(source))
      std::move(quit_closure_).Run();
  }

 private:
  bool LoadStateMatches(content::WebContents* contents) {
    DCHECK(contents == web_contents_);
    return waiting_host_ == contents->GetLoadStateHost() &&
           waiting_state_ == contents->GetLoadState().state;
  }
  base::OnceClosure quit_closure_;
  content::WebContents* web_contents_ = nullptr;
  base::string16 waiting_host_;
  net::LoadState waiting_state_;

  DISALLOW_COPY_AND_ASSIGN(LoadStateWaiter);
};

}  // namespace

// TODO(csharrison,mmenke):  Beef up testing of LoadState a little. In
// particular, check upload progress and check the LoadState param.
IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, UpdateLoadState) {
  base::string16 a_host = url_formatter::IDNToUnicode("a.com");
  base::string16 b_host = url_formatter::IDNToUnicode("b.com");
  base::string16 paused_host = url_formatter::IDNToUnicode("paused.com");

  // Controlled responses for image requests made in the test. They will
  // alternate being the "most interesting" for the purposes of notifying the
  // WebContents.
  auto a_response =
      std::make_unique<net::test_server::ControllableHttpResponse>(
          embedded_test_server(), "/a_img");
  auto b_response =
      std::make_unique<net::test_server::ControllableHttpResponse>(
          embedded_test_server(), "/b_img");

  LoadStateWaiter waiter(shell()->web_contents());
  ASSERT_TRUE(embedded_test_server()->Start());

  EXPECT_TRUE(NavigateToURL(
      shell(), embedded_test_server()->GetURL(
                   "a.com", "/cross_site_iframe_factory.html?a(b)")));
  WebContentsImpl* web_contents =
      static_cast<WebContentsImpl*>(shell()->web_contents());
  FrameTreeNode* a_frame = web_contents->GetFrameTree()->root();
  FrameTreeNode* b_frame = a_frame->child_at(0);

  // Start loading the respective resources in each frame.
  auto load_resource = [](FrameTreeNode* frame, const std::string url) {
    const char kLoadResourceScript[] = R"(
      var img = new Image();
      img.src = '%s';
      document.body.appendChild(img);
    )";
    std::string script = base::StringPrintf(kLoadResourceScript, url.c_str());
    EXPECT_TRUE(ExecuteScript(frame, script));
  };

  // There should be no outgoing requests, so the load state should be empty.
  waiter.Wait(net::LOAD_STATE_IDLE, base::string16());

  // The |frame_pauser| pauses the navigation after every step. It will only
  // finish by calling WaitForNavigationFinished or ResumeNavigation.
  GURL paused_url(embedded_test_server()->GetURL("paused.com", "/title1.html"));
  TestNavigationManager frame_pauser(web_contents, paused_url);
  const char kLoadFrameScript[] = R"(
    var frame = document.createElement('iframe');
    frame.src = "%s";
    document.body.appendChild(frame);
  )";
  EXPECT_TRUE(ExecuteScript(
      web_contents,
      base::StringPrintf(kLoadFrameScript, paused_url.spec().c_str())));

  // Wait for the response to be ready, but never finish it.
  EXPECT_TRUE(frame_pauser.WaitForResponse());
  EXPECT_FALSE(frame_pauser.was_successful());
  // Note: the pausing only works for the non-network service path because of
  // http://crbug.com/791049.
  if (base::FeatureList::IsEnabled(network::features::kNetworkService))
    waiter.Wait(net::LOAD_STATE_IDLE, base::string16());
  else
    waiter.Wait(net::LOAD_STATE_WAITING_FOR_DELEGATE, paused_host);

  load_resource(a_frame, "/a_img");
  a_response->WaitForRequest();
  waiter.Wait(net::LOAD_STATE_WAITING_FOR_RESPONSE, a_host);

  // Start loading b_img and have it pass a_img by providing one byte of data.
  load_resource(b_frame, "/b_img");
  b_response->WaitForRequest();

  const char kPartialResponse[] = "HTTP/1.1 200 OK\r\n\r\nx";
  b_response->Send(kPartialResponse);
  waiter.Wait(net::LOAD_STATE_READING_RESPONSE, b_host);

  // Finish b_img and expect that a_img is back to being most interesting.
  b_response->Done();
  waiter.Wait(net::LOAD_STATE_WAITING_FOR_RESPONSE, a_host);

  // Advance and finish a_img.
  a_response->Send(kPartialResponse);
  waiter.Wait(net::LOAD_STATE_READING_RESPONSE, a_host);
  a_response->Done();

  if (!base::FeatureList::IsEnabled(network::features::kNetworkService)) {
    // Now the only request in flight should be the delayed frame.
    waiter.Wait(net::LOAD_STATE_WAITING_FOR_DELEGATE, paused_host);
    frame_pauser.ResumeNavigation();
    waiter.Wait(net::LOAD_STATE_IDLE, base::string16());
  }
}

IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, NotifyPreferencesChanged) {
  ASSERT_TRUE(embedded_test_server()->Start());
  WebContentsImpl* web_contents =
      static_cast<WebContentsImpl*>(shell()->web_contents());
  RenderFrameHost* main_frame = web_contents->GetMainFrame();

  // Navigate to a site with two iframes in different origins.
  GURL url = embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b,c)");
  EXPECT_TRUE(NavigateToURL(shell(), url));

  auto* main_frame_rvh = main_frame->GetRenderViewHost();
  auto* b_subframe_rvh = ChildFrameAt(main_frame, 0)->GetRenderViewHost();
  auto* c_subframe_rvh = ChildFrameAt(main_frame, 1)->GetRenderViewHost();

  NotifyPreferencesChangedTestContentBrowserClient new_client;
  ContentBrowserClient* old_client = SetBrowserClientForTesting(&new_client);

  web_contents->NotifyPreferencesChanged();

  // We should have updated the preferences for all three RenderViewHosts.
  EXPECT_EQ(std::unordered_set<RenderViewHost*>(
                {main_frame_rvh, b_subframe_rvh, c_subframe_rvh}),
            new_client.override_webkit_prefs_rvh_set());

  SetBrowserClientForTesting(old_client);
}

IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, SetPageFrozen) {
  EXPECT_TRUE(embedded_test_server()->Start());

  GURL test_url = embedded_test_server()->GetURL("/pause_schedule_task.html");
  NavigateToURL(shell(), test_url);
  EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));

  int text_length;
  while (true) {
    EXPECT_TRUE(content::ExecuteScriptAndExtractInt(
        shell(),
        "domAutomationController.send(document.getElementById('textfield')."
        "value.length)",
        &text_length));

    // Wait until |text_length| exceed 0.
    if (text_length > 0)
      break;
  }

  // Freeze the blink page.
  shell()->web_contents()->WasHidden();
  shell()->web_contents()->SetPageFrozen(true);

  // Make the javascript work.
  for (int i = 0; i < 10; i++) {
    EXPECT_TRUE(content::ExecuteScriptAndExtractInt(
        shell(),
        "domAutomationController.send(document.getElementById('textfield')."
        "value.length)",
        &text_length));
  }

  // Check if |next_text_length| is equal to |text_length|.
  int next_text_length;
  EXPECT_TRUE(content::ExecuteScriptAndExtractInt(
      shell(),
      "domAutomationController.send(document.getElementById('textfield')."
      "value.length)",
      &next_text_length));
  EXPECT_EQ(text_length, next_text_length);

  // Wake the frozen page up.
  shell()->web_contents()->WasHidden();
  shell()->web_contents()->SetPageFrozen(false);

  // Wait for an amount of time in order to give the javascript time to
  // work again. If the javascript doesn't work again, the test will fail due to
  // the time out.
  while (true) {
    EXPECT_TRUE(content::ExecuteScriptAndExtractInt(
        shell(),
        "domAutomationController.send(document.getElementById('textfield')."
        "value.length)",
        &next_text_length));
    if (next_text_length > text_length)
      break;
  }

  // Check if |next_text_length| exceeds |text_length| because the blink
  // schedule tasks have resumed.
  EXPECT_TRUE(content::ExecuteScriptAndExtractInt(
      shell(),
      "domAutomationController.send(document.getElementById('textfield')."
      "value.length)",
      &next_text_length));
  EXPECT_GT(next_text_length, text_length);
}

IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
                       PopupWindowBrowserNavResumeLoad) {
  // This test verifies a pop up that requires navigation from browser side
  // works with a delegate that delays navigations of pop ups.
  // Create a file: scheme pop up from a file: scheme page, which requires
  // requires an OpenURL IPC to the browser process.
  base::FilePath test_data_dir;
  CHECK(base::PathService::Get(base::DIR_SOURCE_ROOT, &test_data_dir));
  base::FilePath simple_links_path =
      test_data_dir.Append(GetTestDataFilePath())
          .Append(FILE_PATH_LITERAL("simple_links.html"));
  GURL url(base::FilePath::StringType(FILE_PATH_LITERAL("file://")) +
           simple_links_path.value());

  shell()->set_delay_popup_contents_delegate_for_testing(true);
  EXPECT_TRUE(NavigateToURL(shell(), url));

  Shell* new_shell = nullptr;
  WebContents* new_contents = nullptr;
  {
    ShellAddedObserver new_shell_observer;
    bool success = false;
    EXPECT_TRUE(ExecuteScriptAndExtractBool(
        shell(),
        "window.domAutomationController.send(clickDeadFileNewWindowLink());",
        &success));
    new_shell = new_shell_observer.GetShell();
    new_contents = new_shell->web_contents();
    // Delaying popup holds the initial load.
    EXPECT_FALSE(WaitForLoadStop(new_contents));
  }

  EXPECT_FALSE(new_contents->GetDelegate());
  new_contents->SetDelegate(new_shell);
  new_contents->ResumeLoadingCreatedWebContents();
  // Dead file link may or may not load depending on OS. The result is not
  // relevant for this test, so not checking the the result.
  WaitForLoadStop(new_contents);
  EXPECT_TRUE(new_contents->GetLastCommittedURL().SchemeIs("file"));
}

namespace {

class FullscreenWebContentsObserver : public WebContentsObserver {
 public:
  FullscreenWebContentsObserver(WebContents* web_contents,
                                RenderFrameHost* wanted_rfh)
      : WebContentsObserver(web_contents), wanted_rfh_(wanted_rfh) {}

  // WebContentsObserver override.
  void DidAcquireFullscreen(RenderFrameHost* rfh) override {
    EXPECT_EQ(wanted_rfh_, rfh);
    EXPECT_FALSE(found_value_);

    if (rfh == wanted_rfh_) {
      found_value_ = true;
      run_loop_.Quit();
    }
  }

  void Wait() {
    if (!found_value_)
      run_loop_.Run();
  }

 private:
  base::RunLoop run_loop_;
  bool found_value_ = false;
  RenderFrameHost* wanted_rfh_;

  DISALLOW_COPY_AND_ASSIGN(FullscreenWebContentsObserver);
};

}  // namespace

IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, NotifyFullscreenAcquired) {
  ASSERT_TRUE(embedded_test_server()->Start());
  WebContentsImpl* web_contents =
      static_cast<WebContentsImpl*>(shell()->web_contents());
  TestWCDelegateForDialogsAndFullscreen test_delegate(web_contents);

  GURL url = embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b{allowfullscreen})");
  EXPECT_TRUE(NavigateToURL(shell(), url));
  RenderFrameHostImpl* main_frame = web_contents->GetMainFrame();
  RenderFrameHostImpl* child_frame =
      static_cast<RenderFrameHostImpl*>(ChildFrameAt(main_frame, 0));

  std::set<RenderFrameHostImpl*> fullscreen_frames;
  EXPECT_EQ(fullscreen_frames, web_contents->fullscreen_frames_);
  EXPECT_FALSE(IsInFullscreen());

  // Make the top page fullscreen.
  {
    FullscreenWebContentsObserver observer(web_contents, main_frame);
    EXPECT_TRUE(
        ExecuteScript(main_frame, "document.body.webkitRequestFullscreen();"));
    observer.Wait();
  }

  fullscreen_frames.insert(main_frame);
  EXPECT_EQ(fullscreen_frames, web_contents->fullscreen_frames_);
  EXPECT_EQ(main_frame, web_contents->current_fullscreen_frame_);

  // Make the child frame fullscreen.
  {
    FullscreenWebContentsObserver observer(web_contents, child_frame);
    EXPECT_TRUE(
        ExecuteScript(child_frame, "document.body.webkitRequestFullscreen();"));
    observer.Wait();
  }

  fullscreen_frames.insert(child_frame);
  EXPECT_EQ(fullscreen_frames, web_contents->fullscreen_frames_);
  EXPECT_EQ(child_frame, web_contents->current_fullscreen_frame_);

  // Exit fullscreen on the child frame.
  // This will not work with --site-per-process until crbug.com/617369
  // is fixed.
  if (!SiteIsolationPolicy::UseDedicatedProcessesForAllSites()) {
    {
      FullscreenWebContentsObserver observer(web_contents, main_frame);
      EXPECT_TRUE(
          ExecuteScript(child_frame, "document.webkitExitFullscreen();"));
      observer.Wait();
    }

    fullscreen_frames.erase(child_frame);
    EXPECT_EQ(fullscreen_frames, web_contents->fullscreen_frames_);
    EXPECT_EQ(main_frame, web_contents->current_fullscreen_frame_);
  }
}

// Regression test for https://crbug.com/855018.
// RenderFrameHostImpls exit fullscreen as soon as they are swapped out.
IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, FullscreenAfterFrameSwap) {
  ASSERT_TRUE(embedded_test_server()->Start());
  WebContentsImpl* web_contents =
      static_cast<WebContentsImpl*>(shell()->web_contents());

  GURL url_a = embedded_test_server()->GetURL("a.com", "/title1.html");
  GURL url_b = embedded_test_server()->GetURL("b.com", "/title1.html");

  // 1) Navigate. There is initially no fullscreen frame.
  EXPECT_TRUE(NavigateToURL(shell(), url_a));
  RenderFrameHostImpl* main_frame =
      static_cast<RenderFrameHostImpl*>(web_contents->GetMainFrame());
  EXPECT_EQ(0u, web_contents->fullscreen_frames_.size());

  // 2) Make it fullscreen.
  FullscreenWebContentsObserver observer(web_contents, main_frame);
  EXPECT_TRUE(
      ExecuteScript(main_frame, "document.body.webkitRequestFullscreen();"));
  observer.Wait();
  EXPECT_EQ(1u, web_contents->fullscreen_frames_.size());

  // 3) Navigate cross origin. Act as if the old frame was very slow delivering
  //    the swapout ack and stayed in pending deletion for a while. Even if the
  //    frame is still present, it must be removed from the list of frame in
  //    fullscreen immediately.
  auto filter = base::MakeRefCounted<DropMessageFilter>(
      FrameMsgStart, FrameHostMsg_SwapOut_ACK::ID);
  main_frame->GetProcess()->AddFilter(filter.get());
  main_frame->DisableSwapOutTimerForTesting();
  EXPECT_TRUE(NavigateToURL(shell(), url_b));
  EXPECT_EQ(0u, web_contents->fullscreen_frames_.size());
}

IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
                       NotifyFullscreenAcquired_Navigate) {
  ASSERT_TRUE(embedded_test_server()->Start());
  WebContentsImpl* web_contents =
      static_cast<WebContentsImpl*>(shell()->web_contents());
  TestWCDelegateForDialogsAndFullscreen test_delegate(web_contents);
  test_delegate.WillWaitForFullscreenExit();

  GURL url = embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b{allowfullscreen})");
  EXPECT_TRUE(NavigateToURL(shell(), url));
  RenderFrameHostImpl* main_frame = web_contents->GetMainFrame();
  RenderFrameHostImpl* child_frame =
      static_cast<RenderFrameHostImpl*>(ChildFrameAt(main_frame, 0));

  std::set<RenderFrameHostImpl*> nodes;
  EXPECT_EQ(nodes, web_contents->fullscreen_frames_);
  EXPECT_FALSE(IsInFullscreen());

  // Make the top page fullscreen.
  {
    FullscreenWebContentsObserver observer(web_contents, main_frame);
    EXPECT_TRUE(
        ExecuteScript(main_frame, "document.body.webkitRequestFullscreen();"));
    observer.Wait();
  }

  nodes.insert(main_frame);
  EXPECT_EQ(nodes, web_contents->fullscreen_frames_);
  EXPECT_EQ(main_frame, web_contents->current_fullscreen_frame_);

  // Make the child frame fullscreen.
  {
    FullscreenWebContentsObserver observer(web_contents, child_frame);
    EXPECT_TRUE(
        ExecuteScript(child_frame, "document.body.webkitRequestFullscreen();"));
    observer.Wait();
  }

  nodes.insert(child_frame);
  EXPECT_EQ(nodes, web_contents->fullscreen_frames_);
  EXPECT_EQ(child_frame, web_contents->current_fullscreen_frame_);

  // Perform a cross origin navigation on the main frame.
  EXPECT_TRUE(
      NavigateToURL(shell(), embedded_test_server()->GetURL(
                                 "c.com", "/cross_site_iframe_factory.html")));
  EXPECT_EQ(0u, web_contents->fullscreen_frames_.size());
  EXPECT_FALSE(IsInFullscreen());
}

IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
                       NotifyFullscreenAcquired_SameOrigin) {
  ASSERT_TRUE(embedded_test_server()->Start());
  WebContentsImpl* web_contents =
      static_cast<WebContentsImpl*>(shell()->web_contents());
  TestWCDelegateForDialogsAndFullscreen test_delegate(web_contents);

  GURL url = embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(a{allowfullscreen})");
  EXPECT_TRUE(NavigateToURL(shell(), url));
  RenderFrameHostImpl* main_frame = web_contents->GetMainFrame();
  RenderFrameHostImpl* child_frame =
      static_cast<RenderFrameHostImpl*>(ChildFrameAt(main_frame, 0));

  std::set<RenderFrameHostImpl*> fullscreen_frames;
  EXPECT_EQ(fullscreen_frames, web_contents->fullscreen_frames_);
  EXPECT_FALSE(IsInFullscreen());

  // Make the top page fullscreen.
  {
    FullscreenWebContentsObserver observer(web_contents, main_frame);
    EXPECT_TRUE(
        ExecuteScript(main_frame, "document.body.webkitRequestFullscreen();"));
    observer.Wait();
  }

  fullscreen_frames.insert(main_frame);
  EXPECT_EQ(fullscreen_frames, web_contents->fullscreen_frames_);
  EXPECT_EQ(main_frame, web_contents->current_fullscreen_frame_);

  // Make the child frame fullscreen.
  {
    FullscreenWebContentsObserver observer(web_contents, child_frame);
    EXPECT_TRUE(
        ExecuteScript(child_frame, "document.body.webkitRequestFullscreen();"));
    observer.Wait();
  }

  fullscreen_frames.insert(child_frame);
  EXPECT_EQ(fullscreen_frames, web_contents->fullscreen_frames_);
  EXPECT_EQ(child_frame, web_contents->current_fullscreen_frame_);

  // Exit fullscreen on the child frame.
  {
    FullscreenWebContentsObserver observer(web_contents, main_frame);
    EXPECT_TRUE(ExecuteScript(child_frame, "document.webkitExitFullscreen();"));
    observer.Wait();
  }

  fullscreen_frames.erase(child_frame);
  EXPECT_EQ(fullscreen_frames, web_contents->fullscreen_frames_);
  EXPECT_EQ(main_frame, web_contents->current_fullscreen_frame_);
}

class MockDidOpenRequestedURLObserver : public WebContentsObserver {
 public:
  explicit MockDidOpenRequestedURLObserver(Shell* shell)
      : WebContentsObserver(shell->web_contents()) {}

  MOCK_METHOD8(DidOpenRequestedURL,
               void(WebContents* new_contents,
                    RenderFrameHost* source_render_frame_host,
                    const GURL& url,
                    const Referrer& referrer,
                    WindowOpenDisposition disposition,
                    ui::PageTransition transition,
                    bool started_from_context_menu,
                    bool renderer_initiated));

 private:
  DISALLOW_COPY_AND_ASSIGN(MockDidOpenRequestedURLObserver);
};

// Test WebContentsObserver::DidOpenRequestedURL for ctrl-click-ed links.
// This is a regression test for https://crbug.com/864736 (although it also
// covers slightly more ground than just the |is_renderer_initiated| value).
IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, CtrlClickSubframeLink) {
  ASSERT_TRUE(embedded_test_server()->Start());

  // Load a page with a subframe link.
  GURL main_url(
      embedded_test_server()->GetURL("/ctrl-click-subframe-link.html"));
  NavigateToURL(shell(), main_url);

  // Start intercepting the DidOpenRequestedURL callback.
  MockDidOpenRequestedURLObserver mock_observer(shell());
  WebContents* new_web_contents1 = nullptr;
  RenderFrameHost* subframe = shell()->web_contents()->GetAllFrames()[1];
  EXPECT_CALL(mock_observer,
              DidOpenRequestedURL(
                  ::testing::_,  // new_contents (captured via SaveArg below)
                  subframe,      // source_render_frame_host
                  embedded_test_server()->GetURL("/title1.html"),
                  ::testing::Field(&Referrer::url, main_url),
                  WindowOpenDisposition::NEW_FOREGROUND_TAB,
                  ::testing::Truly([](ui::PageTransition arg) {
                    return ui::PageTransitionCoreTypeIs(
                        arg, ui::PAGE_TRANSITION_LINK);
                  }),
                  false,  // started_from_context_menu
                  true))  // is_renderer_initiated
      .WillOnce(testing::SaveArg<0>(&new_web_contents1));

  // Simulate a ctrl click on the link and ask GMock to verify that the
  // MockDidOpenRequestedURLObserver got called with the expected args.
  WebContentsAddedObserver new_web_contents_observer;
  EXPECT_TRUE(ExecuteScript(
      shell(), "window.domAutomationController.send(ctrlClickLink());"));
  WebContents* new_web_contents2 = new_web_contents_observer.GetWebContents();
  EXPECT_TRUE(testing::Mock::VerifyAndClearExpectations(&mock_observer));
  EXPECT_EQ(new_web_contents1, new_web_contents2);
}

IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, SetVisibilityBeforeLoad) {
  ASSERT_TRUE(embedded_test_server()->Start());
  GURL url(embedded_test_server()->GetURL("/hello.html"));

  WebContents* attached_web_contents = shell()->web_contents();

  // Create a WebContents detached from native windows so that visibility of
  // the WebContents is fully controlled by the app.
  WebContents::CreateParams create_params(
      attached_web_contents->GetBrowserContext(), nullptr /* site_instance */);
  create_params.initial_size = gfx::Size(100, 100);
  std::unique_ptr<WebContents> web_contents =
      WebContents::Create(create_params);
  EXPECT_EQ(Visibility::VISIBLE, web_contents->GetVisibility());

  web_contents->WasHidden();
  EXPECT_EQ(Visibility::HIDDEN, web_contents->GetVisibility());

  EXPECT_TRUE(NavigateToURL(web_contents.get(), url));
  EXPECT_TRUE(EvalJs(web_contents.get(), "document.hidden").ExtractBool());
}

// This test verifies that if we attach an inner WebContents that has
// descendants in the WebContentsTree, that the descendants also have their
// views registered with the top-level WebContents' InputEventRouter. This
// ensures the descendants will receive events that should be routed to them.
IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
                       AttachNestedInnerWebContents) {
  ASSERT_TRUE(embedded_test_server()->Start());
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(a)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  auto* root_web_contents =
      static_cast<WebContentsImpl*>(shell()->web_contents());
  FrameTreeNode* root = root_web_contents->GetFrameTree()->root();
  ASSERT_EQ(1u, root->child_count());
  FrameTreeNode* child_to_replace = root->child_at(0);
  auto* child_to_replace_rfh = child_to_replace->current_frame_host();

  WebContents::CreateParams inner_params(
      root_web_contents->GetBrowserContext());

  std::unique_ptr<WebContents> child_contents_ptr =
      WebContents::Create(inner_params);
  auto* child_rfh =
      static_cast<RenderFrameHostImpl*>(child_contents_ptr->GetMainFrame());

  std::unique_ptr<WebContents> grandchild_contents_ptr =
      WebContents::Create(inner_params);

  // Attach grandchild to child.
  child_contents_ptr->AttachInnerWebContents(std::move(grandchild_contents_ptr),
                                             child_rfh);

  // At this point the child hasn't been attached to the root.
  EXPECT_EQ(1U, root_web_contents->GetInputEventRouter()
                    ->RegisteredViewCountForTesting());

  // Attach child+grandchild subtree to root.
  root_web_contents->AttachInnerWebContents(std::move(child_contents_ptr),
                                            child_to_replace_rfh);

  // Verify views registered for both child and grandchild.
  EXPECT_EQ(3U, root_web_contents->GetInputEventRouter()
                    ->RegisteredViewCountForTesting());
}

IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
                       ShutdownDuringSpeculativeNavigation) {
  ASSERT_TRUE(embedded_test_server()->Start());
  GURL url(embedded_test_server()->GetURL("/hello.html"));

  WebContents* attached_web_contents = shell()->web_contents();

  WebContents::CreateParams create_params(
      attached_web_contents->GetBrowserContext(), /*site_instance=*/nullptr);
  create_params.initial_size = gfx::Size(100, 100);
  std::unique_ptr<WebContents> public_web_contents =
      WebContents::Create(create_params);
  auto* web_contents = static_cast<WebContentsImpl*>(public_web_contents.get());

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

  // Complete a navigation.
  GURL url1 = embedded_test_server()->GetURL("a.com", "/title1.html");
  EXPECT_TRUE(NavigateToURL(web_contents, url1));

  // Start navigating to a second page.
  GURL url2 = embedded_test_server()->GetURL("b.com", "/title2.html");
  TestNavigationManager manager(web_contents, url2);
  web_contents->GetController().LoadURL(
      url2, Referrer(), ui::PAGE_TRANSITION_LINK, std::string());
  EXPECT_TRUE(manager.WaitForRequestStart());

  // While there is a speculative RenderFrameHost in the root FrameTreeNode...
  ASSERT_TRUE(root->render_manager()->speculative_frame_host());

  auto* frame_process = static_cast<RenderProcessHostImpl*>(
      root->render_manager()->speculative_frame_host()->GetProcess());
  int frame_routing_id =
      root->render_manager()->speculative_frame_host()->GetRoutingID();

  std::vector<int> deleted_routing_ids;
  auto watcher = base::BindRepeating(
      [](std::vector<int>* deleted_routing_ids, const IPC::Message& message) {
        if (message.type() == FrameMsg_Delete::ID) {
          deleted_routing_ids->push_back(message.routing_id());
        }
      },
      &deleted_routing_ids);
  frame_process->SetIpcSendWatcherForTesting(watcher);

  // ...shutdown the WebContents.
  public_web_contents.reset();

  // What should have happened is the speculative RenderFrameHost deletes the
  // provisional RenderFrame. The |watcher| verifies that this happened.
  EXPECT_THAT(deleted_routing_ids, testing::Contains(frame_routing_id));
}

}  // namespace content
