1// Copyright (c) 2013 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#ifndef CHROME_BROWSER_CHROMEOS_SYSTEM_AUTOMATIC_REBOOT_MANAGER_H_ 6#define CHROME_BROWSER_CHROMEOS_SYSTEM_AUTOMATIC_REBOOT_MANAGER_H_ 7 8#include "base/basictypes.h" 9#include "base/compiler_specific.h" 10#include "base/memory/scoped_ptr.h" 11#include "base/memory/weak_ptr.h" 12#include "base/observer_list.h" 13#include "base/prefs/pref_change_registrar.h" 14#include "base/time/time.h" 15#include "base/timer/timer.h" 16#include "chromeos/dbus/power_manager_client.h" 17#include "chromeos/dbus/update_engine_client.h" 18#include "content/public/browser/notification_observer.h" 19#include "content/public/browser/notification_registrar.h" 20#include "ui/wm/core/user_activity_observer.h" 21 22class PrefRegistrySimple; 23 24namespace base { 25class TickClock; 26} 27 28namespace chromeos { 29namespace system { 30 31class AutomaticRebootManagerObserver; 32 33// Schedules and executes automatic reboots. 34// 35// Automatic reboots may be scheduled for any number of reasons. Currently, the 36// following are implemented: 37// * When Chrome OS has applied a system update, a reboot may become necessary 38// to complete the update process. If the policy to automatically reboot after 39// an update is enabled, a reboot is scheduled at that point. 40// * If an uptime limit is set through policy, a reboot is scheduled when the 41// device's uptime reaches the limit. Time spent sleeping counts as uptime as 42// well. 43// 44// When the time of the earliest scheduled reboot is reached, the reboot is 45// requested. The reboot is performed immediately unless one of the following 46// reasons inhibits it: 47// * If the login screen is being shown: Reboots are inhibited while the user is 48// interacting with the screen (determined by checking whether there has been 49// any user activity in the past 60 seconds). 50// * If a session is in progress: Reboots are inhibited until the session ends, 51// the browser is restarted or the device is suspended. 52// 53// If reboots are inhibited, a 24 hour grace period is started. The reboot 54// request is carried out the moment none of the inhibiting criteria apply 55// anymore (e.g. the user becomes idle on the login screen, the user logs exits 56// a session, the user suspends the device). If reboots remain inhibited for the 57// entire grace period, a reboot is unconditionally performed at its end. 58// 59// Note: Currently, automatic reboots are only enabled while the login screen is 60// being shown or a kiosk app session is in progress. This will change in the 61// future and the policy will always apply, regardless of whether a session of 62// any particular type is in progress or not. http://crbug.com/244972 63// 64// Reboots may be scheduled and canceled at any time. This causes the time at 65// which a reboot should be requested and the grace period that follows it to 66// be recalculated. 67// 68// Reboots are scheduled in terms of device uptime. The current uptime is read 69// from /proc/uptime. The time at which a reboot became necessary to finish 70// applying an update is stored in /var/run/chrome/update_reboot_needed_uptime, 71// making it persist across browser restarts and crashes. Placing the file under 72// /var/run ensures that it gets cleared automatically on every boot. 73class AutomaticRebootManager : public PowerManagerClient::Observer, 74 public UpdateEngineClient::Observer, 75 public wm::UserActivityObserver, 76 public content::NotificationObserver { 77 public: 78 // The current uptime and the uptime at which an update was applied and a 79 // reboot became necessary (if any). Used to pass this information from the 80 // blocking thread pool to the UI thread. 81 struct SystemEventTimes { 82 SystemEventTimes(); 83 SystemEventTimes(const base::TimeDelta& uptime, 84 const base::TimeDelta& update_reboot_needed_uptime); 85 86 bool has_boot_time; 87 base::TimeTicks boot_time; 88 89 bool has_update_reboot_needed_time; 90 base::TimeTicks update_reboot_needed_time; 91 }; 92 93 explicit AutomaticRebootManager(scoped_ptr<base::TickClock> clock); 94 virtual ~AutomaticRebootManager(); 95 96 void AddObserver(AutomaticRebootManagerObserver* observer); 97 void RemoveObserver(AutomaticRebootManagerObserver* observer); 98 99 // PowerManagerClient::Observer: 100 virtual void SuspendDone(const base::TimeDelta& sleep_duration) OVERRIDE; 101 102 // UpdateEngineClient::Observer: 103 virtual void UpdateStatusChanged( 104 const UpdateEngineClient::Status& status) OVERRIDE; 105 106 // wm::UserActivityObserver: 107 virtual void OnUserActivity(const ui::Event* event) OVERRIDE; 108 109 // content::NotificationObserver: 110 virtual void Observe(int type, 111 const content::NotificationSource& source, 112 const content::NotificationDetails& details) OVERRIDE; 113 114 static void RegisterPrefs(PrefRegistrySimple* registry); 115 116 private: 117 friend class AutomaticRebootManagerBasicTest; 118 119 // Finishes initialization. Called after the |system_event_times| have been 120 // loaded in the blocking thread pool. 121 void Init(const SystemEventTimes& system_event_times); 122 123 // Reschedules the reboot request, start and end of the grace period. Reboots 124 // immediately if the end of the grace period has already passed. 125 void Reschedule(); 126 127 // Requests a reboot. 128 void RequestReboot(); 129 130 // Called whenever the status of the criteria inhibiting reboots may have 131 // changed. Reboots immediately if a reboot has actually been requested and 132 // none of the criteria inhibiting it apply anymore. Otherwise, does nothing. 133 // If |ignore_session|, a session in progress does not inhibit reboots. 134 void MaybeReboot(bool ignore_session); 135 136 // Reboots immediately. 137 void Reboot(); 138 139 // A clock that can be mocked in tests to fast-forward time. 140 scoped_ptr<base::TickClock> clock_; 141 142 PrefChangeRegistrar local_state_registrar_; 143 144 content::NotificationRegistrar notification_registrar_; 145 146 // Fires when the user has been idle on the login screen for a set amount of 147 // time. 148 scoped_ptr<base::OneShotTimer<AutomaticRebootManager> > 149 login_screen_idle_timer_; 150 151 // The time at which the device was booted, in |clock_| ticks. 152 bool have_boot_time_; 153 base::TimeTicks boot_time_; 154 155 // The time at which an update was applied and a reboot became necessary to 156 // complete the update process, in |clock_| ticks. 157 bool have_update_reboot_needed_time_; 158 base::TimeTicks update_reboot_needed_time_; 159 160 // Whether a reboot has been requested. 161 bool reboot_requested_; 162 163 // Timers that start and end the grace period. 164 scoped_ptr<base::OneShotTimer<AutomaticRebootManager> > grace_start_timer_; 165 scoped_ptr<base::OneShotTimer<AutomaticRebootManager> > grace_end_timer_; 166 167 base::WeakPtrFactory<AutomaticRebootManager> weak_ptr_factory_; 168 169 ObserverList<AutomaticRebootManagerObserver, true> observers_; 170 171 DISALLOW_COPY_AND_ASSIGN(AutomaticRebootManager); 172}; 173 174} // namespace system 175} // namespace chromeos 176 177#endif // CHROME_BROWSER_CHROMEOS_SYSTEM_AUTOMATIC_REBOOT_MANAGER_H_ 178