File: pointer_lock_controller.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (130 lines) | stat: -rw-r--r-- 5,214 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
// Copyright 2015 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_UI_EXCLUSIVE_ACCESS_POINTER_LOCK_CONTROLLER_H_
#define CHROME_BROWSER_UI_EXCLUSIVE_ACCESS_POINTER_LOCK_CONTROLLER_H_

#include <set>
#include <utility>

#include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
#include "chrome/browser/ui/exclusive_access/exclusive_access_bubble_hide_callback.h"
#include "chrome/browser/ui/exclusive_access/exclusive_access_controller_base.h"
#include "components/content_settings/core/common/content_settings.h"
#include "content/public/browser/global_routing_id.h"

// This class implements the mouse pointer lock behavior.
class PointerLockController : public ExclusiveAccessControllerBase {
 public:
  explicit PointerLockController(ExclusiveAccessManager* manager);

  PointerLockController(const PointerLockController&) = delete;
  PointerLockController& operator=(const PointerLockController&) = delete;

  ~PointerLockController() override;

  // Returns true if the mouse pointer is locked.
  bool IsPointerLocked() const;

  // Returns true if the mouse pointer was locked and no notification should be
  // displayed to the user. This is the case when a notice has already been
  // displayed to the user, and the application voluntarily unlocks, then
  // re-locks the pointer (a duplicate notification should not be given). See
  // content::PointerLockDispatcher::LockPointer.
  bool IsPointerLockedSilently() const;

  void RequestToLockPointer(content::WebContents* web_contents,
                            bool user_gesture,
                            bool last_unlocked_by_target);

  // Returns true if we are waiting for the user to make a selection on the
  // pointer lock permission request dialog.
  bool IsWaitingForPointerLockPrompt(content::WebContents* web_contents);

  // Override from ExclusiveAccessControllerBase
  bool HandleUserPressedEscape() override;
  void HandleUserHeldEscape() override;
  void HandleUserReleasedEscapeEarly() override;
  bool RequiresPressAndHoldEscToExit() const override;
  void ExitExclusiveAccessToPreviousState() override;

  void UnlockPointer();

  void set_bubble_hide_callback_for_test(
      ExclusiveAccessBubbleHideCallbackForTest callback) {
    bubble_hide_callback_for_test_ = std::move(callback);
  }

  void set_lock_state_callback_for_test(base::OnceClosure callback) {
    lock_state_callback_for_test_ = std::move(callback);
  }

 private:
  friend class ExclusiveAccessTest;

  enum PointerLockState {
    POINTERLOCK_UNLOCKED,
    // Pointer has been locked.
    POINTERLOCK_LOCKED,
    // Pointer has been locked silently, with no notification to user.
    POINTERLOCK_LOCKED_SILENTLY
  };

  void LockPointer(base::WeakPtr<content::WebContents> web_contents,
                   content::GlobalRenderFrameHostId rfh_id,
                   bool last_unlocked_by_target);
  void RejectRequestToLockPointer(
      base::WeakPtr<content::WebContents> web_contents,
      content::GlobalRenderFrameHostId rfh_id);

  void ExitExclusiveAccessIfNecessary() override;
  void NotifyTabExclusiveAccessLost() override;

  void OnBubbleHidden(base::WeakPtr<content::WebContents>,
                      ExclusiveAccessBubbleHideReason);

  bool ShouldSuppressBubbleReshowForStateChange();

  // Returns true if the RenderFrameHost identified by `rfh_id` is waiting
  // for the user to make a selection on the pointer lock prompt.
  bool IsWaitingForPointerLockPromptHelper(
      content::GlobalRenderFrameHostId rfh_id);

  PointerLockState pointer_lock_state_;

  // Optionally a WebContents instance that is granted permission to silently
  // lock the mouse pointer. This is granted only if the WebContents instance
  // has previously locked and displayed the permission bubble until the bubble
  // time out has expired. https://crbug.com/725370
  raw_ptr<content::WebContents, AcrossTasksDanglingUntriaged>
      web_contents_granted_silent_pointer_lock_permission_ = nullptr;

  // If true, does not call into the WebContents to lock the mouse pointer. Just
  // assumes that it works. This may be necessary when calling
  // Browser::RequestToLockPointer in tests, because the proper signal will not
  // have been passed to the RenderViewHost.
  bool fake_pointer_lock_for_test_;

  // If set, |bubble_hide_callback_for_test_| will be called during
  // |OnBubbleHidden()|.
  ExclusiveAccessBubbleHideCallbackForTest bubble_hide_callback_for_test_;

  // Called when the page requests (successfully or not) or loses pointer lock.
  base::OnceClosure lock_state_callback_for_test_;

  // Timestamp when the user last successfully escaped from a lock request.
  base::TimeTicks last_user_escape_time_;

  // Set of RenderFrameHost IDs waiting for pointer lock permission prompt
  // selection by the user.
  std::set<content::GlobalRenderFrameHostId>
      hosts_waiting_for_pointer_lock_permission_prompt_;

  base::WeakPtrFactory<PointerLockController> weak_ptr_factory_{this};
};

#endif  // CHROME_BROWSER_UI_EXCLUSIVE_ACCESS_POINTER_LOCK_CONTROLLER_H_