Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / ui / wm / core / shadow_controller_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/shadow_controller.h"
6
7 #include <algorithm>
8 #include <vector>
9
10 #include "base/memory/scoped_ptr.h"
11 #include "ui/aura/client/window_tree_client.h"
12 #include "ui/aura/test/aura_test_base.h"
13 #include "ui/aura/window.h"
14 #include "ui/aura/window_event_dispatcher.h"
15 #include "ui/compositor/layer.h"
16 #include "ui/wm/core/default_activation_client.h"
17 #include "ui/wm/core/shadow.h"
18 #include "ui/wm/core/shadow_types.h"
19 #include "ui/wm/core/window_util.h"
20 #include "ui/wm/core/wm_state.h"
21 #include "ui/wm/public/activation_client.h"
22
23 namespace wm {
24
25 class ShadowControllerTest : public aura::test::AuraTestBase {
26  public:
27   ShadowControllerTest() {}
28   virtual ~ShadowControllerTest() {}
29
30   virtual void SetUp() OVERRIDE {
31     wm_state_.reset(new wm::WMState);
32     AuraTestBase::SetUp();
33     new wm::DefaultActivationClient(root_window());
34     aura::client::ActivationClient* activation_client =
35         aura::client::GetActivationClient(root_window());
36     shadow_controller_.reset(new ShadowController(activation_client));
37   }
38   virtual void TearDown() OVERRIDE {
39     shadow_controller_.reset();
40     AuraTestBase::TearDown();
41     wm_state_.reset();
42   }
43
44  protected:
45   ShadowController* shadow_controller() { return shadow_controller_.get(); }
46
47   void ActivateWindow(aura::Window* window) {
48     DCHECK(window);
49     DCHECK(window->GetRootWindow());
50     aura::client::GetActivationClient(window->GetRootWindow())->ActivateWindow(
51         window);
52   }
53
54  private:
55   scoped_ptr<ShadowController> shadow_controller_;
56   scoped_ptr<wm::WMState> wm_state_;
57
58   DISALLOW_COPY_AND_ASSIGN(ShadowControllerTest);
59 };
60
61 // Tests that various methods in Window update the Shadow object as expected.
62 TEST_F(ShadowControllerTest, Shadow) {
63   scoped_ptr<aura::Window> window(new aura::Window(NULL));
64   window->SetType(ui::wm::WINDOW_TYPE_NORMAL);
65   window->Init(aura::WINDOW_LAYER_TEXTURED);
66   ParentWindow(window.get());
67
68   // We should create the shadow before the window is visible (the shadow's
69   // layer won't get drawn yet since it's a child of the window's layer).
70   ShadowController::TestApi api(shadow_controller());
71   const Shadow* shadow = api.GetShadowForWindow(window.get());
72   ASSERT_TRUE(shadow != NULL);
73   EXPECT_TRUE(shadow->layer()->visible());
74
75   // The shadow should remain visible after window visibility changes.
76   window->Show();
77   EXPECT_TRUE(shadow->layer()->visible());
78   window->Hide();
79   EXPECT_TRUE(shadow->layer()->visible());
80
81   // If the shadow is disabled, it should be hidden.
82   SetShadowType(window.get(), SHADOW_TYPE_NONE);
83   window->Show();
84   EXPECT_FALSE(shadow->layer()->visible());
85   SetShadowType(window.get(), SHADOW_TYPE_RECTANGULAR);
86   EXPECT_TRUE(shadow->layer()->visible());
87
88   // The shadow's layer should be a child of the window's layer.
89   EXPECT_EQ(window->layer(), shadow->layer()->parent());
90
91   window->parent()->RemoveChild(window.get());
92   aura::Window* window_ptr = window.get();
93   window.reset();
94   EXPECT_TRUE(api.GetShadowForWindow(window_ptr) == NULL);
95 }
96
97 // Tests that the window's shadow's bounds are updated correctly.
98 TEST_F(ShadowControllerTest, ShadowBounds) {
99   scoped_ptr<aura::Window> window(new aura::Window(NULL));
100   window->SetType(ui::wm::WINDOW_TYPE_NORMAL);
101   window->Init(aura::WINDOW_LAYER_TEXTURED);
102   ParentWindow(window.get());
103   window->Show();
104
105   const gfx::Rect kOldBounds(20, 30, 400, 300);
106   window->SetBounds(kOldBounds);
107
108   // When the shadow is first created, it should use the window's size (but
109   // remain at the origin, since it's a child of the window's layer).
110   SetShadowType(window.get(), SHADOW_TYPE_RECTANGULAR);
111   ShadowController::TestApi api(shadow_controller());
112   const Shadow* shadow = api.GetShadowForWindow(window.get());
113   ASSERT_TRUE(shadow != NULL);
114   EXPECT_EQ(gfx::Rect(kOldBounds.size()).ToString(),
115             shadow->content_bounds().ToString());
116
117   // When we change the window's bounds, the shadow's should be updated too.
118   gfx::Rect kNewBounds(50, 60, 500, 400);
119   window->SetBounds(kNewBounds);
120   EXPECT_EQ(gfx::Rect(kNewBounds.size()).ToString(),
121             shadow->content_bounds().ToString());
122 }
123
124 // Tests that activating a window changes the shadow style.
125 TEST_F(ShadowControllerTest, ShadowStyle) {
126   ShadowController::TestApi api(shadow_controller());
127
128   scoped_ptr<aura::Window> window1(new aura::Window(NULL));
129   window1->SetType(ui::wm::WINDOW_TYPE_NORMAL);
130   window1->Init(aura::WINDOW_LAYER_TEXTURED);
131   ParentWindow(window1.get());
132   window1->SetBounds(gfx::Rect(10, 20, 300, 400));
133   window1->Show();
134   ActivateWindow(window1.get());
135
136   // window1 is active, so style should have active appearance.
137   Shadow* shadow1 = api.GetShadowForWindow(window1.get());
138   ASSERT_TRUE(shadow1 != NULL);
139   EXPECT_EQ(Shadow::STYLE_ACTIVE, shadow1->style());
140
141   // Create another window and activate it.
142   scoped_ptr<aura::Window> window2(new aura::Window(NULL));
143   window2->SetType(ui::wm::WINDOW_TYPE_NORMAL);
144   window2->Init(aura::WINDOW_LAYER_TEXTURED);
145   ParentWindow(window2.get());
146   window2->SetBounds(gfx::Rect(11, 21, 301, 401));
147   window2->Show();
148   ActivateWindow(window2.get());
149
150   // window1 is now inactive, so shadow should go inactive.
151   Shadow* shadow2 = api.GetShadowForWindow(window2.get());
152   ASSERT_TRUE(shadow2 != NULL);
153   EXPECT_EQ(Shadow::STYLE_INACTIVE, shadow1->style());
154   EXPECT_EQ(Shadow::STYLE_ACTIVE, shadow2->style());
155 }
156
157 // Tests that we use smaller shadows for tooltips and menus.
158 TEST_F(ShadowControllerTest, SmallShadowsForTooltipsAndMenus) {
159   ShadowController::TestApi api(shadow_controller());
160
161   scoped_ptr<aura::Window> tooltip_window(new aura::Window(NULL));
162   tooltip_window->SetType(ui::wm::WINDOW_TYPE_TOOLTIP);
163   tooltip_window->Init(aura::WINDOW_LAYER_TEXTURED);
164   ParentWindow(tooltip_window.get());
165   tooltip_window->SetBounds(gfx::Rect(10, 20, 300, 400));
166   tooltip_window->Show();
167
168   Shadow* tooltip_shadow = api.GetShadowForWindow(tooltip_window.get());
169   ASSERT_TRUE(tooltip_shadow != NULL);
170   EXPECT_EQ(Shadow::STYLE_SMALL, tooltip_shadow->style());
171
172   scoped_ptr<aura::Window> menu_window(new aura::Window(NULL));
173   menu_window->SetType(ui::wm::WINDOW_TYPE_MENU);
174   menu_window->Init(aura::WINDOW_LAYER_TEXTURED);
175   ParentWindow(menu_window.get());
176   menu_window->SetBounds(gfx::Rect(10, 20, 300, 400));
177   menu_window->Show();
178
179   Shadow* menu_shadow = api.GetShadowForWindow(tooltip_window.get());
180   ASSERT_TRUE(menu_shadow != NULL);
181   EXPECT_EQ(Shadow::STYLE_SMALL, menu_shadow->style());
182 }
183
184 // http://crbug.com/120210 - transient parents of certain types of transients
185 // should not lose their shadow when they lose activation to the transient.
186 TEST_F(ShadowControllerTest, TransientParentKeepsActiveShadow) {
187   ShadowController::TestApi api(shadow_controller());
188
189   scoped_ptr<aura::Window> window1(new aura::Window(NULL));
190   window1->SetType(ui::wm::WINDOW_TYPE_NORMAL);
191   window1->Init(aura::WINDOW_LAYER_TEXTURED);
192   ParentWindow(window1.get());
193   window1->SetBounds(gfx::Rect(10, 20, 300, 400));
194   window1->Show();
195   ActivateWindow(window1.get());
196
197   // window1 is active, so style should have active appearance.
198   Shadow* shadow1 = api.GetShadowForWindow(window1.get());
199   ASSERT_TRUE(shadow1 != NULL);
200   EXPECT_EQ(Shadow::STYLE_ACTIVE, shadow1->style());
201
202   // Create a window that is transient to window1, and that has the 'hide on
203   // deactivate' property set. Upon activation, window1 should still have an
204   // active shadow.
205   scoped_ptr<aura::Window> window2(new aura::Window(NULL));
206   window2->SetType(ui::wm::WINDOW_TYPE_NORMAL);
207   window2->Init(aura::WINDOW_LAYER_TEXTURED);
208   ParentWindow(window2.get());
209   window2->SetBounds(gfx::Rect(11, 21, 301, 401));
210   AddTransientChild(window1.get(), window2.get());
211   aura::client::SetHideOnDeactivate(window2.get(), true);
212   window2->Show();
213   ActivateWindow(window2.get());
214
215   // window1 is now inactive, but its shadow should still appear active.
216   EXPECT_EQ(Shadow::STYLE_ACTIVE, shadow1->style());
217 }
218
219 }  // namespace wm