// Copyright 2016 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 "base/command_line.h"
#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/test_timeouts.h"
#include "build/build_config.h"
#include "chrome/browser/password_manager/chrome_password_manager_client.h"
#include "chrome/browser/renderer_context_menu/render_view_context_menu_browsertest_util.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/exclusive_access/fullscreen_controller_test.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/browser/ui/views_mode_controller.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/interactive_test_utils.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/autofill/core/browser/autofill_client.h"
#include "components/autofill/core/browser/test_autofill_client.h"
#include "components/guest_view/browser/guest_view_manager_delegate.h"
#include "components/guest_view/browser/test_guest_view_manager.h"
#include "components/security_state/core/security_state.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/focused_node_details.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/notification_details.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_source.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_widget_host.h"
#include "content/public/browser/render_widget_host_iterator.h"
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/browser/web_contents.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test_utils.h"
#include "content/public/test/hit_test_region_observer.h"
#include "content/public/test/test_navigation_observer.h"
#include "content/public/test/test_utils.h"
#include "extensions/browser/api/extensions_api_client.h"
#include "extensions/common/constants.h"
#include "net/dns/mock_host_resolver.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "ui/base/test/ui_controls.h"
#include "ui/display/display.h"
#include "ui/display/screen.h"
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/vector2d.h"
#include "url/gurl.h"

namespace autofill {
class AutofillPopupDelegate;
struct Suggestion;
}

namespace {

// Counts and returns the number of RenderWidgetHosts in the browser process.
size_t GetNumberOfRenderWidgetHosts() {
  std::unique_ptr<content::RenderWidgetHostIterator> all_widgets =
      content::RenderWidgetHost::GetRenderWidgetHosts();
  size_t count = 0;
  while (auto* widget = all_widgets->GetNextHost())
    count++;
  return count;
}

// Waits and polls the current number of RenderWidgetHosts and stops when the
// number reaches |target_count|.
void WaitForRenderWidgetHostCount(size_t target_count) {
  while (GetNumberOfRenderWidgetHosts() != target_count) {
    base::RunLoop run_loop;
    base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
        FROM_HERE, run_loop.QuitClosure(), TestTimeouts::tiny_timeout());
    run_loop.Run();
  }
}

// Used to disable a few problematic tests for MacViews:
// https://crbug.com/850594
bool IsMacViewsBrowser() {
#if defined(OS_MACOSX)
  return !views_mode_controller::IsViewsBrowserCocoa();
#else
  return false;
#endif
}

}  // namespace

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

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

  void SetUpOnMainThread() override {
    host_resolver()->AddRule("*", "127.0.0.1");

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

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

  gfx::Size GetScreenSize() {
    content::WebContents* web_contents =
        browser()->tab_strip_model()->GetActiveWebContents();
    const display::Display display =
        display::Screen::GetScreen()->GetDisplayNearestView(
            web_contents->GetRenderWidgetHostView()->GetNativeView());
    return display.bounds().size();
  }

  enum class FullscreenExitMethod {
    JS_CALL,
    ESC_PRESS,
  };

  void FullscreenElementInABA(FullscreenExitMethod exit_method);

 private:
  DISALLOW_COPY_AND_ASSIGN(SitePerProcessInteractiveBrowserTest);
};

// Check that document.hasFocus() works properly with out-of-process iframes.
// The test builds a page with four cross-site frames and then focuses them one
// by one, checking the value of document.hasFocus() in all frames.  For any
// given focused frame, document.hasFocus() should return true for that frame
// and all its ancestor frames.
IN_PROC_BROWSER_TEST_F(SitePerProcessInteractiveBrowserTest, DocumentHasFocus) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b(c),d)"));
  ui_test_utils::NavigateToURL(browser(), main_url);

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

  content::RenderFrameHost* main_frame = web_contents->GetMainFrame();
  content::RenderFrameHost* child1 = ChildFrameAt(main_frame, 0);
  ASSERT_NE(nullptr, child1);
  content::RenderFrameHost* child2 = ChildFrameAt(main_frame, 1);
  ASSERT_NE(nullptr, child2);
  content::RenderFrameHost* grandchild = ChildFrameAt(child1, 0);
  ASSERT_NE(nullptr, grandchild);

  EXPECT_NE(main_frame->GetSiteInstance(), child1->GetSiteInstance());
  EXPECT_NE(main_frame->GetSiteInstance(), child2->GetSiteInstance());
  EXPECT_NE(child1->GetSiteInstance(), grandchild->GetSiteInstance());

  // Helper function to check document.hasFocus() for a given frame.
  auto document_has_focus = [](content::RenderFrameHost* rfh) -> bool {
    bool has_focus = false;
    EXPECT_TRUE(ExecuteScriptAndExtractBool(
        rfh,
        "window.domAutomationController.send(document.hasFocus())",
        &has_focus));
    return has_focus;
  };

  // The main frame should be focused to start with.
  EXPECT_EQ(main_frame, web_contents->GetFocusedFrame());

  EXPECT_TRUE(document_has_focus(main_frame));
  EXPECT_FALSE(document_has_focus(child1));
  EXPECT_FALSE(document_has_focus(grandchild));
  EXPECT_FALSE(document_has_focus(child2));

  EXPECT_TRUE(ExecuteScript(child1, "window.focus();"));
  EXPECT_EQ(child1, web_contents->GetFocusedFrame());

  EXPECT_TRUE(document_has_focus(main_frame));
  EXPECT_TRUE(document_has_focus(child1));
  EXPECT_FALSE(document_has_focus(grandchild));
  EXPECT_FALSE(document_has_focus(child2));

  EXPECT_TRUE(ExecuteScript(grandchild, "window.focus();"));
  EXPECT_EQ(grandchild, web_contents->GetFocusedFrame());

  EXPECT_TRUE(document_has_focus(main_frame));
  EXPECT_TRUE(document_has_focus(child1));
  EXPECT_TRUE(document_has_focus(grandchild));
  EXPECT_FALSE(document_has_focus(child2));

  EXPECT_TRUE(ExecuteScript(child2, "window.focus();"));
  EXPECT_EQ(child2, web_contents->GetFocusedFrame());

  EXPECT_TRUE(document_has_focus(main_frame));
  EXPECT_FALSE(document_has_focus(child1));
  EXPECT_FALSE(document_has_focus(grandchild));
  EXPECT_TRUE(document_has_focus(child2));
}

// Ensure that a cross-process subframe can receive keyboard events when in
// focus.
IN_PROC_BROWSER_TEST_F(SitePerProcessInteractiveBrowserTest,
                       SubframeKeyboardEventRouting) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/frame_tree/page_with_one_frame.html"));
  ui_test_utils::NavigateToURL(browser(), main_url);
  content::WebContents* web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();

  GURL frame_url(
      embedded_test_server()->GetURL("b.com", "/page_with_input_field.html"));
  EXPECT_TRUE(NavigateIframeToURL(web_contents, "child0", frame_url));

  // Focus the subframe and then its input field.  The return value
  // "input-focus" will be sent once the input field's focus event fires.
  content::RenderFrameHost* child =
      ChildFrameAt(web_contents->GetMainFrame(), 0);
  std::string result;
  std::string script =
      "function onInput(e) {"
      "  domAutomationController.send(getInputFieldText());"
      "}"
      "inputField = document.getElementById('text-field');"
      "inputField.addEventListener('input', onInput, false);";
  EXPECT_TRUE(ExecuteScript(child, script));
  EXPECT_TRUE(ExecuteScriptAndExtractString(
      child, "window.focus(); focusInputField();", &result));
  EXPECT_EQ("input-focus", result);

  // The subframe should now be focused.
  EXPECT_EQ(child, web_contents->GetFocusedFrame());

  // Generate a few keyboard events and route them to currently focused frame.
  // We wait for replies to be sent back from the page, since keystrokes may
  // take time to propagate to the renderer's main thread.
  content::DOMMessageQueue msg_queue;
  std::string reply;
  SimulateKeyPress(web_contents, ui::DomKey::FromCharacter('F'),
                   ui::DomCode::US_F, ui::VKEY_F, false, false, false, false);
  EXPECT_TRUE(msg_queue.WaitForMessage(&reply));
  EXPECT_EQ("\"F\"", reply);

  SimulateKeyPress(web_contents, ui::DomKey::FromCharacter('O'),
                   ui::DomCode::US_O, ui::VKEY_O, false, false, false, false);
  EXPECT_TRUE(msg_queue.WaitForMessage(&reply));
  EXPECT_EQ("\"FO\"", reply);

  SimulateKeyPress(web_contents, ui::DomKey::FromCharacter('O'),
                   ui::DomCode::US_O, ui::VKEY_O, false, false, false, false);
  EXPECT_TRUE(msg_queue.WaitForMessage(&reply));
  EXPECT_EQ("\"FOO\"", reply);
}

