Updating trunk VERSION from 2139.0 to 2140.0
[chromium-blink-merge.git] / ash / wm / lock_state_controller.cc
blobebb0698c8f46c6b6262584883b4833de808d485d
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.
5 #include "ash/wm/lock_state_controller.h"
7 #include <algorithm>
9 #include "ash/accessibility_delegate.h"
10 #include "ash/ash_switches.h"
11 #include "ash/cancel_mode.h"
12 #include "ash/metrics/user_metrics_recorder.h"
13 #include "ash/shell.h"
14 #include "ash/shell_delegate.h"
15 #include "ash/shell_window_ids.h"
16 #include "ash/wm/session_state_animator.h"
17 #include "base/bind_helpers.h"
18 #include "base/command_line.h"
19 #include "base/strings/string_util.h"
20 #include "base/timer/timer.h"
21 #include "ui/aura/window_tree_host.h"
22 #include "ui/compositor/layer_animation_sequence.h"
23 #include "ui/compositor/scoped_layer_animation_settings.h"
24 #include "ui/views/controls/menu/menu_controller.h"
25 #include "ui/wm/core/compound_event_filter.h"
27 #if defined(OS_CHROMEOS)
28 #include "base/sys_info.h"
29 #include "media/audio/sounds/sounds_manager.h"
30 #endif
32 #if defined(OS_CHROMEOS)
33 using media::SoundsManager;
34 #endif
36 namespace ash {
38 namespace {
40 #if defined(OS_CHROMEOS)
41 const int kMaxShutdownSoundDurationMs = 1500;
42 #endif
44 aura::Window* GetBackground() {
45 aura::Window* root_window = Shell::GetPrimaryRootWindow();
46 return Shell::GetContainer(root_window,
47 kShellWindowId_DesktopBackgroundContainer);
50 bool IsBackgroundHidden() {
51 return !GetBackground()->IsVisible();
54 void ShowBackground() {
55 ui::ScopedLayerAnimationSettings settings(
56 GetBackground()->layer()->GetAnimator());
57 settings.SetTransitionDuration(base::TimeDelta());
58 GetBackground()->Show();
61 void HideBackground() {
62 ui::ScopedLayerAnimationSettings settings(
63 GetBackground()->layer()->GetAnimator());
64 settings.SetTransitionDuration(base::TimeDelta());
65 GetBackground()->Hide();
68 // This observer is intended to use in cases when some action has to be taken
69 // once some animation successfully completes (i.e. it was not aborted).
70 // Observer will count a number of sequences it is attached to, and a number of
71 // finished sequences (either Ended or Aborted). Once these two numbers are
72 // equal, observer will delete itself, calling callback passed to constructor if
73 // there were no aborted animations.
74 // This way it can be either used to wait for some animation to be finished in
75 // multiple layers, to wait once a sequence of animations is finished in one
76 // layer or the mixture of both.
77 class AnimationFinishedObserver : public ui::LayerAnimationObserver {
78 public:
79 explicit AnimationFinishedObserver(base::Closure &callback)
80 : callback_(callback),
81 sequences_attached_(0),
82 sequences_completed_(0),
83 paused_(false) {
86 // Pauses observer: no checks will be made while paused. It can be used when
87 // a sequence has some immediate animations in the beginning, and for
88 // animations that can be tested with flag that makes all animations
89 // immediate.
90 void Pause() {
91 paused_ = true;
94 // Unpauses observer. It does a check and calls callback if conditions are
95 // met.
96 void Unpause() {
97 if (!paused_)
98 return;
99 paused_ = false;
100 if (sequences_completed_ == sequences_attached_) {
101 callback_.Run();
102 delete this;
106 private:
107 virtual ~AnimationFinishedObserver() {
110 // LayerAnimationObserver implementation
111 virtual void OnLayerAnimationEnded(
112 ui::LayerAnimationSequence* sequence) OVERRIDE {
113 sequences_completed_++;
114 if ((sequences_completed_ == sequences_attached_) && !paused_) {
115 callback_.Run();
116 delete this;
120 virtual void OnLayerAnimationAborted(
121 ui::LayerAnimationSequence* sequence) OVERRIDE {
122 sequences_completed_++;
123 if ((sequences_completed_ == sequences_attached_) && !paused_)
124 delete this;
127 virtual void OnLayerAnimationScheduled(
128 ui::LayerAnimationSequence* sequence) OVERRIDE {
131 virtual void OnAttachedToSequence(
132 ui::LayerAnimationSequence* sequence) OVERRIDE {
133 LayerAnimationObserver::OnAttachedToSequence(sequence);
134 sequences_attached_++;
137 // Callback to be called.
138 base::Closure callback_;
140 // Number of sequences this observer was attached to.
141 int sequences_attached_;
143 // Number of sequences either ended or aborted.
144 int sequences_completed_;
146 bool paused_;
148 DISALLOW_COPY_AND_ASSIGN(AnimationFinishedObserver);
151 } // namespace
153 const int LockStateController::kLockTimeoutMs = 400;
154 const int LockStateController::kShutdownTimeoutMs = 400;
155 const int LockStateController::kLockFailTimeoutMs = 8000;
156 const int LockStateController::kLockToShutdownTimeoutMs = 150;
157 const int LockStateController::kShutdownRequestDelayMs = 50;
159 LockStateController::TestApi::TestApi(LockStateController* controller)
160 : controller_(controller) {
163 LockStateController::TestApi::~TestApi() {
166 LockStateController::LockStateController()
167 : animator_(new SessionStateAnimator()),
168 login_status_(user::LOGGED_IN_NONE),
169 system_is_locked_(false),
170 shutting_down_(false),
171 shutdown_after_lock_(false),
172 animating_lock_(false),
173 can_cancel_lock_animation_(false),
174 weak_ptr_factory_(this) {
175 Shell::GetPrimaryRootWindow()->GetHost()->AddObserver(this);
178 LockStateController::~LockStateController() {
179 Shell::GetPrimaryRootWindow()->GetHost()->RemoveObserver(this);
182 void LockStateController::SetDelegate(LockStateControllerDelegate* delegate) {
183 delegate_.reset(delegate);
186 void LockStateController::AddObserver(LockStateObserver* observer) {
187 observers_.AddObserver(observer);
190 void LockStateController::RemoveObserver(LockStateObserver* observer) {
191 observers_.RemoveObserver(observer);
194 bool LockStateController::HasObserver(LockStateObserver* observer) {
195 return observers_.HasObserver(observer);
198 void LockStateController::StartLockAnimation(
199 bool shutdown_after_lock) {
200 if (animating_lock_)
201 return;
202 shutdown_after_lock_ = shutdown_after_lock;
203 can_cancel_lock_animation_ = true;
205 StartCancellablePreLockAnimation();
208 void LockStateController::StartShutdownAnimation() {
209 StartCancellableShutdownAnimation();
212 void LockStateController::StartLockAnimationAndLockImmediately() {
213 if (animating_lock_)
214 return;
215 StartImmediatePreLockAnimation(true /* request_lock_on_completion */);
218 bool LockStateController::LockRequested() {
219 return lock_fail_timer_.IsRunning();
222 bool LockStateController::ShutdownRequested() {
223 return shutting_down_;
226 bool LockStateController::CanCancelLockAnimation() {
227 return can_cancel_lock_animation_;
230 void LockStateController::CancelLockAnimation() {
231 if (!CanCancelLockAnimation())
232 return;
233 shutdown_after_lock_ = false;
234 animating_lock_ = false;
235 CancelPreLockAnimation();
238 bool LockStateController::CanCancelShutdownAnimation() {
239 return pre_shutdown_timer_.IsRunning() ||
240 shutdown_after_lock_ ||
241 lock_to_shutdown_timer_.IsRunning();
244 void LockStateController::CancelShutdownAnimation() {
245 if (!CanCancelShutdownAnimation())
246 return;
247 if (lock_to_shutdown_timer_.IsRunning()) {
248 lock_to_shutdown_timer_.Stop();
249 return;
251 if (shutdown_after_lock_) {
252 shutdown_after_lock_ = false;
253 return;
256 animator_->StartGlobalAnimation(
257 SessionStateAnimator::ANIMATION_UNDO_GRAYSCALE_BRIGHTNESS,
258 SessionStateAnimator::ANIMATION_SPEED_REVERT_SHUTDOWN);
259 pre_shutdown_timer_.Stop();
262 void LockStateController::OnStartingLock() {
263 if (shutting_down_ || system_is_locked_)
264 return;
265 if (animating_lock_)
266 return;
267 StartImmediatePreLockAnimation(false /* request_lock_on_completion */);
270 void LockStateController::RequestShutdown() {
271 if (shutting_down_)
272 return;
274 shutting_down_ = true;
276 Shell* shell = ash::Shell::GetInstance();
277 shell->cursor_manager()->HideCursor();
278 shell->cursor_manager()->LockCursor();
280 animator_->StartGlobalAnimation(
281 SessionStateAnimator::ANIMATION_GRAYSCALE_BRIGHTNESS,
282 SessionStateAnimator::ANIMATION_SPEED_SHUTDOWN);
283 StartRealShutdownTimer(true);
286 void LockStateController::OnLockScreenHide(
287 base::Callback<void(void)>& callback) {
288 StartUnlockAnimationBeforeUIDestroyed(callback);
291 void LockStateController::SetLockScreenDisplayedCallback(
292 const base::Closure& callback) {
293 lock_screen_displayed_callback_ = callback;
296 void LockStateController::OnHostCloseRequested(
297 const aura::WindowTreeHost* host) {
298 Shell::GetInstance()->delegate()->Exit();
301 void LockStateController::OnLoginStateChanged(
302 user::LoginStatus status) {
303 if (status != user::LOGGED_IN_LOCKED)
304 login_status_ = status;
305 system_is_locked_ = (status == user::LOGGED_IN_LOCKED);
308 void LockStateController::OnAppTerminating() {
309 // If we hear that Chrome is exiting but didn't request it ourselves, all we
310 // can really hope for is that we'll have time to clear the screen.
311 // This is also the case when the user signs off.
312 if (!shutting_down_) {
313 shutting_down_ = true;
314 Shell* shell = ash::Shell::GetInstance();
315 shell->cursor_manager()->HideCursor();
316 shell->cursor_manager()->LockCursor();
317 animator_->StartAnimation(SessionStateAnimator::kAllContainersMask,
318 SessionStateAnimator::ANIMATION_HIDE_IMMEDIATELY,
319 SessionStateAnimator::ANIMATION_SPEED_IMMEDIATE);
323 void LockStateController::OnLockStateChanged(bool locked) {
324 VLOG(1) << "OnLockStateChanged " << locked;
325 if (shutting_down_ || (system_is_locked_ == locked))
326 return;
328 system_is_locked_ = locked;
330 if (locked) {
331 StartPostLockAnimation();
332 lock_fail_timer_.Stop();
333 } else {
334 StartUnlockAnimationAfterUIDestroyed();
338 void LockStateController::OnLockFailTimeout() {
339 DCHECK(!system_is_locked_);
340 CHECK(false) << "We can not be sure about the lock state. Crash and let the "
341 << "SessionManager end the session";
344 void LockStateController::StartLockToShutdownTimer() {
345 shutdown_after_lock_ = false;
346 lock_to_shutdown_timer_.Stop();
347 lock_to_shutdown_timer_.Start(
348 FROM_HERE,
349 base::TimeDelta::FromMilliseconds(kLockToShutdownTimeoutMs),
350 this, &LockStateController::OnLockToShutdownTimeout);
353 void LockStateController::OnLockToShutdownTimeout() {
354 DCHECK(system_is_locked_);
355 StartCancellableShutdownAnimation();
358 void LockStateController::StartPreShutdownAnimationTimer() {
359 pre_shutdown_timer_.Stop();
360 pre_shutdown_timer_.Start(
361 FROM_HERE,
362 animator_->GetDuration(SessionStateAnimator::ANIMATION_SPEED_SHUTDOWN),
363 this,
364 &LockStateController::OnPreShutdownAnimationTimeout);
367 void LockStateController::OnPreShutdownAnimationTimeout() {
368 VLOG(1) << "OnPreShutdownAnimationTimeout";
369 shutting_down_ = true;
371 Shell* shell = ash::Shell::GetInstance();
372 shell->cursor_manager()->HideCursor();
374 StartRealShutdownTimer(false);
377 void LockStateController::StartRealShutdownTimer(bool with_animation_time) {
378 base::TimeDelta duration =
379 base::TimeDelta::FromMilliseconds(kShutdownRequestDelayMs);
380 if (with_animation_time) {
381 duration +=
382 animator_->GetDuration(SessionStateAnimator::ANIMATION_SPEED_SHUTDOWN);
385 #if defined(OS_CHROMEOS)
386 const AccessibilityDelegate* const delegate =
387 Shell::GetInstance()->accessibility_delegate();
388 base::TimeDelta sound_duration = delegate->PlayShutdownSound();
389 sound_duration =
390 std::min(sound_duration,
391 base::TimeDelta::FromMilliseconds(kMaxShutdownSoundDurationMs));
392 duration = std::max(duration, sound_duration);
393 #endif
395 real_shutdown_timer_.Start(
396 FROM_HERE, duration, this, &LockStateController::OnRealShutdownTimeout);
399 void LockStateController::OnRealShutdownTimeout() {
400 VLOG(1) << "OnRealShutdownTimeout";
401 DCHECK(shutting_down_);
402 #if defined(OS_CHROMEOS)
403 if (!base::SysInfo::IsRunningOnChromeOS()) {
404 ShellDelegate* delegate = Shell::GetInstance()->delegate();
405 if (delegate) {
406 delegate->Exit();
407 return;
410 #endif
411 Shell::GetInstance()->metrics()->RecordUserMetricsAction(
412 UMA_ACCEL_SHUT_DOWN_POWER_BUTTON);
413 delegate_->RequestShutdown();
416 void LockStateController::StartCancellableShutdownAnimation() {
417 Shell* shell = ash::Shell::GetInstance();
418 // Hide cursor, but let it reappear if the mouse moves.
419 shell->cursor_manager()->HideCursor();
421 animator_->StartGlobalAnimation(
422 SessionStateAnimator::ANIMATION_GRAYSCALE_BRIGHTNESS,
423 SessionStateAnimator::ANIMATION_SPEED_SHUTDOWN);
424 StartPreShutdownAnimationTimer();
427 void LockStateController::StartImmediatePreLockAnimation(
428 bool request_lock_on_completion) {
429 VLOG(1) << "StartImmediatePreLockAnimation " << request_lock_on_completion;
430 animating_lock_ = true;
431 StoreUnlockedProperties();
433 base::Closure next_animation_starter =
434 base::Bind(&LockStateController::PreLockAnimationFinished,
435 weak_ptr_factory_.GetWeakPtr(),
436 request_lock_on_completion);
437 AnimationFinishedObserver* observer =
438 new AnimationFinishedObserver(next_animation_starter);
440 observer->Pause();
442 animator_->StartAnimationWithObserver(
443 SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS,
444 SessionStateAnimator::ANIMATION_LIFT,
445 SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS,
446 observer);
447 animator_->StartAnimationWithObserver(
448 SessionStateAnimator::LAUNCHER,
449 SessionStateAnimator::ANIMATION_FADE_OUT,
450 SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS,
451 observer);
452 // Hide the screen locker containers so we can raise them later.
453 animator_->StartAnimation(SessionStateAnimator::LOCK_SCREEN_CONTAINERS,
454 SessionStateAnimator::ANIMATION_HIDE_IMMEDIATELY,
455 SessionStateAnimator::ANIMATION_SPEED_IMMEDIATE);
456 AnimateBackgroundAppearanceIfNecessary(
457 SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS, observer);
459 observer->Unpause();
461 DispatchCancelMode();
462 FOR_EACH_OBSERVER(LockStateObserver, observers_,
463 OnLockStateEvent(LockStateObserver::EVENT_LOCK_ANIMATION_STARTED));
466 void LockStateController::StartCancellablePreLockAnimation() {
467 animating_lock_ = true;
468 StoreUnlockedProperties();
469 VLOG(1) << "StartCancellablePreLockAnimation";
470 base::Closure next_animation_starter =
471 base::Bind(&LockStateController::PreLockAnimationFinished,
472 weak_ptr_factory_.GetWeakPtr(),
473 true /* request_lock */);
474 AnimationFinishedObserver* observer =
475 new AnimationFinishedObserver(next_animation_starter);
477 observer->Pause();
479 animator_->StartAnimationWithObserver(
480 SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS,
481 SessionStateAnimator::ANIMATION_LIFT,
482 SessionStateAnimator::ANIMATION_SPEED_UNDOABLE,
483 observer);
484 animator_->StartAnimationWithObserver(
485 SessionStateAnimator::LAUNCHER,
486 SessionStateAnimator::ANIMATION_FADE_OUT,
487 SessionStateAnimator::ANIMATION_SPEED_UNDOABLE,
488 observer);
489 // Hide the screen locker containers so we can raise them later.
490 animator_->StartAnimation(SessionStateAnimator::LOCK_SCREEN_CONTAINERS,
491 SessionStateAnimator::ANIMATION_HIDE_IMMEDIATELY,
492 SessionStateAnimator::ANIMATION_SPEED_IMMEDIATE);
493 AnimateBackgroundAppearanceIfNecessary(
494 SessionStateAnimator::ANIMATION_SPEED_UNDOABLE, observer);
496 DispatchCancelMode();
497 FOR_EACH_OBSERVER(LockStateObserver, observers_,
498 OnLockStateEvent(LockStateObserver::EVENT_PRELOCK_ANIMATION_STARTED));
499 observer->Unpause();
502 void LockStateController::CancelPreLockAnimation() {
503 VLOG(1) << "CancelPreLockAnimation";
504 base::Closure next_animation_starter =
505 base::Bind(&LockStateController::LockAnimationCancelled,
506 weak_ptr_factory_.GetWeakPtr());
507 AnimationFinishedObserver* observer =
508 new AnimationFinishedObserver(next_animation_starter);
510 observer->Pause();
512 animator_->StartAnimationWithObserver(
513 SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS,
514 SessionStateAnimator::ANIMATION_UNDO_LIFT,
515 SessionStateAnimator::ANIMATION_SPEED_UNDO_MOVE_WINDOWS,
516 observer);
517 animator_->StartAnimationWithObserver(
518 SessionStateAnimator::LAUNCHER,
519 SessionStateAnimator::ANIMATION_FADE_IN,
520 SessionStateAnimator::ANIMATION_SPEED_UNDO_MOVE_WINDOWS,
521 observer);
522 AnimateBackgroundHidingIfNecessary(
523 SessionStateAnimator::ANIMATION_SPEED_UNDO_MOVE_WINDOWS, observer);
525 observer->Unpause();
528 void LockStateController::StartPostLockAnimation() {
529 VLOG(1) << "StartPostLockAnimation";
530 base::Closure next_animation_starter =
531 base::Bind(&LockStateController::PostLockAnimationFinished,
532 weak_ptr_factory_.GetWeakPtr());
534 AnimationFinishedObserver* observer =
535 new AnimationFinishedObserver(next_animation_starter);
537 observer->Pause();
538 animator_->StartAnimationWithObserver(
539 SessionStateAnimator::LOCK_SCREEN_CONTAINERS,
540 SessionStateAnimator::ANIMATION_RAISE_TO_SCREEN,
541 SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS,
542 observer);
543 observer->Unpause();
546 void LockStateController::StartUnlockAnimationBeforeUIDestroyed(
547 base::Closure& callback) {
548 VLOG(1) << "StartUnlockAnimationBeforeUIDestroyed";
549 animator_->StartAnimationWithCallback(
550 SessionStateAnimator::LOCK_SCREEN_CONTAINERS,
551 SessionStateAnimator::ANIMATION_LIFT,
552 SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS,
553 callback);
556 void LockStateController::StartUnlockAnimationAfterUIDestroyed() {
557 VLOG(1) << "StartUnlockAnimationAfterUIDestroyed";
558 base::Closure next_animation_starter =
559 base::Bind(&LockStateController::UnlockAnimationAfterUIDestroyedFinished,
560 weak_ptr_factory_.GetWeakPtr());
562 AnimationFinishedObserver* observer =
563 new AnimationFinishedObserver(next_animation_starter);
565 observer->Pause();
567 animator_->StartAnimationWithObserver(
568 SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS,
569 SessionStateAnimator::ANIMATION_DROP,
570 SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS,
571 observer);
572 animator_->StartAnimationWithObserver(
573 SessionStateAnimator::LAUNCHER,
574 SessionStateAnimator::ANIMATION_FADE_IN,
575 SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS,
576 observer);
577 AnimateBackgroundHidingIfNecessary(
578 SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS, observer);
579 observer->Unpause();
582 void LockStateController::LockAnimationCancelled() {
583 can_cancel_lock_animation_ = false;
584 RestoreUnlockedProperties();
587 void LockStateController::PreLockAnimationFinished(bool request_lock) {
588 VLOG(1) << "PreLockAnimationFinished";
589 can_cancel_lock_animation_ = false;
591 // Don't do anything (including starting the lock-fail timer) if the screen
592 // was already locked while the animation was going.
593 if (system_is_locked_) {
594 DCHECK(!request_lock) << "Got request to lock already-locked system "
595 << "at completion of pre-lock animation";
596 return;
599 if (request_lock) {
600 Shell::GetInstance()->metrics()->RecordUserMetricsAction(
601 shutdown_after_lock_ ?
602 UMA_ACCEL_LOCK_SCREEN_POWER_BUTTON :
603 UMA_ACCEL_LOCK_SCREEN_LOCK_BUTTON);
604 delegate_->RequestLockScreen();
607 base::TimeDelta timeout =
608 base::TimeDelta::FromMilliseconds(kLockFailTimeoutMs);
609 #if defined(OS_CHROMEOS)
610 // Increase lock timeout for slower hardware, see http://crbug.com/350628
611 const std::string board = base::SysInfo::GetLsbReleaseBoard();
612 if (board == "x86-mario" ||
613 StartsWithASCII(board, "x86-alex", true /* case_sensitive */) ||
614 StartsWithASCII(board, "x86-zgb", true /* case_sensitive */)) {
615 timeout *= 2;
617 #endif
618 lock_fail_timer_.Start(
619 FROM_HERE, timeout, this, &LockStateController::OnLockFailTimeout);
622 void LockStateController::PostLockAnimationFinished() {
623 animating_lock_ = false;
624 VLOG(1) << "PostLockAnimationFinished";
625 FOR_EACH_OBSERVER(LockStateObserver, observers_,
626 OnLockStateEvent(LockStateObserver::EVENT_LOCK_ANIMATION_FINISHED));
627 if (!lock_screen_displayed_callback_.is_null()) {
628 lock_screen_displayed_callback_.Run();
629 lock_screen_displayed_callback_.Reset();
631 CHECK(!views::MenuController::GetActiveInstance());
632 if (shutdown_after_lock_) {
633 shutdown_after_lock_ = false;
634 StartLockToShutdownTimer();
638 void LockStateController::UnlockAnimationAfterUIDestroyedFinished() {
639 RestoreUnlockedProperties();
642 void LockStateController::StoreUnlockedProperties() {
643 if (!unlocked_properties_) {
644 unlocked_properties_.reset(new UnlockedStateProperties());
645 unlocked_properties_->background_is_hidden = IsBackgroundHidden();
647 if (unlocked_properties_->background_is_hidden) {
648 // Hide background so that it can be animated later.
649 animator_->StartAnimation(SessionStateAnimator::DESKTOP_BACKGROUND,
650 SessionStateAnimator::ANIMATION_HIDE_IMMEDIATELY,
651 SessionStateAnimator::ANIMATION_SPEED_IMMEDIATE);
652 ShowBackground();
656 void LockStateController::RestoreUnlockedProperties() {
657 if (!unlocked_properties_)
658 return;
659 if (unlocked_properties_->background_is_hidden) {
660 HideBackground();
661 // Restore background visibility.
662 animator_->StartAnimation(SessionStateAnimator::DESKTOP_BACKGROUND,
663 SessionStateAnimator::ANIMATION_FADE_IN,
664 SessionStateAnimator::ANIMATION_SPEED_IMMEDIATE);
666 unlocked_properties_.reset();
669 void LockStateController::AnimateBackgroundAppearanceIfNecessary(
670 SessionStateAnimator::AnimationSpeed speed,
671 ui::LayerAnimationObserver* observer) {
672 if (unlocked_properties_.get() &&
673 unlocked_properties_->background_is_hidden) {
674 animator_->StartAnimationWithObserver(
675 SessionStateAnimator::DESKTOP_BACKGROUND,
676 SessionStateAnimator::ANIMATION_FADE_IN,
677 speed,
678 observer);
682 void LockStateController::AnimateBackgroundHidingIfNecessary(
683 SessionStateAnimator::AnimationSpeed speed,
684 ui::LayerAnimationObserver* observer) {
685 if (unlocked_properties_.get() &&
686 unlocked_properties_->background_is_hidden) {
687 animator_->StartAnimationWithObserver(
688 SessionStateAnimator::DESKTOP_BACKGROUND,
689 SessionStateAnimator::ANIMATION_FADE_OUT,
690 speed,
691 observer);
695 } // namespace ash