Index: ash/wm/session_state_controller_impl2.cc |
diff --git a/ash/wm/session_state_controller_impl2.cc b/ash/wm/session_state_controller_impl2.cc |
index 8b19827738b8c4faf5ba24b2ec5be5497c1c128f..9ff659e90bbb940f0634daf8f6371176b9d1dba6 100644 |
--- a/ash/wm/session_state_controller_impl2.cc |
+++ b/ash/wm/session_state_controller_impl2.cc |
@@ -11,7 +11,9 @@ |
#include "ash/wm/session_state_animator.h" |
#include "base/bind_helpers.h" |
#include "base/command_line.h" |
+#include "base/timer.h" |
#include "ui/aura/root_window.h" |
+#include "ui/compositor/scoped_layer_animation_settings.h" |
#include "ui/views/corewm/compound_event_filter.h" |
#if defined(OS_CHROMEOS) |
@@ -20,6 +22,34 @@ |
namespace ash { |
+namespace { |
+ |
+aura::Window* GetBackground() { |
+ aura::RootWindow* root_window = Shell::GetPrimaryRootWindow(); |
+ return Shell::GetContainer(root_window, |
+ internal::kShellWindowId_DesktopBackgroundContainer); |
+} |
+ |
+bool IsBackgroundHidden() { |
+ return !GetBackground()->IsVisible(); |
+} |
+ |
+void ShowBackground() { |
+ ui::ScopedLayerAnimationSettings settings( |
+ GetBackground()->layer()->GetAnimator()); |
+ settings.SetTransitionDuration(base::TimeDelta()); |
+ GetBackground()->Show(); |
+} |
+ |
+void HideBackground() { |
+ ui::ScopedLayerAnimationSettings settings( |
+ GetBackground()->layer()->GetAnimator()); |
+ settings.SetTransitionDuration(base::TimeDelta()); |
+ GetBackground()->Hide(); |
+} |
+ |
+} // namespace |
+ |
SessionStateControllerImpl2::TestApi::TestApi( |
SessionStateControllerImpl2* controller) |
: controller_(controller) { |
@@ -32,7 +62,9 @@ SessionStateControllerImpl2::SessionStateControllerImpl2() |
: login_status_(user::LOGGED_IN_NONE), |
system_is_locked_(false), |
shutting_down_(false), |
- shutdown_after_lock_(false) { |
+ shutdown_after_lock_(false), |
+ animating_lock_(false), |
+ undoable_lock_animation_(false) { |
Shell::GetPrimaryRootWindow()->AddRootWindowObserver(this); |
} |
@@ -50,6 +82,7 @@ void SessionStateControllerImpl2::OnLoginStateChanged( |
void SessionStateControllerImpl2::OnAppTerminating() { |
// If we hear that Chrome is exiting but didn't request it ourselves, all we |
// can really hope for is that we'll have time to clear the screen. |
+ // This is also a case when user signs off. |
if (!shutting_down_) { |
shutting_down_ = true; |
Shell* shell = ash::Shell::GetInstance(); |
@@ -69,22 +102,10 @@ void SessionStateControllerImpl2::OnLockStateChanged(bool locked) { |
system_is_locked_ = locked; |
if (locked) { |
- base::Callback<void(void)> callback = |
- base::Bind(&SessionStateControllerImpl2::OnLockScreenAnimationFinished, |
- base::Unretained(this)); |
- animator_->StartAnimationWithCallback( |
- internal::SessionStateAnimator::LOCK_SCREEN_CONTAINERS, |
- internal::SessionStateAnimator::ANIMATION_RAISE_TO_SCREEN, |
- internal::SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS, |
- callback); |
- lock_timer_.Stop(); |
+ StartLockAnimationPhaseTwo(); |
lock_fail_timer_.Stop(); |
} else { |
- animator_->StartAnimation( |
- internal::SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS | |
- internal::SessionStateAnimator::LAUNCHER, |
- internal::SessionStateAnimator::ANIMATION_DROP, |
- internal::SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS); |
+ StartUnlockAnimationPhaseTwo(); |
} |
} |
@@ -93,68 +114,27 @@ void SessionStateControllerImpl2::SetLockScreenDisplayedCallback( |
lock_screen_displayed_callback_ = callback; |
} |
-void SessionStateControllerImpl2::OnLockScreenAnimationFinished() { |
- FOR_EACH_OBSERVER(SessionStateObserver, observers_, |
- OnSessionStateEvent( |
- SessionStateObserver::EVENT_LOCK_ANIMATION_FINISHED)); |
- if (!lock_screen_displayed_callback_.is_null()) { |
- lock_screen_displayed_callback_.Run(); |
- lock_screen_displayed_callback_.Reset(); |
- } |
- if (shutdown_after_lock_) { |
- shutdown_after_lock_ = false; |
- StartLockToShutdownTimer(); |
- } |
-} |
- |
void SessionStateControllerImpl2::OnStartingLock() { |
if (shutting_down_ || system_is_locked_) |
return; |
- |
- animator_->StartAnimation( |
- internal::SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS | |
- internal::SessionStateAnimator::LAUNCHER, |
- internal::SessionStateAnimator::ANIMATION_LIFT, |
- internal::SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS); |
- FOR_EACH_OBSERVER(SessionStateObserver, observers_, |
- OnSessionStateEvent(SessionStateObserver::EVENT_LOCK_ANIMATION_STARTED)); |
- // Hide the screen locker containers so we can raise them later. |
- animator_->StartAnimation( |
- internal::SessionStateAnimator::LOCK_SCREEN_CONTAINERS, |
- internal::SessionStateAnimator::ANIMATION_HIDE_IMMEDIATELY, |
- internal::SessionStateAnimator::ANIMATION_SPEED_IMMEDIATE); |
+ if (animating_lock_) |
+ return; |
+ StartImmediateLockAnimationPhaseOne(); |
} |
void SessionStateControllerImpl2::StartLockAnimationAndLockImmediately() { |
- animator_->StartAnimation( |
- internal::SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS | |
- internal::SessionStateAnimator::LAUNCHER, |
- internal::SessionStateAnimator::ANIMATION_LIFT, |
- internal::SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS); |
- FOR_EACH_OBSERVER(SessionStateObserver, observers_, |
- OnSessionStateEvent(SessionStateObserver::EVENT_LOCK_ANIMATION_STARTED)); |
- OnLockTimeout(); |
+ if (animating_lock_) |
+ return; |
+ StartImmediateLockAnimationPhaseOne(); |
} |
void SessionStateControllerImpl2::StartLockAnimation(bool shutdown_after_lock) { |
+ if (animating_lock_) |
+ return; |
shutdown_after_lock_ = shutdown_after_lock; |
+ undoable_lock_animation_ = true; |
- animator_->StartAnimation( |
- internal::SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS | |
- internal::SessionStateAnimator::LAUNCHER, |
- internal::SessionStateAnimator::ANIMATION_LIFT, |
- internal::SessionStateAnimator::ANIMATION_SPEED_UNDOABLE); |
- FOR_EACH_OBSERVER(SessionStateObserver, observers_, |
- OnSessionStateEvent( |
- SessionStateObserver::EVENT_PRELOCK_ANIMATION_STARTED)); |
- StartLockTimer(); |
-} |
- |
-void SessionStateControllerImpl2::StartShutdownAnimation() { |
- animator_->StartGlobalAnimation( |
- internal::SessionStateAnimator::ANIMATION_GRAYSCALE_BRIGHTNESS, |
- internal::SessionStateAnimator::ANIMATION_SPEED_SHUTDOWN); |
- StartPreShutdownAnimationTimer(); |
+ StartUndoableLockAnimationPhaseOne(); |
} |
bool SessionStateControllerImpl2::LockRequested() { |
@@ -166,19 +146,15 @@ bool SessionStateControllerImpl2::ShutdownRequested() { |
} |
bool SessionStateControllerImpl2::CanCancelLockAnimation() { |
- return lock_timer_.IsRunning(); |
+ return undoable_lock_animation_; |
} |
void SessionStateControllerImpl2::CancelLockAnimation() { |
if (!CanCancelLockAnimation()) |
return; |
shutdown_after_lock_ = false; |
- animator_->StartAnimation( |
- internal::SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS | |
- internal::SessionStateAnimator::LAUNCHER, |
- internal::SessionStateAnimator::ANIMATION_DROP, |
- internal::SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS); |
- lock_timer_.Stop(); |
+ animating_lock_ = false; |
+ UndoLockAnimationPhaseOne(); |
} |
bool SessionStateControllerImpl2::CanCancelShutdownAnimation() { |
@@ -187,6 +163,13 @@ bool SessionStateControllerImpl2::CanCancelShutdownAnimation() { |
lock_to_shutdown_timer_.IsRunning(); |
} |
+void SessionStateControllerImpl2::StartShutdownAnimation() { |
+ animator_->StartGlobalAnimation( |
+ internal::SessionStateAnimator::ANIMATION_GRAYSCALE_BRIGHTNESS, |
+ internal::SessionStateAnimator::ANIMATION_SPEED_SHUTDOWN); |
+ StartPreShutdownAnimationTimer(); |
+} |
+ |
void SessionStateControllerImpl2::CancelShutdownAnimation() { |
if (!CanCancelShutdownAnimation()) |
return; |
@@ -220,6 +203,7 @@ void SessionStateControllerImpl2::RequestShutdownImpl() { |
animator_->StartGlobalAnimation( |
internal::SessionStateAnimator::ANIMATION_GRAYSCALE_BRIGHTNESS, |
internal::SessionStateAnimator::ANIMATION_SPEED_SHUTDOWN); |
+ |
StartRealShutdownTimer(); |
} |
@@ -228,31 +212,10 @@ void SessionStateControllerImpl2::OnRootWindowHostCloseRequested( |
Shell::GetInstance()->delegate()->Exit(); |
} |
-void SessionStateControllerImpl2::StartLockTimer() { |
- lock_timer_.Stop(); |
- lock_timer_.Start( |
- FROM_HERE, |
- animator_->GetDuration( |
- internal::SessionStateAnimator::ANIMATION_SPEED_UNDOABLE), |
- this, &SessionStateControllerImpl2::OnLockTimeout); |
-} |
- |
-void SessionStateControllerImpl2::OnLockTimeout() { |
- delegate_->RequestLockScreen(); |
- lock_fail_timer_.Start( |
- FROM_HERE, |
- base::TimeDelta::FromMilliseconds(kLockFailTimeoutMs), |
- this, &SessionStateControllerImpl2::OnLockFailTimeout); |
-} |
- |
void SessionStateControllerImpl2::OnLockFailTimeout() { |
DCHECK(!system_is_locked_); |
// Undo lock animation. |
- animator_->StartAnimation( |
- internal::SessionStateAnimator::LAUNCHER | |
- internal::SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS, |
- internal::SessionStateAnimator::ANIMATION_DROP, |
- internal::SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS); |
+ StartUnlockAnimationPhaseTwo(); |
} |
void SessionStateControllerImpl2::StartLockToShutdownTimer() { |
@@ -264,7 +227,6 @@ void SessionStateControllerImpl2::StartLockToShutdownTimer() { |
this, &SessionStateControllerImpl2::OnLockToShutdownTimeout); |
} |
- |
void SessionStateControllerImpl2::OnLockToShutdownTimeout() { |
DCHECK(system_is_locked_); |
StartShutdownAnimation(); |
@@ -310,6 +272,163 @@ void SessionStateControllerImpl2::OnRealShutdownTimeout() { |
void SessionStateControllerImpl2::OnLockScreenHide( |
base::Callback<void(void)>& callback) { |
+ StartUnlockAnimationPhaseOne(callback); |
+} |
+ |
+void SessionStateControllerImpl2::LockAnimationUndone() { |
+ undoable_lock_animation_ = false; |
+ RestoreUnlockedProperties(); |
+} |
+ |
+void SessionStateControllerImpl2::LockAnimationPhaseOneCompleted() { |
+ undoable_lock_animation_ = false; |
+ |
+ delegate_->RequestLockScreen(); |
+ lock_fail_timer_.Start( |
+ FROM_HERE, |
+ base::TimeDelta::FromMilliseconds(kLockFailTimeoutMs), |
+ this, &SessionStateControllerImpl2::OnLockFailTimeout); |
+} |
+ |
+void SessionStateControllerImpl2::LockAnimationPhaseTwoCompleted() { |
+ animating_lock_ = false; |
+ |
+ FOR_EACH_OBSERVER(SessionStateObserver, observers_, |
+ OnSessionStateEvent( |
+ SessionStateObserver::EVENT_LOCK_ANIMATION_FINISHED)); |
+ if (!lock_screen_displayed_callback_.is_null()) { |
+ lock_screen_displayed_callback_.Run(); |
+ lock_screen_displayed_callback_.Reset(); |
+ } |
+ if (shutdown_after_lock_) { |
+ shutdown_after_lock_ = false; |
+ StartLockToShutdownTimer(); |
+ } |
+} |
+ |
+void SessionStateControllerImpl2::UnlockAnimationPhaseTwoCompleted() { |
+ RestoreUnlockedProperties(); |
+} |
+ |
+void SessionStateControllerImpl2::StartImmediateLockAnimationPhaseOne() { |
+ animating_lock_ = true; |
+ |
+ StoreUnlockedProperties(); |
+ |
+ base::Closure next_animation_starter = |
+ base::Bind(&SessionStateControllerImpl2::LockAnimationPhaseOneCompleted, |
+ base::Unretained(this)); |
+ ui::LayerAnimationObserver* observer = |
+ new ui::AnimationFinishedObserver(next_animation_starter); |
+ |
+ animator_->StartAnimationWithObserver( |
+ internal::SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS, |
+ internal::SessionStateAnimator::ANIMATION_LIFT, |
+ internal::SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS, |
+ observer); |
+ |
+ animator_->StartAnimationWithObserver( |
+ internal::SessionStateAnimator::LAUNCHER, |
+ internal::SessionStateAnimator::ANIMATION_FADE_OUT, |
+ internal::SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS, |
+ observer); |
+ |
+ // Hide the screen locker containers so we can raise them later. |
+ animator_->StartAnimation( |
+ internal::SessionStateAnimator::LOCK_SCREEN_CONTAINERS, |
+ internal::SessionStateAnimator::ANIMATION_HIDE_IMMEDIATELY, |
+ internal::SessionStateAnimator::ANIMATION_SPEED_IMMEDIATE); |
+ |
+ AnimateBackgroundAppearanceIfNecessary( |
+ internal::SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS, |
+ observer); |
+ |
+ FOR_EACH_OBSERVER(SessionStateObserver, observers_, |
+ OnSessionStateEvent(SessionStateObserver::EVENT_LOCK_ANIMATION_STARTED)); |
+} |
+ |
+void SessionStateControllerImpl2::StartUndoableLockAnimationPhaseOne() { |
+ animating_lock_ = true; |
+ StoreUnlockedProperties(); |
+ |
+ base::Closure next_animation_starter = |
+ base::Bind(&SessionStateControllerImpl2::LockAnimationPhaseOneCompleted, |
+ base::Unretained(this)); |
+ ui::LayerAnimationObserver* observer = |
+ new ui::AnimationFinishedObserver(next_animation_starter); |
+ |
+ animator_->StartAnimationWithObserver( |
+ internal::SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS, |
+ internal::SessionStateAnimator::ANIMATION_LIFT, |
+ internal::SessionStateAnimator::ANIMATION_SPEED_UNDOABLE, |
+ observer); |
+ |
+ animator_->StartAnimationWithObserver( |
+ internal::SessionStateAnimator::LAUNCHER, |
+ internal::SessionStateAnimator::ANIMATION_FADE_OUT, |
+ internal::SessionStateAnimator::ANIMATION_SPEED_UNDOABLE, |
+ observer); |
+ |
+ // Hide the screen locker containers so we can raise them later. |
+ animator_->StartAnimation( |
+ internal::SessionStateAnimator::LOCK_SCREEN_CONTAINERS, |
+ internal::SessionStateAnimator::ANIMATION_HIDE_IMMEDIATELY, |
+ internal::SessionStateAnimator::ANIMATION_SPEED_IMMEDIATE); |
+ |
+ AnimateBackgroundAppearanceIfNecessary( |
+ internal::SessionStateAnimator::ANIMATION_SPEED_UNDOABLE, |
+ observer); |
+ |
+ FOR_EACH_OBSERVER(SessionStateObserver, observers_, |
+ OnSessionStateEvent( |
+ SessionStateObserver::EVENT_PRELOCK_ANIMATION_STARTED)); |
+} |
+ |
+void SessionStateControllerImpl2::UndoLockAnimationPhaseOne() { |
+ base::Closure next_animation_starter = |
+ base::Bind(&SessionStateControllerImpl2::LockAnimationUndone, |
+ base::Unretained(this)); |
+ ui::AnimationFinishedObserver* observer = |
+ new ui::AnimationFinishedObserver(next_animation_starter); |
+ |
+ observer->Pause(); |
+ |
+ animator_->StartAnimationWithObserver( |
+ internal::SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS, |
+ internal::SessionStateAnimator::ANIMATION_DROP, |
+ internal::SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS, |
+ observer); |
+ |
+ animator_->StartAnimationWithObserver( |
+ internal::SessionStateAnimator::LAUNCHER, |
+ internal::SessionStateAnimator::ANIMATION_FADE_IN, |
+ internal::SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS, |
+ observer); |
+ |
+ AnimateBackgroundHidingIfNecessary( |
+ internal::SessionStateAnimator::ANIMATION_SPEED_UNDOABLE, |
+ observer); |
+ |
+ observer->Unpause(); |
+} |
+ |
+void SessionStateControllerImpl2::StartLockAnimationPhaseTwo() { |
+ base::Closure next_animation_starter = |
+ base::Bind(&SessionStateControllerImpl2::LockAnimationPhaseTwoCompleted, |
+ base::Unretained(this)); |
+ |
+ ui::LayerAnimationObserver* observer = |
+ new ui::AnimationFinishedObserver(next_animation_starter); |
+ |
+ animator_->StartAnimationWithObserver( |
+ internal::SessionStateAnimator::LOCK_SCREEN_CONTAINERS, |
+ internal::SessionStateAnimator::ANIMATION_RAISE_TO_SCREEN, |
+ internal::SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS, |
+ observer); |
+} |
+ |
+void SessionStateControllerImpl2::StartUnlockAnimationPhaseOne( |
+ base::Closure& callback) { |
animator_->StartAnimationWithCallback( |
internal::SessionStateAnimator::LOCK_SCREEN_CONTAINERS, |
internal::SessionStateAnimator::ANIMATION_LIFT, |
@@ -317,4 +436,84 @@ void SessionStateControllerImpl2::OnLockScreenHide( |
callback); |
} |
+void SessionStateControllerImpl2::StartUnlockAnimationPhaseTwo() { |
+ base::Closure next_animation_starter = |
+ base::Bind(&SessionStateControllerImpl2::UnlockAnimationPhaseTwoCompleted, |
+ base::Unretained(this)); |
+ |
+ ui::LayerAnimationObserver* observer = |
+ new ui::AnimationFinishedObserver(next_animation_starter); |
+ |
+ animator_->StartAnimationWithObserver( |
+ internal::SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS, |
+ internal::SessionStateAnimator::ANIMATION_DROP, |
+ internal::SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS, |
+ observer); |
+ |
+ animator_->StartAnimationWithObserver( |
+ internal::SessionStateAnimator::LAUNCHER, |
+ internal::SessionStateAnimator::ANIMATION_FADE_IN, |
+ internal::SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS, |
+ observer); |
+ |
+ AnimateBackgroundHidingIfNecessary( |
+ internal::SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS, |
+ observer); |
+} |
+ |
+void SessionStateControllerImpl2::StoreUnlockedProperties() { |
+ if (!unlocked_properties_.get()) { |
+ unlocked_properties_.reset(new UnlockedStateProperties()); |
+ unlocked_properties_->background_is_hidden = IsBackgroundHidden(); |
+ } |
+ if (unlocked_properties_->background_is_hidden) { |
+ // Hide background so that it can be animated later. |
+ animator_->StartAnimation( |
+ internal::SessionStateAnimator::DESKTOP_BACKGROUND, |
+ internal::SessionStateAnimator::ANIMATION_HIDE_IMMEDIATELY, |
+ internal::SessionStateAnimator::ANIMATION_SPEED_IMMEDIATE); |
+ ShowBackground(); |
+ } |
+} |
+ |
+void SessionStateControllerImpl2::RestoreUnlockedProperties() { |
+ if (!unlocked_properties_.get()) |
+ return; |
+ if (unlocked_properties_->background_is_hidden) { |
+ HideBackground(); |
+ // Restore background visibility. |
+ animator_->StartAnimation( |
+ internal::SessionStateAnimator::DESKTOP_BACKGROUND, |
+ internal::SessionStateAnimator::ANIMATION_FADE_IN, |
+ internal::SessionStateAnimator::ANIMATION_SPEED_IMMEDIATE); |
+ } |
+ unlocked_properties_.reset(); |
+} |
+ |
+void SessionStateControllerImpl2::AnimateBackgroundAppearanceIfNecessary( |
+ internal::SessionStateAnimator::AnimationSpeed speed, |
+ ui::LayerAnimationObserver* observer) { |
+ if (unlocked_properties_.get() && |
+ unlocked_properties_->background_is_hidden) { |
+ animator_->StartAnimationWithObserver( |
+ internal::SessionStateAnimator::DESKTOP_BACKGROUND, |
+ internal::SessionStateAnimator::ANIMATION_FADE_IN, |
+ speed, |
+ observer); |
+ } |
+} |
+ |
+void SessionStateControllerImpl2::AnimateBackgroundHidingIfNecessary( |
+ internal::SessionStateAnimator::AnimationSpeed speed, |
+ ui::LayerAnimationObserver* observer) { |
+ if (unlocked_properties_.get() && |
+ unlocked_properties_->background_is_hidden) { |
+ animator_->StartAnimationWithObserver( |
+ internal::SessionStateAnimator::DESKTOP_BACKGROUND, |
+ internal::SessionStateAnimator::ANIMATION_FADE_OUT, |
+ speed, |
+ observer); |
+ } |
+} |
+ |
} // namespace ash |