Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / ui / wm / core / window_animations_unittest.cc
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.
4
5 #include "ui/wm/core/window_animations.h"
6
7 #include "base/time/time.h"
8 #include "ui/aura/test/aura_test_base.h"
9 #include "ui/aura/test/test_windows.h"
10 #include "ui/aura/window.h"
11 #include "ui/compositor/layer.h"
12 #include "ui/compositor/layer_animator.h"
13 #include "ui/compositor/scoped_animation_duration_scale_mode.h"
14 #include "ui/gfx/animation/animation_container_element.h"
15 #include "ui/gfx/vector2d.h"
16 #include "ui/wm/core/transient_window_manager.h"
17 #include "ui/wm/core/transient_window_stacking_client.h"
18 #include "ui/wm/core/window_util.h"
19 #include "ui/wm/public/animation_host.h"
20
21 using aura::Window;
22 using ui::Layer;
23
24 namespace wm {
25 namespace {
26
27 template<typename T>int GetZPosition(const T* child) {
28   const T* parent = child->parent();
29   const std::vector<T*> children = parent->children();
30   typename std::vector<T*>::const_iterator iter =
31       std::find(children.begin(), children.end(), child);
32   DCHECK(iter != children.end());
33   return iter - children.begin();
34 }
35
36 int GetWindowZPosition(const aura::Window* child) {
37   return GetZPosition<aura::Window>(child);
38 }
39
40 int GetLayerZPosition(const ui::Layer* child) {
41   return GetZPosition<ui::Layer>(child);
42 }
43
44 }  // namespace
45
46 class WindowAnimationsTest : public aura::test::AuraTestBase {
47  public:
48   WindowAnimationsTest() {}
49
50   virtual void TearDown() OVERRIDE {
51     AuraTestBase::TearDown();
52   }
53
54  private:
55   DISALLOW_COPY_AND_ASSIGN(WindowAnimationsTest);
56 };
57
58 TEST_F(WindowAnimationsTest, LayerTargetVisibility) {
59   scoped_ptr<aura::Window> window(
60       aura::test::CreateTestWindowWithId(0, NULL));
61
62   // Layer target visibility changes according to Show/Hide.
63   window->Show();
64   EXPECT_TRUE(window->layer()->GetTargetVisibility());
65   window->Hide();
66   EXPECT_FALSE(window->layer()->GetTargetVisibility());
67   window->Show();
68   EXPECT_TRUE(window->layer()->GetTargetVisibility());
69 }
70
71 TEST_F(WindowAnimationsTest, LayerTargetVisibility_AnimateShow) {
72   // Tests if opacity and transform are reset when only show animation is
73   // enabled.  See also LayerTargetVisibility_AnimateHide.
74   // Since the window is not visible after Hide() is called, opacity and
75   // transform shouldn't matter in case of ANIMATE_SHOW, but we reset them
76   // to keep consistency.
77
78   scoped_ptr<aura::Window> window(aura::test::CreateTestWindowWithId(0, NULL));
79   SetWindowVisibilityAnimationTransition(window.get(), ANIMATE_SHOW);
80
81   // Layer target visibility and opacity change according to Show/Hide.
82   window->Show();
83   AnimateOnChildWindowVisibilityChanged(window.get(), true);
84   EXPECT_TRUE(window->layer()->GetTargetVisibility());
85   EXPECT_EQ(1, window->layer()->opacity());
86
87   window->Hide();
88   AnimateOnChildWindowVisibilityChanged(window.get(), false);
89   EXPECT_FALSE(window->layer()->GetTargetVisibility());
90   EXPECT_EQ(0, window->layer()->opacity());
91   EXPECT_EQ(gfx::Transform(), window->layer()->transform());
92
93   window->Show();
94   AnimateOnChildWindowVisibilityChanged(window.get(), true);
95   EXPECT_TRUE(window->layer()->GetTargetVisibility());
96   EXPECT_EQ(1, window->layer()->opacity());
97 }
98
99 TEST_F(WindowAnimationsTest, LayerTargetVisibility_AnimateHide) {
100   // Tests if opacity and transform are reset when only hide animation is
101   // enabled.  Hide animation changes opacity and transform in addition to
102   // visibility, so we need to reset not only visibility but also opacity
103   // and transform to show the window.
104
105   scoped_ptr<aura::Window> window(aura::test::CreateTestWindowWithId(0, NULL));
106   SetWindowVisibilityAnimationTransition(window.get(), ANIMATE_HIDE);
107
108   // Layer target visibility and opacity change according to Show/Hide.
109   window->Show();
110   AnimateOnChildWindowVisibilityChanged(window.get(), true);
111   EXPECT_TRUE(window->layer()->GetTargetVisibility());
112   EXPECT_EQ(1, window->layer()->opacity());
113   EXPECT_EQ(gfx::Transform(), window->layer()->transform());
114
115   window->Hide();
116   AnimateOnChildWindowVisibilityChanged(window.get(), false);
117   EXPECT_FALSE(window->layer()->GetTargetVisibility());
118   EXPECT_EQ(0, window->layer()->opacity());
119
120   window->Show();
121   AnimateOnChildWindowVisibilityChanged(window.get(), true);
122   EXPECT_TRUE(window->layer()->GetTargetVisibility());
123   EXPECT_EQ(1, window->layer()->opacity());
124   EXPECT_EQ(gfx::Transform(), window->layer()->transform());
125 }
126
127 TEST_F(WindowAnimationsTest, HideAnimationDetachLayers) {
128   scoped_ptr<aura::Window> parent(aura::test::CreateTestWindowWithId(0, NULL));
129
130   scoped_ptr<aura::Window> other(
131       aura::test::CreateTestWindowWithId(1, parent.get()));
132
133   scoped_ptr<aura::Window> animating_window(
134       aura::test::CreateTestWindowWithId(2, parent.get()));
135   SetWindowVisibilityAnimationTransition(animating_window.get(), ANIMATE_HIDE);
136
137   EXPECT_EQ(0, GetWindowZPosition(other.get()));
138   EXPECT_EQ(1, GetWindowZPosition(animating_window.get()));
139   EXPECT_EQ(0, GetLayerZPosition(other->layer()));
140   EXPECT_EQ(1, GetLayerZPosition(animating_window->layer()));
141
142   {
143     ui::ScopedAnimationDurationScaleMode scale_mode(
144         ui::ScopedAnimationDurationScaleMode::FAST_DURATION);
145     ui::Layer* animating_layer = animating_window->layer();
146
147     animating_window->Hide();
148     EXPECT_TRUE(AnimateOnChildWindowVisibilityChanged(
149         animating_window.get(), false));
150     EXPECT_TRUE(animating_layer->GetAnimator()->is_animating());
151     EXPECT_FALSE(animating_layer->delegate());
152
153     // Make sure the Hide animation create another layer, and both are in
154     // the parent layer.
155     EXPECT_NE(animating_window->layer(), animating_layer);
156     EXPECT_TRUE(
157         std::find(parent->layer()->children().begin(),
158                   parent->layer()->children().end(),
159                   animating_layer) !=
160         parent->layer()->children().end());
161     EXPECT_TRUE(
162         std::find(parent->layer()->children().begin(),
163                   parent->layer()->children().end(),
164                   animating_window->layer()) !=
165         parent->layer()->children().end());
166     // Current layer must be already hidden.
167     EXPECT_FALSE(animating_window->layer()->visible());
168
169     EXPECT_EQ(1, GetWindowZPosition(animating_window.get()));
170     EXPECT_EQ(1, GetLayerZPosition(animating_window->layer()));
171     EXPECT_EQ(2, GetLayerZPosition(animating_layer));
172
173     parent->StackChildAtTop(other.get());
174     EXPECT_EQ(0, GetWindowZPosition(animating_window.get()));
175     EXPECT_EQ(1, GetWindowZPosition(other.get()));
176
177     EXPECT_EQ(0, GetLayerZPosition(animating_window->layer()));
178     EXPECT_EQ(1, GetLayerZPosition(other->layer()));
179     // Make sure the animating layer is on top.
180     EXPECT_EQ(2, GetLayerZPosition(animating_layer));
181
182     // Animating layer must be gone
183     animating_layer->GetAnimator()->StopAnimating();
184     EXPECT_TRUE(
185         std::find(parent->layer()->children().begin(),
186                   parent->layer()->children().end(),
187                   animating_layer) ==
188         parent->layer()->children().end());
189   }
190 }
191
192 TEST_F(WindowAnimationsTest, HideAnimationDetachLayersWithTransientChildren) {
193   TransientWindowStackingClient transient_stacking_client;
194
195   scoped_ptr<aura::Window> parent(aura::test::CreateTestWindowWithId(0, NULL));
196
197   scoped_ptr<aura::Window> other(
198       aura::test::CreateTestWindowWithId(1, parent.get()));
199
200   scoped_ptr<aura::Window> animating_window(
201       aura::test::CreateTestWindowWithId(2, parent.get()));
202   SetWindowVisibilityAnimationTransition(animating_window.get(), ANIMATE_HIDE);
203
204   scoped_ptr<aura::Window> transient1(
205       aura::test::CreateTestWindowWithId(3, parent.get()));
206   scoped_ptr<aura::Window> transient2(
207       aura::test::CreateTestWindowWithId(4, parent.get()));
208
209   TransientWindowManager::Get(animating_window.get());
210   AddTransientChild(animating_window.get(), transient1.get());
211   AddTransientChild(animating_window.get(), transient2.get());
212
213   EXPECT_EQ(0, GetWindowZPosition(other.get()));
214   EXPECT_EQ(1, GetWindowZPosition(animating_window.get()));
215   EXPECT_EQ(2, GetWindowZPosition(transient1.get()));
216   EXPECT_EQ(3, GetWindowZPosition(transient2.get()));
217
218   {
219     ui::ScopedAnimationDurationScaleMode scale_mode(
220         ui::ScopedAnimationDurationScaleMode::FAST_DURATION);
221     ui::Layer* animating_layer = animating_window->layer();
222
223     animating_window->Hide();
224     EXPECT_TRUE(AnimateOnChildWindowVisibilityChanged(
225         animating_window.get(), false));
226     EXPECT_TRUE(animating_layer->GetAnimator()->is_animating());
227     EXPECT_FALSE(animating_layer->delegate());
228
229     EXPECT_EQ(1, GetWindowZPosition(animating_window.get()));
230     EXPECT_EQ(2, GetWindowZPosition(transient1.get()));
231     EXPECT_EQ(3, GetWindowZPosition(transient2.get()));
232
233     EXPECT_EQ(1, GetLayerZPosition(animating_window->layer()));
234     EXPECT_EQ(2, GetLayerZPosition(transient1->layer()));
235     EXPECT_EQ(3, GetLayerZPosition(transient2->layer()));
236     EXPECT_EQ(4, GetLayerZPosition(animating_layer));
237
238     parent->StackChildAtTop(other.get());
239
240     EXPECT_EQ(0, GetWindowZPosition(animating_window.get()));
241     EXPECT_EQ(1, GetWindowZPosition(transient1.get()));
242     EXPECT_EQ(2, GetWindowZPosition(transient2.get()));
243     EXPECT_EQ(3, GetWindowZPosition(other.get()));
244
245     EXPECT_EQ(0, GetLayerZPosition(animating_window->layer()));
246     EXPECT_EQ(1, GetLayerZPosition(transient1->layer()));
247     EXPECT_EQ(2, GetLayerZPosition(transient2->layer()));
248     EXPECT_EQ(3, GetLayerZPosition(other->layer()));
249     // Make sure the animating layer is on top of all windows.
250     EXPECT_EQ(4, GetLayerZPosition(animating_layer));
251   }
252 }
253
254 // A simple AnimationHost implementation for the NotifyHideCompleted test.
255 class NotifyHideCompletedAnimationHost : public aura::client::AnimationHost {
256  public:
257   NotifyHideCompletedAnimationHost() : hide_completed_(false) {}
258   virtual ~NotifyHideCompletedAnimationHost() {}
259
260   // Overridden from TestWindowDelegate:
261   virtual void OnWindowHidingAnimationCompleted() OVERRIDE {
262     hide_completed_ = true;
263   }
264
265   virtual void SetHostTransitionOffsets(
266       const gfx::Vector2d& top_left,
267       const gfx::Vector2d& bottom_right) OVERRIDE {}
268
269   bool hide_completed() const { return hide_completed_; }
270
271  private:
272   bool hide_completed_;
273
274   DISALLOW_COPY_AND_ASSIGN(NotifyHideCompletedAnimationHost);
275 };
276
277 TEST_F(WindowAnimationsTest, NotifyHideCompleted) {
278   NotifyHideCompletedAnimationHost animation_host;
279   scoped_ptr<aura::Window> window(aura::test::CreateTestWindowWithId(0, NULL));
280   aura::client::SetAnimationHost(window.get(), &animation_host);
281   wm::SetWindowVisibilityAnimationType(
282       window.get(), WINDOW_VISIBILITY_ANIMATION_TYPE_FADE);
283   AnimateOnChildWindowVisibilityChanged(window.get(), true);
284   EXPECT_TRUE(window->layer()->visible());
285
286   EXPECT_FALSE(animation_host.hide_completed());
287   AnimateOnChildWindowVisibilityChanged(window.get(), false);
288   EXPECT_TRUE(animation_host.hide_completed());
289 }
290
291 // The rotation animation for hiding a window should not leak the animation
292 // observer.
293 TEST_F(WindowAnimationsTest, RotateHideNoLeak) {
294   ui::ScopedAnimationDurationScaleMode scale_mode(
295       ui::ScopedAnimationDurationScaleMode::FAST_DURATION);
296
297   scoped_ptr<aura::Window> window(aura::test::CreateTestWindowWithId(0, NULL));
298   ui::Layer* animating_layer = window->layer();
299   wm::SetWindowVisibilityAnimationType(window.get(),
300                                        WINDOW_VISIBILITY_ANIMATION_TYPE_ROTATE);
301
302   AnimateOnChildWindowVisibilityChanged(window.get(), true);
303   AnimateOnChildWindowVisibilityChanged(window.get(), false);
304
305   animating_layer->GetAnimator()->StopAnimating();
306 }
307
308 }  // namespace wm