// 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/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/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();
  }
}
}  // 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::WaitForChildFrameSurfaceReady(child1);
  content::WaitForChildFrameSurfaceReady(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 = base::MakeUnique<content::FrameFocusedObserver>(child1);
  EXPECT_EQ("\"child1-focused-input1\"",
            click_element_and_wait_for_message(child1_input_coords[0]));
  frame_focused->Wait();
  frame_focused = base::MakeUnique<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 = base::MakeUnique<content::FrameFocusedObserver>(child2);
  EXPECT_EQ("\"child2-focused-input2\"",
            click_element_and_wait_for_message(child2_input_coords[1]));
  frame_focused->Wait();
  frame_focused = base::MakeUnique<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 = base::MakeUnique<content::FrameFocusedObserver>(child2);
  EXPECT_EQ("\"child2-focused-input1\"",
            click_element_and_wait_for_message(child2_input_coords[0]));
  frame_focused->Wait();
  frame_focused = base::MakeUnique<content::FrameFocusedObserver>(child1);
  EXPECT_EQ("\"child1-focused-input2\"",
            click_element_and_wait_for_message(child1_input_coords[1]));
  frame_focused->Wait();
  frame_focused = base::MakeUnique<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 = base::MakeUnique<content::FrameFocusedObserver>(child1);
  EXPECT_EQ("\"child1-focused-input2\"",
            click_element_and_wait_for_message(child1_input_coords[1]));
  frame_focused->Wait();
  frame_focused = base::MakeUnique<content::FrameFocusedObserver>(child2);
  EXPECT_EQ("\"child2-focused-input1\"",
            click_element_and_wait_for_message(child2_input_coords[0]));
  frame_focused->Wait();
  frame_focused = base::MakeUnique<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) {
  // 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));
}

IN_PROC_BROWSER_TEST_F(SitePerProcessInteractiveBrowserTest,
                       FullscreenElementInABAAndExitViaEscapeKey) {
  FullscreenElementInABA(FullscreenExitMethod::ESC_PRESS);
}

IN_PROC_BROWSER_TEST_F(SitePerProcessInteractiveBrowserTest,
                       FullscreenElementInABAAndExitViaJS) {
  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(content::NotificationService::AllSources());

  // 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 {}

  void SetUpCommandLine(base::CommandLine* command_line) override {
    SitePerProcessInteractiveBrowserTest::SetUpCommandLine(command_line);
    // We need to set the feature state before the render process is created,
    // in order for it to inherit the feature state from the browser process.
    // SetUp() runs too early, and SetUpOnMainThread() runs too late.
    scoped_feature_list_.InitAndEnableFeature(
        security_state::kHttpFormWarningFeature);
  }

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

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

    browser()->tab_strip_model()->AppendWebContents(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 displacements (margin, etc) in the position of an
// OOPIF is considered when showing an AutofillClient warning pop-up for
// unsecure web sites.
IN_PROC_BROWSER_TEST_F(SitePerProcessAutofillTest,
                       PasswordAutofillPopupPositionInsideOOPIF) {
  SetupMainTab();
  ASSERT_TRUE(
      base::FeatureList::IsEnabled(security_state::kHttpFormWarningFeature));

  GURL main_url(embedded_test_server()->GetURL("a.com", "/iframe.html"));
  ui_test_utils::NavigateToURL(browser(), main_url);
  content::WebContents* active_web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();

  // Add some displacement for <iframe>.
  ASSERT_TRUE(content::ExecuteScript(
      active_web_contents,
      base::StringPrintf("var iframe = document.querySelector('iframe');"
                         "iframe.style.position = 'fixed';"
                         "iframe.style.border = 'none';"
                         "iframe.style.top = '%dpx';"
                         "iframe.style.left = '%dpx';",
                         kIframeTopDisplacement, kIframeLeftDisplacement)));

  // Navigate the <iframe> to a simple page.
  GURL frame_url = embedded_test_server()->GetURL("b.com", "/title1.html");
  EXPECT_TRUE(NavigateIframeToURL(active_web_contents, "test", frame_url));
  content::RenderFrameHost* child_frame = content::FrameMatchingPredicate(
      active_web_contents, base::Bind(&content::FrameIsChildOfMainFrame));

  WaitForFramePositionUpdated(
      child_frame, gfx::Point(),
      gfx::Point(kIframeLeftDisplacement, kIframeTopDisplacement), 1.4143f);

  // We will need to listen to focus changes to find out about the container
  // bounds of any focused <input> elements on the page.
  FocusedEditableNodeChangedObserver focus_observer;

  // Focus the child frame, add an <input> with type "password", and focus it.
  ASSERT_TRUE(ExecuteScript(child_frame,
                            "window.focus();"
                            "var input = document.createElement('input');"
                            "input.type = 'password';"
                            "document.body.appendChild(input);"
                            "input.focus();"));
  focus_observer.WaitForFocusChangeInPage();

  // The user gesture (input) should lead to a security warning.
  content::SimulateKeyPress(active_web_contents, ui::DomKey::FromCharacter('A'),
                            ui::DomCode::US_A, ui::VKEY_A, false, false, false,
                            false);
  autofill_client().WaitForNextPopup();

  gfx::Point bounds_origin(
      static_cast<int>(autofill_client().last_element_bounds().origin().x()),
      static_cast<int>(autofill_client().last_element_bounds().origin().y()));

  // Convert the bounds to screen coordinates (to then compare against the ones
  // reported by focus change observer).
  bounds_origin += active_web_contents->GetRenderWidgetHostView()
                       ->GetViewBounds()
                       .OffsetFromOrigin();

  gfx::Vector2d error =
      bounds_origin - focus_observer.focused_node_bounds_in_screen();

  // Ideally, the length of the error vector should be 0.0f. But due to
  // potential rounding errors, we assume a larger limit (which is slightly
  // larger than square root of 2).
  EXPECT_LT(error.Length(), 1.4143f)
      << "Origin of bounds from focused node changed event is '"
      << focus_observer.focused_node_bounds_in_screen().ToString()
      << "' but AutofillClient is reporting '" << bounds_origin.ToString()
      << "'";
}

// 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 << "'.";
}
