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

#include <string>

#include "content/browser/pointer_lock_browsertest.h"

#include "base/memory/raw_ptr.h"
#include "base/test/scoped_feature_list.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "content/browser/renderer_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.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 {
    if (user_gesture)
      web_contents->GotResponseToLockMouseRequest(
          blink::mojom::PointerLockResult::kSuccess);
    else
      web_contents->GotResponseToLockMouseRequest(
          blink::mojom::PointerLockResult::kRequiresUserGesture);
  }

  void LostMouseLock() override {}
};

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

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

  blink::mojom::PointerLockResult 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 blink::mojom::PointerLockResult::kSuccess;
  }

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

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

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

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

  bool HasFocus() override { return has_focus_; }

  raw_ptr<RenderWidgetHostImpl> host_;
  bool has_focus_ = true;
};

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

namespace {
class PointerLockHelper {
 public:
  // requestPointerLock is an asynchronous operation. This method returns when
  // document.body.requestPointerLock() either succeeds or fails.
  // Returns true if Pointer Lock on body was successful.
  static EvalJsResult RequestPointerLockOnBody(
      const ToRenderFrameHost& execution_target,
      const int options = EXECUTE_SCRIPT_DEFAULT_OPTIONS) {
    return EvalJs(execution_target,
                  set_pointer_lock_promise_ +
                      "document.body.requestPointerLock();" +
                      wait_for_pointer_lock_promise_,
                  options);
  }
  static EvalJsResult RequestPointerLockWithUnadjustedMovementOnBody(
      const ToRenderFrameHost& execution_target,
      const int options = EXECUTE_SCRIPT_DEFAULT_OPTIONS) {
    return EvalJs(
        execution_target,
        set_pointer_lock_promise_ +
            "document.body.requestPointerLock({unadjustedMovement:true});" +
            wait_for_pointer_lock_promise_,
        options);
  }
  // exitPointerLock is an asynchronous operation. This method returns when
  // document.exitPointerLock() either succeeds or fails.
  // Returns true if Exit Pointer Lock was successful
  static EvalJsResult ExitPointerLock(
      const ToRenderFrameHost& execution_target,
      const int options = EXECUTE_SCRIPT_DEFAULT_OPTIONS) {
    return EvalJs(execution_target,
                  set_pointer_lock_promise_ + "document.exitPointerLock();" +
                      wait_for_pointer_lock_promise_,
                  options);
  }
  static EvalJsResult IsPointerLockOnBody(
      const ToRenderFrameHost& execution_target,
      const int options = EXECUTE_SCRIPT_DEFAULT_OPTIONS) {
    return EvalJs(execution_target,
                  "document.pointerLockElement === document.body", options);
  }

 private:
  static const std::string set_pointer_lock_promise_;
  static const std::string wait_for_pointer_lock_promise_;
};

// static
const std::string PointerLockHelper::set_pointer_lock_promise_ =
    R"code(pointerLockPromise=new Promise(function (resolve, reject){
        document.addEventListener('pointerlockchange', resolve);
        document.addEventListener('pointerlockerror', reject);
     });)code";
