Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / ash / window_positioner_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 "ash/wm/window_positioner.h"
6
7 #include "ash/shell.h"
8 #include "ash/test/ash_test_base.h"
9 #include "ash/test/test_shell_delegate.h"
10 #include "ash/wm/window_resizer.h"
11 #include "base/compiler_specific.h"
12 #include "base/logging.h"
13 #include "chrome/browser/ui/browser.h"
14 #include "chrome/browser/ui/host_desktop.h"
15 #include "chrome/test/base/test_browser_window.h"
16 #include "chrome/test/base/testing_profile.h"
17 #include "content/public/test/render_view_test.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19 #include "ui/aura/env.h"
20 #include "ui/aura/test/test_windows.h"
21 #include "ui/aura/window_event_dispatcher.h"
22 #include "ui/gfx/screen.h"
23
24 namespace ash {
25 namespace test {
26
27 namespace {
28
29 // A browser window proxy which is able to associate an aura native window with
30 // it.
31 class TestBrowserWindowAura : public TestBrowserWindow {
32  public:
33   explicit TestBrowserWindowAura(aura::Window* native_window);
34   ~TestBrowserWindowAura() override;
35
36   gfx::NativeWindow GetNativeWindow() const override { return native_window_; }
37
38  private:
39   gfx::NativeWindow native_window_;
40
41   DISALLOW_COPY_AND_ASSIGN(TestBrowserWindowAura);
42 };
43
44 TestBrowserWindowAura::TestBrowserWindowAura(aura::Window *native_window)
45     : native_window_(native_window) {
46 }
47
48 TestBrowserWindowAura::~TestBrowserWindowAura() {}
49
50 }  // namespace
51
52 // A test class for preparing window positioner tests - it creates a testing
53 // base by adding a window and a popup which can be independently
54 // positioned to see where the positioner will place the window.
55 class WindowPositionerTest : public AshTestBase {
56  public:
57   WindowPositionerTest();
58
59   void SetUp() override;
60   void TearDown() override;
61
62  protected:
63   aura::Window* window() { return window_.get(); }
64   aura::Window* popup() { return popup_.get(); }
65
66   Browser* window_browser() { return window_owning_browser_.get(); }
67   Browser* popup_browser() { return popup_owning_browser_.get(); }
68
69   WindowPositioner* window_positioner() { return window_positioner_; }
70
71   // The positioner & desktop's used grid alignment size.
72   const int grid_size_;
73
74  private:
75   WindowPositioner* window_positioner_;
76
77   // These two need to be deleted after everything else is gone.
78   TestingProfile profile_;
79
80   // These get created for each session.
81   scoped_ptr<aura::Window> window_;
82   scoped_ptr<aura::Window> popup_;
83
84   scoped_ptr<BrowserWindow> browser_window_;
85   scoped_ptr<BrowserWindow> browser_popup_;
86
87   scoped_ptr<Browser> window_owning_browser_;
88   scoped_ptr<Browser> popup_owning_browser_;
89
90   DISALLOW_COPY_AND_ASSIGN(WindowPositionerTest);
91 };
92
93 WindowPositionerTest::WindowPositionerTest()
94     : grid_size_(WindowPositioner::kMinimumWindowOffset),
95       window_positioner_(NULL) {
96 }
97
98 void WindowPositionerTest::SetUp() {
99   AshTestBase::SetUp();
100   // Create some default dummy windows.
101   window_.reset(CreateTestWindowInShellWithId(0));
102   window_->SetBounds(gfx::Rect(16, 32, 640, 320));
103   popup_.reset(CreateTestWindowInShellWithId(1));
104   popup_->SetBounds(gfx::Rect(16, 32, 128, 256));
105
106   // Create a browser for the window.
107   browser_window_.reset(new TestBrowserWindowAura(window_.get()));
108   Browser::CreateParams window_params(&profile_,
109                                       chrome::HOST_DESKTOP_TYPE_ASH);
110   window_params.window = browser_window_.get();
111   window_owning_browser_.reset(new Browser(window_params));
112
113   // Creating a browser for the popup.
114   browser_popup_.reset(new TestBrowserWindowAura(popup_.get()));
115   Browser::CreateParams popup_params(Browser::TYPE_POPUP, &profile_,
116                                      chrome::HOST_DESKTOP_TYPE_ASH);
117   popup_params.window = browser_popup_.get();
118   popup_owning_browser_.reset(new Browser(popup_params));
119
120   // We hide all windows upon start - each user is required to set it up
121   // as he needs it.
122   window()->Hide();
123   popup()->Hide();
124   window_positioner_ = new WindowPositioner();
125 }
126
127 void WindowPositionerTest::TearDown() {
128   // Since the AuraTestBase is needed to create our assets, we have to
129   // also delete them before we tear it down.
130   window_owning_browser_.reset(NULL);
131   popup_owning_browser_.reset(NULL);
132
133   browser_window_.reset(NULL);
134   browser_popup_.reset(NULL);
135
136   window_.reset(NULL);
137   popup_.reset(NULL);
138
139   AshTestBase::TearDown();
140   delete window_positioner_;
141   window_positioner_ = NULL;
142 }
143
144 int AlignToGridRoundDown(int location, int grid_size) {
145   if (grid_size <= 1 || location % grid_size == 0)
146     return location;
147   return location / grid_size * grid_size;
148 }
149
150 TEST_F(WindowPositionerTest, cascading) {
151   const gfx::Rect work_area =
152       Shell::GetScreen()->GetPrimaryDisplay().work_area();
153
154   // First see that the window will cascade down when there is no space.
155   window()->SetBounds(work_area);
156   window()->Show();
157
158   gfx::Rect popup_position(0, 0, 200, 200);
159   // Check that it gets cascaded.
160   gfx::Rect cascade_1 = window_positioner()->GetPopupPosition(popup_position);
161   EXPECT_EQ(gfx::Rect(work_area.x() + grid_size_, work_area.y() + grid_size_,
162                       popup_position.width(), popup_position.height()),
163                       cascade_1);
164
165   gfx::Rect cascade_2 = window_positioner()->GetPopupPosition(popup_position);
166   EXPECT_EQ(gfx::Rect(work_area.x() + 2 * grid_size_,
167                       work_area.y() + 2 * grid_size_,
168                       popup_position.width(), popup_position.height()),
169                       cascade_2);
170
171   // Check that if there is even only a pixel missing it will cascade.
172   window()->SetBounds(gfx::Rect(work_area.x() + popup_position.width() - 1,
173                                 work_area.y() + popup_position.height() - 1,
174                                 work_area.width() -
175                                     2 * (popup_position.width() - 1),
176                                 work_area.height() -
177                                     2 * (popup_position.height() - 1)));
178
179   gfx::Rect cascade_3 = window_positioner()->GetPopupPosition(popup_position);
180   EXPECT_EQ(gfx::Rect(work_area.x() + 3 * grid_size_,
181                       work_area.y() + 3 * grid_size_,
182                       popup_position.width(), popup_position.height()),
183                       cascade_3);
184
185   // Check that we overflow into the next line when we do not fit anymore in Y.
186   gfx::Rect popup_position_4(0, 0, 200,
187                              work_area.height() -
188                                  (cascade_3.y() - work_area.y()));
189   gfx::Rect cascade_4 =
190       window_positioner()->GetPopupPosition(popup_position_4);
191   EXPECT_EQ(gfx::Rect(work_area.x() + 2 * grid_size_,
192                       work_area.y() + grid_size_,
193                       popup_position_4.width(), popup_position_4.height()),
194                       cascade_4);
195
196   // Check that we overflow back to the first possible location if we overflow
197   // to the end.
198   gfx::Rect popup_position_5(0, 0,
199                             work_area.width() + 1 -
200                                 (cascade_4.x() - work_area.x()),
201                             work_area.height() -
202                                 (2 * grid_size_ - work_area.y()));
203   gfx::Rect cascade_5 =
204       window_positioner()->GetPopupPosition(popup_position_5);
205   EXPECT_EQ(gfx::Rect(work_area.x() + grid_size_,
206                       work_area.y() + grid_size_,
207                       popup_position_5.width(), popup_position_5.height()),
208                       cascade_5);
209 }
210
211 TEST_F(WindowPositionerTest, filling) {
212   const gfx::Rect work_area =
213       Shell::GetScreen()->GetPrimaryDisplay().work_area();
214   gfx::Rect popup_position(0, 0, 256, 128);
215   // Leave space on the left and the right and see if we fill top to bottom.
216   window()->SetBounds(gfx::Rect(work_area.x() + popup_position.width(),
217                                 work_area.y(),
218                                 work_area.width() - 2 * popup_position.width(),
219                                 work_area.height()));
220   window()->Show();
221   // Check that we are positioned in the top left corner.
222   gfx::Rect top_left = window_positioner()->GetPopupPosition(popup_position);
223   EXPECT_EQ(gfx::Rect(work_area.x(), work_area.y(),
224                       popup_position.width(), popup_position.height()),
225                       top_left);
226
227   // Now block the found location.
228   popup()->SetBounds(top_left);
229   popup()->Show();
230   gfx::Rect mid_left = window_positioner()->GetPopupPosition(popup_position);
231   EXPECT_EQ(gfx::Rect(work_area.x(),
232                       AlignToGridRoundDown(
233                           work_area.y() + top_left.height(), grid_size_),
234                           popup_position.width(), popup_position.height()),
235                       mid_left);
236
237   // Block now everything so that we can only put the popup on the bottom
238   // of the left side.
239   // Note: We need to keep one "grid spacing free" if the window does not
240   // fit into the grid (which is true for 200 height).`
241   popup()->SetBounds(gfx::Rect(work_area.x(), work_area.y(),
242                                popup_position.width(),
243                                work_area.height() - popup_position.height() -
244                                    grid_size_ + 1));
245   gfx::Rect bottom_left = window_positioner()->GetPopupPosition(
246                               popup_position);
247   EXPECT_EQ(gfx::Rect(work_area.x(),
248                       work_area.bottom() - popup_position.height(),
249                       popup_position.width(), popup_position.height()),
250                       bottom_left);
251
252   // Block now enough to force the right side.
253   popup()->SetBounds(gfx::Rect(work_area.x(), work_area.y(),
254                                popup_position.width(),
255                                work_area.height() - popup_position.height() +
256                                1));
257   gfx::Rect top_right = window_positioner()->GetPopupPosition(
258                             popup_position);
259   EXPECT_EQ(gfx::Rect(AlignToGridRoundDown(work_area.right() -
260                                            popup_position.width(), grid_size_),
261                       work_area.y(),
262                       popup_position.width(), popup_position.height()),
263                       top_right);
264 }
265
266 TEST_F(WindowPositionerTest, biggerThenBorder) {
267   const gfx::Rect work_area =
268       Shell::GetScreen()->GetPrimaryDisplay().work_area();
269
270   gfx::Rect pop_position(0, 0, work_area.width(), work_area.height());
271
272   // Check that the popup is placed full screen.
273   gfx::Rect full = window_positioner()->GetPopupPosition(pop_position);
274   EXPECT_EQ(gfx::Rect(work_area.x(), work_area.y(),
275                       pop_position.width(), pop_position.height()),
276                       full);
277 }
278
279 }  // namespace test
280 }  // namespace ash