Added speed/duration to SessionStateAnimator, fixed call in SystemTrayDelegate
Exposed Grayscale/Brightness animation from WindowAnimations, used it in SessionStateAnimator.
BUG=139461
Review URL: https://chromiumcodereview.appspot.com/11360170
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@167357 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/ash/wm/session_state_animator.cc b/ash/wm/session_state_animator.cc
index b66384b..82f41f8 100644
--- a/ash/wm/session_state_animator.cc
+++ b/ash/wm/session_state_animator.cc
@@ -6,6 +6,7 @@
#include "ash/shell.h"
#include "ash/shell_window_ids.h"
+#include "ash/wm/window_animations.h"
#include "ash/wm/workspace/workspace_animations.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/root_window.h"
@@ -18,24 +19,6 @@
namespace {
-// Amount of time taken to scale the snapshot of the screen down to a
-// slightly-smaller size once the user starts holding the power button. Used
-// for both the pre-lock and pre-shutdown animations.
-const int kSlowCloseAnimMs = 400;
-
-// Amount of time taken to scale the snapshot of the screen back to its original
-// size when the button is released.
-const int kUndoSlowCloseAnimMs = 100;
-
-// Amount of time taken to scale the snapshot down to a point in the center of
-// the screen once the screen has been locked or we've been notified that the
-// system is shutting down.
-const int kFastCloseAnimMs = 150;
-
-// Amount of time taken to make the lock window fade in when the screen is
-// locked.
-const int kLockFadeInAnimMs = 200;
-
// Slightly-smaller size that we scale the screen down to for the pre-lock and
// pre-shutdown states.
const float kSlowCloseSizeRatio = 0.95f;
@@ -68,6 +51,7 @@
// Slowly shrinks |window| to a slightly-smaller size.
void StartSlowCloseAnimationForWindow(aura::Window* window,
+ base::TimeDelta duration,
ui::LayerAnimationObserver* observer) {
ui::LayerAnimator* animator = window->layer()->GetAnimator();
animator->set_preemption_strategy(
@@ -75,7 +59,7 @@
ui::LayerAnimationSequence* sequence = new ui::LayerAnimationSequence(
ui::LayerAnimationElement::CreateTransformElement(
GetSlowCloseTransform(),
- base::TimeDelta::FromMilliseconds(kSlowCloseAnimMs)));
+ duration));
animator->StartAnimation(sequence);
if (observer)
sequence->AddObserver(observer);
@@ -84,6 +68,7 @@
// Quickly undoes the effects of the slow-close animation on |window|.
void StartUndoSlowCloseAnimationForWindow(
aura::Window* window,
+ base::TimeDelta duration,
ui::LayerAnimationObserver* observer) {
ui::LayerAnimator* animator = window->layer()->GetAnimator();
animator->set_preemption_strategy(
@@ -91,7 +76,7 @@
ui::LayerAnimationSequence* sequence = new ui::LayerAnimationSequence(
ui::LayerAnimationElement::CreateTransformElement(
gfx::Transform(),
- base::TimeDelta::FromMilliseconds(kUndoSlowCloseAnimMs)));
+ duration));
animator->StartAnimation(sequence);
if (observer)
sequence->AddObserver(observer);
@@ -100,6 +85,7 @@
// Quickly shrinks |window| down to a point in the center of the screen and
// fades it out to 0 opacity.
void StartFastCloseAnimationForWindow(aura::Window* window,
+ base::TimeDelta duration,
ui::LayerAnimationObserver* observer) {
ui::LayerAnimator* animator = window->layer()->GetAnimator();
animator->set_preemption_strategy(
@@ -107,41 +93,39 @@
animator->StartAnimation(
new ui::LayerAnimationSequence(
ui::LayerAnimationElement::CreateTransformElement(
- GetFastCloseTransform(),
- base::TimeDelta::FromMilliseconds(kFastCloseAnimMs))));
+ GetFastCloseTransform(), duration)));
ui::LayerAnimationSequence* sequence = new ui::LayerAnimationSequence(
- ui::LayerAnimationElement::CreateOpacityElement(
- 0.0, base::TimeDelta::FromMilliseconds(kFastCloseAnimMs)));
+ ui::LayerAnimationElement::CreateOpacityElement(0.0, duration));
animator->StartAnimation(sequence);
if (observer)
sequence->AddObserver(observer);
}
-// Fades |window| to |target_opacity| over |length| milliseconds.
+// Fades |window| to |target_opacity| over |duration|.
void StartPartialFadeAnimation(aura::Window* window,
float target_opacity,
- base::TimeDelta length,
+ base::TimeDelta duration,
ui::LayerAnimationObserver* observer) {
ui::LayerAnimator* animator = window->layer()->GetAnimator();
animator->set_preemption_strategy(
ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
ui::LayerAnimationSequence* sequence = new ui::LayerAnimationSequence(
ui::LayerAnimationElement::CreateOpacityElement(
- target_opacity, length));
+ target_opacity, duration));
animator->StartAnimation(sequence);
if (observer)
sequence->AddObserver(observer);
}
-// Fades |window| in to full opacity.
+// Fades |window| in to full opacity over |duration|.
void FadeInWindow(aura::Window* window,
+ base::TimeDelta duration,
ui::LayerAnimationObserver* observer) {
ui::LayerAnimator* animator = window->layer()->GetAnimator();
animator->set_preemption_strategy(
ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
ui::LayerAnimationSequence* sequence = new ui::LayerAnimationSequence(
- ui::LayerAnimationElement::CreateOpacityElement(
- 1.0, base::TimeDelta::FromMilliseconds(kLockFadeInAnimMs)));
+ ui::LayerAnimationElement::CreateOpacityElement(1.0, duration));
animator->StartAnimation(sequence);
if (observer)
sequence->AddObserver(observer);
@@ -165,7 +149,7 @@
}
void HideWindow(aura::Window* window,
- base::TimeDelta length,
+ base::TimeDelta duration,
WorkspaceAnimationDirection direction,
ui::LayerAnimationObserver* observer) {
WorkspaceAnimationDetails details;
@@ -173,7 +157,7 @@
details.animate = true;
details.animate_scale = true;
details.animate_opacity = true;
- details.duration = length;
+ details.duration = duration;
HideWorkspace(window, details);
// A bit of a dirty trick: we need to catch the end of the animation we don't
// control. So we use two facts we know: which animator will be used and the
@@ -212,6 +196,27 @@
window->layer()->GetAnimator()->ScheduleAnimation(sequence);
}
+// Starts grayscale/brightness animation for |window| over |duration|. Target
+// value for both grayscale and brightness are specified by |target|.
+void StartGrayscaleBrightnessAnimationForWindow(
+ aura::Window* window,
+ float target,
+ base::TimeDelta duration,
+ ui::LayerAnimationObserver* observer) {
+ ui::LayerAnimator* animator = window->layer()->GetAnimator();
+
+ std::vector<ui::LayerAnimationSequence*> animations =
+ CreateBrightnessGrayscaleAnimationSequence(target, duration);
+
+ if (observer)
+ animations[0]->AddObserver(observer);
+
+ animator->set_preemption_strategy(
+ ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
+
+ animator->StartTogether(animations);
+}
+
// Animation observer that will drop animated foreground once animation is
// finished. It is used in when undoing shutdown animation.
class CallbackAnimationObserver : public ui::LayerAnimationObserver {
@@ -308,6 +313,31 @@
SessionStateAnimator::~SessionStateAnimator() {
}
+base::TimeDelta SessionStateAnimator::GetDuration(AnimationSpeed speed) {
+ switch (speed) {
+ case ANIMATION_SPEED_IMMEDIATE:
+ return base::TimeDelta();
+ case ANIMATION_SPEED_UNDOABLE:
+ return base::TimeDelta::FromMilliseconds(400);
+ case ANIMATION_SPEED_REVERT:
+ return base::TimeDelta::FromMilliseconds(100);
+ case ANIMATION_SPEED_FAST:
+ return base::TimeDelta::FromMilliseconds(150);
+ case ANIMATION_SPEED_SHOW_LOCK_SCREEN:
+ return base::TimeDelta::FromMilliseconds(200);
+ case ANIMATION_SPEED_MOVE_WINDOWS:
+ return base::TimeDelta::FromMilliseconds(400);
+ case ANIMATION_SPEED_SHUTDOWN:
+ return base::TimeDelta::FromMilliseconds(1000);
+ case ANIMATION_SPEED_REVERT_SHUTDOWN:
+ return base::TimeDelta::FromMilliseconds(400);
+ }
+ // Satisfy compilers that do not understand that we will return from switch
+ // above anyway.
+ DCHECK(false) << "Unhandled animation speed " << speed;
+ return base::TimeDelta();
+}
+
// Fills |containers| with the containers described by |container_mask|.
void SessionStateAnimator::GetContainers(int container_mask,
aura::Window::Windows* containers) {
@@ -363,12 +393,13 @@
}
void SessionStateAnimator::StartAnimation(int container_mask,
- AnimationType type) {
+ AnimationType type,
+ AnimationSpeed speed) {
aura::Window::Windows containers;
GetContainers(container_mask, &containers);
for (aura::Window::Windows::const_iterator it = containers.begin();
it != containers.end(); ++it) {
- RunAnimationForWindow(*it, type, NULL);
+ RunAnimationForWindow(*it, type, speed, NULL);
}
}
@@ -376,6 +407,7 @@
void SessionStateAnimator::StartAnimationWithCallback(
int container_mask,
AnimationType type,
+ AnimationSpeed speed,
base::Callback<void(void)>& callback) {
aura::Window::Windows containers;
GetContainers(container_mask, &containers);
@@ -383,74 +415,74 @@
it != containers.end(); ++it) {
ui::LayerAnimationObserver* observer =
new CallbackAnimationObserver(callback);
- RunAnimationForWindow(*it, type, observer);
+ RunAnimationForWindow(*it, type, speed, observer);
}
}
+void SessionStateAnimator::StartGlobalAnimation(AnimationType type,
+ AnimationSpeed speed) {
+ aura::RootWindow* root_window = Shell::GetPrimaryRootWindow();
+ RunAnimationForWindow(root_window, type, speed, NULL);
+}
+
void SessionStateAnimator::RunAnimationForWindow(
aura::Window* window,
AnimationType type,
+ AnimationSpeed speed,
ui::LayerAnimationObserver* observer) {
+ base::TimeDelta duration = GetDuration(speed);
+
switch (type) {
case ANIMATION_PARTIAL_CLOSE:
- StartSlowCloseAnimationForWindow(window, observer);
+ StartSlowCloseAnimationForWindow(window, duration, observer);
break;
case ANIMATION_UNDO_PARTIAL_CLOSE:
- StartUndoSlowCloseAnimationForWindow(window, observer);
+ StartUndoSlowCloseAnimationForWindow(window, duration, observer);
break;
case ANIMATION_FULL_CLOSE:
- StartFastCloseAnimationForWindow(window, observer);
+ StartFastCloseAnimationForWindow(window, duration, observer);
break;
case ANIMATION_FADE_IN:
- FadeInWindow(window, observer);
+ FadeInWindow(window, duration, observer);
break;
case ANIMATION_HIDE_IMMEDIATELY:
+ DCHECK_EQ(speed, ANIMATION_SPEED_IMMEDIATE);
HideWindowImmediately(window, observer);
break;
case ANIMATION_RESTORE:
+ DCHECK_EQ(speed, ANIMATION_SPEED_IMMEDIATE);
RestoreWindow(window, observer);
break;
case ANIMATION_LIFT:
- HideWindow(window,
- base::TimeDelta::FromMilliseconds(kSlowCloseAnimMs),
- WORKSPACE_ANIMATE_UP,
- observer);
+ HideWindow(window, duration, WORKSPACE_ANIMATE_UP, observer);
break;
case ANIMATION_DROP:
- ShowWindow(window,
- base::TimeDelta::FromMilliseconds(kSlowCloseAnimMs),
- WORKSPACE_ANIMATE_DOWN,
- observer);
+ ShowWindow(window, duration, WORKSPACE_ANIMATE_DOWN, observer);
break;
case ANIMATION_RAISE_TO_SCREEN:
- ShowWindow(window,
- base::TimeDelta::FromMilliseconds(kSlowCloseAnimMs),
- WORKSPACE_ANIMATE_UP,
- observer);
+ ShowWindow(window, duration, WORKSPACE_ANIMATE_UP, observer);
break;
case ANIMATION_LOWER_BELOW_SCREEN:
- HideWindow(window,
- base::TimeDelta::FromMilliseconds(kSlowCloseAnimMs),
- WORKSPACE_ANIMATE_DOWN,
- observer);
+ HideWindow(window, duration, WORKSPACE_ANIMATE_DOWN, observer);
break;
case ANIMATION_PARTIAL_FADE_IN:
- StartPartialFadeAnimation(window, kPartialFadeRatio,
- base::TimeDelta::FromMilliseconds(kSlowCloseAnimMs),
- observer);
+ StartPartialFadeAnimation(
+ window, kPartialFadeRatio, duration, observer);
break;
case ANIMATION_UNDO_PARTIAL_FADE_IN:
- StartPartialFadeAnimation(window, 0.0,
- base::TimeDelta::FromMilliseconds(kUndoSlowCloseAnimMs),
- observer);
+ StartPartialFadeAnimation(window, 0.0, duration, observer);
break;
case ANIMATION_FULL_FADE_IN:
- StartPartialFadeAnimation(window, 1.0,
- base::TimeDelta::FromMilliseconds(kFastCloseAnimMs),
- observer);
+ StartPartialFadeAnimation(window, 1.0, duration, observer);
break;
- default:
- NOTREACHED() << "Unhandled animation type " << type;
+ case ANIMATION_GRAYSCALE_BRIGHTNESS:
+ StartGrayscaleBrightnessAnimationForWindow(
+ window, 1.0, duration, observer);
+ break;
+ case ANIMATION_UNDO_GRAYSCALE_BRIGHTNESS:
+ StartGrayscaleBrightnessAnimationForWindow(
+ window, 0.0, duration, observer);
+ break;
}
}
diff --git a/ash/wm/session_state_animator.h b/ash/wm/session_state_animator.h
index 0c6013e..e46e2dfc 100644
--- a/ash/wm/session_state_animator.h
+++ b/ash/wm/session_state_animator.h
@@ -46,6 +46,32 @@
ANIMATION_PARTIAL_FADE_IN,
ANIMATION_UNDO_PARTIAL_FADE_IN,
ANIMATION_FULL_FADE_IN,
+ ANIMATION_GRAYSCALE_BRIGHTNESS,
+ ANIMATION_UNDO_GRAYSCALE_BRIGHTNESS,
+ };
+
+ // Constants for determining animation speed.
+ enum AnimationSpeed {
+ // Immediately change state.
+ ANIMATION_SPEED_IMMEDIATE = 0,
+ // Speed for animations associated with user action that can be undone.
+ // Used for pre-lock and pre-shutdown animations.
+ ANIMATION_SPEED_UNDOABLE,
+ // Speed for animation that reverts undoable action. Used for aborting
+ // pre-lock and pre-shutdown animations.
+ ANIMATION_SPEED_REVERT,
+ // Speed for user action that can not be undone, Used for lock and shutdown
+ // animations requested via menus/shortcuts and for animating remaining
+ // parts of partial lock/shutdown animations.
+ ANIMATION_SPEED_FAST,
+ // Speed for lock screen appearance in "old" animation set.
+ ANIMATION_SPEED_SHOW_LOCK_SCREEN,
+ // Speed for workspace-like animations in "new" animation set.
+ ANIMATION_SPEED_MOVE_WINDOWS,
+ // Speed for shutdown in "new" animation set.
+ ANIMATION_SPEED_SHUTDOWN,
+ // Speed for reverting shutdown in "new" animation set.
+ ANIMATION_SPEED_REVERT_SHUTDOWN,
};
// Specific containers or groups of containers that can be animated.
@@ -100,30 +126,42 @@
SessionStateAnimator();
virtual ~SessionStateAnimator();
+ // Reports animation duration for |speed|.
+ static base::TimeDelta GetDuration(AnimationSpeed speed);
+
+ // Fills |containers| with the containers included in |container_mask|.
+ static void GetContainers(int container_mask,
+ aura::Window::Windows* containers);
+
// Create |foreground_| layer if it doesn't already exist, but makes it
// completely transparent.
void CreateForeground();
// Destroy |foreground_| when it is not needed anymore.
void DropForeground();
- // Apply animation |type| to all containers included in |container_mask|.
+ // Apply animation |type| to all containers included in |container_mask| with
+ // specified |speed|.
void StartAnimation(int container_mask,
- AnimationType type);
+ AnimationType type,
+ AnimationSpeed speed);
- // Apply animation |type| to all containers included in |container_mask| and
- // call a |callback| at the end of the animation, if it is not null.
+ // Apply animation |type| to all containers included in |container_mask| with
+ // specified |speed| and call a |callback| at the end of the animation, if it
+ // is not null.
void StartAnimationWithCallback(int container_mask,
AnimationType type,
+ AnimationSpeed speed,
base::Callback<void(void)>& callback);
- // Fills |containers| with the containers included in |container_mask|.
- void GetContainers(int container_mask,
- aura::Window::Windows* containers);
+ // Applies animation |type| whith specified |speed| to the root container.
+ void StartGlobalAnimation(AnimationType type,
+ AnimationSpeed speed);
- // Apply animation |type| to window |window| and add |observer| if it is not
- // NULL to the last animation sequence.
+ // Apply animation |type| to window |window| with |speed| and add |observer|
+ // if it is not NULL to the last animation sequence.
void RunAnimationForWindow(aura::Window* window,
AnimationType type,
+ AnimationSpeed speed,
ui::LayerAnimationObserver* observer);
// White foreground that is used during shutdown animation to "fade
diff --git a/ash/wm/session_state_controller.cc b/ash/wm/session_state_controller.cc
index 6de1351..ea12b8d 100644
--- a/ash/wm/session_state_controller.cc
+++ b/ash/wm/session_state_controller.cc
@@ -23,9 +23,6 @@
const int SessionStateController::kShutdownTimeoutMs = 400;
const int SessionStateController::kLockFailTimeoutMs = 4000;
const int SessionStateController::kLockToShutdownTimeoutMs = 150;
-const int SessionStateController::kSlowCloseAnimMs = 400;
-const int SessionStateController::kUndoSlowCloseAnimMs = 100;
-const int SessionStateController::kFastCloseAnimMs = 150;
const int SessionStateController::kShutdownRequestDelayMs = 50;
SessionStateController::SessionStateController()
diff --git a/ash/wm/session_state_controller.h b/ash/wm/session_state_controller.h
index b0b3efe..53e28cd9 100644
--- a/ash/wm/session_state_controller.h
+++ b/ash/wm/session_state_controller.h
@@ -63,20 +63,6 @@
// starting the pre-shutdown animation.
static const int kLockToShutdownTimeoutMs;
- // Amount of time taken to scale the snapshot of the screen down to a
- // slightly-smaller size once the user starts holding the power button. Used
- // for both the pre-lock and pre-shutdown animations.
- static const int kSlowCloseAnimMs;
-
- // Amount of time taken to scale the snapshot of the screen back to its
- // original size when the button is released.
- static const int kUndoSlowCloseAnimMs;
-
- // Amount of time taken to scale the snapshot down to a point in the center of
- // the screen once the screen has been locked or we've been notified that the
- // system is shutting down.
- static const int kFastCloseAnimMs;
-
// Additional time (beyond kFastCloseAnimMs) to wait after starting the
// fast-close shutdown animation before actually requesting shutdown, to give
// the animation time to finish.
diff --git a/ash/wm/session_state_controller_impl.cc b/ash/wm/session_state_controller_impl.cc
index 18e041d5f..9abb3b8b 100644
--- a/ash/wm/session_state_controller_impl.cc
+++ b/ash/wm/session_state_controller_impl.cc
@@ -55,7 +55,8 @@
shell->cursor_manager()->ShowCursor(false);
animator_->StartAnimation(
internal::SessionStateAnimator::kAllContainersMask,
- internal::SessionStateAnimator::ANIMATION_HIDE_IMMEDIATELY);
+ internal::SessionStateAnimator::ANIMATION_HIDE_IMMEDIATELY,
+ internal::SessionStateAnimator::ANIMATION_SPEED_IMMEDIATE);
}
}
@@ -68,7 +69,8 @@
if (locked) {
animator_->StartAnimation(
internal::SessionStateAnimator::LOCK_SCREEN_CONTAINERS,
- internal::SessionStateAnimator::ANIMATION_FADE_IN);
+ internal::SessionStateAnimator::ANIMATION_FADE_IN,
+ internal::SessionStateAnimator::ANIMATION_SPEED_SHOW_LOCK_SCREEN);
lock_timer_.Stop();
lock_fail_timer_.Stop();
@@ -81,7 +83,8 @@
internal::SessionStateAnimator::DESKTOP_BACKGROUND |
internal::SessionStateAnimator::LAUNCHER |
internal::SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS,
- internal::SessionStateAnimator::ANIMATION_RESTORE);
+ internal::SessionStateAnimator::ANIMATION_RESTORE,
+ internal::SessionStateAnimator::ANIMATION_SPEED_IMMEDIATE);
}
}
@@ -91,22 +94,26 @@
animator_->StartAnimation(
internal::SessionStateAnimator::LAUNCHER,
- internal::SessionStateAnimator::ANIMATION_HIDE_IMMEDIATELY);
+ internal::SessionStateAnimator::ANIMATION_HIDE_IMMEDIATELY,
+ internal::SessionStateAnimator::ANIMATION_SPEED_IMMEDIATE);
animator_->StartAnimation(
internal::SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS,
- internal::SessionStateAnimator::ANIMATION_FULL_CLOSE);
+ internal::SessionStateAnimator::ANIMATION_FULL_CLOSE,
+ internal::SessionStateAnimator::ANIMATION_SPEED_FAST);
// Hide the screen locker containers so we can make them fade in later.
animator_->StartAnimation(
internal::SessionStateAnimator::LOCK_SCREEN_CONTAINERS,
- internal::SessionStateAnimator::ANIMATION_HIDE_IMMEDIATELY);
+ internal::SessionStateAnimator::ANIMATION_HIDE_IMMEDIATELY,
+ internal::SessionStateAnimator::ANIMATION_SPEED_IMMEDIATE);
}
void SessionStateControllerImpl::StartLockAnimationAndLockImmediately() {
animator_->StartAnimation(
internal::SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS,
- internal::SessionStateAnimator::ANIMATION_PARTIAL_CLOSE);
+ internal::SessionStateAnimator::ANIMATION_PARTIAL_CLOSE,
+ internal::SessionStateAnimator::ANIMATION_SPEED_UNDOABLE);
OnLockTimeout();
}
@@ -115,14 +122,16 @@
animator_->StartAnimation(
internal::SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS,
- internal::SessionStateAnimator::ANIMATION_PARTIAL_CLOSE);
+ internal::SessionStateAnimator::ANIMATION_PARTIAL_CLOSE,
+ internal::SessionStateAnimator::ANIMATION_SPEED_UNDOABLE);
StartLockTimer();
}
void SessionStateControllerImpl::StartShutdownAnimation() {
animator_->StartAnimation(
internal::SessionStateAnimator::kAllContainersMask,
- internal::SessionStateAnimator::ANIMATION_PARTIAL_CLOSE);
+ internal::SessionStateAnimator::ANIMATION_PARTIAL_CLOSE,
+ internal::SessionStateAnimator::ANIMATION_SPEED_UNDOABLE);
StartPreShutdownAnimationTimer();
}
@@ -153,7 +162,8 @@
shutdown_after_lock_ = false;
animator_->StartAnimation(
internal::SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS,
- internal::SessionStateAnimator::ANIMATION_UNDO_PARTIAL_CLOSE);
+ internal::SessionStateAnimator::ANIMATION_UNDO_PARTIAL_CLOSE,
+ internal::SessionStateAnimator::ANIMATION_SPEED_REVERT);
lock_timer_.Stop();
}
@@ -180,14 +190,17 @@
// desktop background needs to be restored immediately.
animator_->StartAnimation(
internal::SessionStateAnimator::DESKTOP_BACKGROUND,
- internal::SessionStateAnimator::ANIMATION_RESTORE);
+ internal::SessionStateAnimator::ANIMATION_RESTORE,
+ internal::SessionStateAnimator::ANIMATION_SPEED_IMMEDIATE);
animator_->StartAnimation(
internal::SessionStateAnimator::kAllLockScreenContainersMask,
- internal::SessionStateAnimator::ANIMATION_UNDO_PARTIAL_CLOSE);
+ internal::SessionStateAnimator::ANIMATION_UNDO_PARTIAL_CLOSE,
+ internal::SessionStateAnimator::ANIMATION_SPEED_REVERT);
} else {
animator_->StartAnimation(
internal::SessionStateAnimator::kAllContainersMask,
- internal::SessionStateAnimator::ANIMATION_UNDO_PARTIAL_CLOSE);
+ internal::SessionStateAnimator::ANIMATION_UNDO_PARTIAL_CLOSE,
+ internal::SessionStateAnimator::ANIMATION_SPEED_REVERT);
}
pre_shutdown_timer_.Stop();
}
@@ -212,14 +225,17 @@
animator_->StartAnimation(
internal::SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS |
internal::SessionStateAnimator::LAUNCHER,
- internal::SessionStateAnimator::ANIMATION_HIDE_IMMEDIATELY);
+ internal::SessionStateAnimator::ANIMATION_HIDE_IMMEDIATELY,
+ internal::SessionStateAnimator::ANIMATION_SPEED_IMMEDIATE);
animator_->StartAnimation(
internal::SessionStateAnimator::kAllLockScreenContainersMask,
- internal::SessionStateAnimator::ANIMATION_FULL_CLOSE);
+ internal::SessionStateAnimator::ANIMATION_FULL_CLOSE,
+ internal::SessionStateAnimator::ANIMATION_SPEED_FAST);
} else {
animator_->StartAnimation(
internal::SessionStateAnimator::kAllContainersMask,
- internal::SessionStateAnimator::ANIMATION_FULL_CLOSE);
+ internal::SessionStateAnimator::ANIMATION_FULL_CLOSE,
+ internal::SessionStateAnimator::ANIMATION_SPEED_FAST);
}
StartRealShutdownTimer();
}
@@ -238,9 +254,11 @@
void SessionStateControllerImpl::StartLockTimer() {
lock_timer_.Stop();
- lock_timer_.Start(FROM_HERE,
- base::TimeDelta::FromMilliseconds(kSlowCloseAnimMs),
- this, &SessionStateControllerImpl::OnLockTimeout);
+ lock_timer_.Start(
+ FROM_HERE,
+ animator_->GetDuration(
+ internal::SessionStateAnimator::ANIMATION_SPEED_UNDOABLE),
+ this, &SessionStateControllerImpl::OnLockTimeout);
}
void SessionStateControllerImpl::OnLockTimeout() {
@@ -257,7 +275,8 @@
animator_->StartAnimation(
internal::SessionStateAnimator::LAUNCHER |
internal::SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS,
- internal::SessionStateAnimator::ANIMATION_RESTORE);
+ internal::SessionStateAnimator::ANIMATION_RESTORE,
+ internal::SessionStateAnimator::ANIMATION_SPEED_IMMEDIATE);
}
void SessionStateControllerImpl::StartLockToShutdownTimer() {
@@ -289,10 +308,14 @@
}
void SessionStateControllerImpl::StartRealShutdownTimer() {
+ base::TimeDelta duration =
+ base::TimeDelta::FromMilliseconds(kShutdownRequestDelayMs);
+ duration += animator_->GetDuration(
+ internal::SessionStateAnimator::ANIMATION_SPEED_FAST);
+
real_shutdown_timer_.Start(
FROM_HERE,
- base::TimeDelta::FromMilliseconds(kFastCloseAnimMs +
- kShutdownRequestDelayMs),
+ duration,
this, &SessionStateControllerImpl::OnRealShutdownTimeout);
}
diff --git a/ash/wm/session_state_controller_impl2.cc b/ash/wm/session_state_controller_impl2.cc
index ebbc3f3..c6456ad 100644
--- a/ash/wm/session_state_controller_impl2.cc
+++ b/ash/wm/session_state_controller_impl2.cc
@@ -55,10 +55,9 @@
Shell* shell = ash::Shell::GetInstance();
shell->env_filter()->set_cursor_hidden_by_filter(false);
shell->cursor_manager()->ShowCursor(false);
- animator_->CreateForeground();
- animator_->StartAnimation(
- internal::SessionStateAnimator::LOCK_SCREEN_SYSTEM_FOREGROUND,
- internal::SessionStateAnimator::ANIMATION_FULL_FADE_IN);
+ animator_->StartGlobalAnimation(
+ internal::SessionStateAnimator::ANIMATION_GRAYSCALE_BRIGHTNESS,
+ internal::SessionStateAnimator::ANIMATION_SPEED_FAST);
}
}
@@ -77,11 +76,13 @@
animator_->StartAnimationWithCallback(
internal::SessionStateAnimator::LOCK_SCREEN_CONTAINERS,
internal::SessionStateAnimator::ANIMATION_DROP,
+ internal::SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS,
callback);
} else {
animator_->StartAnimationWithCallback(
internal::SessionStateAnimator::LOCK_SCREEN_CONTAINERS,
internal::SessionStateAnimator::ANIMATION_RAISE_TO_SCREEN,
+ internal::SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS,
callback);
}
lock_timer_.Stop();
@@ -95,7 +96,8 @@
animator_->StartAnimation(
internal::SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS |
internal::SessionStateAnimator::LAUNCHER,
- internal::SessionStateAnimator::ANIMATION_DROP);
+ internal::SessionStateAnimator::ANIMATION_DROP,
+ internal::SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS);
}
}
@@ -118,19 +120,22 @@
animator_->StartAnimation(
internal::SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS |
internal::SessionStateAnimator::LAUNCHER,
- internal::SessionStateAnimator::ANIMATION_LIFT);
+ internal::SessionStateAnimator::ANIMATION_LIFT,
+ internal::SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS);
// 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_HIDE_IMMEDIATELY,
+ internal::SessionStateAnimator::ANIMATION_SPEED_IMMEDIATE);
}
void SessionStateControllerImpl2::StartLockAnimationAndLockImmediately() {
animator_->StartAnimation(
internal::SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS |
internal::SessionStateAnimator::LAUNCHER,
- internal::SessionStateAnimator::ANIMATION_LIFT);
+ internal::SessionStateAnimator::ANIMATION_LIFT,
+ internal::SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS);
OnLockTimeout();
}
@@ -140,15 +145,15 @@
animator_->StartAnimation(
internal::SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS |
internal::SessionStateAnimator::LAUNCHER,
- internal::SessionStateAnimator::ANIMATION_LIFT);
+ internal::SessionStateAnimator::ANIMATION_LIFT,
+ internal::SessionStateAnimator::ANIMATION_SPEED_UNDOABLE);
StartLockTimer();
}
void SessionStateControllerImpl2::StartShutdownAnimation() {
- animator_->CreateForeground();
- animator_->StartAnimation(
- internal::SessionStateAnimator::LOCK_SCREEN_SYSTEM_FOREGROUND,
- internal::SessionStateAnimator::ANIMATION_PARTIAL_FADE_IN);
+ animator_->StartGlobalAnimation(
+ internal::SessionStateAnimator::ANIMATION_GRAYSCALE_BRIGHTNESS,
+ internal::SessionStateAnimator::ANIMATION_SPEED_SHUTDOWN);
StartPreShutdownAnimationTimer();
}
@@ -179,7 +184,8 @@
animator_->StartAnimation(
internal::SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS |
internal::SessionStateAnimator::LAUNCHER,
- internal::SessionStateAnimator::ANIMATION_DROP);
+ internal::SessionStateAnimator::ANIMATION_DROP,
+ internal::SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS);
lock_timer_.Stop();
}
@@ -200,14 +206,9 @@
shutdown_after_lock_ = false;
return;
}
- animator_->CreateForeground();
- base::Callback<void(void)> callback =
- base::Bind(&internal::SessionStateAnimator::DropForeground,
- base::Unretained(animator_.get()));
- animator_->StartAnimationWithCallback(
- internal::SessionStateAnimator::LOCK_SCREEN_SYSTEM_FOREGROUND,
- internal::SessionStateAnimator::ANIMATION_UNDO_PARTIAL_FADE_IN,
- callback);
+ animator_->StartGlobalAnimation(
+ internal::SessionStateAnimator::ANIMATION_UNDO_GRAYSCALE_BRIGHTNESS,
+ internal::SessionStateAnimator::ANIMATION_SPEED_REVERT);
pre_shutdown_timer_.Stop();
}
@@ -224,10 +225,9 @@
shell->env_filter()->set_cursor_hidden_by_filter(false);
shell->cursor_manager()->ShowCursor(false);
- animator_->CreateForeground();
- animator_->StartAnimation(
- internal::SessionStateAnimator::LOCK_SCREEN_SYSTEM_FOREGROUND,
- internal::SessionStateAnimator::ANIMATION_FULL_FADE_IN);
+ animator_->StartGlobalAnimation(
+ internal::SessionStateAnimator::ANIMATION_GRAYSCALE_BRIGHTNESS,
+ internal::SessionStateAnimator::ANIMATION_SPEED_SHUTDOWN);
StartRealShutdownTimer();
}
@@ -245,9 +245,11 @@
void SessionStateControllerImpl2::StartLockTimer() {
lock_timer_.Stop();
- lock_timer_.Start(FROM_HERE,
- base::TimeDelta::FromMilliseconds(kSlowCloseAnimMs),
- this, &SessionStateControllerImpl2::OnLockTimeout);
+ lock_timer_.Start(
+ FROM_HERE,
+ animator_->GetDuration(
+ internal::SessionStateAnimator::ANIMATION_SPEED_UNDOABLE),
+ this, &SessionStateControllerImpl2::OnLockTimeout);
}
void SessionStateControllerImpl2::OnLockTimeout() {
@@ -264,7 +266,8 @@
animator_->StartAnimation(
internal::SessionStateAnimator::LAUNCHER |
internal::SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS,
- internal::SessionStateAnimator::ANIMATION_DROP);
+ internal::SessionStateAnimator::ANIMATION_DROP,
+ internal::SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS);
}
void SessionStateControllerImpl2::StartLockToShutdownTimer() {
@@ -296,10 +299,13 @@
}
void SessionStateControllerImpl2::StartRealShutdownTimer() {
+ base::TimeDelta duration =
+ base::TimeDelta::FromMilliseconds(kShutdownRequestDelayMs);
+ duration += animator_->GetDuration(
+ internal::SessionStateAnimator::ANIMATION_SPEED_SHUTDOWN);
real_shutdown_timer_.Start(
FROM_HERE,
- base::TimeDelta::FromMilliseconds(kFastCloseAnimMs +
- kShutdownRequestDelayMs),
+ duration,
this, &SessionStateControllerImpl2::OnRealShutdownTimeout);
}
@@ -324,11 +330,13 @@
animator_->StartAnimationWithCallback(
internal::SessionStateAnimator::LOCK_SCREEN_CONTAINERS,
internal::SessionStateAnimator::ANIMATION_LIFT,
+ internal::SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS,
callback);
} else {
animator_->StartAnimationWithCallback(
internal::SessionStateAnimator::LOCK_SCREEN_CONTAINERS,
internal::SessionStateAnimator::ANIMATION_LOWER_BELOW_SCREEN,
+ internal::SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS,
callback);
}
}
diff --git a/ash/wm/window_animations.cc b/ash/wm/window_animations.cc
index 2c3c185..855c453 100644
--- a/ash/wm/window_animations.cc
+++ b/ash/wm/window_animations.cc
@@ -450,45 +450,18 @@
window->layer()->SetVisible(true);
}
- int animation_duration = kBrightnessGrayscaleFadeDurationMs;
- ui::Tween::Type animation_type = ui::Tween::EASE_OUT;
- if (CommandLine::ForCurrentProcess()->HasSwitch(
- ash::switches::kAshBootAnimationFunction2)) {
- animation_type = ui::Tween::EASE_OUT_2;
- } else if (CommandLine::ForCurrentProcess()->HasSwitch(
- ash::switches::kAshBootAnimationFunction3)) {
- animation_type = ui::Tween::EASE_OUT_3;
- }
+ base::TimeDelta duration =
+ base::TimeDelta::FromMilliseconds(kBrightnessGrayscaleFadeDurationMs);
ui::ScopedLayerAnimationSettings settings(window->layer()->GetAnimator());
- settings.SetTransitionDuration(
- base::TimeDelta::FromMilliseconds(animation_duration));
+ settings.SetTransitionDuration(duration);
if (!show)
settings.AddObserver(new HidingWindowAnimationObserver(window));
- scoped_ptr<ui::LayerAnimationSequence> brightness_sequence(
- new ui::LayerAnimationSequence());
- scoped_ptr<ui::LayerAnimationSequence> grayscale_sequence(
- new ui::LayerAnimationSequence());
-
- scoped_ptr<ui::LayerAnimationElement> brightness_element(
- ui::LayerAnimationElement::CreateBrightnessElement(
- end_value,
- base::TimeDelta::FromMilliseconds(animation_duration)));
- brightness_element->set_tween_type(animation_type);
- brightness_sequence->AddElement(brightness_element.release());
-
- scoped_ptr<ui::LayerAnimationElement> grayscale_element(
- ui::LayerAnimationElement::CreateGrayscaleElement(
- end_value,
- base::TimeDelta::FromMilliseconds(animation_duration)));
- grayscale_element->set_tween_type(animation_type);
- grayscale_sequence->AddElement(grayscale_element.release());
-
- std::vector<ui::LayerAnimationSequence*> animations;
- animations.push_back(brightness_sequence.release());
- animations.push_back(grayscale_sequence.release());
- window->layer()->GetAnimator()->ScheduleTogether(animations);
+ window->layer()->GetAnimator()->
+ ScheduleTogether(
+ internal::CreateBrightnessGrayscaleAnimationSequence(end_value,
+ duration));
if (!show) {
window->layer()->SetOpacity(kWindowAnimation_HideOpacity);
window->layer()->SetVisible(false);
@@ -882,5 +855,40 @@
}
}
+std::vector<ui::LayerAnimationSequence*>
+CreateBrightnessGrayscaleAnimationSequence(float target_value,
+ base::TimeDelta duration) {
+ ui::Tween::Type animation_type = ui::Tween::EASE_OUT;
+ if (CommandLine::ForCurrentProcess()->HasSwitch(
+ ash::switches::kAshBootAnimationFunction2)) {
+ animation_type = ui::Tween::EASE_OUT_2;
+ } else if (CommandLine::ForCurrentProcess()->HasSwitch(
+ ash::switches::kAshBootAnimationFunction3)) {
+ animation_type = ui::Tween::EASE_OUT_3;
+ }
+ scoped_ptr<ui::LayerAnimationSequence> brightness_sequence(
+ new ui::LayerAnimationSequence());
+ scoped_ptr<ui::LayerAnimationSequence> grayscale_sequence(
+ new ui::LayerAnimationSequence());
+
+ scoped_ptr<ui::LayerAnimationElement> brightness_element(
+ ui::LayerAnimationElement::CreateBrightnessElement(
+ target_value, duration));
+ brightness_element->set_tween_type(animation_type);
+ brightness_sequence->AddElement(brightness_element.release());
+
+ scoped_ptr<ui::LayerAnimationElement> grayscale_element(
+ ui::LayerAnimationElement::CreateGrayscaleElement(
+ target_value, duration));
+ grayscale_element->set_tween_type(animation_type);
+ grayscale_sequence->AddElement(grayscale_element.release());
+
+ std::vector<ui::LayerAnimationSequence*> animations;
+ animations.push_back(brightness_sequence.release());
+ animations.push_back(grayscale_sequence.release());
+
+ return animations;
+}
+
} // namespace internal
} // namespace ash
diff --git a/ash/wm/window_animations.h b/ash/wm/window_animations.h
index b7655e11..9179aac 100644
--- a/ash/wm/window_animations.h
+++ b/ash/wm/window_animations.h
@@ -5,6 +5,8 @@
#ifndef ASH_WM_WINDOW_ANIMATIONS_H_
#define ASH_WM_WINDOW_ANIMATIONS_H_
+#include <vector>
+
#include "ash/ash_export.h"
namespace aura {
@@ -19,6 +21,7 @@
namespace ui {
class ImplicitAnimationObserver;
class Layer;
+class LayerAnimationSequence;
}
namespace ash {
@@ -96,6 +99,13 @@
ASH_EXPORT bool AnimateOnChildWindowVisibilityChanged(aura::Window* window,
bool visible);
+// Creates vector of animation sequences that lasts for |duration| and changes
+// brightness and grayscale to |target_value|. Caller takes ownership of
+// returned LayerAnimationSequence objects.
+ASH_EXPORT std::vector<ui::LayerAnimationSequence*>
+CreateBrightnessGrayscaleAnimationSequence(float target_value,
+ base::TimeDelta duration);
+
} // namespace internal
} // namespace ash
diff --git a/chrome/browser/chromeos/system/ash_system_tray_delegate.cc b/chrome/browser/chromeos/system/ash_system_tray_delegate.cc
index 9ac78405..f84fe74 100644
--- a/chrome/browser/chromeos/system/ash_system_tray_delegate.cc
+++ b/chrome/browser/chromeos/system/ash_system_tray_delegate.cc
@@ -22,6 +22,7 @@
#include "ash/system/user/update_observer.h"
#include "ash/system/user/user_observer.h"
#include "ash/volume_control_delegate.h"
+#include "ash/wm/session_state_controller.h"
#include "base/bind_helpers.h"
#include "base/callback.h"
#include "base/chromeos/chromeos_version.h"
@@ -353,9 +354,7 @@
}
virtual void ShutDown() OVERRIDE {
- DBusThreadManager::Get()->GetPowerManagerClient()->RequestShutdown();
- if (!base::chromeos::IsRunningOnChromeOS())
- browser::AttemptUserExit();
+ ash::Shell::GetInstance()->session_state_controller()->RequestShutdown();
}
virtual void SignOut() OVERRIDE {
diff --git a/ui/compositor/layer_animator.cc b/ui/compositor/layer_animator.cc
index a8d61a4..d49edc5 100644
--- a/ui/compositor/layer_animator.cc
+++ b/ui/compositor/layer_animator.cc
@@ -65,7 +65,8 @@
transition_duration_(transition_duration),
tween_type_(Tween::LINEAR),
is_started_(false),
- disable_timer_for_test_(false) {
+ disable_timer_for_test_(false),
+ adding_animations_(false) {
}
LayerAnimator::~LayerAnimator() {
@@ -231,6 +232,45 @@
UpdateAnimationState();
}
+void LayerAnimator::StartTogether(
+ const std::vector<LayerAnimationSequence*>& animations) {
+ scoped_refptr<LayerAnimator> retain(this);
+ if (preemption_strategy_ == IMMEDIATELY_SET_NEW_TARGET) {
+ std::vector<LayerAnimationSequence*>::const_iterator iter;
+ for (iter = animations.begin(); iter != animations.end(); ++iter) {
+ StartAnimation(*iter);
+ }
+ return;
+ }
+ adding_animations_ = true;
+
+ // Collect all the affected properties.
+ LayerAnimationElement::AnimatableProperties animated_properties;
+ std::vector<LayerAnimationSequence*>::const_iterator iter;
+ for (iter = animations.begin(); iter != animations.end(); ++iter) {
+ animated_properties.insert((*iter)->properties().begin(),
+ (*iter)->properties().end());
+ }
+
+ // Starting a zero duration pause that affects all the animated properties
+ // will prevent any of the sequences from animating until there are no
+ // running animations that affect any of these properties, as well as
+ // handle preemption strategy.
+ StartAnimation(new LayerAnimationSequence(
+ LayerAnimationElement::CreatePauseElement(animated_properties,
+ base::TimeDelta())));
+
+ // These animations (provided they don't animate any common properties) will
+ // now animate together if trivially scheduled.
+ for (iter = animations.begin(); iter != animations.end(); ++iter) {
+ ScheduleAnimation(*iter);
+ }
+
+ adding_animations_ = false;
+ UpdateAnimationState();
+}
+
+
void LayerAnimator::ScheduleTogether(
const std::vector<LayerAnimationSequence*>& animations) {
scoped_refptr<LayerAnimator> retain(this);
@@ -691,7 +731,7 @@
// last_tick_time() from there to ensure animations started during the same
// event complete at the same time.
base::TimeTicks start_time;
- if (is_animating())
+ if (is_animating() || adding_animations_)
start_time = last_step_time_;
else if (GetAnimationContainer()->is_running())
start_time = GetAnimationContainer()->last_tick_time();
diff --git a/ui/compositor/layer_animator.h b/ui/compositor/layer_animator.h
index da2976a0..764be17 100644
--- a/ui/compositor/layer_animator.h
+++ b/ui/compositor/layer_animator.h
@@ -113,7 +113,12 @@
// of this animation sequence.
void ScheduleAnimation(LayerAnimationSequence* animation);
- // Schedules the animations to be run together. Obviously will no work if
+ // Starts the animations to be run together. Obviously will not work if
+ // they animate any common properties. The animator takes ownership of the
+ // animation sequences. Takes PreemptionStrategy into account.
+ void StartTogether(const std::vector<LayerAnimationSequence*>& animations);
+
+ // Schedules the animations to be run together. Obviously will not work if
// they animate any common properties. The animator takes ownership of the
// animation sequences.
void ScheduleTogether(const std::vector<LayerAnimationSequence*>& animations);
@@ -331,6 +336,10 @@
// and allows for manual stepping.
bool disable_timer_for_test_;
+ // Prevents timer adjustments in case when we start multiple animations
+ // with preemption strategies that discard previous animations.
+ bool adding_animations_;
+
// This causes all animations to complete immediately.
static bool disable_animations_for_test_;
diff --git a/ui/compositor/layer_animator_unittest.cc b/ui/compositor/layer_animator_unittest.cc
index d1219a15..d73ca39 100644
--- a/ui/compositor/layer_animator_unittest.cc
+++ b/ui/compositor/layer_animator_unittest.cc
@@ -32,6 +32,22 @@
SkColorGetB(color));
}
+// Creates vector with two LayerAnimationSequences, based on |first| and
+// |second| layer animation elements.
+std::vector<LayerAnimationSequence*> CreateMultiSequence(
+ LayerAnimationElement* first,
+ LayerAnimationElement* second) {
+ LayerAnimationSequence* first_sequence = new LayerAnimationSequence();
+ first_sequence->AddElement(first);
+ LayerAnimationSequence* second_sequence = new LayerAnimationSequence();
+ second_sequence->AddElement(second);
+
+ std::vector<ui::LayerAnimationSequence*> animations;
+ animations.push_back(first_sequence);
+ animations.push_back(second_sequence);
+ return animations;
+}
+
class TestImplicitAnimationObserver : public ImplicitAnimationObserver {
public:
explicit TestImplicitAnimationObserver(bool notify_when_animator_destructed)
@@ -686,6 +702,249 @@
EXPECT_FLOAT_EQ(delegate.GetOpacityForAnimation(), start_opacity);
}
+//-------------------------------------------------------
+// Preempt by immediately setting new target.
+TEST(LayerAnimatorTest, MultiPreemptBySettingNewTarget) {
+ scoped_refptr<LayerAnimator> animator(LayerAnimator::CreateDefaultAnimator());
+ animator->set_disable_timer_for_test(true);
+ TestLayerAnimationDelegate delegate;
+ animator->SetDelegate(&delegate);
+
+ double start_opacity(0.0);
+ double target_opacity(1.0);
+ double start_brightness(0.1);
+ double target_brightness(0.9);
+
+ base::TimeDelta delta = base::TimeDelta::FromSeconds(1);
+
+ delegate.SetOpacityFromAnimation(start_opacity);
+ delegate.SetBrightnessFromAnimation(start_brightness);
+
+ animator->set_preemption_strategy(LayerAnimator::IMMEDIATELY_SET_NEW_TARGET);
+
+ animator->StartTogether(
+ CreateMultiSequence(
+ LayerAnimationElement::CreateOpacityElement(target_opacity, delta),
+ LayerAnimationElement::CreateBrightnessElement(target_brightness,
+ delta)
+ ));
+
+ animator->StartTogether(
+ CreateMultiSequence(
+ LayerAnimationElement::CreateOpacityElement(start_opacity, delta),
+ LayerAnimationElement::CreateBrightnessElement(start_brightness,
+ delta)
+ ));
+
+ EXPECT_FALSE(animator->is_animating());
+ EXPECT_FLOAT_EQ(delegate.GetOpacityForAnimation(), start_opacity);
+ EXPECT_FLOAT_EQ(delegate.GetBrightnessForAnimation(), start_brightness);
+}
+
+// Preempt by animating to new target.
+TEST(LayerAnimatorTest, MultiPreemptByImmediatelyAnimatingToNewTarget) {
+ scoped_refptr<LayerAnimator> animator(LayerAnimator::CreateDefaultAnimator());
+ AnimationContainerElement* element = animator.get();
+ animator->set_disable_timer_for_test(true);
+ TestLayerAnimationDelegate delegate;
+ animator->SetDelegate(&delegate);
+
+ double start_opacity(0.0);
+ double middle_opacity(0.5);
+ double target_opacity(1.0);
+
+ double start_brightness(0.1);
+ double middle_brightness(0.2);
+ double target_brightness(0.3);
+
+ base::TimeDelta delta = base::TimeDelta::FromSeconds(1);
+
+ delegate.SetOpacityFromAnimation(start_opacity);
+ delegate.SetBrightnessFromAnimation(start_brightness);
+
+ animator->set_preemption_strategy(
+ LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
+
+ animator->StartTogether(
+ CreateMultiSequence(
+ LayerAnimationElement::CreateOpacityElement(target_opacity, delta),
+ LayerAnimationElement::CreateBrightnessElement(target_brightness,
+ delta)
+ ));
+
+ base::TimeTicks start_time = animator->last_step_time();
+
+ element->Step(start_time + base::TimeDelta::FromMilliseconds(500));
+
+ animator->StartTogether(
+ CreateMultiSequence(
+ LayerAnimationElement::CreateOpacityElement(start_opacity, delta),
+ LayerAnimationElement::CreateBrightnessElement(start_brightness,
+ delta)));
+
+ EXPECT_TRUE(animator->is_animating());
+ EXPECT_FLOAT_EQ(delegate.GetOpacityForAnimation(), middle_opacity);
+ EXPECT_FLOAT_EQ(delegate.GetBrightnessForAnimation(), middle_brightness);
+
+ animator->StartTogether(
+ CreateMultiSequence(
+ LayerAnimationElement::CreateOpacityElement(start_opacity, delta),
+ LayerAnimationElement::CreateBrightnessElement(start_brightness,
+ delta)));
+
+ EXPECT_TRUE(animator->is_animating());
+
+ element->Step(start_time + base::TimeDelta::FromMilliseconds(1000));
+
+ EXPECT_TRUE(animator->is_animating());
+ EXPECT_FLOAT_EQ(delegate.GetOpacityForAnimation(),
+ 0.5 * (start_opacity + middle_opacity));
+ EXPECT_FLOAT_EQ(delegate.GetBrightnessForAnimation(),
+ 0.5 * (start_brightness + middle_brightness));
+
+ element->Step(start_time + base::TimeDelta::FromMilliseconds(1500));
+
+ EXPECT_FALSE(animator->is_animating());
+ EXPECT_FLOAT_EQ(delegate.GetOpacityForAnimation(), start_opacity);
+ EXPECT_FLOAT_EQ(delegate.GetBrightnessForAnimation(), start_brightness);
+}
+
+// Preempt by enqueuing the new animation.
+TEST(LayerAnimatorTest, MultiPreemptEnqueueNewAnimation) {
+ scoped_refptr<LayerAnimator> animator(LayerAnimator::CreateDefaultAnimator());
+ AnimationContainerElement* element = animator.get();
+ animator->set_disable_timer_for_test(true);
+ TestLayerAnimationDelegate delegate;
+ animator->SetDelegate(&delegate);
+
+ double start_opacity(0.0);
+ double middle_opacity(0.5);
+ double target_opacity(1.0);
+
+ double start_brightness(0.1);
+ double middle_brightness(0.2);
+ double target_brightness(0.3);
+
+ base::TimeDelta delta = base::TimeDelta::FromSeconds(1);
+
+ delegate.SetOpacityFromAnimation(start_opacity);
+ delegate.SetBrightnessFromAnimation(start_brightness);
+
+ animator->set_preemption_strategy(LayerAnimator::ENQUEUE_NEW_ANIMATION);
+
+ animator->StartTogether(
+ CreateMultiSequence(
+ LayerAnimationElement::CreateOpacityElement(target_opacity, delta),
+ LayerAnimationElement::CreateBrightnessElement(target_brightness,
+ delta)));
+
+ base::TimeTicks start_time = animator->last_step_time();
+
+ element->Step(start_time + base::TimeDelta::FromMilliseconds(500));
+
+ animator->StartTogether(
+ CreateMultiSequence(
+ LayerAnimationElement::CreateOpacityElement(start_opacity, delta),
+ LayerAnimationElement::CreateBrightnessElement(start_brightness,
+ delta)));
+
+ EXPECT_TRUE(animator->is_animating());
+ EXPECT_FLOAT_EQ(delegate.GetOpacityForAnimation(), middle_opacity);
+ EXPECT_FLOAT_EQ(delegate.GetBrightnessForAnimation(), middle_brightness);
+
+ EXPECT_TRUE(animator->is_animating());
+
+ element->Step(start_time + base::TimeDelta::FromMilliseconds(1000));
+
+ EXPECT_TRUE(animator->is_animating());
+ EXPECT_FLOAT_EQ(delegate.GetOpacityForAnimation(), target_opacity);
+ EXPECT_FLOAT_EQ(delegate.GetBrightnessForAnimation(), target_brightness);
+
+ element->Step(start_time + base::TimeDelta::FromMilliseconds(1500));
+
+ EXPECT_TRUE(animator->is_animating());
+ EXPECT_FLOAT_EQ(delegate.GetOpacityForAnimation(), middle_opacity);
+ EXPECT_FLOAT_EQ(delegate.GetBrightnessForAnimation(), middle_brightness);
+
+ element->Step(start_time + base::TimeDelta::FromMilliseconds(2000));
+
+ EXPECT_FALSE(animator->is_animating());
+ EXPECT_FLOAT_EQ(delegate.GetOpacityForAnimation(), start_opacity);
+ EXPECT_FLOAT_EQ(delegate.GetBrightnessForAnimation(), start_brightness);
+}
+
+// Start an animation when there are sequences waiting in the queue. In this
+// case, all pending and running animations should be finished, and the new
+// animation started.
+TEST(LayerAnimatorTest, MultiPreemptByReplacingQueuedAnimations) {
+ scoped_refptr<LayerAnimator> animator(LayerAnimator::CreateDefaultAnimator());
+ AnimationContainerElement* element = animator.get();
+ animator->set_disable_timer_for_test(true);
+ TestLayerAnimationDelegate delegate;
+ animator->SetDelegate(&delegate);
+
+ double start_opacity(0.0);
+ double middle_opacity(0.5);
+ double target_opacity(1.0);
+
+ double start_brightness(0.1);
+ double middle_brightness(0.2);
+ double target_brightness(0.3);
+
+ base::TimeDelta delta = base::TimeDelta::FromSeconds(1);
+
+ delegate.SetOpacityFromAnimation(start_opacity);
+ delegate.SetBrightnessFromAnimation(start_brightness);
+
+ animator->set_preemption_strategy(LayerAnimator::REPLACE_QUEUED_ANIMATIONS);
+
+ animator->StartTogether(
+ CreateMultiSequence(
+ LayerAnimationElement::CreateOpacityElement(target_opacity, delta),
+ LayerAnimationElement::CreateBrightnessElement(target_brightness,
+ delta)));
+
+ base::TimeTicks start_time = animator->last_step_time();
+
+ element->Step(start_time + base::TimeDelta::FromMilliseconds(500));
+
+ animator->StartTogether(
+ CreateMultiSequence(
+ LayerAnimationElement::CreateOpacityElement(middle_opacity, delta),
+ LayerAnimationElement::CreateBrightnessElement(middle_brightness,
+ delta)));
+
+ // Queue should now have two animations. Starting a third should replace the
+ // second.
+ animator->StartTogether(
+ CreateMultiSequence(
+ LayerAnimationElement::CreateOpacityElement(start_opacity, delta),
+ LayerAnimationElement::CreateBrightnessElement(start_brightness,
+ delta)));
+
+ EXPECT_TRUE(animator->is_animating());
+ EXPECT_FLOAT_EQ(delegate.GetOpacityForAnimation(), middle_opacity);
+ EXPECT_FLOAT_EQ(delegate.GetBrightnessForAnimation(), middle_brightness);
+
+ element->Step(start_time + base::TimeDelta::FromMilliseconds(1000));
+
+ EXPECT_TRUE(animator->is_animating());
+ EXPECT_FLOAT_EQ(delegate.GetOpacityForAnimation(), target_opacity);
+ EXPECT_FLOAT_EQ(delegate.GetBrightnessForAnimation(), target_brightness);
+
+ element->Step(start_time + base::TimeDelta::FromMilliseconds(1500));
+
+ EXPECT_TRUE(animator->is_animating());
+ EXPECT_FLOAT_EQ(delegate.GetOpacityForAnimation(), middle_opacity);
+ EXPECT_FLOAT_EQ(delegate.GetBrightnessForAnimation(), middle_brightness);
+
+ element->Step(start_time + base::TimeDelta::FromMilliseconds(2000));
+
+ EXPECT_FALSE(animator->is_animating());
+ EXPECT_FLOAT_EQ(delegate.GetOpacityForAnimation(), start_opacity);
+ EXPECT_FLOAT_EQ(delegate.GetBrightnessForAnimation(), start_brightness);
+}
+//-------------------------------------------------------
// Test that cyclic sequences continue to animate.
TEST(LayerAnimatorTest, CyclicSequences) {
scoped_refptr<LayerAnimator> animator(LayerAnimator::CreateDefaultAnimator());