// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/browser/pointer_lock_browsertest.h"

#include "content/browser/frame_host/frame_tree.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_input_event_router.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/web_contents_delegate.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_utils.h"
#include "content/public/test/test_utils.h"
#include "content/shell/browser/shell.h"
#include "content/test/content_browser_test_utils_internal.h"
#include "net/dns/mock_host_resolver.h"
#include "net/test/embedded_test_server/embedded_test_server.h"

#ifdef USE_AURA
#include "content/browser/renderer_host/render_widget_host_view_aura.h"
#include "content/browser/web_contents/web_contents_view_aura.h"
#endif  // USE_AURA

namespace content {

namespace {

#ifdef USE_AURA
class MockRenderWidgetHostView : public RenderWidgetHostViewAura {
 public:
  MockRenderWidgetHostView(RenderWidgetHost* host, bool is_guest_view_hack)
      : RenderWidgetHostViewAura(host,
                                 is_guest_view_hack,
                                 false /* is_mus_browser_plugin_guest */),
        host_(RenderWidgetHostImpl::From(host)) {}
  ~MockRenderWidgetHostView() override {
    if (mouse_locked_)
      UnlockMouse();
  }

  bool LockMouse() override {
    mouse_locked_ = true;
    return true;
  }

  void UnlockMouse() override {
    host_->LostMouseLock();
    mouse_locked_ = false;
  }

  bool IsMouseLocked() override { return mouse_locked_; }

  bool HasFocus() const override { return true; }

  void OnWindowFocused(aura::Window* gained_focus,
                       aura::Window* lost_focus) override {
    // Ignore window focus events.
  }

  RenderWidgetHostImpl* host_;
};
#endif  // USE_AURA

}  // namespace

class MockPointerLockWebContentsDelegate : public WebContentsDelegate {
 public:
  MockPointerLockWebContentsDelegate() {}
  ~MockPointerLockWebContentsDelegate() override {}

  void RequestToLockMouse(WebContents* web_contents,
                          bool user_gesture,
                          bool last_unlocked_by_target) override {
    web_contents->GotResponseToLockMouseRequest(true);
  }

  void LostMouseLock() override {}
};

#ifdef USE_AURA
void InstallCreateHooksForPointerLockBrowserTests() {
  WebContentsViewAura::InstallCreateHookForTests(
      [](RenderWidgetHost* host,
         bool is_guest_view_hack) -> RenderWidgetHostViewAura* {
        return new MockRenderWidgetHostView(host, is_guest_view_hack);
      });
}
#endif  // USE_AURA

class PointerLockBrowserTest : public ContentBrowserTest {
 public:
  PointerLockBrowserTest() {}

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

  void SetUp() override {
    InstallCreateHooksForPointerLockBrowserTests();
    ContentBrowserTest::SetUp();
  }

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

    web_contents()->SetDelegate(&web_contents_delegate_);
  }

  WebContentsImpl* web_contents() const {
    return static_cast<WebContentsImpl*>(shell()->web_contents());
  }

 protected:
  MockPointerLockWebContentsDelegate web_contents_delegate_;
};

IN_PROC_BROWSER_TEST_F(PointerLockBrowserTest, PointerLock) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  FrameTreeNode* root = web_contents()->GetFrameTree()->root();
  FrameTreeNode* child = root->child_at(0);

  // Request a pointer lock on the root frame's body.
  EXPECT_TRUE(ExecuteScript(root, "document.body.requestPointerLock()"));

  // Root frame should have been granted pointer lock.
  bool locked = false;
  EXPECT_TRUE(ExecuteScriptAndExtractBool(root,
                                          "window.domAutomationController.send("
                                          "document.pointerLockElement == "
                                          "document.body);",
                                          &locked));
  EXPECT_TRUE(locked);

  // Request a pointer lock on the child frame's body.
  EXPECT_TRUE(ExecuteScript(child, "document.body.requestPointerLock()"));

  // Child frame should not be granted pointer lock since the root frame has it.
  EXPECT_TRUE(ExecuteScriptAndExtractBool(child,
                                          "window.domAutomationController.send("
                                          "document.pointerLockElement == "
                                          "document.body);",
                                          &locked));
  EXPECT_FALSE(locked);

  // Release pointer lock on root frame.
  EXPECT_TRUE(ExecuteScript(root, "document.exitPointerLock()"));

  // Request a pointer lock on the child frame's body.
  EXPECT_TRUE(ExecuteScript(child, "document.body.requestPointerLock()"));

  // Child frame should have been granted pointer lock.
  EXPECT_TRUE(ExecuteScriptAndExtractBool(child,
                                          "window.domAutomationController.send("
                                          "document.pointerLockElement == "
                                          "document.body);",
                                          &locked));
  EXPECT_TRUE(locked);
}