// Ensure that sequential focus navigation (advancing focused elements with
// <tab> and <shift-tab>) works across cross-process subframes.
// The test sets up six inputs fields in a page with two cross-process
// subframes:
//                 child1            child2
//             /------------\    /------------\.
//             | 2. <input> |    | 4. <input> |
//  1. <input> | 3. <input> |    | 5. <input> |  6. <input>
//             \------------/    \------------/.
//
// The test then presses <tab> six times to cycle through focused elements 1-6.
// The test then repeats this with <shift-tab> to cycle in reverse order.
IN_PROC_BROWSER_TEST_F(SitePerProcessInteractiveBrowserTest,
                       SequentialFocusNavigation) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b,c)"));
  ui_test_utils::NavigateToURL(browser(), main_url);

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

  content::RenderFrameHost* main_frame = web_contents->GetMainFrame();
  content::RenderFrameHost* child1 = ChildFrameAt(main_frame, 0);
  ASSERT_NE(nullptr, child1);
  content::RenderFrameHost* child2 = ChildFrameAt(main_frame, 1);
  ASSERT_NE(nullptr, child2);

  // Assign a name to each frame.  This will be sent along in test messages
  // from focus events.
  EXPECT_TRUE(ExecuteScript(main_frame, "window.name = 'root';"));
  EXPECT_TRUE(ExecuteScript(child1, "window.name = 'child1';"));
  EXPECT_TRUE(ExecuteScript(child2, "window.name = 'child2';"));

  // This script will insert two <input> fields in the document, one at the
  // beginning and one at the end.  For root frame, this means that we will
  // have an <input>, then two <iframe> elements, then another <input>.
  std::string script =
      "function onFocus(e) {"
      "  domAutomationController.send(window.name + '-focused-' + e.target.id);"
      "}"
      "var input1 = document.createElement('input');"
      "input1.id = 'input1';"
      "var input2 = document.createElement('input');"
      "input2.id = 'input2';"
      "document.body.insertBefore(input1, document.body.firstChild);"
      "document.body.appendChild(input2);"
      "input1.addEventListener('focus', onFocus, false);"
      "input2.addEventListener('focus', onFocus, false);";

  // Add two input fields to each of the three frames.
  EXPECT_TRUE(ExecuteScript(main_frame, script));
  EXPECT_TRUE(ExecuteScript(child1, script));
  EXPECT_TRUE(ExecuteScript(child2, script));

  // Helper to simulate a tab press and wait for a focus message.
  auto press_tab_and_wait_for_message = [web_contents](bool reverse) {
    content::DOMMessageQueue msg_queue;
    std::string reply;
    SimulateKeyPress(web_contents, ui::DomKey::TAB, ui::DomCode::TAB,
                     ui::VKEY_TAB, false, reverse /* shift */, false, false);
    EXPECT_TRUE(msg_queue.WaitForMessage(&reply));
    return reply;
  };

  // Press <tab> six times to focus each of the <input> elements in turn.
  EXPECT_EQ("\"root-focused-input1\"", press_tab_and_wait_for_message(false));
  EXPECT_EQ(main_frame, web_contents->GetFocusedFrame());
  EXPECT_EQ("\"child1-focused-input1\"", press_tab_and_wait_for_message(false));
  EXPECT_EQ(child1, web_contents->GetFocusedFrame());
  EXPECT_EQ("\"child1-focused-input2\"", press_tab_and_wait_for_message(false));
  EXPECT_EQ("\"child2-focused-input1\"", press_tab_and_wait_for_message(false));
  EXPECT_EQ(child2, web_contents->GetFocusedFrame());
  EXPECT_EQ("\"child2-focused-input2\"", press_tab_and_wait_for_message(false));
  EXPECT_EQ("\"root-focused-input2\"", press_tab_and_wait_for_message(false));
  EXPECT_EQ(main_frame, web_contents->GetFocusedFrame());

  // Now, press <shift-tab> to navigate focus in the reverse direction.
  EXPECT_EQ("\"child2-focused-input2\"", press_tab_and_wait_for_message(true));
  EXPECT_EQ(child2, web_contents->GetFocusedFrame());
  EXPECT_EQ("\"child2-focused-input1\"", press_tab_and_wait_for_message(true));
  EXPECT_EQ("\"child1-focused-input2\"", press_tab_and_wait_for_message(true));
  EXPECT_EQ(child1, web_contents->GetFocusedFrame());
  EXPECT_EQ("\"child1-focused-input1\"", press_tab_and_wait_for_message(true));
  EXPECT_EQ("\"root-focused-input1\"", press_tab_and_wait_for_message(true));
  EXPECT_EQ(main_frame, web_contents->GetFocusedFrame());
}

