// 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 "base/test/scoped_feature_list.h"
#include "build/build_config.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/common/content_features.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/hit_test_region_observer.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"
#include "ui/base/ui_base_features.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 {

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(user_gesture);
  }

  void LostMouseLock() override {}
};

#ifdef USE_AURA
class ScopedEnableUnadjustedMouseEventsForTesting
    : public aura::ScopedEnableUnadjustedMouseEvents {
 public:
  explicit ScopedEnableUnadjustedMouseEventsForTesting() {}
  ~ScopedEnableUnadjustedMouseEventsForTesting() override {}
};

class MockPointerLockRenderWidgetHostView : public RenderWidgetHostViewAura {
 public:
  MockPointerLockRenderWidgetHostView(RenderWidgetHost* host,
                                      bool is_guest_view_hack)
      : RenderWidgetHostViewAura(host, is_guest_view_hack),
        host_(RenderWidgetHostImpl::From(host)) {}
  ~MockPointerLockRenderWidgetHostView() override {
    if (IsMouseLocked())
      UnlockMouse();
  }

  bool LockMouse(bool request_unadjusted_movement) override {
    event_handler()->mouse_locked_ = true;
    event_handler()->mouse_locked_unadjusted_movement_ =
        request_unadjusted_movement
            ? std::make_unique<ScopedEnableUnadjustedMouseEventsForTesting>()
            : nullptr;
    return true;
  }

  void UnlockMouse() override {
    host_->LostMouseLock();
    event_handler()->mouse_locked_ = false;
    event_handler()->mouse_locked_unadjusted_movement_.reset();
  }

  bool IsMouseLocked() override { return event_handler()->mouse_locked(); }

  bool HasFocus() override { return true; }

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

  bool GetIsMouseLockedUnadjustedMovementForTesting() override {
    return IsMouseLocked() &&
           event_handler()->mouse_locked_unadjusted_movement_;
  }

  RenderWidgetHostImpl* host_;
};