IN_PROC_BROWSER_TEST_F(PointerLockBrowserTest, PointerLockEventRouting) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  FrameTreeNode* root = web_contents()->GetFrameTree()->root();
  FrameTreeNode* child = root->child_at(0);
  RenderWidgetHostInputEventRouter* router =
      web_contents()->GetInputEventRouter();
  RenderWidgetHostViewBase* root_view = static_cast<RenderWidgetHostViewBase*>(
      root->current_frame_host()->GetView());
  RenderWidgetHostViewBase* child_view = static_cast<RenderWidgetHostViewBase*>(
      child->current_frame_host()->GetView());

  WaitForChildFrameSurfaceReady(child->current_frame_host());

  // Request a pointer lock on the root frame's body.
  EXPECT_TRUE(ExecuteScript(root, "document.body.requestPointerLock()"));

  // Root frame should have been granted pointer lock.
  bool locked = false;
  EXPECT_TRUE(ExecuteScriptAndExtractBool(root,
                                          "window.domAutomationController.send("
                                          "document.pointerLockElement == "
                                          "document.body);",
                                          &locked));
  EXPECT_TRUE(locked);

  // Add a mouse move event listener to the root frame.
  EXPECT_TRUE(ExecuteScript(
      root,
      "var x; var y; var mX; var mY; document.addEventListener('mousemove', "
      "function(e) {x = e.x; y = e.y; mX = e.movementX; mY = e.movementY;});"));

  blink::WebMouseEvent mouse_event(
      blink::WebInputEvent::kMouseMove, blink::WebInputEvent::kNoModifiers,
      blink::WebInputEvent::GetStaticTimeStampForTests());
  mouse_event.SetPositionInWidget(10, 11);
  mouse_event.movement_x = 12;
  mouse_event.movement_y = 13;
  router->RouteMouseEvent(root_view, &mouse_event, ui::LatencyInfo());

  // Make sure that the renderer handled the input event.
  MainThreadFrameObserver root_observer(root_view->GetRenderWidgetHost());
  root_observer.Wait();

  int x, y, movementX, movementY;
  EXPECT_TRUE(ExecuteScriptAndExtractInt(
      root, "window.domAutomationController.send(x);", &x));
  EXPECT_TRUE(ExecuteScriptAndExtractInt(
      root, "window.domAutomationController.send(y);", &y));
  EXPECT_TRUE(ExecuteScriptAndExtractInt(
      root, "window.domAutomationController.send(mX);", &movementX));
  EXPECT_TRUE(ExecuteScriptAndExtractInt(
      root, "window.domAutomationController.send(mY);", &movementY));
  EXPECT_EQ(10, x);
  EXPECT_EQ(11, y);
  EXPECT_EQ(12, movementX);
  EXPECT_EQ(13, movementY);

  // Release pointer lock on root frame.
  EXPECT_TRUE(ExecuteScript(root, "document.exitPointerLock()"));

  // Request a pointer lock on the child frame's body.
  EXPECT_TRUE(ExecuteScript(child, "document.body.requestPointerLock()"));

  // Child frame should have been granted pointer lock.
  EXPECT_TRUE(ExecuteScriptAndExtractBool(child,
                                          "window.domAutomationController.send("
                                          "document.pointerLockElement == "
                                          "document.body);",
                                          &locked));
  EXPECT_TRUE(locked);

  // Add a mouse move event listener to the child frame.
  EXPECT_TRUE(ExecuteScript(
      child,
      "var x; var y; var mX; var mY; document.addEventListener('mousemove', "
      "function(e) {x = e.x; y = e.y; mX = e.movementX; mY = e.movementY;});"));

  gfx::PointF transformed_point;
  root_view->TransformPointToCoordSpaceForView(gfx::PointF(0, 0), child_view,
                                               &transformed_point,
                                               viz::EventSource::MOUSE);

  mouse_event.SetPositionInWidget(-transformed_point.x() + 14,
                                  -transformed_point.y() + 15);
  mouse_event.movement_x = 16;
  mouse_event.movement_y = 17;
  // We use root_view intentionally as the RenderWidgetHostInputEventRouter is
  // responsible for correctly routing the event to the child frame.
  router->RouteMouseEvent(root_view, &mouse_event, ui::LatencyInfo());

  // Make sure that the renderer handled the input event.
  MainThreadFrameObserver child_observer(child_view->GetRenderWidgetHost());
  child_observer.Wait();

  EXPECT_TRUE(ExecuteScriptAndExtractInt(
      child, "window.domAutomationController.send(x);", &x));
  EXPECT_TRUE(ExecuteScriptAndExtractInt(
      child, "window.domAutomationController.send(y);", &y));
  EXPECT_TRUE(ExecuteScriptAndExtractInt(
      child, "window.domAutomationController.send(mX);", &movementX));
  EXPECT_TRUE(ExecuteScriptAndExtractInt(
      child, "window.domAutomationController.send(mY);", &movementY));
  EXPECT_EQ(14, x);
  EXPECT_EQ(15, y);
  EXPECT_EQ(16, movementX);
  EXPECT_EQ(17, movementY);
}