// static
const std::string PointerLockHelper::wait_for_pointer_lock_promise_ =
    "(async()=> {return await pointerLockPromise.then(()=>true, "
    "()=>false);})()";
}  // namespace

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()->GetPrimaryFrameTree().root();
  FrameTreeNode* child = root->child_at(0);

  // Request a pointer lock on the root frame's body.
  EXPECT_EQ(true, PointerLockHelper::RequestPointerLockOnBody(root));
  EXPECT_EQ(true, PointerLockHelper::IsPointerLockOnBody(root));

  // Request a pointer lock on the child frame's body.
  EXPECT_EQ(false, PointerLockHelper::RequestPointerLockOnBody(child));
  // Child frame should not be granted pointer lock since the root frame has it.
  EXPECT_EQ(false, PointerLockHelper::IsPointerLockOnBody(child));

  // Release pointer lock on root frame.
  EXPECT_EQ(true, PointerLockHelper::ExitPointerLock(root));

  // Request a pointer lock on the child frame's body.
  EXPECT_EQ(true, PointerLockHelper::RequestPointerLockOnBody(child));
  // ensure request finishes before moving on.

  // Child frame should have been granted pointer lock.
  EXPECT_EQ(true, PointerLockHelper::IsPointerLockOnBody(child));
}

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()->GetPrimaryFrameTree().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_EQ(false, PointerLockHelper::RequestPointerLockOnBody(
                       child, EXECUTE_SCRIPT_NO_USER_GESTURE));
  EXPECT_EQ(false, PointerLockHelper::IsPointerLockOnBody(
                       child, EXECUTE_SCRIPT_NO_USER_GESTURE));

  EXPECT_EQ(false, PointerLockHelper::RequestPointerLockOnBody(
                       grand_child, EXECUTE_SCRIPT_NO_USER_GESTURE));
  EXPECT_EQ(false, PointerLockHelper::IsPointerLockOnBody(
                       grand_child, 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_EQ(true, PointerLockHelper::RequestPointerLockOnBody(
                      child, EXECUTE_SCRIPT_NO_USER_GESTURE));
  EXPECT_EQ(true, PointerLockHelper::IsPointerLockOnBody(
                      child, EXECUTE_SCRIPT_NO_USER_GESTURE));

  // But with user activation in the child frame, pointer lock from the
  // grand_child frame fails.
  EXPECT_EQ(false, PointerLockHelper::RequestPointerLockOnBody(
                       grand_child, EXECUTE_SCRIPT_NO_USER_GESTURE));
  EXPECT_EQ(false, PointerLockHelper::IsPointerLockOnBody(
                       grand_child, EXECUTE_SCRIPT_NO_USER_GESTURE));
}

// crbug.com/1210940: flaky on Linux
#if BUILDFLAG(IS_LINUX)
#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()->GetPrimaryFrameTree().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());

  std::string set_mouse_move_event_listener = R"(
    mouseMoveExecuted = new Promise(function (resolve, reject) {
      mousemoveHandler = function(e) {
        x = e.x;
        y = e.y;
        mX = e.movementX;
        mY = e.movementY;
        resolve();
      };
      document.addEventListener('mousemove', mousemoveHandler, {once: true});
    });
    true; // A promise is defined above, but do not wait.
  )";
  std::string define_variables = R"(
    var x;
    var y;
    var mX;
    var mY;
    var mouseMoveExecuted;
    var mousemoveHandler;
  )";
  // Add a mouse move event listener to the root frame.
  EXPECT_TRUE(ExecJs(root, define_variables));
  EXPECT_TRUE(ExecJs(root, set_mouse_move_event_listener));

  // Send a mouse move to root frame before lock to set last mouse position.
  blink::WebMouseEvent mouse_event(
      blink::WebInputEvent::Type::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());

  // wait for mouse move to fire mouse move event
  EXPECT_EQ(true, EvalJs(root,
                         "(async ()=> {return await "
                         "mouseMoveExecuted.then(()=>true);})();"));
  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])"));

  EXPECT_EQ(true, PointerLockHelper::RequestPointerLockOnBody(root));
  // Root frame should have been granted pointer lock.
  EXPECT_EQ(true, PointerLockHelper::IsPointerLockOnBody(root));
  EXPECT_TRUE(ExecJs(root, set_mouse_move_event_listener));

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

  EXPECT_EQ(true, EvalJs(root,
                         "(async ()=> {return await "
                         "mouseMoveExecuted.then(()=>true);})();"));
  // 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])"));

  EXPECT_EQ(true, PointerLockHelper::ExitPointerLock(root));

  EXPECT_EQ(true, PointerLockHelper::RequestPointerLockOnBody(child));

  // define all all global variables on the child
  EXPECT_TRUE(ExecJs(child, define_variables));
  // Child frame should have been granted pointer lock.
  EXPECT_EQ(true, PointerLockHelper::IsPointerLockOnBody(child));

  // Add a mouse move event listener to the child frame.
  EXPECT_TRUE(ExecJs(child, set_mouse_move_event_listener));

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

  EXPECT_EQ(true, EvalJs(child,
                         "(async ()=> {return await "
                         "mouseMoveExecuted.then(()=>true);})()"));
  // 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()->GetPrimaryFrameTree().root();

  // Request a pointer lock on the root frame's body.
  EXPECT_EQ(true, PointerLockHelper::RequestPointerLockOnBody(root));
  // Root frame should have been granted pointer lock.
  EXPECT_EQ(true, PointerLockHelper::IsPointerLockOnBody(root));

  // 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()->GetPrimaryFrameTree().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(true, PointerLockHelper::RequestPointerLockOnBody(
                      inner_contents->GetPrimaryMainFrame()));
  EXPECT_EQ(true, PointerLockHelper::IsPointerLockOnBody(
                      inner_contents->GetPrimaryMainFrame()));

  // 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->GetPrimaryMainFrame()->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_.get());
  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()->GetPrimaryFrameTree().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(true, PointerLockHelper::RequestPointerLockOnBody(lock_node));
    EXPECT_EQ(true, PointerLockHelper::IsPointerLockOnBody(lock_node));

    // 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_.get());
    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());
  }
}

