File: custom_cursor_suppressor.h

package info (click to toggle)
chromium 138.0.7204.183-1~deb12u1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm-proposed-updates
  • size: 6,080,960 kB
  • sloc: cpp: 34,937,079; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,954; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,811; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (141 lines) | stat: -rw-r--r-- 5,877 bytes parent folder | download | duplicates (5)
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
131
132
133
134
135
136
137
138
139
140
141
// Copyright 2023 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_VIEWS_AUTOFILL_POPUP_CUSTOM_CURSOR_SUPPRESSOR_H_
#define CHROME_BROWSER_UI_VIEWS_AUTOFILL_POPUP_CUSTOM_CURSOR_SUPPRESSOR_H_

#include <map>
#include <memory>
#include <vector>

#include "base/functional/callback_helpers.h"
#include "base/scoped_multi_source_observation.h"
#include "base/scoped_observation.h"
#include "chrome/browser/ui/browser_list.h"
#include "chrome/browser/ui/browser_list_observer.h"
#include "chrome/browser/ui/tabs/tab_strip_model_observer.h"
#include "content/public/browser/global_routing_id.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents_observer.h"
#include "extensions/browser/extension_host_registry.h"

namespace content {
class BrowserContext;
class WebContents;
}  // namespace content

namespace extensions {
class ExtensionHost;
}  // namespace extensions

// While active, this class suppresses custom cursors exceeding a given size
// limit on all the active `WebContents` or all `Browser`s of the current
// profile.
// Note that `CustomCursorSuppressor` is expected to have a short lifetime, e.g.
// while an Autofill popup is showing - therefore it does not clean up (safe,
// but stale) observation entries related to `RenderFrameHost`s of previous
// navigations or of `WebContents` that are no longer active.
// Should the class become used in a wider context, additional logic to remove
// such stale entries should be added.
class CustomCursorSuppressor
    : public BrowserListObserver,
      public TabStripModelObserver,
      public extensions::ExtensionHostRegistry::Observer {
 public:
  CustomCursorSuppressor();
  CustomCursorSuppressor(const CustomCursorSuppressor&) = delete;
  CustomCursorSuppressor(CustomCursorSuppressor&&) = delete;
  CustomCursorSuppressor& operator=(const CustomCursorSuppressor&) = delete;
  CustomCursorSuppressor& operator=(CustomCursorSuppressor&&) = delete;
  ~CustomCursorSuppressor() override;

  // Starts suppressing cursors with height or width >= `max_dimension_dips` on
  // all active tabs of all browser windows.
  void Start(int max_dimension_dips = 0);
  // Stops suppressing custom cursors.
  void Stop();

  // Returns whether custom cursors are disallowed on `web_contents`.
  bool IsSuppressing(content::WebContents& web_contents) const;

  // Returns the ids of `RenderFrameHost`s on which custom cursors are
  // suppressed. Note that not every id needs to correspond to an active
  // `RenderFrameHost` - some may already have been deleted.
  std::vector<content::GlobalRenderFrameHostId>
  SuppressedRenderFrameHostIdsForTesting() const;

 private:
  // Starts observing the `ExtensionHostRegistry` for profile and suppresses
  // all custom cursors in its extensions. This is a no-op if the profile
  // custom cursors for the extensions of this profile are already suppressed.
  void ObserveAndSuppressExtensionsForProfile(Profile& profile);

  // Disallows custom cursors beyond the permitted size on `web_contents`. If
  // `this` is already disallowing custom cursors on `web_contents`, this is a
  // no-op.
  void SuppressForWebContents(content::WebContents& web_contents);

  // Observes navigations in `web_contents` that lead to changes in the
  // `RenderFrameHost` of the primary main frame iff custom cursors are not
  // already disallowed on `web_contents`.
  void MaybeObserveNavigationsInWebContents(content::WebContents& web_contents);

  // BrowserListObserver:
  // Starts observing the tab strip model of `browser`. Note that there is
  // no corresponding `OnBrowserRemoved`, since `TabStripModelObserver`
  // already handles model destruction itself.
  void OnBrowserAdded(Browser* browser) override;

  // TabStripModelObserver:
  void OnTabStripModelChanged(
      TabStripModel* tab_strip_model,
      const TabStripModelChange& change,
      const TabStripSelectionChange& selection) override;

  // extensions::ExtensionHostRegistry::Observer:
  void OnExtensionHostDocumentElementAvailable(
      content::BrowserContext* browser_context,
      extensions::ExtensionHost* extension_host) override;
  void OnExtensionHostRegistryShutdown(
      extensions::ExtensionHostRegistry* registry) override;

  // A helper to filter and forward `RenderFrameHostChanged` events of a single
  // `WebContents`. Used to allow `CustomCursorSuppressor` to effectively
  // observe multiple `WebContents`.
  class NavigationObserver : public content::WebContentsObserver {
   public:
    // A callback that is called whenever the `RenderFrameHost` of the primary
    // main frame of the observed `WebContents` has changed.
    using Callback = base::RepeatingCallback<void(content::WebContents&)>;

    NavigationObserver(content::WebContents* web_contents, Callback callback);
    ~NavigationObserver() override;

   private:
    // content::WebContentsObserver:
    void RenderFrameHostChanged(content::RenderFrameHost* old_host,
                                content::RenderFrameHost* new_host) override;

    Callback callback_;
  };

  base::ScopedObservation<BrowserList, BrowserListObserver>
      browser_list_observation_{this};

  // Observes when new `ExtensionHost`s load their documents and when
  // `ExtensionHostRegistry`s shut down.
  base::ScopedMultiSourceObservation<
      extensions::ExtensionHostRegistry,
      extensions::ExtensionHostRegistry::Observer>
      extension_host_registry_observation_{this};

  int max_dimension_dips_ = 0;

  std::map<content::GlobalRenderFrameHostId, base::ScopedClosureRunner>
      disallow_custom_cursor_scopes_;

  std::vector<std::unique_ptr<NavigationObserver>> navigation_observers_;
};

#endif  // CHROME_BROWSER_UI_VIEWS_AUTOFILL_POPUP_CUSTOM_CURSOR_SUPPRESSOR_H_