// Tests that the browser will not unlock the pointer if a RenderWidgetHostView
// that doesn't hold the pointer lock is destroyed.
IN_PROC_BROWSER_TEST_F(PointerLockBrowserTest, PointerLockChildFrameDetached) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

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

  // Request a pointer lock on the root frame's body.
  EXPECT_TRUE(ExecuteScript(root, "document.body.requestPointerLock()"));

  // Root frame should have been granted pointer lock.
  bool locked = false;
  EXPECT_TRUE(ExecuteScriptAndExtractBool(root,
                                          "window.domAutomationController.send("
                                          "document.pointerLockElement == "
                                          "document.body);",
                                          &locked));
  EXPECT_TRUE(locked);

  // Root (platform) RenderWidgetHostView should have the pointer locked.
  EXPECT_TRUE(root->current_frame_host()->GetView()->IsMouseLocked());
  EXPECT_EQ(root->current_frame_host()->GetRenderWidgetHost(),
            web_contents()->GetMouseLockWidget());

  // Detach the child frame.
  EXPECT_TRUE(ExecuteScript(root, "document.querySelector('iframe').remove()"));

  // Root (platform) RenderWidgetHostView should still have the pointer locked.
  EXPECT_TRUE(root->current_frame_host()->GetView()->IsMouseLocked());
  EXPECT_EQ(root->current_frame_host()->GetRenderWidgetHost(),
            web_contents()->GetMouseLockWidget());
}

// Tests that the browser will unlock the pointer if a RenderWidgetHostView that
// holds the pointer lock crashes.
IN_PROC_BROWSER_TEST_F(PointerLockBrowserTest,
                       PointerLockInnerContentsCrashes) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b(b))"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

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

  // Attach an inner WebContents; it's owned by the FrameTree, so we obtain an
  // observer to it.
  WebContents* inner_contents = CreateAndAttachInnerContents(
      root->child_at(0)->child_at(0)->current_frame_host());
  WebContentsDestroyedWatcher inner_death_observer(inner_contents);

  // Override the delegate so that we can stub out pointer lock events.
  inner_contents->SetDelegate(&web_contents_delegate_);

  // Navigate the inner webcontents to a page.
  EXPECT_TRUE(NavigateToURLFromRenderer(
      inner_contents, embedded_test_server()->GetURL(
                          "c.com", "/cross_site_iframe_factory.html?c(d)")));

  // Request a pointer lock to the inner WebContents's document.body.
  std::string result;
  EXPECT_TRUE(ExecuteScriptAndExtractString(inner_contents->GetMainFrame(), R"(
        (new Promise((resolve, reject) => {
            document.addEventListener('pointerlockchange', resolve);
            document.addEventListener('pointerlockerror', reject);
        }).then(() => {
            window.domAutomationController.send(
                (document.pointerLockElement == document.body) ?
                     "success" : "error");
        }).catch(error => {
            window.domAutomationController.send("" + error);
        }));
        document.body.requestPointerLock();)",
                                            &result));
  EXPECT_EQ("success", result);

  // Root (platform) RenderWidgetHostView should have the pointer locked.
  EXPECT_TRUE(root->current_frame_host()->GetView()->IsMouseLocked());

  // The widget doing the lock is the one from the inner WebContents. A link
  // to that RWH is saved into the outer webcontents.
  RenderWidgetHost* expected_lock_widget =
      inner_contents->GetMainFrame()->GetView()->GetRenderWidgetHost();
  EXPECT_EQ(expected_lock_widget, web_contents()->GetMouseLockWidget());
  EXPECT_EQ(expected_lock_widget, web_contents()->mouse_lock_widget_);
  EXPECT_EQ(expected_lock_widget,
            static_cast<WebContentsImpl*>(inner_contents)->mouse_lock_widget_);

  // Crash the subframe process.
  RenderProcessHost* crash_process =
      root->child_at(0)->current_frame_host()->GetProcess();
  RenderProcessHostWatcher crash_observer(
      crash_process, RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
  crash_process->Shutdown(0);
  crash_observer.Wait();

  // Wait for destruction of |inner_contents|.
  inner_death_observer.Wait();
  inner_contents = nullptr;

  // This should cancel the pointer lock.
  EXPECT_EQ(nullptr, web_contents()->GetMouseLockWidget());
  EXPECT_EQ(nullptr, web_contents()->mouse_lock_widget_);
  EXPECT_FALSE(web_contents()->HasMouseLock(
      root->current_frame_host()->GetRenderWidgetHost()));
}

