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