Home | History | Annotate | Download | only in system
      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 "ash/wm/user_activity_observer.h"
      9 #include "base/basictypes.h"
     10 #include "base/compiler_specific.h"
     11 #include "base/memory/scoped_ptr.h"
     12 #include "base/memory/weak_ptr.h"
     13 #include "base/observer_list.h"
     14 #include "base/prefs/pref_change_registrar.h"
     15 #include "base/time/time.h"
     16 #include "base/timer/timer.h"
     17 #include "chromeos/dbus/power_manager_client.h"
     18 #include "chromeos/dbus/update_engine_client.h"
     19 #include "content/public/browser/notification_observer.h"
     20 #include "content/public/browser/notification_registrar.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 ash::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 SystemResumed(const base::TimeDelta& sleep_duration) OVERRIDE;
    101 
    102   // UpdateEngineClient::Observer:
    103   virtual void UpdateStatusChanged(
    104       const UpdateEngineClient::Status& status) OVERRIDE;
    105 
    106   // ash::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