File: relaunch_notification_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 (206 lines) | stat: -rw-r--r-- 9,191 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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
// Copyright 2018 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_RELAUNCH_NOTIFICATION_RELAUNCH_NOTIFICATION_CONTROLLER_H_
#define CHROME_BROWSER_UI_VIEWS_RELAUNCH_NOTIFICATION_RELAUNCH_NOTIFICATION_CONTROLLER_H_

#include "base/functional/callback_forward.h"
#include "base/memory/raw_ptr.h"
#include "base/time/time.h"
#include "base/timer/wall_clock_timer.h"
#include "chrome/browser/upgrade_detector/upgrade_detector.h"
#include "chrome/browser/upgrade_detector/upgrade_observer.h"
#include "components/prefs/pref_change_registrar.h"

#if BUILDFLAG(IS_CHROMEOS)
#include "chrome/browser/ui/views/relaunch_notification/relaunch_notification_controller_platform_impl_chromeos.h"
#else
#include "chrome/browser/ui/views/relaunch_notification/relaunch_notification_controller_platform_impl_desktop.h"
#endif  // BUILDFLAG(IS_CHROMEOS)

namespace base {
class Clock;
class TickClock;
}  // namespace base

// A class that observes changes to the browser.relaunch_notification
// preference (which is backed by the RelaunchNotification policy
// setting) and upgrade notifications from the UpgradeDetector. The two
// values for the RelaunchNotification policy setting are handled as follows:
//
// On Chrome desktop:
// - Recommended (1): The controller displays the relaunch recommended bubble on
//   each change to the UpgradeDetector's upgrade_notification_stage (an
//   "annoyance level" of low, elevated, grace or high). Once the high annoyance
//   level is reached, the controller continually reshows a the bubble on a
//   timer with a period equal to the time delta between the "elevated" and
//   "high" showings.
//
// - Required (2): The controller displays the relaunch required dialog when the
// UpgradeDetector's upgrade_notification_stage changes to an "annoyance level"
// of low, elevated, and grace. The browser is relaunched when the "annoyance
// level" reaches "high".
//
// On Chrome OS both notifications (recommended and required, described above)
// are shown in the unified system tray, overwriting the default "update
// available" notification. It cannot be deferred, so it persists until reboot.
// In certain conditions, the preference value could be overridden by the
// UpgradeDetector which then takes priority over the original value and any
// further changes to the preference have no effect.
class RelaunchNotificationController : public UpgradeObserver {
 public:
  // |upgrade_detector| is expected to be the process-wide detector, and must
  // outlive the controller.
  explicit RelaunchNotificationController(UpgradeDetector* upgrade_detector);

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

  ~RelaunchNotificationController() override;

 protected:
  // The length of the final countdown given to the user before the browser is
  // summarily relaunched on Chrome desktop, or the device is rebooted on
  // Chrome OS.
  static constexpr base::TimeDelta kRelaunchGracePeriod = base::Hours(1);

  RelaunchNotificationController(UpgradeDetector* upgrade_detector,
                                 const base::Clock* clock,
                                 const base::TickClock* tick_clock);

  // The deadline may be extended to ensure that the user has at least the full
  // duration of the grace period to take action.
  base::Time IncreaseRelaunchDeadlineOnShow();

  // UpgradeObserver:
  void OnUpgradeRecommended() override;
  void OnRelaunchOverriddenToRequired(bool overridden) override;

 private:
  enum class NotificationStyle {
    kNone,         // No notifications are shown.
    kRecommended,  // Relaunches are recommended.
    kRequired,     // Relaunches are required.
  };

  // Adjusts to the current notification style as indicated by the
  // browser.relaunch_notification Local State preference. If the notification
  // style has been overridden, then that value is given priority over the
  // preference value.
  void HandleCurrentStyle();

  // Bring the instance out of or back to dormant mode.
  void StartObservingUpgrades();
  void StopObservingUpgrades();

  // Shows the proper notification based on the preference setting and starts
  // the timer to either reshow the bubble or restart the browser/device as
  // appropriate. |level| is the current annoyance level reported by the
  // UpgradeDetector, and |high_deadline| is the time at which the
  // UpgradeDetector will reach the high annoyance level; see the class comment
  // for further details.
  void ShowRelaunchNotification(
      UpgradeDetector::UpgradeNotificationAnnoyanceLevel level,
      base::Time high_deadline);