#if (defined(OS_LINUX) && !defined(USE_OZONE)) || defined(OS_WIN)
// Ensures that renderers know to advance focus to sibling frames and parent
// frames in the presence of mouse click initiated focus changes.
// Verifies against regression of https://crbug.com/702330
IN_PROC_BROWSER_TEST_F(SitePerProcessInteractiveBrowserTest,
                       TabAndMouseFocusNavigation) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b,c)"));
  ui_test_utils::NavigateToURL(browser(), main_url);

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

  content::RenderFrameHost* main_frame = web_contents->GetMainFrame();
  content::RenderFrameHost* child1 = ChildFrameAt(main_frame, 0);
  ASSERT_NE(nullptr, child1);
  content::RenderFrameHost* child2 = ChildFrameAt(main_frame, 1);
  ASSERT_NE(nullptr, child2);

  // Needed to avoid flakiness with --enable-browser-side-navigation.
  content::WaitForHitTestDataOrChildSurfaceReady(child1);
  content::WaitForHitTestDataOrChildSurfaceReady(child2);

  // Assign a name to each frame.  This will be sent along in test messages
  // from focus events.
  EXPECT_TRUE(ExecuteScript(main_frame, "window.name = 'root';"));
  EXPECT_TRUE(ExecuteScript(child1, "window.name = 'child1';"));
  EXPECT_TRUE(ExecuteScript(child2, "window.name = 'child2';"));

  // This script will insert two <input> fields in the document, one at the
  // beginning and one at the end.  For root frame, this means that we will
  // have an <input>, then two <iframe> elements, then another <input>.
  // The script will send back the coordinates to click for each <input>, in the
  // document's space. Additionally, the outer frame will return  the top left
  // point of each <iframe> to transform the coordinates of the inner <input>
  // elements. For example, main frame: 497,18;497,185:381,59;499,59 and each
  // iframe: 55,18;55,67
  std::string script =
      "function onFocus(e) {"
      "  console.log(window.name + '-focused-' + e.target.id);"
      "  domAutomationController.send(window.name + '-focused-' + e.target.id);"
      "}"
      ""
      "function getElementCoords(element) {"
      "  var rect = element.getBoundingClientRect();"
      "  return Math.floor(rect.left + 0.5 * rect.width) +','+"
      "         Math.floor(rect.top + 0.5 * rect.height);"
      "}"
      "function getIframeCoords(element) {"
      "  var rect = element.getBoundingClientRect();"
      "  return Math.floor(rect.left) +','+"
      "         Math.floor(rect.top);"
      "}"
      "function onClick(e) {"
      " console.log('Click event ' + window.name + ' at: ' + e.x + ', ' + e.y "
      "             + ' screen: ' + e.screenX + ', ' + e.screenY);"
      "}"
      ""
      "window.addEventListener('click', onClick);"
      "console.log(document.location.origin);"
      "document.styleSheets[0].insertRule('input {width:100%;margin:0;}', 1);"
      "document.styleSheets[0].insertRule('h2 {margin:0;}', 1);"
      "var input1 = document.createElement('input');"
      "input1.id = 'input1';"
      "input1.addEventListener('focus', onFocus, false);"
      "var input2 = document.createElement('input');"
      "input2.id = 'input2';"
      "input2.addEventListener('focus', onFocus, false);"
      "document.body.insertBefore(input1, document.body.firstChild);"
      "document.body.appendChild(input2);"
      ""
      "var frames = document.querySelectorAll('iframe');"
      "frames = Array.prototype.map.call(frames, getIframeCoords).join(';');"
      "var inputCoords = [input1, input2].map(getElementCoords).join(';');"
      "if (frames) {"
      "  inputCoords = inputCoords + ':' + frames;"
      "}"
      "domAutomationController.send(inputCoords);";

  auto parse_points = [](const std::string& input, const gfx::Point& offset) {
    base::StringPairs pieces;
    base::SplitStringIntoKeyValuePairs(input, ',', ';', &pieces);
    std::vector<gfx::Point> points;
    for (const auto& piece : pieces) {
      int x, y;
      EXPECT_TRUE(base::StringToInt(piece.first, &x));
      EXPECT_TRUE(base::StringToInt(piece.second, &y));
      points.push_back(gfx::Point(x + offset.x(), y + offset.y()));
    }
    return points;
  };
  auto parse_points_and_offsets = [parse_points](const std::string& input) {
    auto pieces = base::SplitString(input, ":", base::TRIM_WHITESPACE,
                                    base::SPLIT_WANT_NONEMPTY);
    gfx::Point empty_offset;
    return make_pair(parse_points(pieces[0], empty_offset),
                     parse_points(pieces[1], empty_offset));
  };

  // Add two input fields to each of the three frames and retrieve click
  // coordinates.
  std::string result;
  EXPECT_TRUE(ExecuteScriptAndExtractString(main_frame, script, &result));
  auto parsed = parse_points_and_offsets(result);
  auto main_frame_input_coords = parsed.first;
  auto iframe1_offset = parsed.second[0];
  auto iframe2_offset = parsed.second[1];

  EXPECT_TRUE(ExecuteScriptAndExtractString(child1, script, &result));
  auto child1_input_coords = parse_points(result, iframe1_offset);
  EXPECT_TRUE(ExecuteScriptAndExtractString(child2, script, &result));
  auto child2_input_coords = parse_points(result, iframe2_offset);

  // Helper to simulate a tab press and wait for a focus message.
  auto press_tab_and_wait_for_message = [web_contents](bool reverse) {
    content::DOMMessageQueue msg_queue;
    std::string reply;
    SimulateKeyPress(web_contents, ui::DomKey::TAB, ui::DomCode::TAB,
                     ui::VKEY_TAB, false, reverse /* shift */, false, false);
    LOG(INFO) << "Press tab";
    EXPECT_TRUE(msg_queue.WaitForMessage(&reply));
    return reply;
  };

  auto click_element_and_wait_for_message =
      [web_contents](const gfx::Point& point) {
        content::DOMMessageQueue msg_queue;

        auto content_bounds = web_contents->GetContainerBounds();
        ui_controls::SendMouseMove(point.x() + content_bounds.x(),
                                   point.y() + content_bounds.y());
        ui_controls::SendMouseClick(ui_controls::LEFT);

        std::string reply;
        LOG(INFO) << "Click element";
        EXPECT_TRUE(msg_queue.WaitForMessage(&reply));
        return reply;
      };

  // Tab from child1 back to root.
  EXPECT_EQ("\"root-focused-input1\"",
            click_element_and_wait_for_message(main_frame_input_coords[0]));
  EXPECT_EQ(main_frame, web_contents->GetFocusedFrame());
  auto frame_focused = std::make_unique<content::FrameFocusedObserver>(child1);
  EXPECT_EQ("\"child1-focused-input1\"",
            click_element_and_wait_for_message(child1_input_coords[0]));
  frame_focused->Wait();
  frame_focused = std::make_unique<content::FrameFocusedObserver>(main_frame);
  EXPECT_EQ("\"root-focused-input1\"", press_tab_and_wait_for_message(true));
  frame_focused->Wait();

  // Tab from child2 forward to root.
  EXPECT_EQ("\"root-focused-input2\"",
            click_element_and_wait_for_message(main_frame_input_coords[1]));
  EXPECT_EQ(main_frame, web_contents->GetFocusedFrame());
  frame_focused = std::make_unique<content::FrameFocusedObserver>(child2);
  EXPECT_EQ("\"child2-focused-input2\"",
            click_element_and_wait_for_message(child2_input_coords[1]));
  frame_focused->Wait();
  frame_focused = std::make_unique<content::FrameFocusedObserver>(main_frame);
  EXPECT_EQ("\"root-focused-input2\"", press_tab_and_wait_for_message(false));
  frame_focused->Wait();

  // Tab forward from child1 to child2.
  frame_focused = std::make_unique<content::FrameFocusedObserver>(child2);
  EXPECT_EQ("\"child2-focused-input1\"",
            click_element_and_wait_for_message(child2_input_coords[0]));
  frame_focused->Wait();
  frame_focused = std::make_unique<content::FrameFocusedObserver>(child1);
  EXPECT_EQ("\"child1-focused-input2\"",
            click_element_and_wait_for_message(child1_input_coords[1]));
  frame_focused->Wait();
  frame_focused = std::make_unique<content::FrameFocusedObserver>(child2);
  EXPECT_EQ("\"child2-focused-input1\"", press_tab_and_wait_for_message(false));
  frame_focused->Wait();

  // Tab backward from child2 to child1.
  frame_focused = std::make_unique<content::FrameFocusedObserver>(child1);
  EXPECT_EQ("\"child1-focused-input2\"",
            click_element_and_wait_for_message(child1_input_coords[1]));
  frame_focused->Wait();
  frame_focused = std::make_unique<content::FrameFocusedObserver>(child2);
  EXPECT_EQ("\"child2-focused-input1\"",
            click_element_and_wait_for_message(child2_input_coords[0]));
  frame_focused->Wait();
  frame_focused = std::make_unique<content::FrameFocusedObserver>(child1);
  EXPECT_EQ("\"child1-focused-input2\"", press_tab_and_wait_for_message(true));
  // EXPECT_EQ(child1, web_contents->GetFocusedFrame());
  frame_focused->Wait();

  // Ensure there are no pending focus events after tabbing.
  EXPECT_EQ("\"root-focused-input1\"",
            click_element_and_wait_for_message(main_frame_input_coords[0]))
      << "Unexpected extra focus events.";
}
#endif

