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