File: user_interaction_observer.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 (149 lines) | stat: -rw-r--r-- 6,525 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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
// Copyright 2020 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_SAFE_BROWSING_USER_INTERACTION_OBSERVER_H_
#define CHROME_BROWSER_SAFE_BROWSING_USER_INTERACTION_OBSERVER_H_

#include "base/memory/raw_ptr.h"
#include "base/time/default_clock.h"
#include "base/time/time.h"
#include "components/permissions/permission_request_manager.h"
#include "components/safe_browsing/content/browser/ui_manager.h"
#include "components/security_interstitials/core/unsafe_resource.h"
#include "content/public/browser/render_widget_host.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/browser/web_contents_user_data.h"

namespace blink {
class WebMouseEvent;
}

namespace safe_browsing {

// Used for UMA. There may be more than one event per navigation (e.g.
// kAll and kWarningShownOnKeypress).
// These values are persisted to logs. Entries should not be renumbered and
// numeric values should never be reused.
enum class DelayedWarningEvent {
  // User loaded a page with a delayed warning.
  kPageLoaded = 0,
  // User left the page and the warning was never shown.
  kWarningNotShown = 1,
  // User pressed a key and the warning was shown.
  kWarningShownOnKeypress = 2,
  // User clicked on the page at least once but the feature isn't configured to
  // show warnings on mouse clicks.
  kWarningNotTriggeredOnMouseClick = 3,
  // User clicked on the page and the warning was shown.
  kWarningShownOnMouseClick = 4,
  // The page tried to enter fullscreen mode.
  kWarningShownOnFullscreenAttempt = 5,
  // The page tried to initiate a download and we cancelled it. This doesn't
  // show an interstitial.
  kDownloadCancelled = 6,
  // The page triggered a permission request. It was denied and the warning was
  // shown.
  kWarningShownOnPermissionRequest = 7,
  // The page tried to display a JavaScript dialog (alert/confirm/prompt). It
  // was blocked and the warning was shown.
  kWarningShownOnJavaScriptDialog = 8,
  // The page was denied a password save or autofill request. This doesn't show
  // an interstitial and is recorded once per navigation.
  kPasswordSaveOrAutofillDenied = 9,
  // The page triggered a desktop capture request ("example.com wants to share
  // the contents of the screen"). It was denied and the warning was shown.
  kWarningShownOnDesktopCaptureRequest = 10,
  // User pasted something on the page and the warning was shown.
  kWarningShownOnPaste = 11,
  kMaxValue = kWarningShownOnPaste,
};

// Observes user interactions and shows an interstitial if necessary.
// Only created when an interstitial was about to be displayed but was delayed
// due to the Delayed Warnings experiment. Deleted once the interstitial is
// shown, or the tab is closed or navigated away.
class SafeBrowsingUserInteractionObserver
    : public content::WebContentsUserData<SafeBrowsingUserInteractionObserver>,
      public content::WebContentsObserver,
      public permissions::PermissionRequestManager::Observer {
 public:
  // Creates an observer for given |web_contents|. |resource| is the unsafe
  // resource for which a delayed interstitial will be displayed.
  // |ui_manager| is the UIManager that shows the actual warning.
  static void CreateForWebContents(
      content::WebContents* web_contents,
      const security_interstitials::UnsafeResource& resource,
      scoped_refptr<SafeBrowsingUIManager> ui_manager);

  ~SafeBrowsingUserInteractionObserver() override;

  // content::WebContentsObserver methods:
  void RenderFrameHostChanged(content::RenderFrameHost* old_frame,
                              content::RenderFrameHost* new_frame) override;
  void WebContentsDestroyed() override;
  void DidFinishNavigation(content::NavigationHandle* handle) override;
  void DidToggleFullscreenModeForTab(bool entered_fullscreen,
                                     bool will_cause_resize) override;
  void OnPaste() override;

  // permissions::PermissionRequestManager::Observer methods:
  void OnPromptAdded() override;

  // Called by the JavaScript dialog manager when the current page is about to
  // show a JavaScript dialog (alert, confirm or prompt). Shows the
  // delayed interstitial immediately.
  void OnJavaScriptDialog();
  // Called when a password save or autofill request is denied to the current
  // page. Records a metric once per navigation.
  void OnPasswordSaveOrAutofillDenied();
  // Called by the desktop capture access handler when the current page requests
  // a desktop capture. Shows the delayed interstitial immediately.
  void OnDesktopCaptureRequest();

  void SetClockForTesting(base::Clock* clock);
  base::Time GetCreationTimeForTesting() const;

 private:
  friend class content::WebContentsUserData<
      SafeBrowsingUserInteractionObserver>;
  WEB_CONTENTS_USER_DATA_KEY_DECL();

  // See CreateForWebContents() for parameters.
  SafeBrowsingUserInteractionObserver(
      content::WebContents* web_contents,
      const security_interstitials::UnsafeResource& resource,
      scoped_refptr<SafeBrowsingUIManager> ui_manager);

  bool HandleKeyPress(const input::NativeWebKeyboardEvent& event);
  bool HandleMouseEvent(const blink::WebMouseEvent& event);

  void ShowInterstitial(DelayedWarningEvent event);
  void CleanUp();
  void Detach();

  content::RenderWidgetHost::KeyPressEventCallback key_press_callback_;
  content::RenderWidgetHost::MouseEventCallback mouse_event_callback_;

  security_interstitials::UnsafeResource resource_;
  scoped_refptr<SafeBrowsingUIManager> ui_manager_;
  bool interstitial_shown_ = false;
  bool mouse_click_with_no_warning_recorded_ = false;
  bool password_save_or_autofill_denied_metric_recorded_ = false;
  // This will be set to true if the initial navigation that caused this
  // observer to be created has finished. We need this extra bit because
  // observers can only detect download navigations in DidFinishNavigation.
  // However, this hook is also called for the initial navigation, so we ignore
  // it the first time the hook is called.
  bool initial_navigation_finished_ = false;

  // The time that this observer was created. Used for recording histograms.
  base::Time creation_time_;
  // This clock is used to record the delta from |creation_time_| when the
  // observer is detached, and can be injected by tests.
  raw_ptr<base::Clock> clock_;
};

}  // namespace safe_browsing

#endif  // CHROME_BROWSER_SAFE_BROWSING_USER_INTERACTION_OBSERVER_H_