namespace {

// Helper to retrieve the frame's (window.innerWidth, window.innerHeight).
gfx::Size GetFrameSize(content::RenderFrameHost* frame) {
  int width = 0;
  EXPECT_TRUE(ExecuteScriptAndExtractInt(
      frame, "domAutomationController.send(window.innerWidth);", &width));

  int height = 0;
  EXPECT_TRUE(ExecuteScriptAndExtractInt(
      frame, "domAutomationController.send(window.innerHeight);", &height));

  return gfx::Size(width, height);
}

// Helper to check |frame|'s document.webkitFullscreenElement and return its ID
// if it's defined (which is the case when |frame| is in fullscreen mode), or
// "none" otherwise.
std::string GetFullscreenElementId(content::RenderFrameHost* frame) {
  std::string fullscreen_element;
  EXPECT_TRUE(ExecuteScriptAndExtractString(
      frame,
      "domAutomationController.send("
      "    document.webkitFullscreenElement ? "
      "        document.webkitFullscreenElement.id : 'none')",
      &fullscreen_element));
  return fullscreen_element;
}

// Helper to check if an element with ID |element_id| has the
// :-webkit-full-screen style.
bool ElementHasFullscreenStyle(content::RenderFrameHost* frame,
                               const std::string& element_id) {
  bool has_style = false;
  std::string script = base::StringPrintf(
      "domAutomationController.send("
      "    document.querySelectorAll('#%s:-webkit-full-screen').length == 1)",
      element_id.c_str());
  EXPECT_TRUE(ExecuteScriptAndExtractBool(frame, script, &has_style));
  return has_style;
}

// Helper to check if an element with ID |element_id| has the
// :-webkit-full-screen-ancestor style.
bool ElementHasFullscreenAncestorStyle(content::RenderFrameHost* host,
                                       const std::string& element_id) {
  bool has_style = false;
  std::string script = base::StringPrintf(
      "domAutomationController.send("
      "    document.querySelectorAll("
      "        '#%s:-webkit-full-screen-ancestor').length == 1)",
      element_id.c_str());
  EXPECT_TRUE(ExecuteScriptAndExtractBool(host, script, &has_style));
  return has_style;
}

// Add a listener that will send back a message whenever the (prefixed)
// fullscreenchange event fires.  The message will be "fullscreenchange",
// followed by a space and the provided |id|.
void AddFullscreenChangeListener(content::RenderFrameHost* frame,
                                 const std::string& id) {
  std::string script = base::StringPrintf(
      "document.addEventListener('webkitfullscreenchange', function() {"
      "    domAutomationController.send('fullscreenchange %s');});",
      id.c_str());
  EXPECT_TRUE(ExecuteScript(frame, script));
}

// Helper to add a listener that will send back a "resize" message when the
// target |frame| is resized to |expected_size|.
void AddResizeListener(content::RenderFrameHost* frame,
                       const gfx::Size& expected_size) {
  std::string script =
      base::StringPrintf("addResizeListener(%d, %d);",
                         expected_size.width(), expected_size.height());
  EXPECT_TRUE(ExecuteScript(frame, script));
}

// Helper to wait for a toggle fullscreen operation to complete in all affected
// frames.  This means waiting for:
// 1. All fullscreenchange events with id's matching the list in
//    |expected_fullscreen_event_ids|.  Typically the list will correspond to
//    events from the actual fullscreen element and all of its ancestor
//    <iframe> elements.
// 2. A resize event.  This will verify that the frame containing the
//    fullscreen element is properly resized.  This assumes that the expected
//    size is already registered via AddResizeListener().
void WaitForMultipleFullscreenEvents(
    const std::set<std::string>& expected_fullscreen_event_ids,
    content::DOMMessageQueue& queue) {
  std::set<std::string> remaining_events(expected_fullscreen_event_ids);
  bool resize_validated = false;
  std::string response;
  while (queue.WaitForMessage(&response)) {
    base::TrimString(response, "\"", &response);
    std::vector<std::string> response_params = base::SplitString(
        response, " ", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
    if (response_params[0] == "fullscreenchange") {
      EXPECT_TRUE(base::ContainsKey(remaining_events, response_params[1]));
      remaining_events.erase(response_params[1]);
    } else if (response_params[0] == "resize") {
      resize_validated = true;
    }
    if (remaining_events.empty() && resize_validated)
      break;
  }
}

}  // namespace

// Check that an element in a cross-process subframe can enter and exit
// fullscreen.  The test will verify that:
// - the subframe is properly resized
// - the WebContents properly enters/exits fullscreen.
// - document.webkitFullscreenElement is correctly updated in both frames.
// - fullscreenchange events fire in both frames.
// - fullscreen CSS is applied correctly in both frames.
//
IN_PROC_BROWSER_TEST_F(SitePerProcessInteractiveBrowserTest,
                       FullscreenElementInSubframe) {
  if (IsMacViewsBrowser())
    return;
  // Start on a page with one subframe (id "child-0") that has
  // "allowfullscreen" enabled.
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/page_with_allowfullscreen_frame.html"));
  ui_test_utils::NavigateToURL(browser(), main_url);
  content::WebContents* web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();

  // Navigate the subframe cross-site to a page with a fullscreenable <div>.
  GURL frame_url(
      embedded_test_server()->GetURL("b.com", "/fullscreen_frame.html"));
  EXPECT_TRUE(NavigateIframeToURL(web_contents, "child-0", frame_url));

  content::RenderFrameHost* main_frame = web_contents->GetMainFrame();
  content::RenderFrameHost* child = ChildFrameAt(main_frame, 0);
  gfx::Size original_child_size = GetFrameSize(child);

  // Fullscreen the <div> inside the cross-site child frame.  Wait until:
  // (1) the fullscreenchange events in main frame and child send a response,
  // (2) the child frame is resized to fill the whole screen.
  // (3) the browser has finished the fullscreen transition.
  AddFullscreenChangeListener(main_frame, "main_frame");
  AddFullscreenChangeListener(child, "child");
  std::set<std::string> expected_events = {"main_frame", "child"};
  AddResizeListener(child, GetScreenSize());
  {
    content::DOMMessageQueue queue;
    std::unique_ptr<FullscreenNotificationObserver> observer(
        new FullscreenNotificationObserver());
    EXPECT_TRUE(ExecuteScript(child, "activateFullscreen()"));
    WaitForMultipleFullscreenEvents(expected_events, queue);
    observer->Wait();
  }

  // Verify that the browser has entered fullscreen for the current tab.
  EXPECT_TRUE(browser()->window()->IsFullscreen());
  EXPECT_TRUE(browser()->exclusive_access_manager()
                       ->fullscreen_controller()
                       ->IsFullscreenForTabOrPending(web_contents));

  // Verify that the <div> has fullscreen style (:-webkit-full-screen) in the
  // subframe.
  EXPECT_TRUE(ElementHasFullscreenStyle(child, "fullscreen-div"));

  // Verify that the main frame has applied proper fullscreen styles to the
  // <iframe> element (:-webkit-full-screen and :-webkit-full-screen-ancestor).
  // This is what causes the <iframe> to stretch and fill the whole viewport.
  EXPECT_TRUE(ElementHasFullscreenStyle(main_frame, "child-0"));
  EXPECT_TRUE(ElementHasFullscreenAncestorStyle(main_frame, "child-0"));

  // Check document.webkitFullscreenElement.  For main frame, it should point
  // to the subframe, and for subframe, it should point to the fullscreened
  // <div>.
  EXPECT_EQ("child-0", GetFullscreenElementId(main_frame));
  EXPECT_EQ("fullscreen-div", GetFullscreenElementId(child));

  // Now exit fullscreen from the subframe.  Wait for two fullscreenchange
  // events from both frames, and also for the child to be resized to its
  // original size.
  AddResizeListener(child, original_child_size);
  {
    content::DOMMessageQueue queue;
    std::unique_ptr<FullscreenNotificationObserver> observer(
        new FullscreenNotificationObserver());
    EXPECT_TRUE(ExecuteScript(child, "exitFullscreen()"));
    WaitForMultipleFullscreenEvents(expected_events, queue);
    observer->Wait();
  }

  EXPECT_FALSE(browser()->window()->IsFullscreen());

  // Verify that the fullscreen styles were removed from the <div> and its
  // container <iframe>.
  EXPECT_FALSE(ElementHasFullscreenStyle(child, "fullscreen-div"));
  EXPECT_FALSE(ElementHasFullscreenStyle(main_frame, "child-0"));
  EXPECT_FALSE(ElementHasFullscreenAncestorStyle(main_frame, "child-0"));

  // Check that both frames cleared their document.webkitFullscreenElement.
  EXPECT_EQ("none", GetFullscreenElementId(main_frame));
  EXPECT_EQ("none", GetFullscreenElementId(child));
}

// Check that on a page with A-embed-B-embed-A frame hierarchy, an element in
// the bottom frame can enter and exit fullscreen.  |exit_method| specifies
// whether to use browser-initiated vs. renderer-initiated fullscreen exit
// (i.e., pressing escape vs. a JS call), since they trigger different code
// paths on the Blink side.
void SitePerProcessInteractiveBrowserTest::FullscreenElementInABA(
    FullscreenExitMethod exit_method) {
  GURL main_url(embedded_test_server()->GetURL("a.com",
                                               "/cross_site_iframe_factory."
                                               "html?a(b{allowfullscreen}(a{"
                                               "allowfullscreen}))"));
  ui_test_utils::NavigateToURL(browser(), main_url);
  content::WebContents* web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();

  content::RenderFrameHost* main_frame = web_contents->GetMainFrame();
  content::RenderFrameHost* child = ChildFrameAt(main_frame, 0);
  content::RenderFrameHost* grandchild = ChildFrameAt(child, 0);

  // Navigate the bottom frame to a page that has a fullscreenable <div>.
  content::TestNavigationObserver observer(web_contents);
  EXPECT_TRUE(
      ExecuteScript(grandchild, "location.href = '/fullscreen_frame.html'"));
  observer.Wait();
  EXPECT_EQ(embedded_test_server()->GetURL("a.com", "/fullscreen_frame.html"),
            grandchild->GetLastCommittedURL());

  // Make fullscreenchange events in all three frames send a message.
  AddFullscreenChangeListener(main_frame, "main_frame");
  AddFullscreenChangeListener(child, "child");
  AddFullscreenChangeListener(grandchild, "grandchild");

  // Add a resize event handler that will send a message when the grandchild
  // frame is resized to the screen size.  Also save its original size.
  AddResizeListener(grandchild, GetScreenSize());
  gfx::Size original_grandchild_size = GetFrameSize(grandchild);

  // Fullscreen a <div> inside the bottom subframe.  This will block until
  // (1) the fullscreenchange events in all frames send a response, and
  // (2) the frame is resized to fill the whole screen.
  // (3) the browser has finished the fullscreen transition.
  std::set<std::string> expected_events = {"main_frame", "child", "grandchild"};
  {
    content::DOMMessageQueue queue;
    std::unique_ptr<FullscreenNotificationObserver> observer(
        new FullscreenNotificationObserver());
    EXPECT_TRUE(ExecuteScript(grandchild, "activateFullscreen()"));
    WaitForMultipleFullscreenEvents(expected_events, queue);
    observer->Wait();
  }

  // Verify that the browser has entered fullscreen for the current tab.
  EXPECT_TRUE(browser()->window()->IsFullscreen());
  EXPECT_TRUE(browser()->exclusive_access_manager()
                       ->fullscreen_controller()
                       ->IsFullscreenForTabOrPending(web_contents));

  // Verify that the <div> has fullscreen style in the bottom frame, and that
  // the proper <iframe> elements have fullscreen style in its ancestor frames.
  EXPECT_TRUE(ElementHasFullscreenStyle(grandchild, "fullscreen-div"));
  EXPECT_TRUE(ElementHasFullscreenStyle(child, "child-0"));
  EXPECT_TRUE(ElementHasFullscreenAncestorStyle(child, "child-0"));
  EXPECT_TRUE(ElementHasFullscreenStyle(main_frame, "child-0"));
  EXPECT_TRUE(ElementHasFullscreenAncestorStyle(main_frame, "child-0"));

  // Check document.webkitFullscreenElement in all frames.
  EXPECT_EQ("child-0", GetFullscreenElementId(main_frame));
  EXPECT_EQ("child-0", GetFullscreenElementId(child));
  EXPECT_EQ("fullscreen-div", GetFullscreenElementId(grandchild));

  // Now exit fullscreen from the subframe.
  AddResizeListener(grandchild, original_grandchild_size);
  {
    content::DOMMessageQueue queue;
    std::unique_ptr<FullscreenNotificationObserver> observer(
        new FullscreenNotificationObserver());
    switch (exit_method) {
      case FullscreenExitMethod::JS_CALL:
        EXPECT_TRUE(ExecuteScript(grandchild, "exitFullscreen()"));
        break;
      case FullscreenExitMethod::ESC_PRESS:
        ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
            browser(), ui::VKEY_ESCAPE, false, false, false, false));
        break;
      default:
        NOTREACHED();
    }
    WaitForMultipleFullscreenEvents(expected_events, queue);
    observer->Wait();
  }

  EXPECT_FALSE(browser()->window()->IsFullscreen());

  // Verify that the fullscreen styles were removed from the <div> and its
  // container <iframe>'s.
  EXPECT_FALSE(ElementHasFullscreenStyle(grandchild, "fullscreen-div"));
  EXPECT_FALSE(ElementHasFullscreenStyle(child, "child-0"));
  EXPECT_FALSE(ElementHasFullscreenAncestorStyle(child, "child-0"));
  EXPECT_FALSE(ElementHasFullscreenStyle(main_frame, "child-0"));
  EXPECT_FALSE(ElementHasFullscreenAncestorStyle(main_frame, "child-0"));

  // Check that document.webkitFullscreenElement was cleared in all three
  // frames.
  EXPECT_EQ("none", GetFullscreenElementId(main_frame));
  EXPECT_EQ("none", GetFullscreenElementId(child));
  EXPECT_EQ("none", GetFullscreenElementId(grandchild));
}

