Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / ash / wm / window_animations_unittest.cc
blobd1c2d924e104a4a0b3fca1b4e4f434095d4dec78
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "ash/wm/window_animations.h"
7 #include "ash/shell_window_ids.h"
8 #include "ash/test/ash_test_base.h"
9 #include "ash/wm/window_state.h"
10 #include "ash/wm/workspace_controller.h"
11 #include "base/time/time.h"
12 #include "ui/aura/test/test_windows.h"
13 #include "ui/aura/window.h"
14 #include "ui/compositor/layer.h"
15 #include "ui/compositor/layer_animation_observer.h"
16 #include "ui/compositor/layer_animator.h"
17 #include "ui/compositor/scoped_animation_duration_scale_mode.h"
18 #include "ui/compositor/scoped_layer_animation_settings.h"
20 using aura::Window;
21 using ui::Layer;
23 namespace ash {
24 class WindowAnimationsTest : public ash::test::AshTestBase {
25 public:
26 WindowAnimationsTest() {}
28 void TearDown() override { AshTestBase::TearDown(); }
30 private:
31 DISALLOW_COPY_AND_ASSIGN(WindowAnimationsTest);
34 // Listens to animation scheduled notifications. Remembers the transition
35 // duration of the first sequence.
36 class MinimizeAnimationObserver : public ui::LayerAnimationObserver {
37 public:
38 explicit MinimizeAnimationObserver(ui::LayerAnimator* animator)
39 : animator_(animator) {
40 animator_->AddObserver(this);
41 // RemoveObserver is called when the first animation is scheduled and so
42 // there should be no need for now to remove it in destructor.
44 base::TimeDelta duration() { return duration_; }
46 protected:
47 // ui::LayerAnimationObserver:
48 void OnLayerAnimationScheduled(
49 ui::LayerAnimationSequence* sequence) override {
50 duration_ = animator_->GetTransitionDuration();
51 animator_->RemoveObserver(this);
53 void OnLayerAnimationEnded(ui::LayerAnimationSequence* sequence) override {}
54 void OnLayerAnimationAborted(ui::LayerAnimationSequence* sequence) override {}
56 private:
57 ui::LayerAnimator* animator_;
58 base::TimeDelta duration_;
60 DISALLOW_COPY_AND_ASSIGN(MinimizeAnimationObserver);
63 TEST_F(WindowAnimationsTest, HideShowBrightnessGrayscaleAnimation) {
64 ui::ScopedAnimationDurationScaleMode test_duration_mode(
65 ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
67 scoped_ptr<aura::Window> window(CreateTestWindowInShellWithId(0));
68 window->Show();
69 EXPECT_TRUE(window->layer()->visible());
71 // Hiding.
72 ::wm::SetWindowVisibilityAnimationType(
73 window.get(),
74 WINDOW_VISIBILITY_ANIMATION_TYPE_BRIGHTNESS_GRAYSCALE);
75 AnimateOnChildWindowVisibilityChanged(window.get(), false);
76 EXPECT_EQ(0.0f, window->layer()->GetTargetOpacity());
77 EXPECT_FALSE(window->layer()->GetTargetVisibility());
78 EXPECT_FALSE(window->layer()->visible());
80 // Showing.
81 ::wm::SetWindowVisibilityAnimationType(
82 window.get(),
83 WINDOW_VISIBILITY_ANIMATION_TYPE_BRIGHTNESS_GRAYSCALE);
84 AnimateOnChildWindowVisibilityChanged(window.get(), true);
85 EXPECT_EQ(0.0f, window->layer()->GetTargetBrightness());
86 EXPECT_EQ(0.0f, window->layer()->GetTargetGrayscale());
87 EXPECT_TRUE(window->layer()->visible());
89 // Stays shown.
90 window->layer()->GetAnimator()->Step(base::TimeTicks::Now() +
91 base::TimeDelta::FromSeconds(5));
92 EXPECT_EQ(0.0f, window->layer()->GetTargetBrightness());
93 EXPECT_EQ(0.0f, window->layer()->GetTargetGrayscale());
94 EXPECT_TRUE(window->layer()->visible());
97 TEST_F(WindowAnimationsTest, LayerTargetVisibility) {
98 scoped_ptr<aura::Window> window(CreateTestWindowInShellWithId(0));
100 // Layer target visibility changes according to Show/Hide.
101 window->Show();
102 EXPECT_TRUE(window->layer()->GetTargetVisibility());
103 window->Hide();
104 EXPECT_FALSE(window->layer()->GetTargetVisibility());
105 window->Show();
106 EXPECT_TRUE(window->layer()->GetTargetVisibility());
109 namespace wm {
111 TEST_F(WindowAnimationsTest, CrossFadeToBounds) {
112 ui::ScopedAnimationDurationScaleMode test_duration_mode(
113 ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
115 scoped_ptr<Window> window(CreateTestWindowInShellWithId(0));
116 window->SetBounds(gfx::Rect(5, 10, 320, 240));
117 window->Show();
119 Layer* old_layer = window->layer();
120 EXPECT_EQ(1.0f, old_layer->GetTargetOpacity());
122 // Cross fade to a larger size, as in a maximize animation.
123 GetWindowState(window.get())->SetBoundsDirectCrossFade(
124 gfx::Rect(0, 0, 640, 480));
125 // Window's layer has been replaced.
126 EXPECT_NE(old_layer, window->layer());
127 // Original layer stays opaque and stretches to new size.
128 EXPECT_EQ(1.0f, old_layer->GetTargetOpacity());
129 EXPECT_EQ("5,10 320x240", old_layer->bounds().ToString());
130 gfx::Transform grow_transform;
131 grow_transform.Translate(-5.f, -10.f);
132 grow_transform.Scale(640.f / 320.f, 480.f / 240.f);
133 EXPECT_EQ(grow_transform, old_layer->GetTargetTransform());
134 // New layer animates in to the identity transform.
135 EXPECT_EQ(1.0f, window->layer()->GetTargetOpacity());
136 EXPECT_EQ(gfx::Transform(), window->layer()->GetTargetTransform());
138 // Run the animations to completion.
139 old_layer->GetAnimator()->Step(base::TimeTicks::Now() +
140 base::TimeDelta::FromSeconds(1));
141 window->layer()->GetAnimator()->Step(base::TimeTicks::Now() +
142 base::TimeDelta::FromSeconds(1));
144 // Cross fade to a smaller size, as in a restore animation.
145 old_layer = window->layer();
146 GetWindowState(window.get())->SetBoundsDirectCrossFade(
147 gfx::Rect(5, 10, 320, 240));
148 // Again, window layer has been replaced.
149 EXPECT_NE(old_layer, window->layer());
150 // Original layer fades out and stretches down to new size.
151 EXPECT_EQ(0.0f, old_layer->GetTargetOpacity());
152 EXPECT_EQ("0,0 640x480", old_layer->bounds().ToString());
153 gfx::Transform shrink_transform;
154 shrink_transform.Translate(5.f, 10.f);
155 shrink_transform.Scale(320.f / 640.f, 240.f / 480.f);
156 EXPECT_EQ(shrink_transform, old_layer->GetTargetTransform());
157 // New layer animates in to the identity transform.
158 EXPECT_EQ(1.0f, window->layer()->GetTargetOpacity());
159 EXPECT_EQ(gfx::Transform(), window->layer()->GetTargetTransform());
161 old_layer->GetAnimator()->Step(base::TimeTicks::Now() +
162 base::TimeDelta::FromSeconds(1));
163 window->layer()->GetAnimator()->Step(base::TimeTicks::Now() +
164 base::TimeDelta::FromSeconds(1));
167 // Tests that when crossfading from a window which has a transform that the
168 // crossfade starts from this transformed size rather than snapping the window
169 // to an identity transform and crossfading from there.
170 TEST_F(WindowAnimationsTest, CrossFadeToBoundsFromTransform) {
171 ui::ScopedAnimationDurationScaleMode test_duration_mode(
172 ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
174 scoped_ptr<Window> window(CreateTestWindowInShellWithId(0));
175 window->SetBounds(gfx::Rect(10, 10, 320, 240));
176 gfx::Transform half_size;
177 half_size.Translate(10, 10);
178 half_size.Scale(0.5f, 0.5f);
179 window->SetTransform(half_size);
180 window->Show();
182 Layer* old_layer = window->layer();
183 EXPECT_EQ(1.0f, old_layer->GetTargetOpacity());
185 // Cross fade to a larger size, as in a maximize animation.
186 GetWindowState(window.get())->SetBoundsDirectCrossFade(
187 gfx::Rect(0, 0, 640, 480));
188 // Window's layer has been replaced.
189 EXPECT_NE(old_layer, window->layer());
190 // Original layer stays opaque and stretches to new size.
191 EXPECT_EQ(1.0f, old_layer->GetTargetOpacity());
192 EXPECT_EQ("10,10 320x240", old_layer->bounds().ToString());
193 EXPECT_EQ(half_size, old_layer->transform());
195 // New layer animates in from the old window's transformed size to the
196 // identity transform.
197 EXPECT_EQ(1.0f, window->layer()->GetTargetOpacity());
198 // Set up the transform necessary to start at the old windows transformed
199 // position.
200 gfx::Transform quarter_size_shifted;
201 quarter_size_shifted.Translate(20, 20);
202 quarter_size_shifted.Scale(0.25f, 0.25f);
203 EXPECT_EQ(quarter_size_shifted, window->layer()->transform());
204 EXPECT_EQ(gfx::Transform(), window->layer()->GetTargetTransform());
207 } // namespace wm
209 TEST_F(WindowAnimationsTest, LockAnimationDuration) {
210 ui::ScopedAnimationDurationScaleMode test_duration_mode(
211 ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
213 scoped_ptr<Window> window(CreateTestWindowInShellWithId(0));
214 Layer* layer = window->layer();
215 window->SetBounds(gfx::Rect(5, 10, 320, 240));
216 window->Show();
218 // Test that it is possible to override transition duration when it is not
219 // locked.
221 ui::ScopedLayerAnimationSettings settings1(layer->GetAnimator());
222 settings1.SetTransitionDuration(base::TimeDelta::FromMilliseconds(1000));
224 ui::ScopedLayerAnimationSettings settings2(layer->GetAnimator());
225 // Duration is not locked so it gets overridden.
226 settings2.SetTransitionDuration(base::TimeDelta::FromMilliseconds(50));
227 wm::GetWindowState(window.get())->Minimize();
228 EXPECT_TRUE(layer->GetAnimator()->is_animating());
229 // Expect duration from the inner scope
230 EXPECT_EQ(50,
231 layer->GetAnimator()->GetTransitionDuration().InMilliseconds());
233 window->Show();
234 layer->GetAnimator()->StopAnimating();
237 // Test that it is possible to lock transition duration
239 // Update layer as minimizing will replace the window's layer.
240 layer = window->layer();
241 ui::ScopedLayerAnimationSettings settings1(layer->GetAnimator());
242 settings1.SetTransitionDuration(base::TimeDelta::FromMilliseconds(1000));
243 // Duration is locked in outer scope.
244 settings1.LockTransitionDuration();
246 ui::ScopedLayerAnimationSettings settings2(layer->GetAnimator());
247 // Transition duration setting is ignored.
248 settings2.SetTransitionDuration(base::TimeDelta::FromMilliseconds(50));
249 wm::GetWindowState(window.get())->Minimize();
250 EXPECT_TRUE(layer->GetAnimator()->is_animating());
251 // Expect duration from the outer scope
252 EXPECT_EQ(1000,
253 layer->GetAnimator()->GetTransitionDuration().InMilliseconds());
255 window->Show();
256 layer->GetAnimator()->StopAnimating();
259 // Test that duration respects default.
261 layer = window->layer();
262 // Query default duration.
263 MinimizeAnimationObserver observer(layer->GetAnimator());
264 wm::GetWindowState(window.get())->Minimize();
265 EXPECT_TRUE(layer->GetAnimator()->is_animating());
266 base::TimeDelta default_duration(observer.duration());
267 window->Show();
268 layer->GetAnimator()->StopAnimating();
270 layer = window->layer();
271 ui::ScopedLayerAnimationSettings settings(layer->GetAnimator());
272 settings.LockTransitionDuration();
273 // Setting transition duration is ignored since duration is locked
274 settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds(1000));
275 wm::GetWindowState(window.get())->Minimize();
276 EXPECT_TRUE(layer->GetAnimator()->is_animating());
277 // Expect default duration (200ms for stock ash minimizing animation).
278 EXPECT_EQ(default_duration.InMilliseconds(),
279 layer->GetAnimator()->GetTransitionDuration().InMilliseconds());
280 window->Show();
281 layer->GetAnimator()->StopAnimating();
285 } // namespace ash