#if BUILDFLAG(IS_LINUX)
#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()->GetPrimaryFrameTree().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::Type::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])"));

  EXPECT_EQ(true, PointerLockHelper::RequestPointerLockOnBody(root));

  // Root frame should have been granted pointer lock.
  EXPECT_EQ(true, PointerLockHelper::IsPointerLockOnBody(root));

  // 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::Type::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])"));

  EXPECT_EQ(true, PointerLockHelper::ExitPointerLock(root));

  EXPECT_EQ(true, PointerLockHelper::RequestPointerLockOnBody(child));

  // Child frame should have been granted pointer lock.
  EXPECT_EQ(true, PointerLockHelper::IsPointerLockOnBody(child));

  // 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()->GetPrimaryFrameTree().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_EQ(true, PointerLockHelper::RequestPointerLockOnBody(child));
  // Child frame should have been granted pointer lock.
  EXPECT_EQ(true, PointerLockHelper::IsPointerLockOnBody(child));

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

#ifdef USE_AURA
IN_PROC_BROWSER_TEST_F(PointerLockBrowserTest, PointerLockOutOfFocus) {
  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()->GetPrimaryFrameTree().root();
  MockPointerLockRenderWidgetHostView* root_view =
      static_cast<MockPointerLockRenderWidgetHostView*>(
          root->current_frame_host()->GetView());

  root_view->has_focus_ = false;
  // Request a pointer lock on the root frame's body.
  EXPECT_EQ(false, PointerLockHelper::RequestPointerLockOnBody(root));
  // Root frame should not have been granted pointer lock.
  EXPECT_EQ(false, PointerLockHelper::IsPointerLockOnBody(root));
}
#endif

IN_PROC_BROWSER_TEST_F(PointerLockBrowserTest, PointerLockOnDroppedElem) {
  GURL url = embedded_test_server()->GetURL(
      "a.com", "/pointerlock_on_dropped_elem.html");
  EXPECT_TRUE(NavigateToURL(shell(), url));

  EXPECT_TRUE(ExecJs(shell(), "document.body.click();"));

  // The second ExecJS() call here delays test termination so that the first
  // call's async tasks get a chance to run.
  EXPECT_TRUE(ExecJs(shell(), "", EXECUTE_SCRIPT_NO_USER_GESTURE));
}

IN_PROC_BROWSER_TEST_F(PointerLockBrowserTest,
                       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()->GetPrimaryFrameTree().root();

  EXPECT_TRUE(ExecJs(root, "var pointerLockPromise;"));
  std::string wait_for_pointer_lock_promise =
      "(async ()=> {return await pointerLockPromise.then(()=>true, "
      "()=>false);})()";
  std::string set_pointer_lock_promise =
      R"code(pointerLockPromise = new Promise( function(resolve, reject){
                        document.addEventListener('pointerlockchange', resolve);
                        document.addEventListener('pointerlockerror', reject)
                     });)code";

  // Request a pointer lock.
  EXPECT_EQ(true, PointerLockHelper::RequestPointerLockOnBody(root));
  // Root frame should have been granted pointer lock.
  EXPECT_EQ(true, PointerLockHelper::IsPointerLockOnBody(root));
  // Mouse is locked and unadjusted_movement is not set.
  EXPECT_TRUE(root->current_frame_host()->GetView()->IsMouseLocked());

  // Release pointer lock.
  EXPECT_EQ(true, PointerLockHelper::ExitPointerLock(root));

#if defined(USE_AURA) || BUILDFLAG(IS_MAC)
  // Request a pointer lock with unadjustedMovement.
  EXPECT_EQ(
      true,
      PointerLockHelper::RequestPointerLockWithUnadjustedMovementOnBody(root));
  // Root frame should have been granted pointer lock.
  EXPECT_EQ(true, PointerLockHelper::IsPointerLockOnBody(root));

  // 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_EQ(true, PointerLockHelper::ExitPointerLock(root));

  EXPECT_FALSE(root->current_frame_host()
                   ->GetView()
                   ->GetIsMouseLockedUnadjustedMovementForTesting());
