| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "ash/wm/power_button_controller.h" | 5 #include "ash/wm/power_button_controller.h" |
| 6 | 6 |
| 7 #include "ash/ash_switches.h" | 7 #include "ash/ash_switches.h" |
| 8 #include "ash/shell.h" | 8 #include "ash/shell.h" |
| 9 #include "ash/shell_delegate.h" | 9 #include "ash/shell_delegate.h" |
| 10 #include "ash/shell_window_ids.h" | 10 #include "ash/shell_window_ids.h" |
| 11 #include "ash/wm/cursor_manager.h" | 11 #include "ash/wm/session_state_animator.h" |
| 12 #include "base/command_line.h" | 12 #include "base/command_line.h" |
| 13 #include "base/logging.h" | |
| 14 #include "base/time.h" | |
| 15 #include "third_party/skia/include/core/SkColor.h" | |
| 16 #include "ui/aura/env.h" | |
| 17 #include "ui/aura/root_window.h" | 13 #include "ui/aura/root_window.h" |
| 18 #include "ui/aura/shared/compound_event_filter.h" | |
| 19 #include "ui/aura/window.h" | |
| 20 #include "ui/compositor/layer.h" | |
| 21 #include "ui/compositor/layer_animation_element.h" | |
| 22 #include "ui/compositor/layer_animation_sequence.h" | |
| 23 #include "ui/compositor/layer_animator.h" | |
| 24 #include "ui/gfx/canvas.h" | |
| 25 #include "ui/gfx/rect.h" | |
| 26 #include "ui/gfx/size.h" | |
| 27 #include "ui/gfx/transform.h" | |
| 28 | 14 |
| 29 namespace ash { | 15 namespace ash { |
| 30 | 16 |
| 31 namespace { | 17 namespace { |
| 32 | 18 |
| 33 // Amount of time that the power button needs to be held before we lock the | 19 // Amount of time that the power button needs to be held before we lock the |
| 34 // screen. | 20 // screen. |
| 35 const int kLockTimeoutMs = 400; | 21 const int kLockTimeoutMs = 400; |
| 36 | 22 |
| 37 // Amount of time that the power button needs to be held before we shut down. | 23 // Amount of time that the power button needs to be held before we shut down. |
| (...skipping 14 matching lines...) Expand all Loading... |
| 52 | 38 |
| 53 // Amount of time taken to scale the snapshot of the screen back to its original | 39 // Amount of time taken to scale the snapshot of the screen back to its original |
| 54 // size when the button is released. | 40 // size when the button is released. |
| 55 const int kUndoSlowCloseAnimMs = 100; | 41 const int kUndoSlowCloseAnimMs = 100; |
| 56 | 42 |
| 57 // Amount of time taken to scale the snapshot down to a point in the center of | 43 // Amount of time taken to scale the snapshot down to a point in the center of |
| 58 // the screen once the screen has been locked or we've been notified that the | 44 // the screen once the screen has been locked or we've been notified that the |
| 59 // system is shutting down. | 45 // system is shutting down. |
| 60 const int kFastCloseAnimMs = 150; | 46 const int kFastCloseAnimMs = 150; |
| 61 | 47 |
| 62 // Amount of time taken to make the lock window fade in when the screen is | |
| 63 // locked. | |
| 64 const int kLockFadeInAnimMs = 200; | |
| 65 | |
| 66 // Additional time (beyond kFastCloseAnimMs) to wait after starting the | 48 // Additional time (beyond kFastCloseAnimMs) to wait after starting the |
| 67 // fast-close shutdown animation before actually requesting shutdown, to give | 49 // fast-close shutdown animation before actually requesting shutdown, to give |
| 68 // the animation time to finish. | 50 // the animation time to finish. |
| 69 const int kShutdownRequestDelayMs = 50; | 51 const int kShutdownRequestDelayMs = 50; |
| 70 | 52 |
| 71 // Slightly-smaller size that we scale the screen down to for the pre-lock and | |
| 72 // pre-shutdown states. | |
| 73 const float kSlowCloseSizeRatio = 0.95f; | |
| 74 | |
| 75 // Returns the transform that should be applied to containers for the slow-close | |
| 76 // animation. | |
| 77 ui::Transform GetSlowCloseTransform() { | |
| 78 gfx::Size root_size = Shell::GetPrimaryRootWindow()->bounds().size(); | |
| 79 ui::Transform transform; | |
| 80 transform.SetScale(kSlowCloseSizeRatio, kSlowCloseSizeRatio); | |
| 81 transform.ConcatTranslate( | |
| 82 floor(0.5 * (1.0 - kSlowCloseSizeRatio) * root_size.width() + 0.5), | |
| 83 floor(0.5 * (1.0 - kSlowCloseSizeRatio) * root_size.height() + 0.5)); | |
| 84 return transform; | |
| 85 } | |
| 86 | |
| 87 // Returns the transform that should be applied to containers for the fast-close | |
| 88 // animation. | |
| 89 ui::Transform GetFastCloseTransform() { | |
| 90 gfx::Size root_size = Shell::GetPrimaryRootWindow()->bounds().size(); | |
| 91 ui::Transform transform; | |
| 92 transform.SetScale(0.0, 0.0); | |
| 93 transform.ConcatTranslate(floor(0.5 * root_size.width() + 0.5), | |
| 94 floor(0.5 * root_size.height() + 0.5)); | |
| 95 return transform; | |
| 96 } | |
| 97 | |
| 98 // Slowly shrinks |window| to a slightly-smaller size. | |
| 99 void StartSlowCloseAnimationForWindow(aura::Window* window) { | |
| 100 ui::LayerAnimator* animator = window->layer()->GetAnimator(); | |
| 101 animator->set_preemption_strategy( | |
| 102 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); | |
| 103 animator->StartAnimation( | |
| 104 new ui::LayerAnimationSequence( | |
| 105 ui::LayerAnimationElement::CreateTransformElement( | |
| 106 GetSlowCloseTransform(), | |
| 107 base::TimeDelta::FromMilliseconds(kSlowCloseAnimMs)))); | |
| 108 } | |
| 109 | |
| 110 // Quickly undoes the effects of the slow-close animation on |window|. | |
| 111 void StartUndoSlowCloseAnimationForWindow(aura::Window* window) { | |
| 112 ui::LayerAnimator* animator = window->layer()->GetAnimator(); | |
| 113 animator->set_preemption_strategy( | |
| 114 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); | |
| 115 animator->StartAnimation( | |
| 116 new ui::LayerAnimationSequence( | |
| 117 ui::LayerAnimationElement::CreateTransformElement( | |
| 118 ui::Transform(), | |
| 119 base::TimeDelta::FromMilliseconds(kUndoSlowCloseAnimMs)))); | |
| 120 } | |
| 121 | |
| 122 // Quickly shrinks |window| down to a point in the center of the screen and | |
| 123 // fades it out to 0 opacity. | |
| 124 void StartFastCloseAnimationForWindow(aura::Window* window) { | |
| 125 ui::LayerAnimator* animator = window->layer()->GetAnimator(); | |
| 126 animator->set_preemption_strategy( | |
| 127 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); | |
| 128 animator->StartAnimation( | |
| 129 new ui::LayerAnimationSequence( | |
| 130 ui::LayerAnimationElement::CreateTransformElement( | |
| 131 GetFastCloseTransform(), | |
| 132 base::TimeDelta::FromMilliseconds(kFastCloseAnimMs)))); | |
| 133 animator->StartAnimation( | |
| 134 new ui::LayerAnimationSequence( | |
| 135 ui::LayerAnimationElement::CreateOpacityElement( | |
| 136 0.0, base::TimeDelta::FromMilliseconds(kFastCloseAnimMs)))); | |
| 137 } | |
| 138 | |
| 139 // Fades |window| in to full opacity. | |
| 140 void FadeInWindow(aura::Window* window) { | |
| 141 ui::LayerAnimator* animator = window->layer()->GetAnimator(); | |
| 142 animator->set_preemption_strategy( | |
| 143 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); | |
| 144 animator->StartAnimation( | |
| 145 new ui::LayerAnimationSequence( | |
| 146 ui::LayerAnimationElement::CreateOpacityElement( | |
| 147 1.0, base::TimeDelta::FromMilliseconds(kLockFadeInAnimMs)))); | |
| 148 } | |
| 149 | |
| 150 // Makes |window| fully transparent instantaneously. | |
| 151 void HideWindow(aura::Window* window) { | |
| 152 window->layer()->SetOpacity(0.0); | |
| 153 } | |
| 154 | |
| 155 // Restores |window| to its original position and scale and full opacity | |
| 156 // instantaneously. | |
| 157 void RestoreWindow(aura::Window* window) { | |
| 158 window->layer()->SetTransform(ui::Transform()); | |
| 159 window->layer()->SetOpacity(1.0); | |
| 160 } | |
| 161 | |
| 162 // Fills |containers| with the containers described by |container_mask|. | |
| 163 void GetContainers(int container_mask, aura::Window::Windows* containers) { | |
| 164 aura::RootWindow* root_window = Shell::GetPrimaryRootWindow(); | |
| 165 containers->clear(); | |
| 166 | |
| 167 if (container_mask & PowerButtonController::DESKTOP_BACKGROUND) { | |
| 168 containers->push_back(Shell::GetContainer( | |
| 169 root_window, | |
| 170 internal::kShellWindowId_DesktopBackgroundContainer)); | |
| 171 } | |
| 172 if (container_mask & PowerButtonController::NON_LOCK_SCREEN_CONTAINERS) { | |
| 173 containers->push_back(Shell::GetContainer( | |
| 174 root_window, | |
| 175 internal::kShellWindowId_NonLockScreenContainersContainer)); | |
| 176 } | |
| 177 if (container_mask & PowerButtonController::LOCK_SCREEN_BACKGROUND) { | |
| 178 containers->push_back(Shell::GetContainer( | |
| 179 root_window, | |
| 180 internal::kShellWindowId_LockScreenBackgroundContainer)); | |
| 181 } | |
| 182 if (container_mask & PowerButtonController::LOCK_SCREEN_CONTAINERS) { | |
| 183 containers->push_back(Shell::GetContainer( | |
| 184 root_window, | |
| 185 internal::kShellWindowId_LockScreenContainersContainer)); | |
| 186 } | |
| 187 if (container_mask & PowerButtonController::LOCK_SCREEN_RELATED_CONTAINERS) { | |
| 188 containers->push_back(Shell::GetContainer( | |
| 189 root_window, | |
| 190 internal::kShellWindowId_LockScreenRelatedContainersContainer)); | |
| 191 } | |
| 192 } | |
| 193 | |
| 194 // Apply animation |type| to all containers described by |container_mask|. | |
| 195 void StartAnimation(int container_mask, | |
| 196 PowerButtonController::AnimationType type) { | |
| 197 aura::Window::Windows containers; | |
| 198 GetContainers(container_mask, &containers); | |
| 199 | |
| 200 for (aura::Window::Windows::const_iterator it = containers.begin(); | |
| 201 it != containers.end(); ++it) { | |
| 202 aura::Window* window = *it; | |
| 203 switch (type) { | |
| 204 case PowerButtonController::ANIMATION_SLOW_CLOSE: | |
| 205 StartSlowCloseAnimationForWindow(window); | |
| 206 break; | |
| 207 case PowerButtonController::ANIMATION_UNDO_SLOW_CLOSE: | |
| 208 StartUndoSlowCloseAnimationForWindow(window); | |
| 209 break; | |
| 210 case PowerButtonController::ANIMATION_FAST_CLOSE: | |
| 211 StartFastCloseAnimationForWindow(window); | |
| 212 break; | |
| 213 case PowerButtonController::ANIMATION_FADE_IN: | |
| 214 FadeInWindow(window); | |
| 215 break; | |
| 216 case PowerButtonController::ANIMATION_HIDE: | |
| 217 HideWindow(window); | |
| 218 break; | |
| 219 case PowerButtonController::ANIMATION_RESTORE: | |
| 220 RestoreWindow(window); | |
| 221 break; | |
| 222 default: | |
| 223 NOTREACHED() << "Unhandled animation type " << type; | |
| 224 } | |
| 225 } | |
| 226 } | |
| 227 | |
| 228 } // namespace | 53 } // namespace |
| 229 | 54 |
| 230 bool PowerButtonController::TestApi::ContainersAreAnimated( | |
| 231 int container_mask, AnimationType type) const { | |
| 232 aura::Window::Windows containers; | |
| 233 GetContainers(container_mask, &containers); | |
| 234 for (aura::Window::Windows::const_iterator it = containers.begin(); | |
| 235 it != containers.end(); ++it) { | |
| 236 aura::Window* window = *it; | |
| 237 ui::Layer* layer = window->layer(); | |
| 238 | |
| 239 switch (type) { | |
| 240 case PowerButtonController::ANIMATION_SLOW_CLOSE: | |
| 241 if (layer->GetTargetTransform() != GetSlowCloseTransform()) | |
| 242 return false; | |
| 243 break; | |
| 244 case PowerButtonController::ANIMATION_UNDO_SLOW_CLOSE: | |
| 245 if (layer->GetTargetTransform() != ui::Transform()) | |
| 246 return false; | |
| 247 break; | |
| 248 case PowerButtonController::ANIMATION_FAST_CLOSE: | |
| 249 if (layer->GetTargetTransform() != GetFastCloseTransform() || | |
| 250 layer->GetTargetOpacity() > 0.0001) | |
| 251 return false; | |
| 252 break; | |
| 253 case PowerButtonController::ANIMATION_FADE_IN: | |
| 254 if (layer->GetTargetOpacity() < 0.9999) | |
| 255 return false; | |
| 256 break; | |
| 257 case PowerButtonController::ANIMATION_HIDE: | |
| 258 if (layer->GetTargetOpacity() > 0.0001) | |
| 259 return false; | |
| 260 break; | |
| 261 case PowerButtonController::ANIMATION_RESTORE: | |
| 262 if (layer->opacity() < 0.9999 || layer->transform() != ui::Transform()) | |
| 263 return false; | |
| 264 break; | |
| 265 default: | |
| 266 NOTREACHED() << "Unhandled animation type " << type; | |
| 267 return false; | |
| 268 } | |
| 269 } | |
| 270 return true; | |
| 271 } | |
| 272 | |
| 273 bool PowerButtonController::TestApi::BlackLayerIsVisible() const { | |
| 274 return controller_->black_layer_.get() && | |
| 275 controller_->black_layer_->visible(); | |
| 276 } | |
| 277 | |
| 278 gfx::Rect PowerButtonController::TestApi::GetBlackLayerBounds() const { | |
| 279 ui::Layer* layer = controller_->black_layer_.get(); | |
| 280 return layer ? layer->bounds() : gfx::Rect(); | |
| 281 } | |
| 282 | |
| 283 // static | |
| 284 int PowerButtonController::GetAllContainersMask() { | |
| 285 return PowerButtonController::DESKTOP_BACKGROUND | | |
| 286 PowerButtonController::NON_LOCK_SCREEN_CONTAINERS | | |
| 287 GetAllLockScreenContainersMask(); | |
| 288 } | |
| 289 | |
| 290 // static | |
| 291 int PowerButtonController::GetAllLockScreenContainersMask() { | |
| 292 return PowerButtonController::LOCK_SCREEN_BACKGROUND | | |
| 293 PowerButtonController::LOCK_SCREEN_CONTAINERS | | |
| 294 PowerButtonController::LOCK_SCREEN_RELATED_CONTAINERS; | |
| 295 } | |
| 296 | |
| 297 PowerButtonController::PowerButtonController() | 55 PowerButtonController::PowerButtonController() |
| 298 : login_status_(user::LOGGED_IN_NONE), | 56 : login_status_(user::LOGGED_IN_NONE), |
| 299 unlocked_login_status_(user::LOGGED_IN_NONE), | 57 unlocked_login_status_(user::LOGGED_IN_NONE), |
| 300 power_button_down_(false), | 58 power_button_down_(false), |
| 301 lock_button_down_(false), | 59 lock_button_down_(false), |
| 302 screen_is_off_(false), | 60 screen_is_off_(false), |
| 303 shutting_down_(false), | 61 shutting_down_(false), |
| 304 has_legacy_power_button_( | 62 has_legacy_power_button_( |
| 305 CommandLine::ForCurrentProcess()->HasSwitch( | 63 CommandLine::ForCurrentProcess()->HasSwitch( |
| 306 switches::kAuraLegacyPowerButton)) { | 64 switches::kAuraLegacyPowerButton)), |
| 65 animator_(new SessionStateAnimator()) { |
| 307 Shell::GetPrimaryRootWindow()->AddRootWindowObserver(this); | 66 Shell::GetPrimaryRootWindow()->AddRootWindowObserver(this); |
| 308 } | 67 } |
| 309 | 68 |
| 310 PowerButtonController::~PowerButtonController() { | 69 PowerButtonController::~PowerButtonController() { |
| 311 Shell::GetPrimaryRootWindow()->RemoveRootWindowObserver(this); | 70 Shell::GetPrimaryRootWindow()->RemoveRootWindowObserver(this); |
| 312 } | 71 } |
| 313 | 72 |
| 314 void PowerButtonController::OnLoginStateChanged(user::LoginStatus status) { | 73 void PowerButtonController::OnLoginStateChanged(user::LoginStatus status) { |
| 315 login_status_ = status; | 74 login_status_ = status; |
| 316 unlocked_login_status_ = user::LOGGED_IN_NONE; | 75 unlocked_login_status_ = user::LOGGED_IN_NONE; |
| 317 } | 76 } |
| 318 | 77 |
| 319 void PowerButtonController::OnAppTerminating() { | 78 void PowerButtonController::OnAppTerminating() { |
| 320 // If we hear that Chrome is exiting but didn't request it ourselves, all we | 79 // If we hear that Chrome is exiting but didn't request it ourselves, all we |
| 321 // can really hope for is that we'll have time to clear the screen. | 80 // can really hope for is that we'll have time to clear the screen. |
| 322 if (!shutting_down_) { | 81 if (!shutting_down_) { |
| 323 shutting_down_ = true; | 82 shutting_down_ = true; |
| 324 Shell* shell = ash::Shell::GetInstance(); | 83 Shell* shell = ash::Shell::GetInstance(); |
| 325 shell->cursor_manager()->ShowCursor(false); | 84 shell->cursor_manager()->ShowCursor(false); |
| 326 ShowBlackLayer(); | 85 animator_->ShowBlackLayer(); |
| 327 StartAnimation(GetAllContainersMask(), ANIMATION_HIDE); | 86 animator_->StartAnimation(SessionStateAnimator::GetAllContainersMask(), |
| 87 SessionStateAnimator::ANIMATION_HIDE); |
| 328 } | 88 } |
| 329 } | 89 } |
| 330 | 90 |
| 331 void PowerButtonController::OnLockStateChanged(bool locked) { | 91 void PowerButtonController::OnLockStateChanged(bool locked) { |
| 332 if (shutting_down_ || (login_status_ == user::LOGGED_IN_LOCKED) == locked) | 92 if (shutting_down_ || (login_status_ == user::LOGGED_IN_LOCKED) == locked) |
| 333 return; | 93 return; |
| 334 | 94 |
| 335 if (!locked && login_status_ == user::LOGGED_IN_LOCKED) { | 95 if (!locked && login_status_ == user::LOGGED_IN_LOCKED) { |
| 336 login_status_ = unlocked_login_status_; | 96 login_status_ = unlocked_login_status_; |
| 337 unlocked_login_status_ = user::LOGGED_IN_NONE; | 97 unlocked_login_status_ = user::LOGGED_IN_NONE; |
| 338 } else { | 98 } else { |
| 339 unlocked_login_status_ = login_status_; | 99 unlocked_login_status_ = login_status_; |
| 340 login_status_ = user::LOGGED_IN_LOCKED; | 100 login_status_ = user::LOGGED_IN_LOCKED; |
| 341 } | 101 } |
| 342 | 102 |
| 343 if (locked) { | 103 if (locked) { |
| 344 StartAnimation(LOCK_SCREEN_CONTAINERS, ANIMATION_FADE_IN); | 104 animator_->StartAnimation(SessionStateAnimator::LOCK_SCREEN_CONTAINERS, |
| 105 SessionStateAnimator::ANIMATION_FADE_IN); |
| 345 lock_timer_.Stop(); | 106 lock_timer_.Stop(); |
| 346 lock_fail_timer_.Stop(); | 107 lock_fail_timer_.Stop(); |
| 347 | 108 |
| 348 if (!has_legacy_power_button_ && power_button_down_) { | 109 if (!has_legacy_power_button_ && power_button_down_) { |
| 349 lock_to_shutdown_timer_.Stop(); | 110 lock_to_shutdown_timer_.Stop(); |
| 350 lock_to_shutdown_timer_.Start( | 111 lock_to_shutdown_timer_.Start( |
| 351 FROM_HERE, | 112 FROM_HERE, |
| 352 base::TimeDelta::FromMilliseconds(kLockToShutdownTimeoutMs), | 113 base::TimeDelta::FromMilliseconds(kLockToShutdownTimeoutMs), |
| 353 this, &PowerButtonController::OnLockToShutdownTimeout); | 114 this, &PowerButtonController::OnLockToShutdownTimeout); |
| 354 } | 115 } |
| 355 } else { | 116 } else { |
| 356 StartAnimation(DESKTOP_BACKGROUND | NON_LOCK_SCREEN_CONTAINERS, | 117 animator_->StartAnimation(SessionStateAnimator::DESKTOP_BACKGROUND | |
| 357 ANIMATION_RESTORE); | 118 SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS, |
| 358 HideBlackLayer(); | 119 SessionStateAnimator::ANIMATION_RESTORE); |
| 120 animator_->DropBlackLayer(); |
| 359 } | 121 } |
| 360 } | 122 } |
| 361 | 123 |
| 362 void PowerButtonController::OnScreenBrightnessChanged(double percent) { | 124 void PowerButtonController::OnScreenBrightnessChanged(double percent) { |
| 363 screen_is_off_ = percent <= 0.001; | 125 screen_is_off_ = percent <= 0.001; |
| 364 } | 126 } |
| 365 | 127 |
| 366 void PowerButtonController::OnStartingLock() { | 128 void PowerButtonController::OnStartingLock() { |
| 367 if (shutting_down_ || login_status_ == user::LOGGED_IN_LOCKED) | 129 if (shutting_down_ || login_status_ == user::LOGGED_IN_LOCKED) |
| 368 return; | 130 return; |
| 369 | 131 |
| 370 // Ensure that the black layer is visible -- if the screen was locked via | 132 // Ensure that the black layer is visible -- if the screen was locked via |
| 371 // the wrench menu, we won't have already shown the black background | 133 // the wrench menu, we won't have already shown the black background |
| 372 // as part of the slow-close animation. | 134 // as part of the slow-close animation. |
| 373 ShowBlackLayer(); | 135 animator_->ShowBlackLayer(); |
| 374 | 136 |
| 375 StartAnimation(NON_LOCK_SCREEN_CONTAINERS, ANIMATION_FAST_CLOSE); | 137 animator_->StartAnimation(SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS, |
| 138 SessionStateAnimator::ANIMATION_FAST_CLOSE); |
| 376 | 139 |
| 377 // Hide the screen locker containers so we can make them fade in later. | 140 // Hide the screen locker containers so we can make them fade in later. |
| 378 StartAnimation(LOCK_SCREEN_CONTAINERS, ANIMATION_HIDE); | 141 animator_->StartAnimation(SessionStateAnimator::LOCK_SCREEN_CONTAINERS, |
| 142 SessionStateAnimator::ANIMATION_HIDE); |
| 379 } | 143 } |
| 380 | 144 |
| 381 void PowerButtonController::OnPowerButtonEvent( | 145 void PowerButtonController::OnPowerButtonEvent( |
| 382 bool down, const base::TimeTicks& timestamp) { | 146 bool down, const base::TimeTicks& timestamp) { |
| 383 power_button_down_ = down; | 147 power_button_down_ = down; |
| 384 | 148 |
| 385 if (shutting_down_) | 149 if (shutting_down_) |
| 386 return; | 150 return; |
| 387 | 151 |
| 388 // Avoid starting the lock/shutdown sequence if the power button is pressed | 152 // Avoid starting the lock/shutdown sequence if the power button is pressed |
| 389 // while the screen is off (http://crbug.com/128451). | 153 // while the screen is off (http://crbug.com/128451). |
| 390 if (screen_is_off_) | 154 if (screen_is_off_) |
| 391 return; | 155 return; |
| 392 | 156 |
| 393 if (has_legacy_power_button_) { | 157 if (has_legacy_power_button_) { |
| 394 // If power button releases won't get reported correctly because we're not | 158 // If power button releases won't get reported correctly because we're not |
| 395 // running on official hardware, just lock the screen or shut down | 159 // running on official hardware, just lock the screen or shut down |
| 396 // immediately. | 160 // immediately. |
| 397 if (down) { | 161 if (down) { |
| 398 ShowBlackLayer(); | 162 animator_->ShowBlackLayer(); |
| 399 if (LoggedInAsNonGuest() && login_status_ != user::LOGGED_IN_LOCKED) { | 163 if (LoggedInAsNonGuest() && login_status_ != user::LOGGED_IN_LOCKED) { |
| 400 StartAnimation(NON_LOCK_SCREEN_CONTAINERS, ANIMATION_SLOW_CLOSE); | 164 animator_->StartAnimation( |
| 165 SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS, |
| 166 SessionStateAnimator::ANIMATION_SLOW_CLOSE); |
| 401 OnLockTimeout(); | 167 OnLockTimeout(); |
| 402 } else { | 168 } else { |
| 403 OnShutdownTimeout(); | 169 OnShutdownTimeout(); |
| 404 } | 170 } |
| 405 } | 171 } |
| 406 } else { // !has_legacy_power_button_ | 172 } else { // !has_legacy_power_button_ |
| 407 if (down) { | 173 if (down) { |
| 408 // If we already have a pending request to lock the screen, wait. | 174 // If we already have a pending request to lock the screen, wait. |
| 409 if (lock_fail_timer_.IsRunning()) | 175 if (lock_fail_timer_.IsRunning()) |
| 410 return; | 176 return; |
| 411 | 177 |
| 412 if (LoggedInAsNonGuest() && login_status_ != user::LOGGED_IN_LOCKED) | 178 if (LoggedInAsNonGuest() && login_status_ != user::LOGGED_IN_LOCKED) |
| 413 StartLockTimer(); | 179 StartLockTimer(); |
| 414 else | 180 else |
| 415 StartShutdownTimer(); | 181 StartShutdownTimer(); |
| 416 } else { // Button is up. | 182 } else { // Button is up. |
| 417 if (lock_timer_.IsRunning() || shutdown_timer_.IsRunning()) { | 183 if (lock_timer_.IsRunning() || shutdown_timer_.IsRunning()) { |
| 418 if (login_status_ == user::LOGGED_IN_LOCKED) { | 184 if (login_status_ == user::LOGGED_IN_LOCKED) { |
| 419 // If we've already started shutdown transition at lock screen | 185 // If we've already started shutdown transition at lock screen |
| 420 // desktop background needs to be restored immediately. | 186 // desktop background needs to be restored immediately. |
| 421 StartAnimation(DESKTOP_BACKGROUND, ANIMATION_RESTORE); | 187 animator_->StartAnimation(SessionStateAnimator::DESKTOP_BACKGROUND, |
| 188 SessionStateAnimator::ANIMATION_RESTORE); |
| 422 } | 189 } |
| 423 StartAnimation( | 190 animator_->StartAnimation( |
| 424 (login_status_ == user::LOGGED_IN_LOCKED) ? | 191 (login_status_ == user::LOGGED_IN_LOCKED) ? |
| 425 GetAllLockScreenContainersMask() : GetAllContainersMask(), | 192 SessionStateAnimator::GetAllLockScreenContainersMask() : |
| 426 ANIMATION_UNDO_SLOW_CLOSE); | 193 SessionStateAnimator::GetAllContainersMask(), |
| 194 SessionStateAnimator::ANIMATION_UNDO_SLOW_CLOSE); |
| 427 } | 195 } |
| 428 | 196 |
| 429 // Drop the black layer after the undo animation finishes. | 197 // Drop the black layer after the undo animation finishes. |
| 430 if (lock_timer_.IsRunning() || | 198 if (lock_timer_.IsRunning() || |
| 431 (shutdown_timer_.IsRunning() && !LoggedInAsNonGuest())) { | 199 (shutdown_timer_.IsRunning() && !LoggedInAsNonGuest())) { |
| 432 hide_black_layer_timer_.Stop(); | 200 animator_->ScheduleDropBlackLayer(); |
| 433 hide_black_layer_timer_.Start( | |
| 434 FROM_HERE, | |
| 435 base::TimeDelta::FromMilliseconds(kUndoSlowCloseAnimMs), | |
| 436 this, &PowerButtonController::HideBlackLayer); | |
| 437 } | 201 } |
| 438 | 202 |
| 439 lock_timer_.Stop(); | 203 lock_timer_.Stop(); |
| 440 shutdown_timer_.Stop(); | 204 shutdown_timer_.Stop(); |
| 441 lock_to_shutdown_timer_.Stop(); | 205 lock_to_shutdown_timer_.Stop(); |
| 442 } | 206 } |
| 443 } | 207 } |
| 444 } | 208 } |
| 445 | 209 |
| 446 void PowerButtonController::OnLockButtonEvent( | 210 void PowerButtonController::OnLockButtonEvent( |
| 447 bool down, const base::TimeTicks& timestamp) { | 211 bool down, const base::TimeTicks& timestamp) { |
| 448 lock_button_down_ = down; | 212 lock_button_down_ = down; |
| 449 | 213 |
| 450 if (shutting_down_ || !LoggedInAsNonGuest()) | 214 if (shutting_down_ || !LoggedInAsNonGuest()) |
| 451 return; | 215 return; |
| 452 | 216 |
| 453 // Bail if we're already locked or are in the process of locking. Also give | 217 // Bail if we're already locked or are in the process of locking. Also give |
| 454 // the power button precedence over the lock button (we don't expect both | 218 // the power button precedence over the lock button (we don't expect both |
| 455 // buttons to be present, so this is just making sure that we don't do | 219 // buttons to be present, so this is just making sure that we don't do |
| 456 // something completely stupid if that assumption changes later). | 220 // something completely stupid if that assumption changes later). |
| 457 if (login_status_ == user::LOGGED_IN_LOCKED || | 221 if (login_status_ == user::LOGGED_IN_LOCKED || |
| 458 lock_fail_timer_.IsRunning() || power_button_down_) | 222 lock_fail_timer_.IsRunning() || power_button_down_) |
| 459 return; | 223 return; |
| 460 | 224 |
| 461 if (down) { | 225 if (down) { |
| 462 StartLockTimer(); | 226 StartLockTimer(); |
| 463 } else { | 227 } else { |
| 464 if (lock_timer_.IsRunning()) { | 228 if (lock_timer_.IsRunning()) { |
| 465 StartAnimation(NON_LOCK_SCREEN_CONTAINERS, ANIMATION_UNDO_SLOW_CLOSE); | 229 animator_->StartAnimation( |
| 466 hide_black_layer_timer_.Stop(); | 230 SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS, |
| 467 hide_black_layer_timer_.Start( | 231 SessionStateAnimator::ANIMATION_UNDO_SLOW_CLOSE); |
| 468 FROM_HERE, | 232 animator_->ScheduleDropBlackLayer(); |
| 469 base::TimeDelta::FromMilliseconds(kUndoSlowCloseAnimMs), | |
| 470 this, &PowerButtonController::HideBlackLayer); | |
| 471 lock_timer_.Stop(); | 233 lock_timer_.Stop(); |
| 472 } | 234 } |
| 473 } | 235 } |
| 474 } | 236 } |
| 475 | 237 |
| 476 void PowerButtonController::RequestShutdown() { | 238 void PowerButtonController::RequestShutdown() { |
| 477 if (!shutting_down_) | 239 if (!shutting_down_) |
| 478 StartShutdownAnimationAndRequestShutdown(); | 240 StartShutdownAnimationAndRequestShutdown(); |
| 479 } | 241 } |
| 480 | 242 |
| 481 void PowerButtonController::OnRootWindowResized(const aura::RootWindow* root, | |
| 482 const gfx::Size& new_size) { | |
| 483 if (black_layer_.get()) | |
| 484 black_layer_->SetBounds(gfx::Rect(root->bounds().size())); | |
| 485 } | |
| 486 | |
| 487 void PowerButtonController::OnRootWindowHostCloseRequested( | 243 void PowerButtonController::OnRootWindowHostCloseRequested( |
| 488 const aura::RootWindow*) { | 244 const aura::RootWindow*) { |
| 489 if(Shell::GetInstance() && Shell::GetInstance()->delegate()) | 245 if(Shell::GetInstance() && Shell::GetInstance()->delegate()) |
| 490 Shell::GetInstance()->delegate()->Exit(); | 246 Shell::GetInstance()->delegate()->Exit(); |
| 491 } | 247 } |
| 492 | 248 |
| 493 bool PowerButtonController::LoggedInAsNonGuest() const { | 249 bool PowerButtonController::LoggedInAsNonGuest() const { |
| 494 if (login_status_ == user::LOGGED_IN_NONE) | 250 if (login_status_ == user::LOGGED_IN_NONE) |
| 495 return false; | 251 return false; |
| 496 if (login_status_ == user::LOGGED_IN_GUEST) | 252 if (login_status_ == user::LOGGED_IN_GUEST) |
| 497 return false; | 253 return false; |
| 498 // TODO(mukai): think about kiosk mode. | 254 // TODO(mukai): think about kiosk mode. |
| 499 return true; | 255 return true; |
| 500 } | 256 } |
| 501 | 257 |
| 502 void PowerButtonController::OnLockTimeout() { | 258 void PowerButtonController::OnLockTimeout() { |
| 503 delegate_->RequestLockScreen(); | 259 delegate_->RequestLockScreen(); |
| 504 lock_fail_timer_.Start( | 260 lock_fail_timer_.Start( |
| 505 FROM_HERE, | 261 FROM_HERE, |
| 506 base::TimeDelta::FromMilliseconds(kLockFailTimeoutMs), | 262 base::TimeDelta::FromMilliseconds(kLockFailTimeoutMs), |
| 507 this, &PowerButtonController::OnLockFailTimeout); | 263 this, &PowerButtonController::OnLockFailTimeout); |
| 508 } | 264 } |
| 509 | 265 |
| 510 void PowerButtonController::OnLockFailTimeout() { | 266 void PowerButtonController::OnLockFailTimeout() { |
| 511 DCHECK_NE(login_status_, user::LOGGED_IN_LOCKED); | 267 DCHECK_NE(login_status_, user::LOGGED_IN_LOCKED); |
| 512 LOG(ERROR) << "Screen lock request timed out"; | 268 LOG(ERROR) << "Screen lock request timed out"; |
| 513 StartAnimation(NON_LOCK_SCREEN_CONTAINERS, ANIMATION_RESTORE); | 269 animator_->StartAnimation(SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS, |
| 514 HideBlackLayer(); | 270 SessionStateAnimator::ANIMATION_RESTORE); |
| 271 animator_->DropBlackLayer(); |
| 515 } | 272 } |
| 516 | 273 |
| 517 void PowerButtonController::OnLockToShutdownTimeout() { | 274 void PowerButtonController::OnLockToShutdownTimeout() { |
| 518 DCHECK_EQ(login_status_, user::LOGGED_IN_LOCKED); | 275 DCHECK_EQ(login_status_, user::LOGGED_IN_LOCKED); |
| 519 StartShutdownTimer(); | 276 StartShutdownTimer(); |
| 520 } | 277 } |
| 521 | 278 |
| 522 void PowerButtonController::OnShutdownTimeout() { | 279 void PowerButtonController::OnShutdownTimeout() { |
| 523 if (!shutting_down_) | 280 if (!shutting_down_) |
| 524 StartShutdownAnimationAndRequestShutdown(); | 281 StartShutdownAnimationAndRequestShutdown(); |
| 525 } | 282 } |
| 526 | 283 |
| 527 void PowerButtonController::OnRealShutdownTimeout() { | 284 void PowerButtonController::OnRealShutdownTimeout() { |
| 528 DCHECK(shutting_down_); | 285 DCHECK(shutting_down_); |
| 529 delegate_->RequestShutdown(); | 286 delegate_->RequestShutdown(); |
| 530 } | 287 } |
| 531 | 288 |
| 532 void PowerButtonController::StartLockTimer() { | 289 void PowerButtonController::StartLockTimer() { |
| 533 ShowBlackLayer(); | 290 animator_->ShowBlackLayer(); |
| 534 StartAnimation(NON_LOCK_SCREEN_CONTAINERS, ANIMATION_SLOW_CLOSE); | 291 animator_->StartAnimation(SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS, |
| 292 SessionStateAnimator::ANIMATION_SLOW_CLOSE); |
| 535 lock_timer_.Stop(); | 293 lock_timer_.Stop(); |
| 536 lock_timer_.Start(FROM_HERE, | 294 lock_timer_.Start(FROM_HERE, |
| 537 base::TimeDelta::FromMilliseconds(kSlowCloseAnimMs), | 295 base::TimeDelta::FromMilliseconds(kSlowCloseAnimMs), |
| 538 this, &PowerButtonController::OnLockTimeout); | 296 this, &PowerButtonController::OnLockTimeout); |
| 539 } | 297 } |
| 540 | 298 |
| 541 void PowerButtonController::StartShutdownTimer() { | 299 void PowerButtonController::StartShutdownTimer() { |
| 542 ShowBlackLayer(); | 300 animator_->ShowBlackLayer(); |
| 543 StartAnimation(GetAllContainersMask(), ANIMATION_SLOW_CLOSE); | 301 animator_->StartAnimation(SessionStateAnimator::GetAllContainersMask(), |
| 302 SessionStateAnimator::ANIMATION_SLOW_CLOSE); |
| 544 shutdown_timer_.Stop(); | 303 shutdown_timer_.Stop(); |
| 545 shutdown_timer_.Start( | 304 shutdown_timer_.Start( |
| 546 FROM_HERE, | 305 FROM_HERE, |
| 547 base::TimeDelta::FromMilliseconds(kShutdownTimeoutMs), | 306 base::TimeDelta::FromMilliseconds(kShutdownTimeoutMs), |
| 548 this, &PowerButtonController::OnShutdownTimeout); | 307 this, &PowerButtonController::OnShutdownTimeout); |
| 549 } | 308 } |
| 550 | 309 |
| 551 void PowerButtonController::StartShutdownAnimationAndRequestShutdown() { | 310 void PowerButtonController::StartShutdownAnimationAndRequestShutdown() { |
| 552 DCHECK(!shutting_down_); | 311 DCHECK(!shutting_down_); |
| 553 shutting_down_ = true; | 312 shutting_down_ = true; |
| 554 | 313 |
| 555 Shell* shell = ash::Shell::GetInstance(); | 314 Shell* shell = ash::Shell::GetInstance(); |
| 556 shell->cursor_manager()->ShowCursor(false); | 315 shell->cursor_manager()->ShowCursor(false); |
| 557 | 316 |
| 558 ShowBlackLayer(); | 317 animator_->ShowBlackLayer(); |
| 559 if (login_status_ != user::LOGGED_IN_NONE) { | 318 if (login_status_ != user::LOGGED_IN_NONE) { |
| 560 // Hide the other containers before starting the animation. | 319 // Hide the other containers before starting the animation. |
| 561 // ANIMATION_FAST_CLOSE will make the screen locker windows partially | 320 // ANIMATION_FAST_CLOSE will make the screen locker windows partially |
| 562 // transparent, and we don't want the other windows to show through. | 321 // transparent, and we don't want the other windows to show through. |
| 563 StartAnimation(NON_LOCK_SCREEN_CONTAINERS, ANIMATION_HIDE); | 322 animator_->StartAnimation(SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS, |
| 564 StartAnimation(GetAllLockScreenContainersMask(), ANIMATION_FAST_CLOSE); | 323 SessionStateAnimator::ANIMATION_HIDE); |
| 324 animator_->StartAnimation( |
| 325 SessionStateAnimator::GetAllLockScreenContainersMask(), |
| 326 SessionStateAnimator::ANIMATION_FAST_CLOSE); |
| 565 } else { | 327 } else { |
| 566 StartAnimation(GetAllContainersMask(), ANIMATION_FAST_CLOSE); | 328 animator_->StartAnimation(SessionStateAnimator::GetAllContainersMask(), |
| 329 SessionStateAnimator::ANIMATION_FAST_CLOSE); |
| 567 } | 330 } |
| 568 | 331 |
| 569 real_shutdown_timer_.Start( | 332 real_shutdown_timer_.Start( |
| 570 FROM_HERE, | 333 FROM_HERE, |
| 571 base::TimeDelta::FromMilliseconds( | 334 base::TimeDelta::FromMilliseconds( |
| 572 kFastCloseAnimMs + kShutdownRequestDelayMs), | 335 kFastCloseAnimMs + kShutdownRequestDelayMs), |
| 573 this, &PowerButtonController::OnRealShutdownTimeout); | 336 this, &PowerButtonController::OnRealShutdownTimeout); |
| 574 } | 337 } |
| 575 | 338 |
| 576 void PowerButtonController::ShowBlackLayer() { | |
| 577 if (hide_black_layer_timer_.IsRunning()) | |
| 578 hide_black_layer_timer_.Stop(); | |
| 579 | |
| 580 if (!black_layer_.get()) { | |
| 581 black_layer_.reset(new ui::Layer(ui::LAYER_SOLID_COLOR)); | |
| 582 black_layer_->SetColor(SK_ColorBLACK); | |
| 583 | |
| 584 ui::Layer* root_layer = Shell::GetPrimaryRootWindow()->layer(); | |
| 585 black_layer_->SetBounds(root_layer->bounds()); | |
| 586 root_layer->Add(black_layer_.get()); | |
| 587 root_layer->StackAtBottom(black_layer_.get()); | |
| 588 } | |
| 589 black_layer_->SetVisible(true); | |
| 590 } | |
| 591 | |
| 592 void PowerButtonController::HideBlackLayer() { | |
| 593 black_layer_.reset(); | |
| 594 } | |
| 595 | |
| 596 } // namespace ash | 339 } // namespace ash |
| OLD | NEW |