Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright (c) 2012 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 #include "ash/wm/session_state_controller.h" | |
| 6 | |
| 7 #include "ash/ash_switches.h" | |
| 8 #include "ash/shell.h" | |
| 9 #include "ash/shell_delegate.h" | |
| 10 #include "ash/shell_window_ids.h" | |
| 11 #include "ash/wm/session_state_animator.h" | |
| 12 #include "base/command_line.h" | |
| 13 #include "ui/aura/root_window.h" | |
| 14 #include "ui/aura/shared/compound_event_filter.h" | |
| 15 | |
| 16 #if defined(OS_CHROMEOS) | |
| 17 #include "base/chromeos/chromeos_version.h" | |
| 18 #endif | |
| 19 | |
| 20 | |
| 21 namespace ash { | |
| 22 | |
| 23 SessionStateController::TestApi::TestApi(SessionStateController* controller) | |
| 24 : controller_(controller) { | |
| 25 } | |
| 26 | |
| 27 SessionStateController::TestApi::~TestApi() { | |
| 28 } | |
| 29 | |
| 30 SessionStateController::SessionStateController() | |
| 31 : login_status_(user::LOGGED_IN_NONE), | |
| 32 unlocked_login_status_(user::LOGGED_IN_NONE), | |
| 33 shutting_down_(false), | |
| 34 shutdown_after_lock_(false), | |
| 35 animator_(new internal::SessionStateAnimator()) { | |
| 36 Shell::GetPrimaryRootWindow()->AddRootWindowObserver(this); | |
| 37 } | |
| 38 | |
| 39 SessionStateController::~SessionStateController() { | |
| 40 Shell::GetPrimaryRootWindow()->RemoveRootWindowObserver(this); | |
| 41 } | |
| 42 | |
| 43 void SessionStateController::OnLoginStateChanged(user::LoginStatus status) { | |
| 44 login_status_ = status; | |
| 45 unlocked_login_status_ = user::LOGGED_IN_NONE; | |
| 46 } | |
| 47 | |
| 48 void SessionStateController::OnAppTerminating() { | |
| 49 // If we hear that Chrome is exiting but didn't request it ourselves, all we | |
| 50 // can really hope for is that we'll have time to clear the screen. | |
| 51 if (!shutting_down_) { | |
| 52 shutting_down_ = true; | |
| 53 Shell* shell = ash::Shell::GetInstance(); | |
| 54 shell->env_filter()->set_cursor_hidden_by_filter(false); | |
| 55 shell->cursor_manager()->ShowCursor(false); | |
| 56 animator_->ShowBlackLayer(); | |
| 57 animator_->StartAnimation( | |
| 58 internal::SessionStateAnimator::kAllContainersMask, | |
| 59 internal::SessionStateAnimator::ANIMATION_HIDE); | |
| 60 } | |
| 61 } | |
| 62 | |
| 63 void SessionStateController::OnLockStateChanged(bool locked) { | |
| 64 if (shutting_down_ || (login_status_ == user::LOGGED_IN_LOCKED) == locked) | |
| 65 return; | |
| 66 | |
| 67 if (!locked && login_status_ == user::LOGGED_IN_LOCKED) { | |
| 68 login_status_ = unlocked_login_status_; | |
| 69 unlocked_login_status_ = user::LOGGED_IN_NONE; | |
| 70 } else { | |
| 71 unlocked_login_status_ = login_status_; | |
| 72 login_status_ = user::LOGGED_IN_LOCKED; | |
| 73 } | |
| 74 | |
| 75 if (locked) { | |
| 76 animator_->StartAnimation( | |
| 77 internal::SessionStateAnimator::LOCK_SCREEN_CONTAINERS, | |
| 78 internal::SessionStateAnimator::ANIMATION_FADE_IN); | |
| 79 lock_timer_.Stop(); | |
| 80 lock_fail_timer_.Stop(); | |
| 81 | |
| 82 if (shutdown_after_lock_) { | |
| 83 shutdown_after_lock_ = false; | |
| 84 StartLockToShutdownTimer(); | |
| 85 } | |
| 86 } else { | |
| 87 animator_->StartAnimation( | |
| 88 internal::SessionStateAnimator::DESKTOP_BACKGROUND | | |
| 89 internal::SessionStateAnimator::LAUNCHER | | |
| 90 internal::SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS, | |
| 91 internal::SessionStateAnimator::ANIMATION_RESTORE); | |
| 92 animator_->DropBlackLayer(); | |
| 93 } | |
| 94 } | |
| 95 | |
| 96 void SessionStateController::OnStartingLock() { | |
| 97 if (shutting_down_ || login_status_ == user::LOGGED_IN_LOCKED) | |
| 98 return; | |
| 99 | |
| 100 // Ensure that the black layer is visible -- if the screen was locked via | |
| 101 // the wrench menu, we won't have already shown the black background | |
| 102 // as part of the slow-close animation. | |
| 103 animator_->ShowBlackLayer(); | |
| 104 | |
| 105 animator_->StartAnimation( | |
| 106 internal::SessionStateAnimator::LAUNCHER, | |
| 107 internal::SessionStateAnimator::ANIMATION_HIDE); | |
| 108 | |
| 109 animator_->StartAnimation( | |
| 110 internal::SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS, | |
| 111 internal::SessionStateAnimator::ANIMATION_FAST_CLOSE); | |
| 112 | |
| 113 // Hide the screen locker containers so we can make them fade in later. | |
| 114 animator_->StartAnimation( | |
| 115 internal::SessionStateAnimator::LOCK_SCREEN_CONTAINERS, | |
| 116 internal::SessionStateAnimator::ANIMATION_HIDE); | |
| 117 } | |
| 118 | |
| 119 void SessionStateController::StartLockAnimationAndLockImmediately() { | |
| 120 animator_->ShowBlackLayer(); | |
| 121 animator_->StartAnimation( | |
| 122 internal::SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS, | |
| 123 internal::SessionStateAnimator::ANIMATION_SLOW_CLOSE); | |
| 124 OnLockTimeout(); | |
| 125 } | |
| 126 | |
| 127 void SessionStateController::ShutdownImmediately() { | |
| 128 animator_->ShowBlackLayer(); | |
| 129 if (!shutting_down_) | |
| 130 RequestShutdownImpl(); | |
| 131 } | |
| 132 | |
| 133 void SessionStateController::StartLockAnimation() { | |
| 134 shutdown_after_lock_ = true; | |
| 135 | |
| 136 animator_->ShowBlackLayer(); | |
| 137 animator_->StartAnimation( | |
| 138 internal::SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS, | |
| 139 internal::SessionStateAnimator::ANIMATION_SLOW_CLOSE); | |
| 140 StartLockTimer(); | |
| 141 } | |
| 142 | |
| 143 void SessionStateController::StartShutdownAnimation() { | |
| 144 animator_->ShowBlackLayer(); | |
| 145 animator_->StartAnimation( | |
| 146 internal::SessionStateAnimator::kAllContainersMask, | |
| 147 internal::SessionStateAnimator::ANIMATION_SLOW_CLOSE); | |
| 148 | |
| 149 StartPreShutdownAnimationTimer(); | |
| 150 } | |
| 151 | |
| 152 bool SessionStateController::IsEligibleForLock() { | |
| 153 return LoggedInAsNonGuest() && !IsLocked(); | |
| 154 } | |
| 155 | |
| 156 bool SessionStateController::IsLocked() { | |
| 157 return login_status_ == user::LOGGED_IN_LOCKED; | |
| 158 } | |
| 159 | |
| 160 bool SessionStateController::LockRequested() { | |
| 161 return lock_fail_timer_.IsRunning(); | |
| 162 } | |
| 163 | |
| 164 bool SessionStateController::IsShuttingDown() { | |
| 165 return shutting_down_; | |
| 166 } | |
| 167 | |
| 168 bool SessionStateController::CanCancelLockAnimation() { | |
| 169 return lock_timer_.IsRunning(); | |
| 170 } | |
| 171 | |
| 172 void SessionStateController::CancelLockAnimation() { | |
| 173 if (!CanCancelLockAnimation()) | |
| 174 return; | |
| 175 shutdown_after_lock_ = false; | |
| 176 animator_->StartAnimation( | |
| 177 internal::SessionStateAnimator::kAllContainersMask, | |
| 178 internal::SessionStateAnimator::ANIMATION_UNDO_SLOW_CLOSE); | |
| 179 animator_->ScheduleDropBlackLayer(); | |
| 180 lock_timer_.Stop(); | |
| 181 } | |
| 182 | |
| 183 void SessionStateController::CancelLockWithOtherAnimation() { | |
| 184 if (!CanCancelLockAnimation()) | |
| 185 return; | |
| 186 shutdown_after_lock_ = false; | |
| 187 animator_->StartAnimation( | |
| 188 internal::SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS, | |
| 189 internal::SessionStateAnimator::ANIMATION_UNDO_SLOW_CLOSE); | |
| 190 animator_->ScheduleDropBlackLayer(); | |
| 191 lock_timer_.Stop(); | |
| 192 } | |
| 193 | |
| 194 bool SessionStateController::CanCancelShutdownAnimation() { | |
| 195 return pre_shutdown_timer_.IsRunning() || | |
| 196 lock_to_shutdown_timer_.IsRunning(); | |
| 197 } | |
| 198 | |
| 199 void SessionStateController::CancelShutdownAnimation() { | |
| 200 if (!CanCancelShutdownAnimation()) | |
| 201 return; | |
| 202 if (lock_to_shutdown_timer_.IsRunning()) { | |
| 203 lock_to_shutdown_timer_.Stop(); | |
| 204 return; | |
| 205 } | |
| 206 | |
| 207 if (login_status_ == user::LOGGED_IN_LOCKED) { | |
| 208 // If we've already started shutdown transition at lock screen | |
| 209 // desktop background needs to be restored immediately. | |
| 210 animator_->StartAnimation( | |
| 211 internal::SessionStateAnimator::DESKTOP_BACKGROUND, | |
| 212 internal::SessionStateAnimator::ANIMATION_RESTORE); | |
| 213 animator_->StartAnimation( | |
| 214 internal::SessionStateAnimator::kAllLockScreenContainersMask, | |
| 215 internal::SessionStateAnimator::ANIMATION_UNDO_SLOW_CLOSE); | |
| 216 animator_->ScheduleDropBlackLayer(); | |
| 217 } else { | |
| 218 animator_->StartAnimation( | |
| 219 internal::SessionStateAnimator::kAllContainersMask, | |
| 220 internal::SessionStateAnimator::ANIMATION_UNDO_SLOW_CLOSE); | |
| 221 animator_->ScheduleDropBlackLayer(); | |
| 222 } | |
| 223 pre_shutdown_timer_.Stop(); | |
| 224 } | |
| 225 | |
| 226 void SessionStateController::RequestShutdown() { | |
| 227 if (!shutting_down_) | |
| 228 RequestShutdownImpl(); | |
| 229 } | |
| 230 | |
| 231 | |
|
Daniel Erat
2012/10/11 16:26:56
nit: remove extra blank line
Denis Kuznetsov (DE-MUC)
2012/10/15 11:49:58
Done.
| |
| 232 void SessionStateController::RequestShutdownImpl() { | |
| 233 DCHECK(!shutting_down_); | |
| 234 shutting_down_ = true; | |
| 235 | |
| 236 Shell* shell = ash::Shell::GetInstance(); | |
| 237 shell->env_filter()->set_cursor_hidden_by_filter(false); | |
| 238 shell->cursor_manager()->ShowCursor(false); | |
| 239 | |
| 240 animator_->ShowBlackLayer(); | |
| 241 if (login_status_ != user::LOGGED_IN_NONE) { | |
| 242 // Hide the other containers before starting the animation. | |
| 243 // ANIMATION_FAST_CLOSE will make the screen locker windows partially | |
| 244 // transparent, and we don't want the other windows to show through. | |
| 245 animator_->StartAnimation( | |
| 246 internal::SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS | | |
| 247 internal::SessionStateAnimator::LAUNCHER, | |
| 248 internal::SessionStateAnimator::ANIMATION_HIDE); | |
| 249 animator_->StartAnimation( | |
| 250 internal::SessionStateAnimator::kAllLockScreenContainersMask, | |
| 251 internal::SessionStateAnimator::ANIMATION_FAST_CLOSE); | |
| 252 } else { | |
| 253 animator_->StartAnimation( | |
| 254 internal::SessionStateAnimator::kAllContainersMask, | |
| 255 internal::SessionStateAnimator::ANIMATION_FAST_CLOSE); | |
| 256 } | |
| 257 StartRealShutdownTimer(); | |
| 258 } | |
| 259 | |
| 260 void SessionStateController::OnRootWindowHostCloseRequested( | |
| 261 const aura::RootWindow*) { | |
| 262 if(Shell::GetInstance() && Shell::GetInstance()->delegate()) | |
| 263 Shell::GetInstance()->delegate()->Exit(); | |
| 264 } | |
| 265 | |
| 266 bool SessionStateController::LoggedInAsNonGuest() const { | |
| 267 if (login_status_ == user::LOGGED_IN_NONE) | |
| 268 return false; | |
| 269 if (login_status_ == user::LOGGED_IN_GUEST) | |
| 270 return false; | |
| 271 // TODO(mukai): think about kiosk mode. | |
| 272 return true; | |
| 273 } | |
| 274 | |
| 275 // ----------- Timer stuff. | |
|
Daniel Erat
2012/10/11 16:26:56
nit: delete this
Denis Kuznetsov (DE-MUC)
2012/10/15 11:49:58
Done.
| |
| 276 | |
| 277 void SessionStateController::StartLockTimer() { | |
| 278 lock_timer_.Stop(); | |
| 279 lock_timer_.Start(FROM_HERE, | |
| 280 base::TimeDelta::FromMilliseconds( | |
| 281 internal::kSlowCloseAnimMs), | |
| 282 this, &SessionStateController::OnLockTimeout); | |
| 283 } | |
| 284 | |
| 285 void SessionStateController::OnLockTimeout() { | |
| 286 delegate_->RequestLockScreen(); | |
| 287 lock_fail_timer_.Start( | |
| 288 FROM_HERE, | |
| 289 base::TimeDelta::FromMilliseconds(internal::kLockFailTimeoutMs), | |
| 290 this, &SessionStateController::OnLockFailTimeout); | |
| 291 } | |
| 292 | |
| 293 void SessionStateController::OnLockFailTimeout() { | |
| 294 DCHECK_NE(login_status_, user::LOGGED_IN_LOCKED); | |
| 295 // Undo lock animation. | |
| 296 animator_->StartAnimation( | |
| 297 internal::SessionStateAnimator::LAUNCHER | | |
| 298 internal::SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS, | |
| 299 internal::SessionStateAnimator::ANIMATION_RESTORE); | |
| 300 animator_->DropBlackLayer(); | |
| 301 } | |
| 302 | |
| 303 void SessionStateController::StartLockToShutdownTimer() { | |
| 304 shutdown_after_lock_ = false; | |
| 305 lock_to_shutdown_timer_.Stop(); | |
| 306 lock_to_shutdown_timer_.Start( | |
| 307 FROM_HERE, | |
| 308 base::TimeDelta::FromMilliseconds(internal::kLockToShutdownTimeoutMs), | |
| 309 this, &SessionStateController::OnLockToShutdownTimeout); | |
| 310 } | |
| 311 | |
| 312 | |
| 313 void SessionStateController::OnLockToShutdownTimeout() { | |
| 314 DCHECK_EQ(login_status_, user::LOGGED_IN_LOCKED); | |
| 315 StartShutdownAnimation(); | |
| 316 } | |
| 317 | |
| 318 void SessionStateController::StartPreShutdownAnimationTimer() { | |
| 319 pre_shutdown_timer_.Stop(); | |
| 320 pre_shutdown_timer_.Start( | |
| 321 FROM_HERE, | |
| 322 base::TimeDelta::FromMilliseconds(internal::kShutdownTimeoutMs), | |
| 323 this, &SessionStateController::OnPreShutdownAnimationTimeout); | |
| 324 } | |
| 325 | |
| 326 void SessionStateController::OnPreShutdownAnimationTimeout() { | |
| 327 if (!shutting_down_) | |
| 328 RequestShutdownImpl(); | |
| 329 } | |
| 330 | |
| 331 void SessionStateController::StartRealShutdownTimer() { | |
| 332 real_shutdown_timer_.Start( | |
| 333 FROM_HERE, | |
| 334 base::TimeDelta::FromMilliseconds( | |
| 335 internal::kFastCloseAnimMs + internal::kShutdownRequestDelayMs), | |
| 336 this, &SessionStateController::OnRealShutdownTimeout); | |
| 337 } | |
| 338 | |
| 339 void SessionStateController::OnRealShutdownTimeout() { | |
| 340 DCHECK(shutting_down_); | |
| 341 #if defined(OS_CHROMEOS) | |
| 342 if (!base::chromeos::IsRunningOnChromeOS()) { | |
| 343 ShellDelegate* delegate = Shell::GetInstance()->delegate(); | |
| 344 if (delegate) | |
| 345 delegate->Exit(); | |
| 346 } | |
| 347 #endif | |
| 348 delegate_->RequestShutdown(); | |
| 349 } | |
| 350 | |
| 351 } // namespace ash | |
| OLD | NEW |