#else
  // Request a pointer lock with unadjustedMovement.
  // On platform that does not support unadjusted movement yet, do not lock and
  // a pointerlockerror event is dispatched.
  EXPECT_EQ(
      false,
      PointerLockHelper::RequestPointerLockWithUnadjustedMovementOnBody(root));
  EXPECT_EQ(false, PointerLockHelper::IsPointerLockOnBody(root));
  EXPECT_FALSE(root->current_frame_host()->GetView()->IsMouseLocked());
#endif
}

#if defined(USE_AURA)
// Flaky on all platforms http://crbug.com/1198612.
IN_PROC_BROWSER_TEST_F(PointerLockBrowserTest, DISABLED_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()->GetPrimaryFrameTree().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::Type::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_EQ(
      true,
      PointerLockHelper::RequestPointerLockWithUnadjustedMovementOnBody(root));

  // Root frame should have been granted pointer lock.
  EXPECT_EQ(true, PointerLockHelper::IsPointerLockOnBody(root));

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

#if defined(USE_AURA)
// TODO(https://crbug.com/982379): Remove failure test when fully implemented
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_CHROMEOS_ASH)
#define MAYBE_ChangeUnadjustedMovementFailure \
  DISABLED_ChangeUnadjustedMovementFailure
#else
#define MAYBE_ChangeUnadjustedMovementFailure ChangeUnadjustedMovementFailure
#endif
// Tests that a subsequent request to RequestPointerLock with different
// options inside a Child view gets piped to the proper places and gives
// the proper unsupported error(this option is only supported on Windows
// This was prompted by this bug: https://crbug.com/1062702
IN_PROC_BROWSER_TEST_F(PointerLockBrowserTest,
                       MAYBE_ChangeUnadjustedMovementFailure) {
  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()->GetPrimaryFrameTree().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 and wait for the promise
  // to resolve.
  EXPECT_EQ(true, PointerLockHelper::RequestPointerLockOnBody(child));
  // Child frame should have been granted pointer lock.
  EXPECT_EQ(true, PointerLockHelper::IsPointerLockOnBody(child));

  EXPECT_TRUE(child_view->IsMouseLocked());
  EXPECT_FALSE(root->current_frame_host()
                   ->GetView()
                   ->GetIsMouseLockedUnadjustedMovementForTesting());
  EXPECT_EQ(child_view->host(), web_contents()->GetMouseLockWidget());

  // Request to change pointer lock options and wait for return.
  EXPECT_EQ(
      "a JavaScript error: \"NotSupportedError: The options asked for in this "
      "request are not supported on this platform.\"\n",
      EvalJs(child,
             "document.body.requestPointerLock({unadjustedMovement:true})")
          .error);

  // The change errored out but the original lock should still be in place.
  EXPECT_TRUE(child_view->IsMouseLocked());
  EXPECT_FALSE(root->current_frame_host()
                   ->GetView()
                   ->GetIsMouseLockedUnadjustedMovementForTesting());
  EXPECT_EQ(child_view->host(), web_contents()->GetMouseLockWidget());
}
#endif

#if defined(USE_AURA)
#if BUILDFLAG(IS_WIN)
// Tests that a subsequent request to RequestPointerLock with different
// options inside a Child view gets piped to the proper places and updates
// the option(this option is only supported on Windows).
// This was prompted by this bug: https://crbug.com/1062702
IN_PROC_BROWSER_TEST_F(PointerLockBrowserTest,
                       ChangeUnadjustedMovementSuccess) {
  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()->GetPrimaryFrameTree().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 and wait for the promise
  // to resolve.
  EXPECT_EQ(true, PointerLockHelper::RequestPointerLockOnBody(child));
  // Child frame should have been granted pointer lock.
  EXPECT_EQ(true, PointerLockHelper::IsPointerLockOnBody(child));

  EXPECT_TRUE(child_view->IsMouseLocked());
  EXPECT_FALSE(root->current_frame_host()
                   ->GetView()
                   ->GetIsMouseLockedUnadjustedMovementForTesting());
  EXPECT_EQ(child_view->host(), web_contents()->GetMouseLockWidget());

  // Request to change pointer lock options and wait for return.
  EXPECT_EQ(
      nullptr,
      EvalJs(child,
             "document.body.requestPointerLock({unadjustedMovement:true})"));

  // The new changed lock should now be in place.
  EXPECT_TRUE(child_view->IsMouseLocked());
  EXPECT_TRUE(root->current_frame_host()
                  ->GetView()
                  ->GetIsMouseLockedUnadjustedMovementForTesting());
  EXPECT_EQ(child_view->host(), web_contents()->GetMouseLockWidget());
}
#endif  // WIN_OS
#endif  // USE_AURA
}  // namespace content
