- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / window_sizer / window_sizer_ash_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/screen_ash.h"
6 #include "ash/shell.h"
7 #include "ash/test/ash_test_base.h"
8 #include "ash/test/test_shell_delegate.h"
9 #include "ash/wm/window_positioner.h"
10 #include "ash/wm/window_resizer.h"
11 #include "ash/wm/window_state.h"
12 #include "base/compiler_specific.h"
13 #include "chrome/browser/ui/browser.h"
14 #include "chrome/browser/ui/window_sizer/window_sizer_common_unittest.h"
15 #include "chrome/common/chrome_switches.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/client/activation_client.h"
20 #include "ui/aura/client/aura_constants.h"
21 #include "ui/aura/env.h"
22 #include "ui/aura/root_window.h"
23 #include "ui/aura/test/test_windows.h"
24
25 typedef ash::test::AshTestBase WindowSizerAshTest;
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   // |native_window| will still be owned by the caller after the constructor
34   // was called.
35   explicit TestBrowserWindowAura(aura::Window* native_window)
36       : native_window_(native_window) {
37   }
38   virtual ~TestBrowserWindowAura() {}
39
40   // TestBrowserWindow overrides:
41   virtual void Show() OVERRIDE {
42     native_window_->Show();
43     Activate();
44   }
45   virtual void Hide() OVERRIDE {
46     native_window_->Hide();
47   }
48   virtual void Activate() OVERRIDE {
49     aura::client::GetActivationClient(
50         native_window_->GetRootWindow())->ActivateWindow(native_window_.get());
51   }
52   virtual gfx::NativeWindow GetNativeWindow() OVERRIDE {
53     return native_window_.get();
54   }
55   virtual gfx::Rect GetBounds() const OVERRIDE {
56     return native_window_->bounds();
57   }
58
59   Browser* browser() { return browser_.get(); }
60
61   void CreateBrowser(const Browser::CreateParams& params) {
62     Browser::CreateParams create_params = params;
63     create_params.window = this;
64     browser_.reset(new Browser(create_params));
65     if (browser_->is_type_tabbed() || browser_->is_app()) {
66       ash::wm::GetWindowState(native_window_.get())->
67           set_window_position_managed(true);
68     }
69   }
70
71  private:
72   scoped_ptr<Browser> browser_;
73   scoped_ptr<aura::Window> native_window_;
74
75   DISALLOW_COPY_AND_ASSIGN(TestBrowserWindowAura);
76 };
77
78 scoped_ptr<TestBrowserWindowAura> CreateTestBrowserWindow(
79     aura::Window* window,
80     const gfx::Rect& bounds,
81     const Browser::CreateParams& params) {
82   if (!bounds.IsEmpty())
83     window->SetBounds(bounds);
84   scoped_ptr<TestBrowserWindowAura> browser_window(
85       new TestBrowserWindowAura(window));
86   browser_window->CreateBrowser(params);
87   return browser_window.Pass();
88 }
89
90 }  // namespace
91
92 // Test that the window is sized appropriately for the first run experience
93 // where the default window bounds calculation is invoked.
94 TEST_F(WindowSizerAshTest, DefaultSizeCase) {
95   { // 4:3 monitor case, 1024x768, no taskbar
96     gfx::Rect window_bounds;
97     GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), gfx::Rect(),
98                     gfx::Rect(), DEFAULT, NULL, gfx::Rect(), &window_bounds);
99     EXPECT_EQ(gfx::Rect(ash::WindowPositioner::kDesktopBorderSize,
100                         ash::WindowPositioner::kDesktopBorderSize,
101                         1024 - ash::WindowPositioner::kDesktopBorderSize * 2,
102                         768 - ash::WindowPositioner::kDesktopBorderSize),
103               window_bounds);
104   }
105
106   { // 4:3 monitor case, 1024x768, taskbar on bottom
107     gfx::Rect window_bounds;
108     GetWindowBounds(p1024x768, taskbar_bottom_work_area, gfx::Rect(),
109                     gfx::Rect(), gfx::Rect(), DEFAULT, NULL, gfx::Rect(),
110                     &window_bounds);
111     EXPECT_EQ(gfx::Rect(ash::WindowPositioner::kDesktopBorderSize,
112                         ash::WindowPositioner::kDesktopBorderSize,
113                         1024 - ash::WindowPositioner::kDesktopBorderSize * 2,
114                         taskbar_bottom_work_area.height() -
115                           ash::WindowPositioner::kDesktopBorderSize),
116               window_bounds);
117   }
118
119   { // 4:3 monitor case, 1024x768, taskbar on right
120     gfx::Rect window_bounds;
121     GetWindowBounds(p1024x768, taskbar_right_work_area, gfx::Rect(),
122                     gfx::Rect(), gfx::Rect(), DEFAULT, NULL, gfx::Rect(),
123                     &window_bounds);
124     EXPECT_EQ(gfx::Rect(ash::WindowPositioner::kDesktopBorderSize,
125                         ash::WindowPositioner::kDesktopBorderSize,
126                         taskbar_right_work_area.width() -
127                           ash::WindowPositioner::kDesktopBorderSize * 2,
128                         768 - ash::WindowPositioner::kDesktopBorderSize),
129               window_bounds);
130   }
131
132   { // 4:3 monitor case, 1024x768, taskbar on left
133     gfx::Rect window_bounds;
134     GetWindowBounds(p1024x768, taskbar_left_work_area, gfx::Rect(),
135                     gfx::Rect(), gfx::Rect(), DEFAULT, NULL, gfx::Rect(),
136                     &window_bounds);
137     EXPECT_EQ(gfx::Rect(taskbar_left_work_area.x() +
138                           ash::WindowPositioner::kDesktopBorderSize,
139                         ash::WindowPositioner::kDesktopBorderSize,
140                         taskbar_left_work_area.width() -
141                           ash::WindowPositioner::kDesktopBorderSize * 2,
142                         taskbar_left_work_area.height() -
143                           ash::WindowPositioner::kDesktopBorderSize),
144               window_bounds);
145   }
146
147   { // 4:3 monitor case, 1024x768, taskbar on top
148     gfx::Rect window_bounds;
149     GetWindowBounds(p1024x768, taskbar_top_work_area, gfx::Rect(),
150                     gfx::Rect(), gfx::Rect(), DEFAULT, NULL, gfx::Rect(),
151                     &window_bounds);
152     EXPECT_EQ(gfx::Rect(ash::WindowPositioner::kDesktopBorderSize,
153                         taskbar_top_work_area.y() +
154                           ash::WindowPositioner::kDesktopBorderSize,
155                         1024 - ash::WindowPositioner::kDesktopBorderSize * 2,
156                         taskbar_top_work_area.height() -
157                             ash::WindowPositioner::kDesktopBorderSize),
158               window_bounds);
159   }
160
161   { // 4:3 monitor case, 1280x1024
162     gfx::Rect window_bounds;
163     GetWindowBounds(p1280x1024, p1280x1024, gfx::Rect(), gfx::Rect(),
164                     gfx::Rect(), DEFAULT, NULL, gfx::Rect(), &window_bounds);
165     EXPECT_EQ(gfx::Rect((1280 - ash::WindowPositioner::kMaximumWindowWidth) / 2,
166                         ash::WindowPositioner::kDesktopBorderSize,
167                         ash::WindowPositioner::kMaximumWindowWidth,
168                         1024 - ash::WindowPositioner::kDesktopBorderSize),
169               window_bounds);
170   }
171
172   { // 4:3 monitor case, 1600x1200
173     gfx::Rect window_bounds;
174     GetWindowBounds(p1600x1200, p1600x1200, gfx::Rect(), gfx::Rect(),
175                     gfx::Rect(), DEFAULT, NULL, gfx::Rect(), &window_bounds);
176     EXPECT_EQ(gfx::Rect((1600 - ash::WindowPositioner::kMaximumWindowWidth) / 2,
177                         ash::WindowPositioner::kDesktopBorderSize,
178                         ash::WindowPositioner::kMaximumWindowWidth,
179                         1200 - ash::WindowPositioner::kDesktopBorderSize),
180               window_bounds);
181   }
182
183   { // 16:10 monitor case, 1680x1050
184     gfx::Rect window_bounds;
185     GetWindowBounds(p1680x1050, p1680x1050, gfx::Rect(), gfx::Rect(),
186                     gfx::Rect(), DEFAULT, NULL, gfx::Rect(), &window_bounds);
187     EXPECT_EQ(gfx::Rect((1680 - ash::WindowPositioner::kMaximumWindowWidth) / 2,
188                         ash::WindowPositioner::kDesktopBorderSize,
189                         ash::WindowPositioner::kMaximumWindowWidth,
190                         1050 - ash::WindowPositioner::kDesktopBorderSize),
191               window_bounds);
192   }
193
194   { // 16:10 monitor case, 1920x1200
195     gfx::Rect window_bounds;
196     GetWindowBounds(p1920x1200, p1920x1200, gfx::Rect(), gfx::Rect(),
197                     gfx::Rect(), DEFAULT, NULL, gfx::Rect(), &window_bounds);
198     EXPECT_EQ(gfx::Rect((1920 - ash::WindowPositioner::kMaximumWindowWidth) / 2,
199                         ash::WindowPositioner::kDesktopBorderSize,
200                         ash::WindowPositioner::kMaximumWindowWidth,
201                         1200 - ash::WindowPositioner::kDesktopBorderSize),
202               window_bounds);
203   }
204 }
205
206 // Test that the next opened window is positioned appropriately given the
207 // bounds of an existing window of the same type.
208 TEST_F(WindowSizerAshTest, LastWindowBoundsCase) {
209   { // normal, in the middle of the screen somewhere.
210     gfx::Rect window_bounds;
211     GetWindowBounds(
212         p1024x768, p1024x768, gfx::Rect(),
213         gfx::Rect(ash::WindowPositioner::kDesktopBorderSize,
214                   ash::WindowPositioner::kDesktopBorderSize, 500, 400),
215         gfx::Rect(), LAST_ACTIVE, NULL, gfx::Rect(),
216         &window_bounds);
217     EXPECT_EQ(
218         gfx::Rect(kWindowTilePixels + ash::WindowPositioner::kDesktopBorderSize,
219                   kWindowTilePixels + ash::WindowPositioner::kDesktopBorderSize,
220                   500, 400).ToString(),
221         window_bounds.ToString());
222   }
223
224   { // taskbar on top.
225     gfx::Rect window_bounds;
226     GetWindowBounds(
227         p1024x768, taskbar_top_work_area, gfx::Rect(),
228         gfx::Rect(ash::WindowPositioner::kDesktopBorderSize,
229                   ash::WindowPositioner::kDesktopBorderSize, 500, 400),
230         gfx::Rect(), LAST_ACTIVE, NULL, gfx::Rect(),
231         &window_bounds);
232     EXPECT_EQ(
233         gfx::Rect(kWindowTilePixels + ash::WindowPositioner::kDesktopBorderSize,
234                   std::max(kWindowTilePixels +
235                            ash::WindowPositioner::kDesktopBorderSize,
236                            34 /* toolbar height */),
237                   500, 400).ToString(),
238         window_bounds.ToString());
239   }
240
241   { // Too small to satisify the minimum visibility condition.
242     gfx::Rect window_bounds;
243     GetWindowBounds(
244         p1024x768, p1024x768, gfx::Rect(),
245         gfx::Rect(ash::WindowPositioner::kDesktopBorderSize,
246                   ash::WindowPositioner::kDesktopBorderSize, 29, 29),
247         gfx::Rect(), LAST_ACTIVE, NULL, gfx::Rect(),
248         &window_bounds);
249     EXPECT_EQ(
250         gfx::Rect(kWindowTilePixels + ash::WindowPositioner::kDesktopBorderSize,
251                   kWindowTilePixels + ash::WindowPositioner::kDesktopBorderSize,
252                   30 /* not 29 */,
253                   30 /* not 29 */).ToString(),
254         window_bounds.ToString());
255   }
256
257
258   { // Normal.
259     gfx::Rect window_bounds;
260     GetWindowBounds(
261         p1024x768, p1024x768, gfx::Rect(),
262         gfx::Rect(ash::WindowPositioner::kDesktopBorderSize,
263                   ash::WindowPositioner::kDesktopBorderSize, 500, 400),
264         gfx::Rect(), LAST_ACTIVE, NULL, gfx::Rect(),
265         &window_bounds);
266     EXPECT_EQ(
267         gfx::Rect(kWindowTilePixels + ash::WindowPositioner::kDesktopBorderSize,
268                   kWindowTilePixels + ash::WindowPositioner::kDesktopBorderSize,
269                   500, 400).ToString(),
270         window_bounds.ToString());
271   }
272 }
273
274 // Test that the window opened is sized appropriately given persisted sizes.
275 TEST_F(WindowSizerAshTest, PersistedBoundsCase) {
276   { // normal, in the middle of the screen somewhere.
277     gfx::Rect initial_bounds(
278         ash::WindowPositioner::kDesktopBorderSize,
279         ash::WindowPositioner::kDesktopBorderSize, 500, 400);
280
281     gfx::Rect window_bounds;
282     GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), initial_bounds,
283                     gfx::Rect(), PERSISTED, NULL, gfx::Rect(), &window_bounds);
284     EXPECT_EQ(initial_bounds.ToString(), window_bounds.ToString());
285   }
286
287   { // Normal.
288     gfx::Rect initial_bounds(0, 0, 1024, 768);
289
290     gfx::Rect window_bounds;
291     GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), initial_bounds,
292                     gfx::Rect(), PERSISTED, NULL, gfx::Rect(), &window_bounds);
293     EXPECT_EQ(initial_bounds.ToString(), window_bounds.ToString());
294   }
295
296   { // normal, on non-primary monitor in negative coords.
297     gfx::Rect initial_bounds(-600, 10, 500, 400);
298
299     gfx::Rect window_bounds;
300     GetWindowBounds(p1024x768, p1024x768, left_s1024x768,
301                     initial_bounds, gfx::Rect(), PERSISTED, NULL, gfx::Rect(),
302                     &window_bounds);
303     EXPECT_EQ(initial_bounds.ToString(), window_bounds.ToString());
304   }
305
306   { // normal, on non-primary monitor in negative coords.
307     gfx::Rect initial_bounds(-1024, 0, 1024, 768);
308
309     gfx::Rect window_bounds;
310     GetWindowBounds(p1024x768, p1024x768, left_s1024x768,
311                     initial_bounds, gfx::Rect(), PERSISTED, NULL, gfx::Rect(),
312                     &window_bounds);
313     EXPECT_EQ(initial_bounds.ToString(), window_bounds.ToString());
314   }
315
316   { // Non-primary monitor resoultion has changed, but the monitor still
317     // completely contains the window.
318
319     gfx::Rect initial_bounds(1074, 50, 600, 500);
320
321     gfx::Rect window_bounds;
322     GetWindowBounds(p1024x768, p1024x768, gfx::Rect(1024, 0, 800, 600),
323                     initial_bounds, right_s1024x768, PERSISTED, NULL,
324                     gfx::Rect(), &window_bounds);
325     EXPECT_EQ(initial_bounds.ToString(), window_bounds.ToString());
326   }
327
328   { // Non-primary monitor resoultion has changed, and the window is partially
329     // off-screen.
330
331     gfx::Rect initial_bounds(1274, 50, 600, 500);
332
333     gfx::Rect window_bounds;
334     GetWindowBounds(p1024x768, p1024x768, gfx::Rect(1024, 0, 800, 600),
335                     initial_bounds, right_s1024x768, PERSISTED,
336                     NULL, gfx::Rect(), &window_bounds);
337     EXPECT_EQ("1224,50 600x500", window_bounds.ToString());
338   }
339
340   { // Non-primary monitor resoultion has changed, and the window is now too
341     // large for the monitor.
342
343     gfx::Rect initial_bounds(1274, 50, 900, 700);
344
345     gfx::Rect window_bounds;
346     GetWindowBounds(p1024x768, p1024x768, gfx::Rect(1024, 0, 800, 600),
347                     initial_bounds, right_s1024x768, PERSISTED,
348                     NULL, gfx::Rect(), &window_bounds);
349     EXPECT_EQ("1024,0 800x600", window_bounds.ToString());
350   }
351
352   { // width and height too small
353     gfx::Rect window_bounds;
354     GetWindowBounds(
355         p1024x768, p1024x768, gfx::Rect(),
356         gfx::Rect(ash::WindowPositioner::kDesktopBorderSize,
357                   ash::WindowPositioner::kDesktopBorderSize, 29, 29),
358         gfx::Rect(), PERSISTED, NULL, gfx::Rect(), &window_bounds);
359     EXPECT_EQ(gfx::Rect(ash::WindowPositioner::kDesktopBorderSize,
360                         ash::WindowPositioner::kDesktopBorderSize,
361                         30 /* not 29 */, 30 /* not 29 */).ToString(),
362               window_bounds.ToString());
363   }
364 }
365
366 //////////////////////////////////////////////////////////////////////////////
367 // The following unittests have different results on Mac/non-Mac because we
368 // reposition windows aggressively on Mac.  The *WithAggressiveReposition tests
369 // are run on Mac, and the *WithNonAggressiveRepositioning tests are run on
370 // other platforms.
371
372 TEST_F(WindowSizerAshTest, LastWindowOffscreenWithNonAggressiveRepositioning) {
373   { // taskbar on left.
374     gfx::Rect window_bounds;
375     GetWindowBounds(
376         p1024x768, taskbar_left_work_area, gfx::Rect(),
377         gfx::Rect(ash::WindowPositioner::kDesktopBorderSize,
378                   ash::WindowPositioner::kDesktopBorderSize, 500, 400),
379         gfx::Rect(), LAST_ACTIVE, NULL, gfx::Rect(),
380         &window_bounds);
381     EXPECT_EQ(
382         gfx::Rect(kWindowTilePixels + ash::WindowPositioner::kDesktopBorderSize,
383                   kWindowTilePixels + ash::WindowPositioner::kDesktopBorderSize,
384                   500, 400).ToString(),
385         window_bounds.ToString());
386   }
387
388   { // offset would put the new window offscreen at the bottom but the minimum
389     // visibility condition is barely satisfied without relocation.
390     gfx::Rect window_bounds;
391     GetWindowBounds(p1024x768, p1024x768, gfx::Rect(),
392                     gfx::Rect(10, 728, 500, 400), gfx::Rect(), LAST_ACTIVE,
393                     NULL, gfx::Rect(), &window_bounds);
394     EXPECT_EQ(gfx::Rect(10 + kWindowTilePixels, 738, 500, 400).ToString(),
395               window_bounds.ToString());
396   }
397
398   { // offset would put the new window offscreen at the bottom and the minimum
399     // visibility condition is satisified by relocation.
400     gfx::Rect window_bounds;
401     GetWindowBounds(p1024x768, p1024x768, gfx::Rect(),
402                     gfx::Rect(10, 729, 500, 400), gfx::Rect(), LAST_ACTIVE,
403                     NULL, gfx::Rect(), &window_bounds);
404     EXPECT_EQ(gfx::Rect(10 + kWindowTilePixels,
405                         738 /* not 739 */,
406                         500,
407                         400).ToString(),
408               window_bounds.ToString());
409   }
410
411   { // offset would put the new window offscreen at the right but the minimum
412     // visibility condition is barely satisfied without relocation.
413     gfx::Rect window_bounds;
414     GetWindowBounds(p1024x768, p1024x768, gfx::Rect(),
415                     gfx::Rect(984, 10, 500, 400), gfx::Rect(), LAST_ACTIVE,
416                     NULL, gfx::Rect(), &window_bounds);
417     EXPECT_EQ(gfx::Rect(994, 10 + kWindowTilePixels, 500, 400).ToString(),
418               window_bounds.ToString());
419   }
420
421   { // offset would put the new window offscreen at the right and the minimum
422     // visibility condition is satisified by relocation.
423     gfx::Rect window_bounds;
424     GetWindowBounds(p1024x768, p1024x768, gfx::Rect(),
425                     gfx::Rect(985, 10, 500, 400), gfx::Rect(), LAST_ACTIVE,
426                     NULL, gfx::Rect(), &window_bounds);
427     EXPECT_EQ(gfx::Rect(994 /* not 995 */,
428                         10 + kWindowTilePixels,
429                         500,
430                         400).ToString(),
431               window_bounds.ToString());
432   }
433
434   { // offset would put the new window offscreen at the bottom right and the
435     // minimum visibility condition is satisified by relocation.
436     gfx::Rect window_bounds;
437     GetWindowBounds(p1024x768, p1024x768, gfx::Rect(),
438                     gfx::Rect(985, 729, 500, 400), gfx::Rect(), LAST_ACTIVE,
439                     NULL, gfx::Rect(), &window_bounds);
440     EXPECT_EQ(gfx::Rect(994 /* not 995 */,
441                         738 /* not 739 */,
442                         500,
443                         400).ToString(),
444               window_bounds.ToString());
445   }
446 }
447
448 // Test the placement of newly created windows.
449 TEST_F(WindowSizerAshTest, PlaceNewWindows) {
450   // Create a browser which we can use to pass into the GetWindowBounds
451   // function.
452   scoped_ptr<TestingProfile> profile(new TestingProfile());
453   // Creating a popup handler here to make sure it does not interfere with the
454   // existing windows.
455   Browser::CreateParams native_params(profile.get(),
456                                       chrome::HOST_DESKTOP_TYPE_ASH);
457   scoped_ptr<Browser> browser(
458       chrome::CreateBrowserWithTestWindowForParams(&native_params));
459
460   // Creating a popup handler here to make sure it does not interfere with the
461   // existing windows.
462   scoped_ptr<BrowserWindow> browser_window(CreateTestBrowserWindow(
463       CreateTestWindowInShellWithId(0),
464       gfx::Rect(16, 32, 640, 320),
465       Browser::CreateParams(profile.get(), chrome::HOST_DESKTOP_TYPE_ASH)));
466
467   // Creating a popup to make sure it does not interfere with the positioning.
468   scoped_ptr<TestBrowserWindowAura> browser_popup(CreateTestBrowserWindow(
469       CreateTestWindowInShellWithId(1),
470       gfx::Rect(16, 32, 128, 256),
471       Browser::CreateParams(Browser::TYPE_POPUP, profile.get(),
472                             chrome::HOST_DESKTOP_TYPE_ASH)));
473
474   // Creating a panel to make sure it does not interfere with the positioning.
475   scoped_ptr<BrowserWindow> browser_panel(CreateTestBrowserWindow(
476       CreateTestWindowInShellWithId(2),
477       gfx::Rect(32, 48, 256, 512),
478       Browser::CreateParams(Browser::TYPE_POPUP, profile.get(),
479                             chrome::HOST_DESKTOP_TYPE_ASH)));
480   browser_window->Show();
481   { // Make sure that popups do not get changed.
482     gfx::Rect window_bounds;
483     GetWindowBounds(p1600x1200, p1600x1200, gfx::Rect(),
484                     gfx::Rect(50, 100, 300, 150), bottom_s1600x1200,
485                     PERSISTED, browser_popup->browser(),
486                     gfx::Rect(), &window_bounds);
487     EXPECT_EQ("50,100 300x150", window_bounds.ToString());
488   }
489
490   browser_window->Hide();
491   { // If a window is there but not shown the persisted default should be used.
492     gfx::Rect window_bounds;
493     GetWindowBounds(p1600x1200, p1600x1200, gfx::Rect(),
494                     gfx::Rect(50, 100, 300, 150), bottom_s1600x1200,
495                     PERSISTED, browser.get(), gfx::Rect(), &window_bounds);
496     EXPECT_EQ("50,100 300x150", window_bounds.ToString());
497   }
498
499   { // If a window is there but not shown the default should be returned.
500     gfx::Rect window_bounds;
501     GetWindowBounds(p1600x1200, p1600x1200, gfx::Rect(),
502                     gfx::Rect(), bottom_s1600x1200,
503                     DEFAULT, browser.get(), gfx::Rect(), &window_bounds);
504     // Note: We need to also take the defaults maximum width into account here
505     // since that might get used if the resolution is too big.
506     EXPECT_EQ(
507         gfx::Rect(
508             std::max(ash::WindowPositioner::kDesktopBorderSize,
509                      (1600 - ash::WindowPositioner::kMaximumWindowWidth) / 2),
510             ash::WindowPositioner::kDesktopBorderSize,
511             std::min(ash::WindowPositioner::kMaximumWindowWidth,
512                      1600 - 2 * ash::WindowPositioner::kDesktopBorderSize),
513             1200 - ash::WindowPositioner::kDesktopBorderSize).ToString(),
514         window_bounds.ToString());
515   }
516 }
517
518 // Test the placement of newly created windows on an empty desktop.
519 // This test supplements "PlaceNewWindows" by testing the creation of a newly
520 // created browser window on an empty desktop.
521 TEST_F(WindowSizerAshTest, PlaceNewBrowserWindowOnEmptyDesktop) {
522   // Create a browser which we can use to pass into the GetWindowBounds
523   // function.
524   scoped_ptr<TestingProfile> profile(new TestingProfile());
525   Browser::CreateParams native_params(profile.get(),
526                                       chrome::HOST_DESKTOP_TYPE_ASH);
527   scoped_ptr<Browser> browser(
528       chrome::CreateBrowserWithTestWindowForParams(&native_params));
529
530   // A common screen size for Chrome OS devices where this behavior is
531   // desirable.
532   const gfx::Rect p1366x768(0, 0, 1366, 768);
533
534   // If there is no previous state the window should get maximized if the
535   // screen is less than or equal to our limit (1366 pixels width).
536   gfx::Rect window_bounds;
537   ui::WindowShowState out_show_state1 = ui::SHOW_STATE_DEFAULT;
538   GetWindowBoundsAndShowState(
539       p1366x768,                    // The screen resolution.
540       p1366x768,                    // The monitor work area.
541       gfx::Rect(),                  // The second monitor.
542       gfx::Rect(),                  // The (persisted) bounds.
543       p1366x768,                    // The overall work area.
544       ui::SHOW_STATE_NORMAL,        // The persisted show state.
545       ui::SHOW_STATE_DEFAULT,       // The last show state.
546       DEFAULT,                      // No persisted values.
547       browser.get(),                // Use this browser.
548       gfx::Rect(),                  // Don't request valid bounds.
549       &window_bounds,
550       &out_show_state1);
551   EXPECT_EQ(ui::SHOW_STATE_MAXIMIZED, out_show_state1);
552
553   // If there is a stored coordinate however, that should be taken instead.
554   ui::WindowShowState out_show_state2 = ui::SHOW_STATE_DEFAULT;
555   GetWindowBoundsAndShowState(
556       p1366x768,                    // The screen resolution.
557       p1366x768,                    // The monitor work area.
558       gfx::Rect(),                  // The second monitor.
559       gfx::Rect(50, 100, 300, 150), // The (persisted) bounds.
560       p1366x768,                    // The overall work area.
561       ui::SHOW_STATE_NORMAL,        // The persisted show state.
562       ui::SHOW_STATE_DEFAULT,       // The last show state.
563       PERSISTED,                    // Set the persisted values.
564       browser.get(),                // Use this browser.
565       gfx::Rect(),                  // Don't request valid bounds.
566       &window_bounds,
567       &out_show_state2);
568   EXPECT_EQ(ui::SHOW_STATE_NORMAL, out_show_state2);
569   EXPECT_EQ("50,100 300x150", window_bounds.ToString());
570
571   // A larger monitor should not trigger auto-maximize.
572   ui::WindowShowState out_show_state3 = ui::SHOW_STATE_DEFAULT;
573   GetWindowBoundsAndShowState(
574       p1600x1200,                   // The screen resolution.
575       p1600x1200,                   // The monitor work area.
576       gfx::Rect(),                  // The second monitor.
577       gfx::Rect(),                  // The (persisted) bounds.
578       p1600x1200,                   // The overall work area.
579       ui::SHOW_STATE_NORMAL,        // The persisted show state.
580       ui::SHOW_STATE_DEFAULT,       // The last show state.
581       DEFAULT,                      // No persisted values.
582       browser.get(),                // Use this browser.
583       gfx::Rect(),                  // Don't request valid bounds.
584       &window_bounds,
585       &out_show_state3);
586   EXPECT_EQ(ui::SHOW_STATE_DEFAULT, out_show_state3);
587 }
588
589 #if defined(OS_CHROMEOS)
590 #define MAYBE_PlaceNewWindowsOnMultipleDisplays PlaceNewWindowsOnMultipleDisplays
591 #else
592 // No multiple displays on windows ash.
593 #define MAYBE_PlaceNewWindowsOnMultipleDisplays DISABLED_PlaceNewWindowsOnMultipleDisplays
594 #endif
595
596 // Test the placement of newly created windows on multiple dislays.
597 TEST_F(WindowSizerAshTest, MAYBE_PlaceNewWindowsOnMultipleDisplays) {
598   UpdateDisplay("1600x1200,1600x1200");
599   gfx::Rect primary_bounds = ash::Shell::GetInstance()->GetScreen()->
600       GetPrimaryDisplay().bounds();
601   gfx::Rect secondary_bounds = ash::ScreenAsh::GetSecondaryDisplay().bounds();
602
603   ash::Shell::GetInstance()->set_target_root_window(
604       ash::Shell::GetPrimaryRootWindow());
605
606   scoped_ptr<TestingProfile> profile(new TestingProfile());
607
608   // Create browser windows that are used as reference.
609   scoped_ptr<BrowserWindow> browser_window(CreateTestBrowserWindow(
610       CreateTestWindowInShellWithId(0),
611       gfx::Rect(10, 10, 200, 200),
612       Browser::CreateParams(profile.get(), chrome::HOST_DESKTOP_TYPE_ASH)));
613   browser_window->Show();
614   EXPECT_EQ(browser_window->GetNativeWindow()->GetRootWindow(),
615             ash::Shell::GetTargetRootWindow());
616
617   scoped_ptr<BrowserWindow> another_browser_window(CreateTestBrowserWindow(
618       CreateTestWindowInShellWithId(1),
619       gfx::Rect(400, 10, 300, 300),
620       Browser::CreateParams(profile.get(), chrome::HOST_DESKTOP_TYPE_ASH)));
621   another_browser_window->Show();
622
623   // Creating a new window to verify the new placement.
624   scoped_ptr<TestBrowserWindowAura> new_browser_window(CreateTestBrowserWindow(
625       CreateTestWindowInShellWithId(0),
626       gfx::Rect(),
627       Browser::CreateParams(profile.get(),
628                             chrome::HOST_DESKTOP_TYPE_ASH)));
629
630   // Make sure the primary root is active.
631   ASSERT_EQ(ash::Shell::GetPrimaryRootWindow(),
632             ash::Shell::GetTargetRootWindow());
633
634   // First new window should be in the primary.
635   {
636     gfx::Rect window_bounds;
637     GetWindowBounds(p1600x1200, p1600x1200, secondary_bounds,
638                     gfx::Rect(), secondary_bounds,
639                     PERSISTED, new_browser_window->browser(),
640                     gfx::Rect(), &window_bounds);
641     // TODO(oshima): Use exact bounds when the window_sizer_ash is
642     // moved to ash and changed to include the result from
643     // RearrangeVisibleWindowOnShow.
644     EXPECT_TRUE(primary_bounds.Contains(window_bounds));
645   }
646
647   // Move the window to the right side of the secondary display and create a new
648   // window. It should be opened then on the secondary display.
649   {
650     gfx::Display second_display = ash::Shell::GetScreen()->
651         GetDisplayNearestPoint(gfx::Point(1600 + 100,10));
652     browser_window->GetNativeWindow()->SetBoundsInScreen(
653         gfx::Rect(secondary_bounds.CenterPoint().x() - 100, 10, 200, 200),
654         second_display);
655     browser_window->Activate();
656     EXPECT_NE(ash::Shell::GetPrimaryRootWindow(),
657               ash::Shell::GetTargetRootWindow());
658     gfx::Rect window_bounds;
659     GetWindowBounds(p1600x1200, p1600x1200, secondary_bounds,
660                     gfx::Rect(), secondary_bounds,
661                     PERSISTED, new_browser_window->browser(),
662                     gfx::Rect(), &window_bounds);
663     // TODO(oshima): Use exact bounds when the window_sizer_ash is
664     // moved to ash and changed to include the result from
665     // RearrangeVisibleWindowOnShow.
666     EXPECT_TRUE(secondary_bounds.Contains(window_bounds));
667   }
668
669   // Activate another window in the primary display and create a new window.
670   // It should be created in the primary display.
671   {
672     another_browser_window->Activate();
673     EXPECT_EQ(ash::Shell::GetPrimaryRootWindow(),
674               ash::Shell::GetTargetRootWindow());
675
676     gfx::Rect window_bounds;
677     GetWindowBounds(p1600x1200, p1600x1200, secondary_bounds,
678                     gfx::Rect(), secondary_bounds,
679                     PERSISTED, new_browser_window->browser(),
680                     gfx::Rect(), &window_bounds);
681     // TODO(oshima): Use exact bounds when the window_sizer_ash is
682     // moved to ash and changed to include the result from
683     // RearrangeVisibleWindowOnShow.
684     EXPECT_TRUE(primary_bounds.Contains(window_bounds));
685   }
686 }
687
688 // Test that the show state is properly returned for non default cases.
689 TEST_F(WindowSizerAshTest, TestShowState) {
690   scoped_ptr<TestingProfile> profile(new TestingProfile());
691
692   // Creating a browser & window to play with.
693   scoped_ptr<TestBrowserWindowAura> browser_window(CreateTestBrowserWindow(
694       CreateTestWindowInShellWithId(0),
695       gfx::Rect(16, 32, 640, 320),
696       Browser::CreateParams(Browser::TYPE_TABBED, profile.get(),
697                             chrome::HOST_DESKTOP_TYPE_ASH)));
698
699   // Create also a popup browser since that behaves different.
700   scoped_ptr<TestBrowserWindowAura> browser_popup(CreateTestBrowserWindow(
701       CreateTestWindowInShellWithId(1),
702       gfx::Rect(16, 32, 640, 320),
703       Browser::CreateParams(Browser::TYPE_POPUP, profile.get(),
704                             chrome::HOST_DESKTOP_TYPE_ASH)));
705
706   // Tabbed windows should retrieve the saved window state - since there is a
707   // top window.
708   EXPECT_EQ(ui::SHOW_STATE_MAXIMIZED,
709             GetWindowShowState(ui::SHOW_STATE_MAXIMIZED,
710                                ui::SHOW_STATE_NORMAL,
711                                BOTH,
712                                browser_window->browser(),
713                                p1600x1200));
714   EXPECT_EQ(ui::SHOW_STATE_DEFAULT,
715             GetWindowShowState(ui::SHOW_STATE_DEFAULT,
716                                ui::SHOW_STATE_NORMAL,
717                                BOTH,
718                                browser_window->browser(),
719                                p1600x1200));
720   // Non tabbed windows should always follow the window saved visibility state.
721   EXPECT_EQ(ui::SHOW_STATE_MAXIMIZED,
722             GetWindowShowState(ui::SHOW_STATE_MAXIMIZED,
723                                ui::SHOW_STATE_NORMAL,
724                                BOTH,
725                                browser_popup->browser(),
726                                p1600x1200));
727   // The non tabbed window will take the status of the last active of its kind.
728   EXPECT_EQ(ui::SHOW_STATE_NORMAL,
729             GetWindowShowState(ui::SHOW_STATE_DEFAULT,
730                                ui::SHOW_STATE_NORMAL,
731                                BOTH,
732                                browser_popup->browser(),
733                                p1600x1200));
734
735   // Now create a top level window and check again for both. Only the tabbed
736   // window should follow the top level window's state.
737   // Creating a browser & window to play with.
738   scoped_ptr<TestBrowserWindowAura> browser_window2(CreateTestBrowserWindow(
739       CreateTestWindowInShellWithId(3),
740       gfx::Rect(16, 32, 640, 320),
741       Browser::CreateParams(Browser::TYPE_TABBED, profile.get(),
742                             chrome::HOST_DESKTOP_TYPE_ASH)));
743
744   // A tabbed window should now take the top level window state.
745   EXPECT_EQ(ui::SHOW_STATE_DEFAULT,
746             GetWindowShowState(ui::SHOW_STATE_MAXIMIZED,
747                                ui::SHOW_STATE_DEFAULT,
748                                BOTH,
749                                browser_window->browser(),
750                                p1600x1200));
751   // Non tabbed windows should always follow the window saved visibility state.
752   EXPECT_EQ(ui::SHOW_STATE_MAXIMIZED,
753             GetWindowShowState(ui::SHOW_STATE_MAXIMIZED,
754                                ui::SHOW_STATE_MINIMIZED,
755                                BOTH,
756                                browser_popup->browser(),
757                                p1600x1200));
758
759   // In smaller screen resolutions we default to maximized if there is no other
760   // window visible.
761   int min_size = ash::WindowPositioner::GetForceMaximizedWidthLimit() / 2;
762   if (min_size > 0) {
763     const gfx::Rect tiny_screen(0, 0, min_size, min_size);
764     EXPECT_EQ(ui::SHOW_STATE_DEFAULT,
765               GetWindowShowState(ui::SHOW_STATE_MAXIMIZED,
766                                  ui::SHOW_STATE_DEFAULT,
767                                  BOTH,
768                                  browser_window->browser(),
769                                  tiny_screen));
770     browser_window->Hide();
771     EXPECT_EQ(ui::SHOW_STATE_MAXIMIZED,
772               GetWindowShowState(ui::SHOW_STATE_MAXIMIZED,
773                                  ui::SHOW_STATE_DEFAULT,
774                                  BOTH,
775                                  browser_window2->browser(),
776                                  tiny_screen));
777
778   }
779 }
780
781 // Test that the default show state override behavior is properly handled.
782 TEST_F(WindowSizerAshTest, TestShowStateDefaults) {
783   // Creating a browser & window to play with.
784   scoped_ptr<TestingProfile> profile(new TestingProfile());
785
786   scoped_ptr<TestBrowserWindowAura> browser_window(CreateTestBrowserWindow(
787       CreateTestWindowInShellWithId(0),
788       gfx::Rect(16, 32, 640, 320),
789       Browser::CreateParams(Browser::TYPE_TABBED, profile.get(),
790                             chrome::HOST_DESKTOP_TYPE_ASH)));
791
792   // Create also a popup browser since that behaves slightly different for
793   // defaults.
794   scoped_ptr<TestBrowserWindowAura> browser_popup(CreateTestBrowserWindow(
795       CreateTestWindowInShellWithId(1),
796       gfx::Rect(16, 32, 128, 256),
797       Browser::CreateParams(Browser::TYPE_POPUP, profile.get(),
798                             chrome::HOST_DESKTOP_TYPE_ASH)));
799
800   // Check that a browser creation state always get used if not given as
801   // SHOW_STATE_DEFAULT.
802   EXPECT_EQ(GetWindowShowState(ui::SHOW_STATE_MAXIMIZED,
803                                ui::SHOW_STATE_MAXIMIZED,
804                                DEFAULT,
805                                browser_window->browser(),
806                                p1600x1200), ui::SHOW_STATE_DEFAULT);
807   browser_window->browser()->set_initial_show_state(ui::SHOW_STATE_MINIMIZED);
808   EXPECT_EQ(GetWindowShowState(ui::SHOW_STATE_MAXIMIZED,
809                                ui::SHOW_STATE_MAXIMIZED,
810                                BOTH,
811                                browser_window->browser(),
812                                p1600x1200), ui::SHOW_STATE_MINIMIZED);
813   browser_window->browser()->set_initial_show_state(ui::SHOW_STATE_NORMAL);
814   EXPECT_EQ(GetWindowShowState(ui::SHOW_STATE_MAXIMIZED,
815                                ui::SHOW_STATE_MAXIMIZED,
816                                BOTH,
817                                browser_window->browser(),
818                                p1600x1200), ui::SHOW_STATE_NORMAL);
819   browser_window->browser()->set_initial_show_state(ui::SHOW_STATE_MAXIMIZED);
820   EXPECT_EQ(GetWindowShowState(ui::SHOW_STATE_NORMAL,
821                                ui::SHOW_STATE_NORMAL,
822                                BOTH,
823                                browser_window->browser(),
824                                p1600x1200), ui::SHOW_STATE_MAXIMIZED);
825
826   // Check that setting the maximized command line option is forcing the
827   // maximized state.
828   CommandLine::ForCurrentProcess()->AppendSwitch(switches::kStartMaximized);
829
830   browser_window->browser()->set_initial_show_state(ui::SHOW_STATE_NORMAL);
831   EXPECT_EQ(GetWindowShowState(ui::SHOW_STATE_NORMAL,
832                                ui::SHOW_STATE_NORMAL,
833                                BOTH,
834                                browser_window->browser(),
835                                p1600x1200), ui::SHOW_STATE_MAXIMIZED);
836
837   // The popup should favor the initial show state over the command line.
838   EXPECT_EQ(GetWindowShowState(ui::SHOW_STATE_NORMAL,
839                                ui::SHOW_STATE_NORMAL,
840                                BOTH,
841                                browser_popup->browser(),
842                                p1600x1200), ui::SHOW_STATE_NORMAL);
843 }