File: automatic_reboot_manager.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 (190 lines) | stat: -rw-r--r-- 7,599 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
// Copyright 2013 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_ASH_SYSTEM_AUTOMATIC_REBOOT_MANAGER_H_
#define CHROME_BROWSER_ASH_SYSTEM_AUTOMATIC_REBOOT_MANAGER_H_

#include <memory>
#include <optional>

#include "base/callback_list.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "base/scoped_observation.h"
#include "base/synchronization/waitable_event.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "base/timer/wall_clock_timer.h"
#include "chrome/browser/ash/system/automatic_reboot_manager_observer.h"
#include "chromeos/ash/components/dbus/update_engine/update_engine_client.h"
#include "chromeos/dbus/power/power_manager_client.h"
#include "components/prefs/pref_change_registrar.h"
#include "components/session_manager/core/session_manager.h"
#include "components/session_manager/core/session_manager_observer.h"
#include "ui/base/user_activity/user_activity_observer.h"

class PrefRegistrySimple;

namespace base {
class TickClock;
}

namespace ash {
namespace system {

namespace internal {
struct SystemEventTimes;
}

// Schedules and executes automatic reboots.
//
// Automatic reboots may be scheduled for any number of reasons. Currently, the
// following are implemented:
// * When Chrome OS has applied a system update, a reboot may become necessary
//   to complete the update process. If the policy to automatically reboot after
//   an update is enabled, a reboot is scheduled at that point.
// * If an uptime limit is set through policy, a reboot is scheduled when the
//   device's uptime reaches the limit. Time spent sleeping counts as uptime as
//   well.
//
// When the time of the earliest scheduled reboot is reached, the reboot is
// requested. The reboot is performed immediately unless one of the following
// reasons inhibits it:
// * If the login screen is being shown: Reboots are inhibited while the user is
//   interacting with the screen (determined by checking whether there has been
//   any user activity in the past 60 seconds).
// * If a session is in progress: Reboots are inhibited until the session ends,
//   the browser is restarted or the device is suspended.
//
// If reboots are inhibited, a 24 hour grace period is started. The reboot
// request is carried out the moment none of the inhibiting criteria apply
// anymore (e.g. the user becomes idle on the login screen, the user logs exits
// a session, the user suspends the device). If reboots remain inhibited for the
// entire grace period, a reboot is performed at its end, unless a non-kiosk
// session is active.
//
// Reboots may be scheduled and canceled at any time. This causes the time at
// which a reboot should be requested and the grace period that follows it to
// be recalculated.
//
// Reboots are scheduled in terms of device uptime. The current uptime is read
// from /proc/uptime. The time at which a reboot became necessary to finish
// applying an update is stored in /var/run/chrome/update_reboot_needed_uptime,
// making it persist across browser restarts and crashes. Placing the file under
// /var/run ensures that it gets cleared automatically on every boot.
class AutomaticRebootManager : public chromeos::PowerManagerClient::Observer,
                               public UpdateEngineClient::Observer,
                               public ui::UserActivityObserver,
                               public session_manager::SessionManagerObserver {
 public:
  AutomaticRebootManager(const base::Clock* clock,
                         const base::TickClock* tick_clock);

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

  ~AutomaticRebootManager() override;

  AutomaticRebootManagerObserver::Reason reboot_reason() const {
    return reboot_reason_;
  }
  bool reboot_requested() const { return reboot_requested_; }

  void AddObserver(AutomaticRebootManagerObserver* observer);
  void RemoveObserver(AutomaticRebootManagerObserver* observer);

  // Blocks until Init() is called and then returns true. If Init() is not
  // called within |timeout|, returns false.
  bool WaitForInitForTesting(const base::TimeDelta& timeout);

  // PowerManagerClient::Observer:
  void SuspendDone(base::TimeDelta sleep_duration) override;

  // UpdateEngineClient::Observer:
  void UpdateStatusChanged(const update_engine::StatusResult& status) override;

  // ui::UserActivityObserver:
  void OnUserActivity(const ui::Event* event) override;

  // session_manager::SessionManagerObserver:
  void OnUserSessionStarted(bool is_primary_user) override;

  static void RegisterPrefs(PrefRegistrySimple* registry);

 private:
  friend class AutomaticRebootManagerBasicTest;

  // Finishes initialization. Called after the |system_event_times| have been
  // loaded in the blocking thread pool.
  void Init(const internal::SystemEventTimes& system_event_times);

  // Reschedules the reboot request, start and end of the grace period. Reboots
  // immediately if the end of the grace period has already passed.
  void Reschedule();

  // Requests a reboot.
  void RequestReboot();

  // Called whenever the status of the criteria inhibiting reboots may have
  // changed. Reboots immediately if a reboot has actually been requested and
  // none of the criteria inhibiting it apply anymore. Otherwise, does nothing.
  // If |ignore_session|, a session in progress does not inhibit reboots.
  void MaybeReboot(bool ignore_session);

  // Reboots immediately unless a non-kiosk session is active.
  void Reboot();

  // Callback invoked when Chrome shuts down.
  void OnAppTerminating();

  // Event that is signaled when Init() runs.
  base::WaitableEvent initialized_{
      base::WaitableEvent::ResetPolicy::MANUAL,
      base::WaitableEvent::InitialState::NOT_SIGNALED};

  // Clocks that can be mocked in tests to fast-forward time.
  const raw_ptr<const base::Clock> clock_;
  const raw_ptr<const base::TickClock> tick_clock_;

  PrefChangeRegistrar local_state_registrar_;

  base::CallbackListSubscription on_app_terminating_subscription_;

  // Fires when the user has been idle on the login screen for a set amount of
  // time.
  std::unique_ptr<base::OneShotTimer> login_screen_idle_timer_;

  // The time at which the device was booted, in |tick_clock_| ticks.
  std::optional<base::TimeTicks> boot_time_;

  // The time at which an update was applied and a reboot became necessary to
  // complete the update process, in |tick_clock_| ticks.
  std::optional<base::TimeTicks> update_reboot_needed_time_;

  // The reason for the reboot request. Updated whenever a reboot is scheduled.
  AutomaticRebootManagerObserver::Reason reboot_reason_ =
      AutomaticRebootManagerObserver::REBOOT_REASON_UNKNOWN;

  // Whether a reboot has been requested.
  bool reboot_requested_ = false;

  // Timers that start and end the grace period.
  std::unique_ptr<base::WallClockTimer> grace_start_timer_;
  std::unique_ptr<base::WallClockTimer> grace_end_timer_;

  base::ObserverList<AutomaticRebootManagerObserver, true>::Unchecked
      observers_;

  base::ScopedObservation<session_manager::SessionManager,
                          session_manager::SessionManagerObserver>
      session_manager_observation_{this};

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

}  // namespace system
}  // namespace ash

#endif  // CHROME_BROWSER_ASH_SYSTEM_AUTOMATIC_REBOOT_MANAGER_H_