// This is flaky on Linux (crbug.com/854294)
#if defined(OS_LINUX)
#define MAYBE_FullscreenElementInABAAndExitViaEscapeKey \
  DISABLED_FullscreenElementInABAAndExitViaEscapeKey
#else
#define MAYBE_FullscreenElementInABAAndExitViaEscapeKey \
  FullscreenElementInABAAndExitViaEscapeKey
#endif
IN_PROC_BROWSER_TEST_F(SitePerProcessInteractiveBrowserTest,
                       MAYBE_FullscreenElementInABAAndExitViaEscapeKey) {
  if (IsMacViewsBrowser())
    return;
  FullscreenElementInABA(FullscreenExitMethod::ESC_PRESS);
}

// This test is flaky on Linux (crbug.com/851236) and also not working
// on Mac (crbug.com/850594).
IN_PROC_BROWSER_TEST_F(SitePerProcessInteractiveBrowserTest,
                       DISABLED_FullscreenElementInABAAndExitViaJS) {
  if (IsMacViewsBrowser())
    return;
  FullscreenElementInABA(FullscreenExitMethod::JS_CALL);
}

// Check that fullscreen works on a more complex page hierarchy with multiple
// local and remote ancestors.  The test uses this frame tree:
//
//             A (a_top)
//             |
//             A (a_bottom)
//            / \   .
// (b_first) B   B (b_second)
//               |
//               C (c_top)
//               |
//               C (c_middle) <- fullscreen target
//               |
//               C (c_bottom)
//
// The c_middle frame will trigger fullscreen for its <div> element.  The test
// verifies that its ancestor chain is properly updated for fullscreen, and
// that the b_first node that's not on the chain is not affected.
//
// The test also exits fullscreen by simulating pressing ESC rather than using
// document.webkitExitFullscreen(), which tests the browser-initiated
// fullscreen exit path.
#if defined(OS_CHROMEOS) || defined(OS_MACOSX)
#define MAYBE_FullscreenElementInMultipleSubframes \
  DISABLED_FullscreenElementInMultipleSubframes
