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