Home | History | Annotate | Download | only in wm
      1 // Copyright 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 ASH_WM_LOCK_STATE_CONTROLLER_H_
      6 #define ASH_WM_LOCK_STATE_CONTROLLER_H_
      7 
      8 #include "ash/ash_export.h"
      9 #include "ash/shell_observer.h"
     10 #include "ash/wm/lock_state_observer.h"
     11 #include "ash/wm/session_state_animator.h"
     12 #include "base/basictypes.h"
     13 #include "base/memory/scoped_ptr.h"
     14 #include "base/observer_list.h"
     15 #include "base/time/time.h"
     16 #include "base/timer/timer.h"
     17 #include "ui/aura/root_window_observer.h"
     18 
     19 namespace gfx {
     20 class Rect;
     21 class Size;
     22 }
     23 
     24 namespace ui {
     25 class Layer;
     26 }
     27 
     28 namespace ash {
     29 
     30 namespace test {
     31 class LockStateControllerTest;
     32 class PowerButtonControllerTest;
     33 }
     34 
     35 // Performs system-related functions on behalf of LockStateController.
     36 class ASH_EXPORT LockStateControllerDelegate {
     37  public:
     38   LockStateControllerDelegate() {}
     39   virtual ~LockStateControllerDelegate() {}
     40 
     41   virtual void RequestLockScreen() = 0;
     42   virtual void RequestShutdown() = 0;
     43 
     44  private:
     45   DISALLOW_COPY_AND_ASSIGN(LockStateControllerDelegate);
     46 };
     47 
     48 // Displays onscreen animations and locks or suspends the system in response to
     49 // the power button being pressed or released.
     50 // Lock workflow:
     51 // Entry points:
     52 //  * StartLockAnimation (bool shutdown after lock) - starts lock that can be
     53 //    cancelled.
     54 //  * StartLockAnimationAndLockImmediately - starts uninterruptible lock
     55 //    animation.
     56 // This leads to call of either StartImmediatePreLockAnimation or
     57 // StartCancellablePreLockAnimation. Once they complete
     58 // PreLockAnimationFinished is called, and system lock is requested.
     59 // Once system locks and lock UI is created, OnLockStateChanged is called, and
     60 // StartPostLockAnimation is called. In PostLockAnimationFinished two
     61 // things happen : EVENT_LOCK_ANIMATION_FINISHED notification is sent (it
     62 // triggers third part of animation within lock UI), and check for continuing to
     63 // shutdown is made.
     64 //
     65 // Unlock workflow:
     66 // WebUI does first part of animation, and calls OnLockScreenHide(callback) that
     67 // triggers StartUnlockAnimationBeforeUIDestroyed(callback). Once callback is
     68 // called at the end of the animation, lock UI is deleted, system unlocks, and
     69 // OnLockStateChanged is called. It leads to
     70 // StartUnlockAnimationAfterUIDestroyed.
     71 class ASH_EXPORT LockStateController : public aura::RootWindowObserver,
     72                                        public ShellObserver {
     73  public:
     74   // Amount of time that the power button needs to be held before we lock the
     75   // screen.
     76   static const int kLockTimeoutMs;
     77 
     78   // Amount of time that the power button needs to be held before we shut down.
     79   static const int kShutdownTimeoutMs;
     80 
     81   // Amount of time to wait for our lock requests to be honored before giving
     82   // up.
     83   static const int kLockFailTimeoutMs;
     84 
     85   // When the button has been held continuously from the unlocked state, amount
     86   // of time that we wait after the screen locker window is shown before
     87   // starting the pre-shutdown animation.
     88   static const int kLockToShutdownTimeoutMs;
     89 
     90   // Additional time (beyond kFastCloseAnimMs) to wait after starting the
     91   // fast-close shutdown animation before actually requesting shutdown, to give
     92   // the animation time to finish.
     93   static const int kShutdownRequestDelayMs;
     94 
     95   // Helper class used by tests to access internal state.
     96   class ASH_EXPORT TestApi {
     97    public:
     98     explicit TestApi(LockStateController* controller);
     99 
    100     virtual ~TestApi();
    101 
    102     bool lock_fail_timer_is_running() const {
    103       return controller_->lock_fail_timer_.IsRunning();
    104     }
    105     bool lock_to_shutdown_timer_is_running() const {
    106       return controller_->lock_to_shutdown_timer_.IsRunning();
    107     }
    108     bool shutdown_timer_is_running() const {
    109       return controller_->pre_shutdown_timer_.IsRunning();
    110     }
    111     bool real_shutdown_timer_is_running() const {
    112       return controller_->real_shutdown_timer_.IsRunning();
    113     }
    114     bool is_animating_lock() const {
    115       return controller_->animating_lock_;
    116     }
    117     bool is_lock_cancellable() const {
    118       return controller_->CanCancelLockAnimation();
    119     }
    120 
    121     void trigger_lock_fail_timeout() {
    122       controller_->OnLockFailTimeout();
    123       controller_->lock_fail_timer_.Stop();
    124     }
    125     void trigger_lock_to_shutdown_timeout() {
    126       controller_->OnLockToShutdownTimeout();
    127       controller_->lock_to_shutdown_timer_.Stop();
    128     }
    129     void trigger_shutdown_timeout() {
    130       controller_->OnPreShutdownAnimationTimeout();
    131       controller_->pre_shutdown_timer_.Stop();
    132     }
    133     void trigger_real_shutdown_timeout() {
    134       controller_->OnRealShutdownTimeout();
    135       controller_->real_shutdown_timer_.Stop();
    136     }
    137    private:
    138     LockStateController* controller_;  // not owned
    139 
    140     DISALLOW_COPY_AND_ASSIGN(TestApi);
    141   };
    142 
    143   LockStateController();
    144   virtual ~LockStateController();
    145 
    146   // Takes ownership of |delegate|.
    147   void SetDelegate(LockStateControllerDelegate* delegate);
    148 
    149   void AddObserver(LockStateObserver* observer);
    150   void RemoveObserver(LockStateObserver* observer);
    151   bool HasObserver(LockStateObserver* observer);
    152 
    153   // Starts locking (with slow animation) that can be cancelled.
    154   // After locking and |kLockToShutdownTimeoutMs| StartShutdownAnimation()
    155   // will be called unless CancelShutdownAnimation() is called, if
    156   // |shutdown_after_lock| is true.
    157   void StartLockAnimation(bool shutdown_after_lock);
    158 
    159   // Starts shutting down (with slow animation) that can be cancelled.
    160   void StartShutdownAnimation();
    161 
    162   // Starts usual lock animation, but locks immediately.
    163   // Unlike StartLockAnimation it does no lead to StartShutdownAnimation.
    164   void StartLockAnimationAndLockImmediately();
    165 
    166   // Returns true if we have requested system to lock, but haven't received
    167   // confirmation yet.
    168   bool LockRequested();
    169 
    170   // Returns true if we are shutting down.
    171   bool ShutdownRequested();
    172 
    173   // Returns true if we are within cancellable lock timeframe.
    174   bool CanCancelLockAnimation();
    175 
    176   // Cancels locking and reverts lock animation.
    177   void CancelLockAnimation();
    178 
    179   // Returns true if we are within cancellable shutdown timeframe.
    180   bool CanCancelShutdownAnimation();
    181 
    182   // Cancels shutting down and reverts shutdown animation.
    183   void CancelShutdownAnimation();
    184 
    185   // Called when Chrome gets a request to display the lock screen.
    186   void OnStartingLock();
    187 
    188   // Displays the shutdown animation and requests shutdown when it's done.
    189   void RequestShutdown();
    190 
    191   // Called when ScreenLocker is ready to close, but not yet destroyed.
    192   // Can be used to display "hiding" animations on unlock.
    193   // |callback| will be called when all animations are done.
    194   void OnLockScreenHide(base::Closure& callback);
    195 
    196   // Sets up the callback that should be called once lock animation is finished.
    197   // Callback is guaranteed to be called once and then discarded.
    198   void SetLockScreenDisplayedCallback(const base::Closure& callback);
    199 
    200   // RootWindowObserver override:
    201   virtual void OnRootWindowHostCloseRequested(
    202      const aura::RootWindow* root) OVERRIDE;
    203 
    204   // ShellObserver overrides:
    205   virtual void OnLoginStateChanged(user::LoginStatus status) OVERRIDE;
    206   virtual void OnAppTerminating() OVERRIDE;
    207   virtual void OnLockStateChanged(bool locked) OVERRIDE;
    208 
    209  private:
    210   friend class test::PowerButtonControllerTest;
    211   friend class test::LockStateControllerTest;
    212 
    213   struct UnlockedStateProperties {
    214     bool background_is_hidden;
    215   };
    216 
    217   // Reverts the pre-lock animation, reports the error.
    218   void OnLockFailTimeout();
    219 
    220   // Starts timer for gap between lock and shutdown.
    221   void StartLockToShutdownTimer();
    222 
    223   // Calls StartShutdownAnimation().
    224   void OnLockToShutdownTimeout();
    225 
    226   // Starts timer for undoable shutdown animation.
    227   void StartPreShutdownAnimationTimer();
    228 
    229   // Calls StartRealShutdownTimer().
    230   void OnPreShutdownAnimationTimeout();
    231 
    232   // Starts timer for final shutdown animation.
    233   // If |with_animation_time| is true, it will also include time of "fade to
    234   // white" shutdown animation.
    235   void StartRealShutdownTimer(bool with_animation_time);
    236 
    237   // Requests that the machine be shut down.
    238   void OnRealShutdownTimeout();
    239 
    240   // Starts shutdown animation that can be cancelled and starts pre-shutdown
    241   // timer.
    242   void StartCancellableShutdownAnimation();
    243 
    244   // If |request_lock_on_completion| is true, a lock request will be sent
    245   // after the pre-lock animation completes.  (The pre-lock animation is
    246   // also displayed in response to already-in-progress lock requests; in
    247   // these cases an additional lock request is undesirable.)
    248   void StartImmediatePreLockAnimation(bool request_lock_on_completion);
    249   void StartCancellablePreLockAnimation();
    250   void CancelPreLockAnimation();
    251   void StartPostLockAnimation();
    252   // This method calls |callback| when animation completes.
    253   void StartUnlockAnimationBeforeUIDestroyed(base::Closure &callback);
    254   void StartUnlockAnimationAfterUIDestroyed();
    255 
    256   // These methods are called when corresponding animation completes.
    257   void LockAnimationCancelled();
    258   void PreLockAnimationFinished(bool request_lock);
    259   void PostLockAnimationFinished();
    260   void UnlockAnimationAfterUIDestroyedFinished();
    261 
    262   // Stores properties of UI that have to be temporarily modified while locking.
    263   void StoreUnlockedProperties();
    264   void RestoreUnlockedProperties();
    265 
    266   // Fades in background layer with |speed| if it was hidden in unlocked state.
    267   void AnimateBackgroundAppearanceIfNecessary(
    268       ash::internal::SessionStateAnimator::AnimationSpeed speed,
    269       ui::LayerAnimationObserver* observer);
    270 
    271   // Fades out background layer with |speed| if it was hidden in unlocked state.
    272   void AnimateBackgroundHidingIfNecessary(
    273       ash::internal::SessionStateAnimator::AnimationSpeed speed,
    274       ui::LayerAnimationObserver* observer);
    275 
    276   scoped_ptr<internal::SessionStateAnimator> animator_;
    277 
    278   scoped_ptr<LockStateControllerDelegate> delegate_;
    279 
    280   ObserverList<LockStateObserver> observers_;
    281 
    282   // The current login status, or original login status from before we locked.
    283   user::LoginStatus login_status_;
    284 
    285   // Current lock status.
    286   bool system_is_locked_;
    287 
    288   // Are we in the process of shutting the machine down?
    289   bool shutting_down_;
    290 
    291   // Indicates whether controller should proceed to (cancellable) shutdown after
    292   // locking.
    293   bool shutdown_after_lock_;
    294 
    295   // Indicates that controller displays lock animation.
    296   bool animating_lock_;
    297 
    298   // Indicates that lock animation can be undone.
    299   bool can_cancel_lock_animation_;
    300 
    301   scoped_ptr<UnlockedStateProperties> unlocked_properties_;
    302 
    303   // Started when we request that the screen be locked.  When it fires, we
    304   // assume that our request got dropped.
    305   base::OneShotTimer<LockStateController> lock_fail_timer_;
    306 
    307   // Started when the screen is locked while the power button is held.  Adds a
    308   // delay between the appearance of the lock screen and the beginning of the
    309   // pre-shutdown animation.
    310   base::OneShotTimer<LockStateController> lock_to_shutdown_timer_;
    311 
    312   // Started when we begin displaying the pre-shutdown animation.  When it
    313   // fires, we start the shutdown animation and get ready to request shutdown.
    314   base::OneShotTimer<LockStateController> pre_shutdown_timer_;
    315 
    316   // Started when we display the shutdown animation.  When it fires, we actually
    317   // request shutdown.  Gives the animation time to complete before Chrome, X,
    318   // etc. are shut down.
    319   base::OneShotTimer<LockStateController> real_shutdown_timer_;
    320 
    321   base::Closure lock_screen_displayed_callback_;
    322 
    323   DISALLOW_COPY_AND_ASSIGN(LockStateController);
    324 };
    325 
    326 }  // namespace ash
    327 
    328 #endif  // ASH_WM_LOCK_STATE_CONTROLLER_H_
    329