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 22 class PrefRegistrySimple; 23 24 namespace base { 25 class TickClock; 26 } 27 28 namespace chromeos { 29 namespace system { 30 31 class 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. 73 class 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