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