IN_PROC_BROWSER_TEST_F(PointerLockBrowserTest, PointerLockWheelEventRouting) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  FrameTreeNode* root = web_contents()->GetFrameTree()->root();
  FrameTreeNode* child = root->child_at(0);
  RenderWidgetHostInputEventRouter* router =
      web_contents()->GetInputEventRouter();
  RenderWidgetHostViewBase* root_view = static_cast<RenderWidgetHostViewBase*>(
      root->current_frame_host()->GetView());
  RenderWidgetHostViewBase* child_view = static_cast<RenderWidgetHostViewBase*>(
      child->current_frame_host()->GetView());

  WaitForChildFrameSurfaceReady(child->current_frame_host());

  // Request a pointer lock on the root frame's body.
  EXPECT_TRUE(ExecuteScript(root, "document.body.requestPointerLock()"));

  // Root frame should have been granted pointer lock.
  bool locked = false;
  EXPECT_TRUE(ExecuteScriptAndExtractBool(root,
                                          "window.domAutomationController.send("
                                          "document.pointerLockElement == "
                                          "document.body);",
                                          &locked));
  EXPECT_TRUE(locked);

  // Add a mouse move wheel event listener to the root frame.
  EXPECT_TRUE(ExecuteScript(
      root,
      "var x; var y; var mX; var mY; document.addEventListener('mousewheel', "
      "function(e) {x = e.x; y = e.y; dX = e.deltaX; dY = e.deltaY;});"));
  MainThreadFrameObserver root_observer(root_view->GetRenderWidgetHost());
  root_observer.Wait();

  blink::WebMouseWheelEvent wheel_event(
      blink::WebInputEvent::kMouseWheel, blink::WebInputEvent::kNoModifiers,
      blink::WebInputEvent::GetStaticTimeStampForTests());
  wheel_event.SetPositionInWidget(10, 11);
  wheel_event.delta_x = -12;
  wheel_event.delta_y = -13;
  wheel_event.phase = blink::WebMouseWheelEvent::kPhaseBegan;
  router->RouteMouseWheelEvent(root_view, &wheel_event, ui::LatencyInfo());

  // Make sure that the renderer handled the input event.
  root_observer.Wait();

  if (root_view->wheel_scroll_latching_enabled()) {
    // When wheel scroll latching is enabled all wheel events during a scroll
    // sequence will be sent to a single target. Send a wheel end event to the
    // current target before sending wheel events to a new target.
    wheel_event.delta_x = 0;
    wheel_event.delta_y = 0;
    wheel_event.phase = blink::WebMouseWheelEvent::kPhaseEnded;
    router->RouteMouseWheelEvent(root_view, &wheel_event, ui::LatencyInfo());

    // Make sure that the renderer handled the input event.
    root_observer.Wait();
  }

  int x, y, deltaX, deltaY;
  EXPECT_TRUE(ExecuteScriptAndExtractInt(
      root, "window.domAutomationController.send(x);", &x));
  EXPECT_TRUE(ExecuteScriptAndExtractInt(
      root, "window.domAutomationController.send(y);", &y));
  EXPECT_TRUE(ExecuteScriptAndExtractInt(
      root, "window.domAutomationController.send(dX);", &deltaX));
  EXPECT_TRUE(ExecuteScriptAndExtractInt(
      root, "window.domAutomationController.send(dY);", &deltaY));
  EXPECT_EQ(10, x);
  EXPECT_EQ(11, y);
  EXPECT_EQ(12, deltaX);
  EXPECT_EQ(13, deltaY);

  // Release pointer lock on root frame.
  EXPECT_TRUE(ExecuteScript(root, "document.exitPointerLock()"));

  // Request a pointer lock on the child frame's body.
  EXPECT_TRUE(ExecuteScript(child, "document.body.requestPointerLock()"));

  // Child frame should have been granted pointer lock.
  EXPECT_TRUE(ExecuteScriptAndExtractBool(child,
                                          "window.domAutomationController.send("
                                          "document.pointerLockElement == "
                                          "document.body);",
                                          &locked));
  EXPECT_TRUE(locked);

  // Add a mouse move event listener to the child frame.
  EXPECT_TRUE(ExecuteScript(
      child,
      "var x; var y; var mX; var mY; document.addEventListener('mousewheel', "
      "function(e) {x = e.x; y = e.y; dX = e.deltaX; dY = e.deltaY;});"));
  MainThreadFrameObserver child_observer(child_view->GetRenderWidgetHost());
  child_observer.Wait();

  gfx::PointF transformed_point;
  root_view->TransformPointToCoordSpaceForView(gfx::PointF(0, 0), child_view,
                                               &transformed_point,
                                               viz::EventSource::MOUSE);

  wheel_event.SetPositionInWidget(-transformed_point.x() + 14,
                                  -transformed_point.y() + 15);
  wheel_event.delta_x = -16;
  wheel_event.delta_y = -17;
  if (root_view->wheel_scroll_latching_enabled())
    wheel_event.phase = blink::WebMouseWheelEvent::kPhaseBegan;
  // We use root_view intentionally as the RenderWidgetHostInputEventRouter is
  // responsible for correctly routing the event to the child frame.
  router->RouteMouseWheelEvent(root_view, &wheel_event, ui::LatencyInfo());

  // Make sure that the renderer handled the input event.
  child_observer.Wait();

  EXPECT_TRUE(ExecuteScriptAndExtractInt(
      child, "window.domAutomationController.send(x);", &x));
  EXPECT_TRUE(ExecuteScriptAndExtractInt(
      child, "window.domAutomationController.send(y);", &y));
  EXPECT_TRUE(ExecuteScriptAndExtractInt(
      child, "window.domAutomationController.send(dX);", &deltaX));
  EXPECT_TRUE(ExecuteScriptAndExtractInt(
      child, "window.domAutomationController.send(dY);", &deltaY));
  EXPECT_EQ(14, x);
  EXPECT_EQ(15, y);
  EXPECT_EQ(16, deltaX);
  EXPECT_EQ(17, deltaY);
}

