chromium/content/browser/pointer_lock_browsertest.cc

// 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 "content/browser/pointer_lock_browsertest.h"

#include <string>

#include "base/memory/raw_ptr.h"
#include "base/test/scoped_feature_list.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "components/input/render_widget_host_input_event_router.h"
#include "content/browser/renderer_host/frame_tree.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/common/features.h"
#include "content/public/browser/web_contents_delegate.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 {};

#ifdef USE_AURA
class ScopedEnableUnadjustedMouseEventsForTesting
    : public aura::ScopedEnableUnadjustedMouseEvents {};

class MockPointerLockRenderWidgetHostView : public RenderWidgetHostViewAura {};

void InstallCreateHooksForPointerLockBrowserTests() {}
#endif  // USE_AURA

class PointerLockBrowserTest : public ContentBrowserTest {};

namespace {
class PointerLockHelper {};

// static
const std::string PointerLockHelper::set_pointer_lock_promise_ =;
// static
const std::string PointerLockHelper::wait_for_pointer_lock_promise_ =;
}  // namespace

IN_PROC_BROWSER_TEST_F(PointerLockBrowserTest, PointerLockBasic) {}

IN_PROC_BROWSER_TEST_F(PointerLockBrowserTest, PointerLockAndUserActivation) {}

// crbug.com/1210940: flaky on Linux
#if BUILDFLAG(IS_LINUX)
#define MAYBE_PointerLockEventRouting
#else
#define MAYBE_PointerLockEventRouting
#endif
IN_PROC_BROWSER_TEST_F(PointerLockBrowserTest, MAYBE_PointerLockEventRouting) {}

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

// Tests that the browser will unlock the pointer if a RenderWidgetHostView that
// holds the pointer lock crashes.
IN_PROC_BROWSER_TEST_F(PointerLockBrowserTest,
                       PointerLockInnerContentsCrashes) {}

IN_PROC_BROWSER_TEST_F(PointerLockBrowserTest, PointerLockOopifCrashes) {}

#if BUILDFLAG(IS_LINUX)
#define MAYBE_PointerLockWheelEventRouting
#else
#define MAYBE_PointerLockWheelEventRouting
#endif
IN_PROC_BROWSER_TEST_F(PointerLockBrowserTest,
                       MAYBE_PointerLockWheelEventRouting) {}

IN_PROC_BROWSER_TEST_F(PointerLockBrowserTest, PointerLockWidgetHidden) {}

#ifdef USE_AURA
IN_PROC_BROWSER_TEST_F(PointerLockBrowserTest, PointerLockOutOfFocus) {}
#endif

IN_PROC_BROWSER_TEST_F(PointerLockBrowserTest, PointerLockOnDroppedElem) {}

IN_PROC_BROWSER_TEST_F(PointerLockBrowserTest,
                       PointerLockRequestUnadjustedMovement) {}

#if defined(USE_AURA)
// Flaky on all platforms http://crbug.com/1198612.
IN_PROC_BROWSER_TEST_F(PointerLockBrowserTest, DISABLED_UnadjustedMovement) {}
#endif

#if defined(USE_AURA)
// TODO(crbug.com/40635377): Remove failure test when fully implemented
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_CHROMEOS_ASH)
#define MAYBE_ChangeUnadjustedMovementFailure
#else
#define MAYBE_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) {}
#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->IsPointerLocked());
  EXPECT_FALSE(root->current_frame_host()
                   ->GetView()
                   ->GetIsPointerLockedUnadjustedMovementForTesting());
  EXPECT_EQ(child_view->host(), web_contents()->GetPointerLockWidget());

  // 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->IsPointerLocked());
  EXPECT_TRUE(root->current_frame_host()
                  ->GetView()
                  ->GetIsPointerLockedUnadjustedMovementForTesting());
  EXPECT_EQ(child_view->host(), web_contents()->GetPointerLockWidget());
}
#endif  // WIN_OS
#endif  // USE_AURA
}  // namespace content