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 (bool shutdown after lock) - starts 56 // uninterruptible lock 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 139 private: 140 LockStateController* controller_; // not owned 141 142 DISALLOW_COPY_AND_ASSIGN(TestApi); 143 }; 144 145 LockStateController(); 146 virtual ~LockStateController(); 147 148 void SetDelegate(scoped_ptr<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. After locking and 164 // |kLockToShutdownTimeoutMs| StartShutdownAnimation() will be called unless 165 // CancelShutdownAnimation() is called, if |shutdown_after_lock| is true. 166 void StartLockAnimationAndLockImmediately(bool shutdown_after_lock); 167 168 // Returns true if we have requested system to lock, but haven't received 169 // confirmation yet. 170 bool LockRequested(); 171 172 // Returns true if we are shutting down. 173 bool ShutdownRequested(); 174 175 // Returns true if we are within cancellable lock timeframe. 176 bool CanCancelLockAnimation(); 177 178 // Cancels locking and reverts lock animation. 179 void CancelLockAnimation(); 180 181 // Returns true if we are within cancellable shutdown timeframe. 182 bool CanCancelShutdownAnimation(); 183 184 // Cancels shutting down and reverts shutdown animation. 185 void CancelShutdownAnimation(); 186 187 // Called when Chrome gets a request to display the lock screen. 188 void OnStartingLock(); 189 190 // Displays the shutdown animation and requests shutdown when it's done. 191 void RequestShutdown(); 192 193 // Called when ScreenLocker is ready to close, but not yet destroyed. 194 // Can be used to display "hiding" animations on unlock. 195 // |callback| will be called when all animations are done. 196 void OnLockScreenHide(base::Closure& callback); 197 198 // Sets up the callback that should be called once lock animation is finished. 199 // Callback is guaranteed to be called once and then discarded. 200 void SetLockScreenDisplayedCallback(const base::Closure& callback); 201 202 // aura::WindowTreeHostObserver override: 203 virtual void OnHostCloseRequested(const aura::WindowTreeHost* host) OVERRIDE; 204 205 // ShellObserver overrides: 206 virtual void OnLoginStateChanged(user::LoginStatus status) OVERRIDE; 207 virtual void OnAppTerminating() OVERRIDE; 208 virtual void OnLockStateChanged(bool locked) OVERRIDE; 209 210 void set_animator_for_test(SessionStateAnimator* animator) { 211 animator_.reset(animator); 212 } 213 214 private: 215 friend class test::PowerButtonControllerTest; 216 friend class test::LockStateControllerTest; 217 218 struct UnlockedStateProperties { 219 bool background_is_hidden; 220 }; 221 222 // Reverts the pre-lock animation, reports the error. 223 void OnLockFailTimeout(); 224 225 // Starts timer for gap between lock and shutdown. 226 void StartLockToShutdownTimer(); 227 228 // Calls StartShutdownAnimation(). 229 void OnLockToShutdownTimeout(); 230 231 // Starts timer for undoable shutdown animation. 232 void StartPreShutdownAnimationTimer(); 233 234 // Calls StartRealShutdownTimer(). 235 void OnPreShutdownAnimationTimeout(); 236 237 // Starts timer for final shutdown animation. 238 // If |with_animation_time| is true, it will also include time of "fade to 239 // white" shutdown animation. 240 void StartRealShutdownTimer(bool with_animation_time); 241 242 // Requests that the machine be shut down. 243 void OnRealShutdownTimeout(); 244 245 // Starts shutdown animation that can be cancelled and starts pre-shutdown 246 // timer. 247 void StartCancellableShutdownAnimation(); 248 249 // If |request_lock_on_completion| is true, a lock request will be sent 250 // after the pre-lock animation completes. (The pre-lock animation is 251 // also displayed in response to already-in-progress lock requests; in 252 // these cases an additional lock request is undesirable.) 253 void StartImmediatePreLockAnimation(bool request_lock_on_completion); 254 void StartCancellablePreLockAnimation(); 255 void CancelPreLockAnimation(); 256 void StartPostLockAnimation(); 257 // This method calls |callback| when animation completes. 258 void StartUnlockAnimationBeforeUIDestroyed(base::Closure &callback); 259 void StartUnlockAnimationAfterUIDestroyed(); 260 261 // These methods are called when corresponding animation completes. 262 void LockAnimationCancelled(); 263 void PreLockAnimationFinished(bool request_lock); 264 void PostLockAnimationFinished(); 265 void UnlockAnimationAfterUIDestroyedFinished(); 266 267 // Stores properties of UI that have to be temporarily modified while locking. 268 void StoreUnlockedProperties(); 269 void RestoreUnlockedProperties(); 270 271 // Fades in background layer with |speed| if it was hidden in unlocked state. 272 void AnimateBackgroundAppearanceIfNecessary( 273 ash::SessionStateAnimator::AnimationSpeed speed, 274 SessionStateAnimator::AnimationSequence* animation_sequence); 275 276 // Fades out background layer with |speed| if it was hidden in unlocked state. 277 void AnimateBackgroundHidingIfNecessary( 278 ash::SessionStateAnimator::AnimationSpeed speed, 279 SessionStateAnimator::AnimationSequence* animation_sequence); 280 281 scoped_ptr<SessionStateAnimator> animator_; 282 283 scoped_ptr<LockStateControllerDelegate> delegate_; 284 285 ObserverList<LockStateObserver> observers_; 286 287 // The current login status, or original login status from before we locked. 288 user::LoginStatus login_status_; 289 290 // Current lock status. 291 bool system_is_locked_; 292 293 // Are we in the process of shutting the machine down? 294 bool shutting_down_; 295 296 // Indicates whether controller should proceed to (cancellable) shutdown after 297 // locking. 298 bool shutdown_after_lock_; 299 300 // Indicates that controller displays lock animation. 301 bool animating_lock_; 302 303 // Indicates that lock animation can be undone. 304 bool can_cancel_lock_animation_; 305 306 scoped_ptr<UnlockedStateProperties> unlocked_properties_; 307 308 // Started when we request that the screen be locked. When it fires, we 309 // assume that our request got dropped. 310 base::OneShotTimer<LockStateController> lock_fail_timer_; 311 312 // Started when the screen is locked while the power button is held. Adds a 313 // delay between the appearance of the lock screen and the beginning of the 314 // pre-shutdown animation. 315 base::OneShotTimer<LockStateController> lock_to_shutdown_timer_; 316 317 // Started when we begin displaying the pre-shutdown animation. When it 318 // fires, we start the shutdown animation and get ready to request shutdown. 319 base::OneShotTimer<LockStateController> pre_shutdown_timer_; 320 321 // Started when we display the shutdown animation. When it fires, we actually 322 // request shutdown. Gives the animation time to complete before Chrome, X, 323 // etc. are shut down. 324 base::OneShotTimer<LockStateController> real_shutdown_timer_; 325 326 base::Closure lock_screen_displayed_callback_; 327 328 base::WeakPtrFactory<LockStateController> weak_ptr_factory_; 329 330 DISALLOW_COPY_AND_ASSIGN(LockStateController); 331 }; 332 333 } // namespace ash 334 335 #endif // ASH_WM_LOCK_STATE_CONTROLLER_H_ 336