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
|
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_CHROMEOS_SYSTEM_AUTOMATIC_REBOOT_MANAGER_H_
#define CHROME_BROWSER_CHROMEOS_SYSTEM_AUTOMATIC_REBOOT_MANAGER_H_
#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "base/prefs/pref_change_registrar.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "chromeos/dbus/power_manager_client.h"
#include "chromeos/dbus/update_engine_client.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
#include "ui/wm/core/user_activity_observer.h"
class PrefRegistrySimple;
namespace base {
class TickClock;
}
namespace chromeos {
namespace system {
class AutomaticRebootManagerObserver;
// 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 unconditionally performed at its end.
//
// Note: Currently, automatic reboots are only enabled while the login screen is
// being shown or a kiosk app session is in progress. This will change in the
// future and the policy will always apply, regardless of whether a session of
// any particular type is in progress or not. http://crbug.com/244972
//
// 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 PowerManagerClient::Observer,
public UpdateEngineClient::Observer,
public wm::UserActivityObserver,
public content::NotificationObserver {
public:
// The current uptime and the uptime at which an update was applied and a
// reboot became necessary (if any). Used to pass this information from the
// blocking thread pool to the UI thread.
struct SystemEventTimes {
SystemEventTimes();
SystemEventTimes(const base::TimeDelta& uptime,
const base::TimeDelta& update_reboot_needed_uptime);
bool has_boot_time;
base::TimeTicks boot_time;
bool has_update_reboot_needed_time;
base::TimeTicks update_reboot_needed_time;
};
explicit AutomaticRebootManager(scoped_ptr<base::TickClock> clock);
virtual ~AutomaticRebootManager();
void AddObserver(AutomaticRebootManagerObserver* observer);
void RemoveObserver(AutomaticRebootManagerObserver* observer);
// PowerManagerClient::Observer:
virtual void SystemResumed(const base::TimeDelta& sleep_duration) OVERRIDE;
// UpdateEngineClient::Observer:
virtual void UpdateStatusChanged(
const UpdateEngineClient::Status& status) OVERRIDE;
// wm::UserActivityObserver:
virtual void OnUserActivity(const ui::Event* event) OVERRIDE;
// content::NotificationObserver:
virtual void Observe(int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) 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 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.
void Reboot();
// A clock that can be mocked in tests to fast-forward time.
scoped_ptr<base::TickClock> clock_;
PrefChangeRegistrar local_state_registrar_;
content::NotificationRegistrar notification_registrar_;
// Fires when the user has been idle on the login screen for a set amount of
// time.
scoped_ptr<base::OneShotTimer<AutomaticRebootManager> >
login_screen_idle_timer_;
// The time at which the device was booted, in |clock_| ticks.
bool have_boot_time_;
base::TimeTicks boot_time_;
// The time at which an update was applied and a reboot became necessary to
// complete the update process, in |clock_| ticks.
bool have_update_reboot_needed_time_;
base::TimeTicks update_reboot_needed_time_;
// Whether a reboot has been requested.
bool reboot_requested_;
// Timers that start and end the grace period.
scoped_ptr<base::OneShotTimer<AutomaticRebootManager> > grace_start_timer_;
scoped_ptr<base::OneShotTimer<AutomaticRebootManager> > grace_end_timer_;
base::WeakPtrFactory<AutomaticRebootManager> weak_ptr_factory_;
ObserverList<AutomaticRebootManagerObserver, true> observers_;
DISALLOW_COPY_AND_ASSIGN(AutomaticRebootManager);
};
} // namespace system
} // namespace chromeos
#endif // CHROME_BROWSER_CHROMEOS_SYSTEM_AUTOMATIC_REBOOT_MANAGER_H_
|