#else
#define MAYBE_FullscreenElementInMultipleSubframes \
  FullscreenElementInMultipleSubframes
#endif
IN_PROC_BROWSER_TEST_F(SitePerProcessInteractiveBrowserTest,
                       MAYBE_FullscreenElementInMultipleSubframes) {
  // Allow fullscreen in all iframes descending to |c_middle|.
  GURL main_url(embedded_test_server()->GetURL(
      "a.com",
      "/cross_site_iframe_factory.html?a(a{allowfullscreen}(b,b{"
      "allowfullscreen}(c{allowfullscreen}(c{allowfullscreen}))))"));
  ui_test_utils::NavigateToURL(browser(), main_url);
  content::WebContents* web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();

  content::RenderFrameHost* a_top = web_contents->GetMainFrame();
  content::RenderFrameHost* a_bottom = ChildFrameAt(a_top, 0);
  content::RenderFrameHost* b_first = ChildFrameAt(a_bottom, 0);
  content::RenderFrameHost* b_second = ChildFrameAt(a_bottom, 1);
  content::RenderFrameHost* c_top = ChildFrameAt(b_second, 0);
  content::RenderFrameHost* c_middle = ChildFrameAt(c_top, 0);

  // Navigate |c_middle| to a page that has a fullscreenable <div> and another
  // frame.
  content::TestNavigationObserver observer(web_contents);
  EXPECT_TRUE(
      ExecuteScript(c_middle, "location.href = '/fullscreen_frame.html'"));
  observer.Wait();
  EXPECT_EQ(embedded_test_server()->GetURL("c.com", "/fullscreen_frame.html"),
            c_middle->GetLastCommittedURL());
  content::RenderFrameHost* c_bottom = ChildFrameAt(c_middle, 0);

  // Save the size of the frame to be fullscreened.
  gfx::Size c_middle_original_size = GetFrameSize(c_middle);

  // Add fullscreenchange and resize event handlers to all frames.
  AddFullscreenChangeListener(a_top, "a_top");
  AddFullscreenChangeListener(a_bottom, "a_bottom");
  AddFullscreenChangeListener(b_first, "b_first");
  AddFullscreenChangeListener(b_second, "b_second");
  AddFullscreenChangeListener(c_top, "c_top");
  AddFullscreenChangeListener(c_middle, "c_middle");
  AddFullscreenChangeListener(c_bottom, "c_bottom");
  AddResizeListener(c_middle, GetScreenSize());

  // Note that expected fullscreenchange events do NOT include |b_first| and
  // |c_bottom|, which aren't on the ancestor chain of |c_middle|.
  // WaitForMultipleFullscreenEvents() below will fail if it hears an
  // unexpected fullscreenchange from one of these frames.
  std::set<std::string> expected_events = {"a_top", "a_bottom", "b_second",
                                           "c_top", "c_middle"};

  // Fullscreen a <div> inside |c_middle|.  Block until (1) the
  // fullscreenchange events in |c_middle| and all its ancestors send a
  // response, (2) |c_middle| is resized to fill the whole screen, and (3) the
  // browser finishes the fullscreen transition.
  {
    content::DOMMessageQueue queue;
    std::unique_ptr<FullscreenNotificationObserver> observer(
        new FullscreenNotificationObserver());
    EXPECT_TRUE(ExecuteScript(c_middle, "activateFullscreen()"));
    WaitForMultipleFullscreenEvents(expected_events, queue);
    observer->Wait();
  }

  // Verify that the browser has entered fullscreen for the current tab.
  EXPECT_TRUE(browser()->window()->IsFullscreen());
  EXPECT_TRUE(browser()->exclusive_access_manager()
                       ->fullscreen_controller()
                       ->IsFullscreenForTabOrPending(web_contents));

  // Check document.webkitFullscreenElement.  It should point to corresponding
  // <iframe> element IDs on |c_middle|'s ancestor chain, and it should be null
  // in b_first and c_bottom.
  EXPECT_EQ("child-0", GetFullscreenElementId(a_top));
  EXPECT_EQ("child-1", GetFullscreenElementId(a_bottom));
  EXPECT_EQ("child-0", GetFullscreenElementId(b_second));
  EXPECT_EQ("child-0", GetFullscreenElementId(c_top));
  EXPECT_EQ("fullscreen-div", GetFullscreenElementId(c_middle));
  EXPECT_EQ("none", GetFullscreenElementId(b_first));
  EXPECT_EQ("none", GetFullscreenElementId(c_bottom));

  // Verify that the fullscreen element and all <iframe> elements on its
  // ancestor chain have fullscreen style, but other frames do not.
  EXPECT_TRUE(ElementHasFullscreenStyle(a_top, "child-0"));
  EXPECT_FALSE(ElementHasFullscreenStyle(a_bottom, "child-0"));
  EXPECT_TRUE(ElementHasFullscreenStyle(a_bottom, "child-1"));
  EXPECT_TRUE(ElementHasFullscreenStyle(b_second, "child-0"));
  EXPECT_TRUE(ElementHasFullscreenStyle(c_top, "child-0"));
  EXPECT_TRUE(ElementHasFullscreenStyle(c_middle, "fullscreen-div"));
  EXPECT_FALSE(ElementHasFullscreenStyle(c_middle, "child-0"));

  // Now exit fullscreen by pressing escape.  Wait for all fullscreenchange
  // events fired for fullscreen exit and verify that the bottom frame was
  // resized back to its original size.
  AddResizeListener(c_middle, c_middle_original_size);
  {
    content::DOMMessageQueue queue;
    std::unique_ptr<FullscreenNotificationObserver> observer(
        new FullscreenNotificationObserver());
    ASSERT_TRUE(ui_test_utils::SendKeyPressSync(browser(), ui::VKEY_ESCAPE,
                                                false, false, false, false));
    WaitForMultipleFullscreenEvents(expected_events, queue);
    observer->Wait();
  }

  EXPECT_FALSE(browser()->window()->IsFullscreen());

  // Check that document.webkitFullscreenElement has been cleared in all
  // frames.
  EXPECT_EQ("none", GetFullscreenElementId(a_top));
  EXPECT_EQ("none", GetFullscreenElementId(a_bottom));
  EXPECT_EQ("none", GetFullscreenElementId(b_first));
  EXPECT_EQ("none", GetFullscreenElementId(b_second));
  EXPECT_EQ("none", GetFullscreenElementId(c_top));
  EXPECT_EQ("none", GetFullscreenElementId(c_middle));
  EXPECT_EQ("none", GetFullscreenElementId(c_bottom));

  // Verify that all fullscreen styles have been cleared.
  EXPECT_FALSE(ElementHasFullscreenStyle(a_top, "child-0"));
  EXPECT_FALSE(ElementHasFullscreenStyle(a_bottom, "child-0"));
  EXPECT_FALSE(ElementHasFullscreenStyle(a_bottom, "child-1"));
  EXPECT_FALSE(ElementHasFullscreenStyle(b_second, "child-0"));
  EXPECT_FALSE(ElementHasFullscreenStyle(c_top, "child-0"));
  EXPECT_FALSE(ElementHasFullscreenStyle(c_middle, "fullscreen-div"));
  EXPECT_FALSE(ElementHasFullscreenStyle(c_middle, "child-0"));
}