  // Closes any previously-shown notifications. This is safe to call if no
  // notifications have been shown. Notifications may be closed by other means
  // (e.g., by the user), so there is no expectation that a previously-shown
  // notification is still open when this is invoked. The timer to either
  // repeatedly show the relaunch recommended notification or to force a
  // relaunch once the deadline is reached is also stopped.
  void CloseRelaunchNotification();

  // Starts or reschedules a timer to periodically re-show the relaunch
  // recommended bubble.
  void StartReshowTimer();

  // Run on a timer once high annoyance has been reached to re-show the relaunch
  // recommended bubble.
  void OnReshowRelaunchRecommended();

  // Handles a new |level| and/or |high_deadline| by adjusting the runtime of
  // the relaunch timer, updating the deadline displayed in the title of the
  // relaunch required notification (if shown), and showing it if needed.
  void HandleRelaunchRequiredState(
      UpgradeDetector::UpgradeNotificationAnnoyanceLevel level,
      base::Time high_deadline);

  // Update |last_relaunch_notification_time_| before calling
  // DoNotifyRelaunchRecommended. |past_deadline| reflects whether the
  // Recommended deadline was already passed or not.
  void NotifyRelaunchRecommended(bool past_deadline);

  // Calls DoNotifyRelaunchRequired to show the notification.
  void NotifyRelaunchRequired();

  // The following methods, which are invoked by the controller to show or close
  // notifications, are virtual for the sake of testing.

  // Shows the relaunch recommended notification if it is not already open.
  // |past_deadline| reflects whether the Recommended deadline was already
  // passed or not.
  virtual void DoNotifyRelaunchRecommended(bool past_deadline);

  // Shows the relaunch required notification if it is not already open.
  // |on_visible| is a callback to be run when the notification is potentially
  // seen by the user to push back the relaunch deadline if the remaining time
  // is less than the grace period.
  virtual void DoNotifyRelaunchRequired(
      base::Time relaunch_deadline,
      base::OnceCallback<base::Time()> on_visible);

  // Closes bubble or dialog if either is still open on desktop, or sets the
  // default notification on Chrome OS.
  virtual void Close();

  // Run to restart the browser/device once the relaunch deadline is reached
  // when relaunches are required by policy.
  virtual void OnRelaunchDeadlineExpired();

  // The process-wide upgrade detector.
  const raw_ptr<UpgradeDetector> upgrade_detector_;

  // A provider of Time to the controller and its timer for the sake of
  // testability.
  const raw_ptr<const base::Clock> clock_;

  // The platform-specific implementation.
  RelaunchNotificationControllerPlatformImpl platform_impl_;

  // Observes changes to the browser.relaunch_notification Local State pref.
  PrefChangeRegistrar pref_change_registrar_;

  // The last observed notification style. When kNone, the controller is
  // said to be "dormant" as there is no work for it to do aside from watch for
  // changes to browser.relaunch_notification. When any other value, the
  // controller is observing the UpgradeDetector to detect when to show a
  // notification.
  NotificationStyle last_notification_style_;

  // The last observed annoyance level. This member is unconditionally
  // UPGRADE_ANNOYANCE_NONE when the controller is dormant
  // (browser.relaunch_notification is 0).
  UpgradeDetector::UpgradeNotificationAnnoyanceLevel last_level_;

  // The last observed high annoyance deadline.
  base::Time last_high_deadline_;

  // The last time recommended relaunch notification triggered
  base::Time last_relaunch_notification_time_;

  // A timer used either to repeatedly reshow the relaunch recommended bubble
  // once the high annoyance level has been reached, or to trigger browser
  // relaunch once the relaunch required dialog's deadline is reached.
  base::WallClockTimer timer_;

  // A flag to denote that the relaunch notification type policy value has been
  // overridden to required. Changes to the policy value will not affect the
  // notification type.
  bool notification_type_required_overridden_ = false;
};

#endif  // CHROME_BROWSER_UI_VIEWS_RELAUNCH_NOTIFICATION_RELAUNCH_NOTIFICATION_CONTROLLER_H_