Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / ash / wm / lock_state_controller.cc
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 #include "ash/wm/lock_state_controller.h"
6
7 #include <algorithm>
8
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/timer/timer.h"
20 #include "ui/aura/root_window.h"
21 #include "ui/compositor/layer_animation_sequence.h"
22 #include "ui/compositor/scoped_layer_animation_settings.h"
23 #include "ui/views/corewm/compound_event_filter.h"
24
25 #if defined(OS_CHROMEOS)
26 #include "base/sys_info.h"
27 #include "media/audio/sounds/sounds_manager.h"
28 #endif
29
30 #if defined(OS_CHROMEOS)
31 using media::SoundsManager;
32 #endif
33
34 namespace ash {
35
36 namespace {
37
38 const int kMaxShutdownSoundDurationMs = 1500;
39
40 aura::Window* GetBackground() {
41   aura::Window* root_window = Shell::GetPrimaryRootWindow();
42   return Shell::GetContainer(root_window,
43       internal::kShellWindowId_DesktopBackgroundContainer);
44 }
45
46 bool IsBackgroundHidden() {
47   return !GetBackground()->IsVisible();
48 }
49
50 void ShowBackground() {
51   ui::ScopedLayerAnimationSettings settings(
52       GetBackground()->layer()->GetAnimator());
53   settings.SetTransitionDuration(base::TimeDelta());
54   GetBackground()->Show();
55 }
56
57 void HideBackground() {
58   ui::ScopedLayerAnimationSettings settings(
59       GetBackground()->layer()->GetAnimator());
60   settings.SetTransitionDuration(base::TimeDelta());
61   GetBackground()->Hide();
62 }
63
64 // This observer is intended to use in cases when some action has to be taken
65 // once some animation successfully completes (i.e. it was not aborted).
66 // Observer will count a number of sequences it is attached to, and a number of
67 // finished sequences (either Ended or Aborted). Once these two numbers are
68 // equal, observer will delete itself, calling callback passed to constructor if
69 // there were no aborted animations.
70 // This way it can be either used to wait for some animation to be finished in
71 // multiple layers, to wait once a sequence of animations is finished in one
72 // layer or the mixture of both.
73 class AnimationFinishedObserver : public ui::LayerAnimationObserver {
74  public:
75   explicit AnimationFinishedObserver(base::Closure &callback)
76       : callback_(callback),
77         sequences_attached_(0),
78         sequences_completed_(0),
79         paused_(false) {
80   }
81
82   // Pauses observer: no checks will be made while paused. It can be used when
83   // a sequence has some immediate animations in the beginning, and for
84   // animations that can be tested with flag that makes all animations
85   // immediate.
86   void Pause() {
87     paused_ = true;
88   }
89
90   // Unpauses observer. It does a check and calls callback if conditions are
91   // met.
92   void Unpause() {
93     if (!paused_)
94       return;
95     paused_ = false;
96     if (sequences_completed_ == sequences_attached_) {
97       callback_.Run();
98       delete this;
99     }
100   }
101
102  private:
103   virtual ~AnimationFinishedObserver() {
104   }
105
106   // LayerAnimationObserver implementation
107   virtual void OnLayerAnimationEnded(
108       ui::LayerAnimationSequence* sequence) OVERRIDE {
109     sequences_completed_++;
110     if ((sequences_completed_ == sequences_attached_) && !paused_) {
111       callback_.Run();
112       delete this;
113     }
114   }
115
116   virtual void OnLayerAnimationAborted(
117       ui::LayerAnimationSequence* sequence) OVERRIDE {
118     sequences_completed_++;
119     if ((sequences_completed_ == sequences_attached_) && !paused_)
120       delete this;
121   }
122
123   virtual void OnLayerAnimationScheduled(
124       ui::LayerAnimationSequence* sequence) OVERRIDE {
125   }
126
127   virtual void OnAttachedToSequence(
128       ui::LayerAnimationSequence* sequence) OVERRIDE {
129     LayerAnimationObserver::OnAttachedToSequence(sequence);
130     sequences_attached_++;
131   }
132
133   // Callback to be called.
134   base::Closure callback_;
135
136   // Number of sequences this observer was attached to.
137   int sequences_attached_;
138
139   // Number of sequences either ended or aborted.
140   int sequences_completed_;
141
142   bool paused_;
143
144   DISALLOW_COPY_AND_ASSIGN(AnimationFinishedObserver);
145 };
146
147 }  // namespace
148
149 const int LockStateController::kLockTimeoutMs = 400;
150 const int LockStateController::kShutdownTimeoutMs = 400;
151 const int LockStateController::kLockFailTimeoutMs = 8000;
152 const int LockStateController::kLockToShutdownTimeoutMs = 150;
153 const int LockStateController::kShutdownRequestDelayMs = 50;
154
155 LockStateController::TestApi::TestApi(LockStateController* controller)
156     : controller_(controller) {
157 }
158
159 LockStateController::TestApi::~TestApi() {
160 }
161
162 LockStateController::LockStateController()
163     : animator_(new internal::SessionStateAnimator()),
164       login_status_(user::LOGGED_IN_NONE),
165       system_is_locked_(false),
166       shutting_down_(false),
167       shutdown_after_lock_(false),
168       animating_lock_(false),
169       can_cancel_lock_animation_(false) {
170   Shell::GetPrimaryRootWindow()->GetDispatcher()->AddRootWindowObserver(this);
171 }
172
173 LockStateController::~LockStateController() {
174   Shell::GetPrimaryRootWindow()->GetDispatcher()->RemoveRootWindowObserver(
175       this);
176 }
177
178 void LockStateController::SetDelegate(LockStateControllerDelegate* delegate) {
179   delegate_.reset(delegate);
180 }
181
182 void LockStateController::AddObserver(LockStateObserver* observer) {
183   observers_.AddObserver(observer);
184 }
185
186 void LockStateController::RemoveObserver(LockStateObserver* observer) {
187   observers_.RemoveObserver(observer);
188 }
189
190 bool LockStateController::HasObserver(LockStateObserver* observer) {
191   return observers_.HasObserver(observer);
192 }
193
194 void LockStateController::StartLockAnimation(
195     bool shutdown_after_lock) {
196   if (animating_lock_)
197     return;
198   shutdown_after_lock_ = shutdown_after_lock;
199   can_cancel_lock_animation_ = true;
200
201   StartCancellablePreLockAnimation();
202 }
203
204 void LockStateController::StartShutdownAnimation() {
205   StartCancellableShutdownAnimation();
206 }
207
208 void LockStateController::StartLockAnimationAndLockImmediately() {
209   if (animating_lock_)
210     return;
211   StartImmediatePreLockAnimation(true /* request_lock_on_completion */);
212 }
213
214 bool LockStateController::LockRequested() {
215   return lock_fail_timer_.IsRunning();
216 }
217
218 bool LockStateController::ShutdownRequested() {
219   return shutting_down_;
220 }
221
222 bool LockStateController::CanCancelLockAnimation() {
223   return can_cancel_lock_animation_;
224 }
225
226 void LockStateController::CancelLockAnimation() {
227   if (!CanCancelLockAnimation())
228     return;
229   shutdown_after_lock_ = false;
230   animating_lock_ = false;
231   CancelPreLockAnimation();
232 }
233
234 bool LockStateController::CanCancelShutdownAnimation() {
235   return pre_shutdown_timer_.IsRunning() ||
236          shutdown_after_lock_ ||
237          lock_to_shutdown_timer_.IsRunning();
238 }
239
240 void LockStateController::CancelShutdownAnimation() {
241   if (!CanCancelShutdownAnimation())
242     return;
243   if (lock_to_shutdown_timer_.IsRunning()) {
244     lock_to_shutdown_timer_.Stop();
245     return;
246   }
247   if (shutdown_after_lock_) {
248     shutdown_after_lock_ = false;
249     return;
250   }
251
252   animator_->StartGlobalAnimation(
253       internal::SessionStateAnimator::ANIMATION_UNDO_GRAYSCALE_BRIGHTNESS,
254       internal::SessionStateAnimator::ANIMATION_SPEED_REVERT_SHUTDOWN);
255   pre_shutdown_timer_.Stop();
256 }
257
258 void LockStateController::OnStartingLock() {
259   if (shutting_down_ || system_is_locked_)
260     return;
261   if (animating_lock_)
262     return;
263   StartImmediatePreLockAnimation(false /* request_lock_on_completion */);
264 }
265
266 void LockStateController::RequestShutdown() {
267   if (shutting_down_)
268     return;
269
270   shutting_down_ = true;
271
272   Shell* shell = ash::Shell::GetInstance();
273   shell->cursor_manager()->HideCursor();
274   shell->cursor_manager()->LockCursor();
275
276   animator_->StartGlobalAnimation(
277       internal::SessionStateAnimator::ANIMATION_GRAYSCALE_BRIGHTNESS,
278       internal::SessionStateAnimator::ANIMATION_SPEED_SHUTDOWN);
279   StartRealShutdownTimer(true);
280 }
281
282 void LockStateController::OnLockScreenHide(
283   base::Callback<void(void)>& callback) {
284   StartUnlockAnimationBeforeUIDestroyed(callback);
285 }
286
287 void LockStateController::SetLockScreenDisplayedCallback(
288     const base::Closure& callback) {
289   lock_screen_displayed_callback_ = callback;
290 }
291
292 void LockStateController::OnWindowTreeHostCloseRequested(
293                                                 const aura::RootWindow*) {
294   Shell::GetInstance()->delegate()->Exit();
295 }
296
297 void LockStateController::OnLoginStateChanged(
298     user::LoginStatus status) {
299   if (status != user::LOGGED_IN_LOCKED)
300     login_status_ = status;
301   system_is_locked_ = (status == user::LOGGED_IN_LOCKED);
302 }
303
304 void LockStateController::OnAppTerminating() {
305   // If we hear that Chrome is exiting but didn't request it ourselves, all we
306   // can really hope for is that we'll have time to clear the screen.
307   // This is also the case when the user signs off.
308   if (!shutting_down_) {
309     shutting_down_ = true;
310     Shell* shell = ash::Shell::GetInstance();
311     shell->cursor_manager()->HideCursor();
312     shell->cursor_manager()->LockCursor();
313     animator_->StartAnimation(
314         internal::SessionStateAnimator::kAllContainersMask,
315         internal::SessionStateAnimator::ANIMATION_HIDE_IMMEDIATELY,
316         internal::SessionStateAnimator::ANIMATION_SPEED_IMMEDIATE);
317   }
318 }
319
320 void LockStateController::OnLockStateChanged(bool locked) {
321   VLOG(1) << "OnLockStateChanged " << locked;
322   if (shutting_down_ || (system_is_locked_ == locked))
323     return;
324
325   system_is_locked_ = locked;
326
327   if (locked) {
328     StartPostLockAnimation();
329     lock_fail_timer_.Stop();
330   } else {
331     StartUnlockAnimationAfterUIDestroyed();
332   }
333 }
334
335 void LockStateController::OnLockFailTimeout() {
336   DCHECK(!system_is_locked_);
337   CHECK(false) << "We can not be sure about the lock state. Crash and let the "
338                << "SessionManager end the session";
339 }
340
341 void LockStateController::StartLockToShutdownTimer() {
342   shutdown_after_lock_ = false;
343   lock_to_shutdown_timer_.Stop();
344   lock_to_shutdown_timer_.Start(
345       FROM_HERE,
346       base::TimeDelta::FromMilliseconds(kLockToShutdownTimeoutMs),
347       this, &LockStateController::OnLockToShutdownTimeout);
348 }
349
350 void LockStateController::OnLockToShutdownTimeout() {
351   DCHECK(system_is_locked_);
352   StartCancellableShutdownAnimation();
353 }
354
355 void LockStateController::StartPreShutdownAnimationTimer() {
356   pre_shutdown_timer_.Stop();
357   pre_shutdown_timer_.Start(
358       FROM_HERE,
359       animator_->
360           GetDuration(internal::SessionStateAnimator::ANIMATION_SPEED_SHUTDOWN),
361       this,
362       &LockStateController::OnPreShutdownAnimationTimeout);
363 }
364
365 void LockStateController::OnPreShutdownAnimationTimeout() {
366   VLOG(1) << "OnPreShutdownAnimationTimeout";
367   shutting_down_ = true;
368
369   Shell* shell = ash::Shell::GetInstance();
370   shell->cursor_manager()->HideCursor();
371
372   StartRealShutdownTimer(false);
373 }
374
375 void LockStateController::StartRealShutdownTimer(bool with_animation_time) {
376   base::TimeDelta duration =
377       base::TimeDelta::FromMilliseconds(kShutdownRequestDelayMs);
378   if (with_animation_time) {
379     duration += animator_->GetDuration(
380         internal::SessionStateAnimator::ANIMATION_SPEED_SHUTDOWN);
381   }
382
383 #if defined(OS_CHROMEOS)
384   const AccessibilityDelegate* const delegate =
385       Shell::GetInstance()->accessibility_delegate();
386   base::TimeDelta sound_duration = delegate->PlayShutdownSound();
387   sound_duration =
388       std::min(sound_duration,
389                base::TimeDelta::FromMilliseconds(kMaxShutdownSoundDurationMs));
390   duration = std::max(duration, sound_duration);
391 #endif
392
393   real_shutdown_timer_.Start(
394       FROM_HERE, duration, this, &LockStateController::OnRealShutdownTimeout);
395 }
396
397 void LockStateController::OnRealShutdownTimeout() {
398   VLOG(1) << "OnRealShutdownTimeout";
399   DCHECK(shutting_down_);
400 #if defined(OS_CHROMEOS)
401   if (!base::SysInfo::IsRunningOnChromeOS()) {
402     ShellDelegate* delegate = Shell::GetInstance()->delegate();
403     if (delegate) {
404       delegate->Exit();
405       return;
406     }
407   }
408 #endif
409   Shell::GetInstance()->metrics()->RecordUserMetricsAction(
410       UMA_ACCEL_SHUT_DOWN_POWER_BUTTON);
411   delegate_->RequestShutdown();
412 }
413
414 void LockStateController::StartCancellableShutdownAnimation() {
415   Shell* shell = ash::Shell::GetInstance();
416   // Hide cursor, but let it reappear if the mouse moves.
417   shell->cursor_manager()->HideCursor();
418
419   animator_->StartGlobalAnimation(
420       internal::SessionStateAnimator::ANIMATION_GRAYSCALE_BRIGHTNESS,
421       internal::SessionStateAnimator::ANIMATION_SPEED_SHUTDOWN);
422   StartPreShutdownAnimationTimer();
423 }
424
425 void LockStateController::StartImmediatePreLockAnimation(
426     bool request_lock_on_completion) {
427   VLOG(1) << "StartImmediatePreLockAnimation " << request_lock_on_completion;
428   animating_lock_ = true;
429   StoreUnlockedProperties();
430
431   base::Closure next_animation_starter =
432       base::Bind(&LockStateController::PreLockAnimationFinished,
433       base::Unretained(this), request_lock_on_completion);
434   AnimationFinishedObserver* observer =
435       new AnimationFinishedObserver(next_animation_starter);
436
437   observer->Pause();
438
439   animator_->StartAnimationWithObserver(
440       internal::SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS,
441       internal::SessionStateAnimator::ANIMATION_LIFT,
442       internal::SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS,
443       observer);
444   animator_->StartAnimationWithObserver(
445       internal::SessionStateAnimator::LAUNCHER,
446       internal::SessionStateAnimator::ANIMATION_FADE_OUT,
447       internal::SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS,
448       observer);
449   // Hide the screen locker containers so we can raise them later.
450   animator_->StartAnimation(
451       internal::SessionStateAnimator::LOCK_SCREEN_CONTAINERS,
452       internal::SessionStateAnimator::ANIMATION_HIDE_IMMEDIATELY,
453       internal::SessionStateAnimator::ANIMATION_SPEED_IMMEDIATE);
454   AnimateBackgroundAppearanceIfNecessary(
455       internal::SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS,
456       observer);
457
458   observer->Unpause();
459
460   DispatchCancelMode();
461   FOR_EACH_OBSERVER(LockStateObserver, observers_,
462       OnLockStateEvent(LockStateObserver::EVENT_LOCK_ANIMATION_STARTED));
463 }
464
465 void LockStateController::StartCancellablePreLockAnimation() {
466   animating_lock_ = true;
467   StoreUnlockedProperties();
468   VLOG(1) << "StartCancellablePreLockAnimation";
469   base::Closure next_animation_starter =
470       base::Bind(&LockStateController::PreLockAnimationFinished,
471       base::Unretained(this), true /* request_lock */);
472   AnimationFinishedObserver* observer =
473       new AnimationFinishedObserver(next_animation_starter);
474
475   observer->Pause();
476
477   animator_->StartAnimationWithObserver(
478       internal::SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS,
479       internal::SessionStateAnimator::ANIMATION_LIFT,
480       internal::SessionStateAnimator::ANIMATION_SPEED_UNDOABLE,
481       observer);
482   animator_->StartAnimationWithObserver(
483       internal::SessionStateAnimator::LAUNCHER,
484       internal::SessionStateAnimator::ANIMATION_FADE_OUT,
485       internal::SessionStateAnimator::ANIMATION_SPEED_UNDOABLE,
486       observer);
487   // Hide the screen locker containers so we can raise them later.
488   animator_->StartAnimation(
489       internal::SessionStateAnimator::LOCK_SCREEN_CONTAINERS,
490       internal::SessionStateAnimator::ANIMATION_HIDE_IMMEDIATELY,
491       internal::SessionStateAnimator::ANIMATION_SPEED_IMMEDIATE);
492   AnimateBackgroundAppearanceIfNecessary(
493       internal::SessionStateAnimator::ANIMATION_SPEED_UNDOABLE,
494       observer);
495
496   DispatchCancelMode();
497   FOR_EACH_OBSERVER(LockStateObserver, observers_,
498       OnLockStateEvent(LockStateObserver::EVENT_PRELOCK_ANIMATION_STARTED));
499   observer->Unpause();
500 }
501
502 void LockStateController::CancelPreLockAnimation() {
503   VLOG(1) << "CancelPreLockAnimation";
504   base::Closure next_animation_starter =
505       base::Bind(&LockStateController::LockAnimationCancelled,
506       base::Unretained(this));
507   AnimationFinishedObserver* observer =
508       new AnimationFinishedObserver(next_animation_starter);
509
510   observer->Pause();
511
512   animator_->StartAnimationWithObserver(
513       internal::SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS,
514       internal::SessionStateAnimator::ANIMATION_UNDO_LIFT,
515       internal::SessionStateAnimator::ANIMATION_SPEED_UNDO_MOVE_WINDOWS,
516       observer);
517   animator_->StartAnimationWithObserver(
518       internal::SessionStateAnimator::LAUNCHER,
519       internal::SessionStateAnimator::ANIMATION_FADE_IN,
520       internal::SessionStateAnimator::ANIMATION_SPEED_UNDO_MOVE_WINDOWS,
521       observer);
522   AnimateBackgroundHidingIfNecessary(
523       internal::SessionStateAnimator::ANIMATION_SPEED_UNDO_MOVE_WINDOWS,
524       observer);
525
526   observer->Unpause();
527 }
528
529 void LockStateController::StartPostLockAnimation() {
530   VLOG(1) << "StartPostLockAnimation";
531   base::Closure next_animation_starter =
532       base::Bind(&LockStateController::PostLockAnimationFinished,
533       base::Unretained(this));
534
535   AnimationFinishedObserver* observer =
536       new AnimationFinishedObserver(next_animation_starter);
537
538   observer->Pause();
539   animator_->StartAnimationWithObserver(
540       internal::SessionStateAnimator::LOCK_SCREEN_CONTAINERS,
541       internal::SessionStateAnimator::ANIMATION_RAISE_TO_SCREEN,
542       internal::SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS,
543       observer);
544   observer->Unpause();
545 }
546
547 void LockStateController::StartUnlockAnimationBeforeUIDestroyed(
548     base::Closure& callback) {
549   VLOG(1) << "StartUnlockAnimationBeforeUIDestroyed";
550   animator_->StartAnimationWithCallback(
551       internal::SessionStateAnimator::LOCK_SCREEN_CONTAINERS,
552       internal::SessionStateAnimator::ANIMATION_LIFT,
553       internal::SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS,
554       callback);
555 }
556
557 void LockStateController::StartUnlockAnimationAfterUIDestroyed() {
558   VLOG(1) << "StartUnlockAnimationAfterUIDestroyed";
559   base::Closure next_animation_starter =
560       base::Bind(&LockStateController::UnlockAnimationAfterUIDestroyedFinished,
561                  base::Unretained(this));
562
563   AnimationFinishedObserver* observer =
564       new AnimationFinishedObserver(next_animation_starter);
565
566   observer->Pause();
567
568   animator_->StartAnimationWithObserver(
569       internal::SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS,
570       internal::SessionStateAnimator::ANIMATION_DROP,
571       internal::SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS,
572       observer);
573   animator_->StartAnimationWithObserver(
574       internal::SessionStateAnimator::LAUNCHER,
575       internal::SessionStateAnimator::ANIMATION_FADE_IN,
576       internal::SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS,
577       observer);
578   AnimateBackgroundHidingIfNecessary(
579       internal::SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS,
580       observer);
581   observer->Unpause();
582 }
583
584 void LockStateController::LockAnimationCancelled() {
585   can_cancel_lock_animation_ = false;
586   RestoreUnlockedProperties();
587 }
588
589 void LockStateController::PreLockAnimationFinished(bool request_lock) {
590   can_cancel_lock_animation_ = false;
591   VLOG(1) << "PreLockAnimationFinished";
592   if (request_lock) {
593     Shell::GetInstance()->metrics()->RecordUserMetricsAction(
594         shutdown_after_lock_ ?
595         UMA_ACCEL_LOCK_SCREEN_POWER_BUTTON :
596         UMA_ACCEL_LOCK_SCREEN_LOCK_BUTTON);
597     delegate_->RequestLockScreen();
598   }
599
600   lock_fail_timer_.Start(
601       FROM_HERE,
602       base::TimeDelta::FromMilliseconds(kLockFailTimeoutMs),
603       this,
604       &LockStateController::OnLockFailTimeout);
605 }
606
607 void LockStateController::PostLockAnimationFinished() {
608   animating_lock_ = false;
609   VLOG(1) << "PostLockAnimationFinished";
610   FOR_EACH_OBSERVER(LockStateObserver, observers_,
611       OnLockStateEvent(LockStateObserver::EVENT_LOCK_ANIMATION_FINISHED));
612   if (!lock_screen_displayed_callback_.is_null()) {
613     lock_screen_displayed_callback_.Run();
614     lock_screen_displayed_callback_.Reset();
615   }
616   if (shutdown_after_lock_) {
617     shutdown_after_lock_ = false;
618     StartLockToShutdownTimer();
619   }
620 }
621
622 void LockStateController::UnlockAnimationAfterUIDestroyedFinished() {
623   RestoreUnlockedProperties();
624 }
625
626 void LockStateController::StoreUnlockedProperties() {
627   if (!unlocked_properties_) {
628     unlocked_properties_.reset(new UnlockedStateProperties());
629     unlocked_properties_->background_is_hidden = IsBackgroundHidden();
630   }
631   if (unlocked_properties_->background_is_hidden) {
632     // Hide background so that it can be animated later.
633     animator_->StartAnimation(
634         internal::SessionStateAnimator::DESKTOP_BACKGROUND,
635         internal::SessionStateAnimator::ANIMATION_HIDE_IMMEDIATELY,
636         internal::SessionStateAnimator::ANIMATION_SPEED_IMMEDIATE);
637     ShowBackground();
638   }
639 }
640
641 void LockStateController::RestoreUnlockedProperties() {
642   if (!unlocked_properties_)
643     return;
644   if (unlocked_properties_->background_is_hidden) {
645     HideBackground();
646     // Restore background visibility.
647     animator_->StartAnimation(
648         internal::SessionStateAnimator::DESKTOP_BACKGROUND,
649         internal::SessionStateAnimator::ANIMATION_FADE_IN,
650         internal::SessionStateAnimator::ANIMATION_SPEED_IMMEDIATE);
651   }
652   unlocked_properties_.reset();
653 }
654
655 void LockStateController::AnimateBackgroundAppearanceIfNecessary(
656     internal::SessionStateAnimator::AnimationSpeed speed,
657     ui::LayerAnimationObserver* observer) {
658   if (unlocked_properties_.get() &&
659       unlocked_properties_->background_is_hidden) {
660     animator_->StartAnimationWithObserver(
661         internal::SessionStateAnimator::DESKTOP_BACKGROUND,
662         internal::SessionStateAnimator::ANIMATION_FADE_IN,
663         speed,
664         observer);
665   }
666 }
667
668 void LockStateController::AnimateBackgroundHidingIfNecessary(
669     internal::SessionStateAnimator::AnimationSpeed speed,
670     ui::LayerAnimationObserver* observer) {
671   if (unlocked_properties_.get() &&
672       unlocked_properties_->background_is_hidden) {
673     animator_->StartAnimationWithObserver(
674         internal::SessionStateAnimator::DESKTOP_BACKGROUND,
675         internal::SessionStateAnimator::ANIMATION_FADE_OUT,
676         speed,
677         observer);
678   }
679 }
680
681 }  // namespace ash