// Test that deleting a RenderWidgetHost that holds the mouse lock won't cause a
// crash. https://crbug.com/619571.
IN_PROC_BROWSER_TEST_F(SitePerProcessInteractiveBrowserTest,
                       RenderWidgetHostDeletedWhileMouseLocked) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)"));
  ui_test_utils::NavigateToURL(browser(), main_url);

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

  content::RenderFrameHost* main_frame = web_contents->GetMainFrame();
  content::RenderFrameHost* child = ChildFrameAt(main_frame, 0);

  EXPECT_TRUE(ExecuteScript(child, "document.body.requestPointerLock()"));
  bool mouse_locked = false;
  EXPECT_TRUE(ExecuteScriptAndExtractBool(child,
                                          "window.domAutomationController.send("
                                          "document.body == "
                                          "document.pointerLockElement)",
                                          &mouse_locked));
  EXPECT_TRUE(mouse_locked);
  EXPECT_TRUE(main_frame->GetView()->IsMouseLocked());

  EXPECT_TRUE(ExecuteScript(main_frame,
                            "document.querySelector('iframe').parentNode."
                            "removeChild(document.querySelector('iframe'))"));
  EXPECT_FALSE(main_frame->GetView()->IsMouseLocked());
}

// Base test class for interactive tests which load and test PDF files.
class SitePerProcessInteractivePDFTest
    : public SitePerProcessInteractiveBrowserTest {
 public:
  SitePerProcessInteractivePDFTest() : test_guest_view_manager_(nullptr) {}
  ~SitePerProcessInteractivePDFTest() override {}

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

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

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

  DISALLOW_COPY_AND_ASSIGN(SitePerProcessInteractivePDFTest);
};

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

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

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

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

  DISALLOW_COPY_AND_ASSIGN(NavigationToExtensionSchemeObserver);
};

// This test loads a PDF inside an OOPIF and then verifies that context menu
// shows up at the correct position.
IN_PROC_BROWSER_TEST_F(SitePerProcessInteractivePDFTest,
                       ContextMenuPositionForEmbeddedPDFInCrossOriginFrame) {
  // Navigate to a page with an <iframe>.
  GURL main_url(embedded_test_server()->GetURL("a.com", "/iframe.html"));
  ui_test_utils::NavigateToURL(browser(), main_url);

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

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

  // Change the position of the <iframe> inside the page.
  EXPECT_TRUE(ExecuteScript(active_web_contents,
                            "document.querySelector('iframe').style ="
                            " 'margin-left: 100px; margin-top: 100px;';"));

  // Navigate subframe to a cross-site page with an embedded PDF.
  GURL frame_url =
      embedded_test_server()->GetURL("b.com", "/page_with_embedded_pdf.html");

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

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

  // Observe navigations in guest to find out when navigation to the (PDF)
  // extension commits. It will be used as an indicator that BrowserPlugin
  // has attached.
  NavigationToExtensionSchemeObserver navigation_observer(guest_contents);

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

  content::RenderWidgetHostView* child_view =
      ChildFrameAt(active_web_contents->GetMainFrame(), 0)->GetView();

  ContextMenuWaiter menu_waiter;

  // Declaring a lambda to send a right-button mouse event to the embedder
  // frame.
  auto send_right_mouse_event = [](content::RenderWidgetHost* host, int x,
                                   int y, blink::WebInputEvent::Type type) {
    blink::WebMouseEvent event;
    event.SetPositionInWidget(x, y);
    event.button = blink::WebMouseEvent::Button::kRight;
    event.SetType(type);
    host->ForwardMouseEvent(event);
  };

  send_right_mouse_event(child_view->GetRenderWidgetHost(), 10, 20,
                         blink::WebInputEvent::kMouseDown);
  send_right_mouse_event(child_view->GetRenderWidgetHost(), 10, 20,
                         blink::WebInputEvent::kMouseUp);
  menu_waiter.WaitForMenuOpenAndClose();

  gfx::Point point_in_root_window =
      child_view->TransformPointToRootCoordSpace(gfx::Point(10, 20));

  EXPECT_EQ(point_in_root_window.x(), menu_waiter.params().x);
  EXPECT_EQ(point_in_root_window.y(), menu_waiter.params().y);
}

class SitePerProcessAutofillTest : public SitePerProcessInteractiveBrowserTest {
 public:
  SitePerProcessAutofillTest() : SitePerProcessInteractiveBrowserTest() {}
  ~SitePerProcessAutofillTest() override {}

 protected:
  class TestAutofillClient : public autofill::TestAutofillClient {
   public:
    TestAutofillClient() : popup_shown_(false) {}
    ~TestAutofillClient() override {}

    void WaitForNextPopup() {
      if (popup_shown_)
        return;
      loop_runner_ = new content::MessageLoopRunner();
      loop_runner_->Run();
    }

    void ShowAutofillPopup(
        const gfx::RectF& element_bounds,
        base::i18n::TextDirection text_direction,
        const std::vector<autofill::Suggestion>& suggestions,
        bool autoselect_first_suggestion,
        base::WeakPtr<autofill::AutofillPopupDelegate> delegate) override {
      element_bounds_ = element_bounds;
      popup_shown_ = true;
      if (loop_runner_)
        loop_runner_->Quit();
    }

    const gfx::RectF& last_element_bounds() const { return element_bounds_; }

   private:
    gfx::RectF element_bounds_;
    bool popup_shown_;
    scoped_refptr<content::MessageLoopRunner> loop_runner_;

    DISALLOW_COPY_AND_ASSIGN(TestAutofillClient);
  };

  const int kIframeTopDisplacement = 150;
  const int kIframeLeftDisplacement = 200;

  void SetupMainTab() {
    // Add a fresh new WebContents for which we add our own version of the
    // ChromePasswordManagerClient that uses a custom TestAutofillClient.
    std::unique_ptr<content::WebContents> new_contents =
        content::WebContents::Create(
            content::WebContents::CreateParams(browser()
                                                   ->tab_strip_model()
                                                   ->GetActiveWebContents()
                                                   ->GetBrowserContext()));
    ASSERT_TRUE(new_contents);
    ASSERT_FALSE(
        ChromePasswordManagerClient::FromWebContents(new_contents.get()));

    // Create ChromePasswordManagerClient and verify it exists for the new
    // WebContents.
    ChromePasswordManagerClient::CreateForWebContentsWithAutofillClient(
        new_contents.get(), &test_autofill_client_);
    ASSERT_TRUE(
        ChromePasswordManagerClient::FromWebContents(new_contents.get()));

    browser()->tab_strip_model()->AppendWebContents(std::move(new_contents),
                                                    true);
  }

  TestAutofillClient& autofill_client() { return test_autofill_client_; }

 private:
  base::test::ScopedFeatureList scoped_feature_list_;
  TestAutofillClient test_autofill_client_;

  DISALLOW_COPY_AND_ASSIGN(SitePerProcessAutofillTest);
};

// Observes the notifications for changes in focused node/element in the page.
class FocusedEditableNodeChangedObserver : content::NotificationObserver {
 public:
  FocusedEditableNodeChangedObserver() : observed_(false) {
    registrar_.Add(this, content::NOTIFICATION_FOCUS_CHANGED_IN_PAGE,
                   content::NotificationService::AllSources());
  }
  ~FocusedEditableNodeChangedObserver() override {}

  void WaitForFocusChangeInPage() {
    if (observed_)
      return;
    loop_runner_ = new content::MessageLoopRunner();
    loop_runner_->Run();
  }

  // content::NotificationObserver override.
  void Observe(int type,
               const content::NotificationSource& source,
               const content::NotificationDetails& details) override {
    auto focused_node_details =
        content::Details<content::FocusedNodeDetails>(details);
    if (!focused_node_details->is_editable_node)
      return;
    focused_node_bounds_in_screen_ =
        focused_node_details->node_bounds_in_screen.origin();
    observed_ = true;
    if (loop_runner_)
      loop_runner_->Quit();
  }

  const gfx::Point& focused_node_bounds_in_screen() const {
    return focused_node_bounds_in_screen_;
  }

