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/memory/weak_ptr.h"
     15 #include "base/observer_list.h"
     16 #include "base/time/time.h"
     17 #include "base/timer/timer.h"
     18 #include "ui/aura/window_tree_host_observer.h"
     19 
     20 namespace gfx {
     21 class Rect;
     22 class Size;
     23 }
     24 
     25 namespace ui {
     26 class Layer;
     27 }
     28 
     29 namespace ash {
     30 
     31 namespace test {
     32 class LockStateControllerTest;
     33 class PowerButtonControllerTest;
     34 }
     35 
     36 // Performs system-related functions on behalf of LockStateController.
     37 class ASH_EXPORT LockStateControllerDelegate {
     38  public:
     39   LockStateControllerDelegate() {}
     40   virtual ~LockStateControllerDelegate() {}
     41 
     42   virtual void RequestLockScreen() = 0;
     43   virtual void RequestShutdown() = 0;
     44 
     45  private:
     46   DISALLOW_COPY_AND_ASSIGN(LockStateControllerDelegate);
     47 };
     48 
     49 // Displays onscreen animations and locks or suspends the system in response to
     50 // the power button being pressed or released.
     51 // Lock workflow:
     52 // Entry points:
     53 //  * StartLockAnimation (bool shutdown after lock) - starts lock that can be
     54 //    cancelled.
     55 //  * StartLockAnimationAndLockImmediately - starts uninterruptible lock
     56 //    animation.
     57 // This leads to call of either StartImmediatePreLockAnimation or
     58 // StartCancellablePreLockAnimation. Once they complete
     59 // PreLockAnimationFinished is called, and system lock is requested.
     60 // Once system locks and lock UI is created, OnLockStateChanged is called, and
     61 // StartPostLockAnimation is called. In PostLockAnimationFinished two
     62 // things happen : EVENT_LOCK_ANIMATION_FINISHED notification is sent (it
     63 // triggers third part of animation within lock UI), and check for continuing to
     64 // shutdown is made.
     65 //
     66 // Unlock workflow:
     67 // WebUI does first part of animation, and calls OnLockScreenHide(callback) that
     68 // triggers StartUnlockAnimationBeforeUIDestroyed(callback). Once callback is
     69 // called at the end of the animation, lock UI is deleted, system unlocks, and
     70 // OnLockStateChanged is called. It leads to
     71 // StartUnlockAnimationAfterUIDestroyed.
     72 class ASH_EXPORT LockStateController : public aura::WindowTreeHostObserver,
     73                                        public ShellObserver {
     74  public:
     75   // Amount of time that the power button needs to be held before we lock the
     76   // screen.
     77   static const int kLockTimeoutMs;
     78 
     79   // Amount of time that the power button needs to be held before we shut down.
     80   static const int kShutdownTimeoutMs;
     81 
     82   // Amount of time to wait for our lock requests to be honored before giving
     83   // up.
     84   static const int kLockFailTimeoutMs;
     85 
     86   // When the button has been held continuously from the unlocked state, amount
     87   // of time that we wait after the screen locker window is shown before
     88   // starting the pre-shutdown animation.
     89   static const int kLockToShutdownTimeoutMs;
     90 
     91   // Additional time (beyond kFastCloseAnimMs) to wait after starting the
     92   // fast-close shutdown animation before actually requesting shutdown, to give
     93   // the animation time to finish.
     94   static const int kShutdownRequestDelayMs;
     95 
     96   // Helper class used by tests to access internal state.
     97   class ASH_EXPORT TestApi {
     98    public:
     99     explicit TestApi(LockStateController* controller);
    100 
    101     virtual ~TestApi();
    102 
    103     bool lock_fail_timer_is_running() const {
    104       return controller_->lock_fail_timer_.IsRunning();
    105     }
    106     bool lock_to_shutdown_timer_is_running() const {
    107       return controller_->lock_to_shutdown_timer_.IsRunning();
    108     }
    109     bool shutdown_timer_is_running() const {
    110       return controller_->pre_shutdown_timer_.IsRunning();
    111     }
    112     bool real_shutdown_timer_is_running() const {
    113       return controller_->real_shutdown_timer_.IsRunning();
    114     }
    115     bool is_animating_lock() const {
    116       return controller_->animating_lock_;
    117     }
    118     bool is_lock_cancellable() const {
    119       return controller_->CanCancelLockAnimation();
    120     }
    121 
    122     void trigger_lock_fail_timeout() {
    123       controller_->OnLockFailTimeout();
    124       controller_->lock_fail_timer_.Stop();
    125     }
    126     void trigger_lock_to_shutdown_timeout() {
    127       controller_->OnLockToShutdownTimeout();
    128       controller_->lock_to_shutdown_timer_.Stop();
    129     }
    130     void trigger_shutdown_timeout() {
    131       controller_->OnPreShutdownAnimationTimeout();
    132       controller_->pre_shutdown_timer_.Stop();
    133     }
    134     void trigger_real_shutdown_timeout() {
    135       controller_->OnRealShutdownTimeout();
    136       controller_->real_shutdown_timer_.Stop();
    137     }
    138    private:
    139     LockStateController* controller_;  // not owned
    140 
    141     DISALLOW_COPY_AND_ASSIGN(TestApi);
    142   };
    143 
    144   LockStateController();
    145   virtual ~LockStateController();
    146 
    147   // Takes ownership of |delegate|.
    148   void SetDelegate(LockStateControllerDelegate* delegate);
    149 
    150   void AddObserver(LockStateObserver* observer);
    151   void RemoveObserver(LockStateObserver* observer);
    152   bool HasObserver(LockStateObserver* observer);
    153 
    154   // Starts locking (with slow animation) that can be cancelled.
    155   // After locking and |kLockToShutdownTimeoutMs| StartShutdownAnimation()
    156   // will be called unless CancelShutdownAnimation() is called, if
    157   // |shutdown_after_lock| is true.
    158   void StartLockAnimation(bool shutdown_after_lock);
    159 
    160   // Starts shutting down (with slow animation) that can be cancelled.
    161   void StartShutdownAnimation();
    162 
    163   // Starts usual lock animation, but locks immediately.
    164   // Unlike StartLockAnimation it does no lead to StartShutdownAnimation.
    165   void StartLockAnimationAndLockImmediately();
    166 
    167   // Returns true if we have requested system to lock, but haven't received
    168   // confirmation yet.
    169   bool LockRequested();
    170 
    171   // Returns true if we are shutting down.
    172   bool ShutdownRequested();
    173 
    174   // Returns true if we are within cancellable lock timeframe.
    175   bool CanCancelLockAnimation();
    176 
    177   // Cancels locking and reverts lock animation.
    178   void CancelLockAnimation();
    179 
    180   // Returns true if we are within cancellable shutdown timeframe.
    181   bool CanCancelShutdownAnimation();
    182 
    183   // Cancels shutting down and reverts shutdown animation.
    184   void CancelShutdownAnimation();
    185 
    186   // Called when Chrome gets a request to display the lock screen.
    187   void OnStartingLock();
    188 
    189   // Displays the shutdown animation and requests shutdown when it's done.
    190   void RequestShutdown();
    191 
    192   // Called when ScreenLocker is ready to close, but not yet destroyed.
    193   // Can be used to display "hiding" animations on unlock.
    194   // |callback| will be called when all animations are done.
    195   void OnLockScreenHide(base::Closure& callback);
    196 
    197   // Sets up the callback that should be called once lock animation is finished.
    198   // Callback is guaranteed to be called once and then discarded.
    199   void SetLockScreenDisplayedCallback(const base::Closure& callback);
    200 
    201   // aura::WindowTreeHostObserver override:
    202   virtual void OnHostCloseRequested(const aura::WindowTreeHost* host) 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::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::SessionStateAnimator::AnimationSpeed speed,
    274       ui::LayerAnimationObserver* observer);
    275 
    276   scoped_ptr<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   base::WeakPtrFactory<LockStateController> weak_ptr_factory_;
    324 
    325   DISALLOW_COPY_AND_ASSIGN(LockStateController);
    326 };
    327 
    328 }  // namespace ash
    329 
    330 #endif  // ASH_WM_LOCK_STATE_CONTROLLER_H_
    331