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