 private:
  content::NotificationRegistrar registrar_;
  bool observed_;
  gfx::Point focused_node_bounds_in_screen_;
  scoped_refptr<content::MessageLoopRunner> loop_runner_;

  DISALLOW_COPY_AND_ASSIGN(FocusedEditableNodeChangedObserver);
};

// Waits until transforming |sample_point| from |render_frame_host| coordinates
// to its root frame's view's coordinates matches |transformed_point| within a
// reasonable error margin less than or equal to |bound|. This method is used to
// verify CSS changes on OOPIFs have been applied properly and the corresponding
// compositor frame is updated as well. This way we can rest assured that the
// future transformed and reported bounds for the elements inside
// |render_frame_host| are correct.
void WaitForFramePositionUpdated(content::RenderFrameHost* render_frame_host,
                                 const gfx::Point& sample_point,
                                 const gfx::Point& transformed_point,
                                 float bound) {
  while ((transformed_point -
          render_frame_host->GetView()->TransformPointToRootCoordSpace(
              sample_point))
             .Length() > bound) {
    base::RunLoop run_loop;
    base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
        FROM_HERE, run_loop.QuitClosure(), TestTimeouts::tiny_timeout());
    run_loop.Run();
  }
}

// This test verifies that when clicking outside the bounds of a date picker
// associated with an <input> inside an OOPIF, the RenderWidgetHostImpl
// corresponding to the WebPagePopup is destroyed (see
// https://crbug.com/671732).
IN_PROC_BROWSER_TEST_F(SitePerProcessInteractiveBrowserTest,
                       ShowAndHideDatePopupInOOPIFMultipleTimes) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)"));
  ui_test_utils::NavigateToURL(browser(), main_url);
  content::RenderFrameHost* child_frame = ChildFrameAt(
      browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(), 0);

  // Add <input type='date'> to the child frame. Adjust the positions that we
  // know where to click to dismiss the popup.
  ASSERT_TRUE(ExecuteScript(
      child_frame,
      "var input = document.createElement('input');"
      "input.type = 'date';"
      "input.value = '2008-09-02';"
      "document.body.appendChild(input);"
      "input.style = 'position: fixed; left: 0px; top: 10px; border: none;' +"
      "              'width: 120px; height: 20px;';"));

  // Cache current date value for a sanity check later.
  std::string cached_date;
  ASSERT_TRUE(ExecuteScriptAndExtractString(
      child_frame, "window.domAutomationController.send(input.value);",
      &cached_date));

  // We use this to determine whether a new RenderWidgetHost is created or an
  // old one is removed.
  size_t default_widget_count = GetNumberOfRenderWidgetHosts();

  // Repeatedly invoke the date picker and then click outside the bounds of the
  // widget to dismiss it and each time verify that a new RenderWidgetHost is
  // added when showing the date picker and a RenderWidgetHost is destroyed when
  // it is dismissed.
  for (size_t tries = 0; tries < 3U; tries++) {
    // Focus the <input>.
    ASSERT_TRUE(
        ExecuteScript(child_frame, "document.querySelector('input').focus();"));

    // Alt + Down seems to be working fine on all platforms.
    ASSERT_TRUE(ui_test_utils::SendKeyPressSync(browser(), ui::VKEY_DOWN, false,
                                                false, true, false));

    // We should get one more widget on the screen.
    WaitForRenderWidgetHostCount(default_widget_count + 1U);

    content::RenderWidgetHost* child_widget_host =
        child_frame->GetView()->GetRenderWidgetHost();

    // Now simulate a click outside the bounds of the popup.
    blink::WebMouseEvent event;
    // Click a little bit to the right and top of the <input>.
    event.SetPositionInWidget(130, 10);
    event.button = blink::WebMouseEvent::Button::kLeft;

    // Send a mouse down event.
    event.SetType(blink::WebInputEvent::kMouseDown);
    child_widget_host->ForwardMouseEvent(event);

    base::RunLoop run_loop;
    base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
        FROM_HERE, run_loop.QuitClosure(), TestTimeouts::tiny_timeout());
    run_loop.Run();

    // Now send a mouse up event.
    event.SetType(blink::WebMouseEvent::kMouseUp);
    child_widget_host->ForwardMouseEvent(event);

    // Wait until the popup disappears and we go back to the normal
    // RenderWidgetHost count.
    WaitForRenderWidgetHostCount(default_widget_count);
  }

  // To make sure we never clicked into the date picker, get current date value
  // and make sure it matches the cached value.
  std::string date;
  ASSERT_TRUE(ExecuteScriptAndExtractString(
      child_frame, "window.domAutomationController.send(input.value);", &date));
  EXPECT_EQ(cached_date, date) << "Cached date was '" << cached_date
                               << "' but current date is '" << date << "'.";
}

// There is a problem of missing keyup events with the command key after
// the NSEvent is sent to NSApplication in ui/base/test/ui_controls_mac.mm .
// This test is disabled on only the Mac until the problem is resolved.
// See http://crbug.com/425859 for more information.
#if !defined(OS_MACOSX)
// Tests that ctrl-click in a subframe results in a background, not a foreground
// tab - see https://crbug.com/804838.  This test is somewhat similar to
// CtrlClickShouldEndUpIn*ProcessTest tests, but this test has to simulate an
// actual mouse click.
IN_PROC_BROWSER_TEST_F(SitePerProcessInteractiveBrowserTest,
                       SubframeAnchorOpenedInBackgroundTab) {
  // Setup the test page - the ctrl-clicked link should be in a subframe.
  GURL main_url(embedded_test_server()->GetURL("foo.com", "/iframe.html"));
  ui_test_utils::NavigateToURL(browser(), main_url);
  GURL subframe_url(embedded_test_server()->GetURL(
      "bar.com", "/frame_tree/anchor_to_same_site_location.html"));
  content::WebContents* old_contents =
      browser()->tab_strip_model()->GetWebContentsAt(0);
  ASSERT_TRUE(NavigateIframeToURL(old_contents, "test", subframe_url));
  EXPECT_LE(2u, old_contents->GetAllFrames().size());
  content::RenderFrameHost* subframe = old_contents->GetAllFrames()[1];
  EXPECT_EQ(subframe_url, subframe->GetLastCommittedURL());

  // Simulate the ctrl-return to open the anchor's link in a new background tab.
  EXPECT_TRUE(ExecuteScript(
      subframe, "document.getElementById('test-anchor-no-target').focus();"));
  content::WebContents* new_contents = nullptr;
  {
    content::WebContentsAddedObserver new_tab_observer;
#if defined(OS_MACOSX)
    ASSERT_TRUE(ui_test_utils::SendKeyPressToWindowSync(
        old_contents->GetTopLevelNativeWindow(), ui::VKEY_RETURN, false, false,
        false, true /* cmd */));
#else
    ASSERT_TRUE(ui_test_utils::SendKeyPressToWindowSync(
        old_contents->GetTopLevelNativeWindow(), ui::VKEY_RETURN,
        true /* ctrl */, false, false, false));
#endif
    new_contents = new_tab_observer.GetWebContents();
  }

  // Verify that the new content has loaded the expected contents.
  GURL target_url(embedded_test_server()->GetURL("bar.com", "/title1.html"));
  EXPECT_TRUE(WaitForLoadStop(new_contents));
  EXPECT_EQ(target_url, new_contents->GetMainFrame()->GetLastCommittedURL());

  // Verify that the anchor opened in a new background tab.
  EXPECT_EQ(2, browser()->tab_strip_model()->count());
  EXPECT_EQ(0, browser()->tab_strip_model()->active_index());
  EXPECT_EQ(0,
            browser()->tab_strip_model()->GetIndexOfWebContents(old_contents));
  EXPECT_EQ(1,
            browser()->tab_strip_model()->GetIndexOfWebContents(new_contents));
}
#endif