IN_PROC_BROWSER_TEST_F(PointerLockBrowserTest, PointerLockWidgetHidden) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  FrameTreeNode* root = web_contents()->GetFrameTree()->root();
  FrameTreeNode* child = root->child_at(0);
  RenderWidgetHostViewBase* child_view = static_cast<RenderWidgetHostViewBase*>(
      child->current_frame_host()->GetView());

  WaitForChildFrameSurfaceReady(child->current_frame_host());

  // Request a pointer lock on the child frame's body.
  EXPECT_TRUE(ExecuteScript(child, "document.body.requestPointerLock()"));

  // Child frame should have been granted pointer lock.
  bool locked = false;
  EXPECT_TRUE(ExecuteScriptAndExtractBool(child,
                                          "window.domAutomationController.send("
                                          "document.pointerLockElement == "
                                          "document.body);",
                                          &locked));
  EXPECT_TRUE(locked);
  EXPECT_TRUE(child_view->IsMouseLocked());
  EXPECT_EQ(child_view->host(), web_contents()->GetMouseLockWidget());

  child_view->Hide();

  // Child frame should've released the mouse lock when hidden.
  EXPECT_FALSE(child_view->IsMouseLocked());
  EXPECT_EQ(nullptr, web_contents()->GetMouseLockWidget());
}

}  // namespace content
