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 20namespace gfx { 21class Rect; 22class Size; 23} 24 25namespace ui { 26class Layer; 27} 28 29namespace ash { 30 31namespace test { 32class LockStateControllerTest; 33class PowerButtonControllerTest; 34} 35 36// Performs system-related functions on behalf of LockStateController. 37class 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. 72class 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