void InstallCreateHooksForPointerLockBrowserTests() {
  WebContentsViewAura::InstallCreateHookForTests(
      [](RenderWidgetHost* host,
         bool is_guest_view_hack) -> RenderWidgetHostViewAura* {
        return new MockPointerLockRenderWidgetHostView(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_;
};

class PointerLockBrowserTestWithOptions : public PointerLockBrowserTest {
 public:
  PointerLockBrowserTestWithOptions() {
    feature_list_.InitAndEnableFeature(features::kPointerLockOptions);
  }

 private:
  base::test::ScopedFeatureList feature_list_;
};

IN_PROC_BROWSER_TEST_F(PointerLockBrowserTest, PointerLockBasic) {
  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(ExecJs(root, "document.body.requestPointerLock()"));

  // Root frame should have been granted pointer lock.
  EXPECT_EQ(true, EvalJs(root, "document.pointerLockElement == document.body"));

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

  // Child frame should not be granted pointer lock since the root frame has it.
  EXPECT_EQ(false,
            EvalJs(child, "document.pointerLockElement == document.body"));

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

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

  // Child frame should have been granted pointer lock.
  EXPECT_EQ(true,
            EvalJs(child, "document.pointerLockElement == document.body"));
}

IN_PROC_BROWSER_TEST_F(PointerLockBrowserTest, PointerLockAndUserActivation) {
  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();
  FrameTreeNode* child = root->child_at(0);
  FrameTreeNode* grand_child = child->child_at(0);

  // Without user activation, pointer lock request from any (child or
  // grand_child) frame fails.
  EXPECT_TRUE(ExecJs(child, "document.body.requestPointerLock()",
                     EXECUTE_SCRIPT_NO_USER_GESTURE));
  EXPECT_EQ(false, EvalJs(child, "document.pointerLockElement == document.body",
                          EXECUTE_SCRIPT_NO_USER_GESTURE));
  EXPECT_TRUE(ExecJs(grand_child, "document.body.requestPointerLock()",
                     EXECUTE_SCRIPT_NO_USER_GESTURE));
  EXPECT_EQ(false,
            EvalJs(grand_child, "document.pointerLockElement == document.body",
                   EXECUTE_SCRIPT_NO_USER_GESTURE));

  // Execute a empty (dummy) JS to activate the child frame.
  EXPECT_TRUE(ExecJs(child, ""));

  // With user activation in the child frame, pointer lock from the same frame
  // succeeds.
  EXPECT_TRUE(ExecJs(child, "document.body.requestPointerLock()",
                     EXECUTE_SCRIPT_NO_USER_GESTURE));
  EXPECT_EQ(true, EvalJs(child, "document.pointerLockElement == document.body",
                         EXECUTE_SCRIPT_NO_USER_GESTURE));

  // But with user activation in the child frame, pointer lock from the
  // grand_child frame fails.
  EXPECT_TRUE(ExecJs(grand_child, "document.body.requestPointerLock()",
                     EXECUTE_SCRIPT_NO_USER_GESTURE));
  EXPECT_EQ(false,
            EvalJs(grand_child, "document.pointerLockElement == document.body",
                   EXECUTE_SCRIPT_NO_USER_GESTURE));
}

// Flaky on Windows.  https://crbug.com/992529
#if defined(OS_WIN)
#define MAYBE_PointerLockEventRouting DISABLED_PointerLockEventRouting
#else
#define MAYBE_PointerLockEventRouting PointerLockEventRouting
#endif

IN_PROC_BROWSER_TEST_F(PointerLockBrowserTest, MAYBE_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());

  WaitForHitTestData(child->current_frame_host());

  // Add a mouse move event listener to the root frame.
  EXPECT_TRUE(ExecJs(
      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;});"));

  // Send a mouse move to root frame before lock to set last mouse position.
  blink::WebMouseEvent mouse_event(
      blink::WebInputEvent::kMouseMove, blink::WebInputEvent::kNoModifiers,
      blink::WebInputEvent::GetStaticTimeStampForTests());
  mouse_event.pointer_type = blink::WebPointerProperties::PointerType::kMouse;
  mouse_event.SetPositionInWidget(6, 7);
  mouse_event.SetPositionInScreen(6, 7);
  mouse_event.movement_x = 8;
  mouse_event.movement_y = 9;
  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();

  if (base::FeatureList::IsEnabled(features::kConsolidatedMovementXY))
    EXPECT_EQ("[6,7,0,0]", EvalJs(root, "JSON.stringify([x,y,mX,mY])"));
  else
    EXPECT_EQ("[6,7,8,9]", EvalJs(root, "JSON.stringify([x,y,mX,mY])"));

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

  // Root frame should have been granted pointer lock.
  EXPECT_EQ(true, EvalJs(root, "document.pointerLockElement == document.body"));

  mouse_event.SetPositionInWidget(10, 12);
  mouse_event.SetPositionInScreen(10, 12);
  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.
  root_observer.Wait();

  // Locked event has same coordinates as before locked.
  if (base::FeatureList::IsEnabled(features::kConsolidatedMovementXY))
    EXPECT_EQ("[6,7,4,5]", EvalJs(root, "JSON.stringify([x,y,mX,mY])"));
  else
    EXPECT_EQ("[6,7,12,13]", EvalJs(root, "JSON.stringify([x,y,mX,mY])"));

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

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

  // Child frame should have been granted pointer lock.
  EXPECT_EQ(true,
            EvalJs(child, "document.pointerLockElement == document.body"));

  // Add a mouse move event listener to the child frame.
  EXPECT_TRUE(ExecJs(
      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);

  mouse_event.SetPositionInWidget(-transformed_point.x() + 14,
                                  -transformed_point.y() + 15);
  mouse_event.SetPositionInScreen(-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();

  // This is the first event to child render, so the coordinates is (0, 0)
  if (base::FeatureList::IsEnabled(features::kConsolidatedMovementXY))
    EXPECT_EQ("[0,0,0,0]", EvalJs(child, "JSON.stringify([x,y,mX,mY])"));
  else
    EXPECT_EQ("[0,0,16,17]", EvalJs(child, "JSON.stringify([x,y,mX,mY])"));
}

// 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(ExecJs(root, "document.body.requestPointerLock()"));

  // Root frame should have been granted pointer lock.
  EXPECT_EQ(true, EvalJs(root, "document.pointerLockElement == document.body"));

  // 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(ExecJs(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.
  EXPECT_EQ("success", EvalJs(inner_contents->GetMainFrame(), R"(
        new Promise((resolve, reject) => {
            document.addEventListener('pointerlockchange', resolve);
            document.addEventListener('pointerlockerror', reject);
            document.body.requestPointerLock();
        }).then(() => 'success');
        )"));

  // 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, PointerLockOopifCrashes) {
  // This test runs three times, testing a crash at each level of the frametree.
  for (int crash_depth = 0; crash_depth < 3; crash_depth++) {
    GURL main_url(embedded_test_server()->GetURL(
        "a.com", "/cross_site_iframe_factory.html?a(b(c))"));
    EXPECT_TRUE(NavigateToURL(shell(), main_url));

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

    // Pick which node to crash.
    FrameTreeNode* crash_node = root;
    for (int i = 0; i < crash_depth; i++)
      crash_node = crash_node->child_at(0);

    // Request a pointer lock to |lock_node|'s document.body.
    EXPECT_EQ("success", EvalJs(lock_node, R"(
        new Promise((resolve, reject) => {
            document.addEventListener('pointerlockchange', resolve);
            document.addEventListener('pointerlockerror', reject);
            document.body.requestPointerLock();
        }).then(() => 'success');
        )"));

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

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

    // 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()));
    if (crash_depth != 0)
      EXPECT_FALSE(root->current_frame_host()->GetView()->IsMouseLocked());
    else
      EXPECT_EQ(nullptr, root->current_frame_host()->GetView());
  }
}

// Flaky on Windows.  https://crbug.com/994228
#if defined(OS_WIN)
#define MAYBE_PointerLockWheelEventRouting DISABLED_PointerLockWheelEventRouting
#else
#define MAYBE_PointerLockWheelEventRouting PointerLockWheelEventRouting
#endif
IN_PROC_BROWSER_TEST_F(PointerLockBrowserTest,
                       MAYBE_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());

  WaitForHitTestData(child->current_frame_host());

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

  // Send a mouse move to root frame before lock to set last mouse position.
  blink::WebMouseEvent mouse_event(
      blink::WebInputEvent::kMouseMove, blink::WebInputEvent::kNoModifiers,
      blink::WebInputEvent::GetStaticTimeStampForTests());
  mouse_event.pointer_type = blink::WebPointerProperties::PointerType::kMouse;
  mouse_event.SetPositionInWidget(6, 7);
  mouse_event.SetPositionInScreen(6, 7);
  mouse_event.movement_x = 8;
  mouse_event.movement_y = 9;
  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();

  if (base::FeatureList::IsEnabled(features::kConsolidatedMovementXY))
    EXPECT_EQ("[6,7,0,0]", EvalJs(root, "JSON.stringify([x,y,mX,mY])"));
  else
    EXPECT_EQ("[6,7,8,9]", EvalJs(root, "JSON.stringify([x,y,mX,mY])"));

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

  // Root frame should have been granted pointer lock.
  EXPECT_EQ(true, EvalJs(root, "document.pointerLockElement == document.body"));

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

  blink::WebMouseWheelEvent wheel_event(
      blink::WebInputEvent::kMouseWheel, blink::WebInputEvent::kNoModifiers,
      blink::WebInputEvent::GetStaticTimeStampForTests());
  wheel_event.SetPositionInScreen(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();

  // 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();

  // Locked event has same coordinates as before locked.
  EXPECT_EQ("[6,7,12,13]", EvalJs(root, "JSON.stringify([x, y, dX, dY])"));

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

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

  // Child frame should have been granted pointer lock.
  EXPECT_EQ(true,
            EvalJs(child, "document.pointerLockElement == document.body"));

  // Add a mouse move event listener to the child frame.
  EXPECT_TRUE(ExecJs(
      child,
      "var x; var y; var dX; var dY; 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);

  wheel_event.SetPositionInWidget(-transformed_point.x() + 14,
                                  -transformed_point.y() + 15);
  wheel_event.SetPositionInScreen(-transformed_point.x() + 14,
                                  -transformed_point.y() + 15);
  wheel_event.delta_x = -16;
  wheel_event.delta_y = -17;
  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();

  // This is the first event to child render, so the coordinates is (0, 0)
  EXPECT_EQ("[0,0,16,17]", EvalJs(child, "JSON.stringify([x, y, dX, dY])"));
}

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());

  WaitForHitTestData(child->current_frame_host());

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

  // Child frame should have been granted pointer lock.
  EXPECT_EQ(true,
            EvalJs(child, "document.pointerLockElement == document.body"));
  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());
}

// Flaky. https://crbug.com/1014324
IN_PROC_BROWSER_TEST_F(PointerLockBrowserTestWithOptions,
                       DISABLED_PointerLockRequestUnadjustedMovement) {
  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();

  EXPECT_TRUE(ExecJs(root,
                     "var PointerLockErrorReceived=false;"
                     "document.addEventListener('pointerlockerror', "
                     "function() {PointerLockErrorReceived = true;});"));
  // Request a pointer lock.
  EXPECT_TRUE(ExecJs(root, "document.body.requestPointerLock()"));
  // Root frame should have been granted pointer lock.
  EXPECT_EQ(true, EvalJs(root, "document.pointerLockElement == document.body"));
  // Mouse is locked and unadjusted_movement is not set.
  EXPECT_TRUE(root->current_frame_host()->GetView()->IsMouseLocked());
  // Release pointer lock.
  EXPECT_TRUE(ExecJs(root, "document.exitPointerLock()"));

  EXPECT_EQ("false", EvalJs(root, "JSON.stringify(PointerLockErrorReceived)"));

  // Request a pointer lock with unadjustedMovement.
  EXPECT_TRUE(ExecJs(
      root, "document.body.requestPointerLock({unadjustedMovement:true})"));
#if defined(USE_AURA)
  // Root frame should have been granted pointer lock.
  EXPECT_EQ(true, EvalJs(root, "document.pointerLockElement == document.body"));
  // Mouse is locked and unadjusted_movement is set.
  EXPECT_TRUE(root->current_frame_host()->GetView()->IsMouseLocked());
  EXPECT_TRUE(root->current_frame_host()
                  ->GetView()
                  ->GetIsMouseLockedUnadjustedMovementForTesting());

  // Release pointer lock, unadjusted_movement bit is reset.
  EXPECT_TRUE(ExecJs(root, "document.exitPointerLock()"));
  EXPECT_FALSE(root->current_frame_host()
                   ->GetView()
                   ->GetIsMouseLockedUnadjustedMovementForTesting());
#else
  // On platform that does not support unadjusted movement yet, do not lock and
  // a pointerlockerror event is dispatched.
  EXPECT_FALSE(root->current_frame_host()->GetView()->IsMouseLocked());
  EXPECT_EQ("true", EvalJs(root, "JSON.stringify(PointerLockErrorReceived)"));
#endif
}

#if defined(USE_AURA)
IN_PROC_BROWSER_TEST_F(PointerLockBrowserTestWithOptions, UnadjustedMovement) {
  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();
  RenderWidgetHostInputEventRouter* router =
      web_contents()->GetInputEventRouter();
  RenderWidgetHostViewBase* root_view = static_cast<RenderWidgetHostViewBase*>(
      root->current_frame_host()->GetView());

  // Add a mouse move event listener to the root frame.
  EXPECT_TRUE(ExecJs(
      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;});"));

  // Send a mouse move to root frame before lock.
  blink::WebMouseEvent mouse_event(
      blink::WebInputEvent::kMouseMove, blink::WebInputEvent::kNoModifiers,
      blink::WebInputEvent::GetStaticTimeStampForTests());
  mouse_event.pointer_type = blink::WebPointerProperties::PointerType::kMouse;
  mouse_event.SetPositionInWidget(6, 7);
  mouse_event.SetPositionInScreen(6, 7);
  mouse_event.movement_x = 8;
  mouse_event.movement_y = 9;
  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();

  EXPECT_EQ("[6,7,0,0]", EvalJs(root, "JSON.stringify([x,y,mX,mY])"));

  // Request a pointer lock with unadjustedMovement.
  EXPECT_TRUE(ExecJs(
      root, "document.body.requestPointerLock({unadjustedMovement:true})"));
  // Root frame should have been granted pointer lock.
  EXPECT_EQ(true, EvalJs(root, "document.pointerLockElement == document.body"));
  // Mouse is locked and unadjusted_movement is not set.
  EXPECT_TRUE(root->current_frame_host()->GetView()->IsMouseLocked());

  mouse_event.SetPositionInWidget(10, 10);
  mouse_event.SetPositionInScreen(10, 10);
  mouse_event.movement_x = 12;
  mouse_event.movement_y = 9;
  mouse_event.is_raw_movement_event = true;
  router->RouteMouseEvent(root_view, &mouse_event, ui::LatencyInfo());
  root_observer.Wait();

  // Raw movement events movement value from WebMouseEvent.movement_x/y.
  EXPECT_EQ("[6,7,12,9]", EvalJs(root, "JSON.stringify([x,y,mX,mY])"));

  mouse_event.SetPositionInWidget(20, 21);
  mouse_event.SetPositionInScreen(20, 21);
  mouse_event.movement_x = 1;
  mouse_event.movement_y = 2;
  mouse_event.is_raw_movement_event = false;
  router->RouteMouseEvent(root_view, &mouse_event, ui::LatencyInfo());
  root_observer.Wait();

  // Non-raw movement events movement value from screen pos - last screen pos.
  EXPECT_EQ("[6,7,10,11]", EvalJs(root, "JSON.stringify([x,y,mX,mY])"));
}
#endif
}  // namespace content
