Home | History | Annotate | Download | only in window_sizer
      1 // Copyright 2013 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/shelf/shelf.h"
      6 #include "ash/shelf/shelf_view.h"
      7 #include "ash/shell.h"
      8 #include "ash/test/shelf_test_api.h"
      9 #include "base/command_line.h"
     10 #include "base/message_loop/message_loop.h"
     11 #include "chrome/browser/lifetime/application_lifetime.h"
     12 #include "chrome/browser/ui/browser.h"
     13 #include "chrome/browser/ui/browser_list.h"
     14 #include "chrome/browser/ui/browser_window.h"
     15 #include "chrome/test/base/in_process_browser_test.h"
     16 #include "ui/aura/window_event_dispatcher.h"
     17 #include "ui/base/test/ui_controls.h"
     18 #include "ui/events/test/event_generator.h"
     19 #include "ui/views/controls/menu/menu_controller.h"
     20 #include "ui/views/view.h"
     21 #include "ui/views/view_model.h"
     22 
     23 namespace {
     24 
     25 class WindowSizerTest : public InProcessBrowserTest {
     26  public:
     27   WindowSizerTest() {}
     28   virtual ~WindowSizerTest() {}
     29 
     30   virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
     31     InProcessBrowserTest::SetUpCommandLine(command_line);
     32     // Make screens sufficiently wide to host 2 browsers side by side.
     33     command_line->AppendSwitchASCII("ash-host-window-bounds",
     34                                     "600x600,601+0-600x600");
     35   }
     36 
     37  private:
     38   DISALLOW_COPY_AND_ASSIGN(WindowSizerTest);
     39 };
     40 
     41 void CloseBrowser(Browser* browser) {
     42   browser->window()->Close();
     43   base::MessageLoop::current()->RunUntilIdle();
     44 }
     45 
     46 gfx::Rect GetChromeIconBoundsForRootWindow(aura::Window* root_window) {
     47   ash::Shelf* shelf = ash::Shelf::ForWindow(root_window);
     48   const ash::ShelfView* shelf_view =
     49       ash::test::ShelfTestAPI(shelf).shelf_view();
     50   const views::ViewModel* view_model = shelf_view->view_model_for_test();
     51 
     52   EXPECT_EQ(2, view_model->view_size());
     53   return view_model->view_at(1)->GetBoundsInScreen();
     54 }
     55 
     56 void OpenBrowserUsingShelfOnRootWindow(aura::Window* root_window) {
     57   ui::test::EventGenerator generator(root_window);
     58   gfx::Point center =
     59       GetChromeIconBoundsForRootWindow(root_window).CenterPoint();
     60   gfx::Display display =
     61       ash::Shell::GetScreen()->GetDisplayNearestWindow(root_window);
     62   const gfx::Point& origin = display.bounds().origin();
     63   center.Offset(- origin.x(), - origin.y());
     64   generator.MoveMouseTo(center);
     65   generator.ClickLeftButton();
     66 }
     67 
     68 }  // namespace
     69 
     70 #if !defined(OS_CHROMEOS)
     71 #define MAYBE_OpenBrowserUsingShelfOnOtherDisplay DISABLED_OpenBrowserUsingShelfOnOtherDisplay
     72 #define MAYBE_OpenBrowserUsingContextMenuOnOtherDisplay DISABLED_OpenBrowserUsingContextMenuOnOtherDisplay
     73 #else
     74 #define MAYBE_OpenBrowserUsingShelfOnOtherDisplay OpenBrowserUsingShelfOnOtherDisplay
     75 #define MAYBE_OpenBrowserUsingContextMenuOnOtherDisplay OpenBrowserUsingContextMenuOnOtherDisplay
     76 #endif
     77 
     78 IN_PROC_BROWSER_TEST_F(WindowSizerTest,
     79                        MAYBE_OpenBrowserUsingShelfOnOtherDisplay) {
     80   // Don't shutdown when closing the last browser window.
     81   chrome::IncrementKeepAliveCount();
     82 
     83   aura::Window::Windows root_windows = ash::Shell::GetAllRootWindows();
     84 
     85   BrowserList* browser_list =
     86       BrowserList::GetInstance(chrome::HOST_DESKTOP_TYPE_ASH);
     87 
     88   EXPECT_EQ(1u, browser_list->size());
     89   // Close the browser window so that clicking icon will create a new window.
     90   CloseBrowser(browser_list->get(0));
     91   EXPECT_EQ(0u, browser_list->size());
     92   EXPECT_EQ(root_windows[0], ash::Shell::GetTargetRootWindow());
     93 
     94   OpenBrowserUsingShelfOnRootWindow(root_windows[1]);
     95 
     96   // A new browser must be created on 2nd display.
     97   EXPECT_EQ(1u, browser_list->size());
     98   EXPECT_EQ(root_windows[1],
     99             browser_list->get(0)->window()->GetNativeWindow()->GetRootWindow());
    100   EXPECT_EQ(root_windows[1], ash::Shell::GetTargetRootWindow());
    101 
    102   // Close the browser window so that clicking icon will create a new window.
    103   CloseBrowser(browser_list->get(0));
    104   EXPECT_EQ(0u, browser_list->size());
    105 
    106   OpenBrowserUsingShelfOnRootWindow(root_windows[0]);
    107 
    108   // A new browser must be created on 1st display.
    109   EXPECT_EQ(1u, browser_list->size());
    110   EXPECT_EQ(root_windows[0],
    111             browser_list->get(0)->window()->GetNativeWindow()->GetRootWindow());
    112   EXPECT_EQ(root_windows[0], ash::Shell::GetTargetRootWindow());
    113 
    114   // Balanced with the chrome::IncrementKeepAliveCount above.
    115   chrome::DecrementKeepAliveCount();
    116 }
    117 
    118 namespace {
    119 
    120 class WindowSizerContextMenuTest : public WindowSizerTest {
    121  public:
    122   WindowSizerContextMenuTest() {}
    123   virtual ~WindowSizerContextMenuTest() {}
    124 
    125   static void Step1(gfx::Point release_point) {
    126     ui_controls::SendMouseEventsNotifyWhenDone(
    127         ui_controls::RIGHT, ui_controls::DOWN,
    128         base::Bind(&WindowSizerContextMenuTest::Step2, release_point));
    129   }
    130 
    131   static void Step2(gfx::Point release_point) {
    132     ui_controls::SendMouseMoveNotifyWhenDone(
    133         release_point.x(), release_point.y(),
    134         base::Bind(&WindowSizerContextMenuTest::Step3));
    135   }
    136 
    137   static void Step3() {
    138     ui_controls::SendMouseEventsNotifyWhenDone(
    139         ui_controls::RIGHT, ui_controls::UP,
    140         base::Bind(&WindowSizerContextMenuTest::QuitLoop));
    141   }
    142 
    143   static void QuitLoop() {
    144     base::MessageLoop::current()->PostTask(
    145         FROM_HERE,
    146         base::MessageLoop::QuitWhenIdleClosure());
    147   }
    148 
    149  private:
    150   DISALLOW_COPY_AND_ASSIGN(WindowSizerContextMenuTest);
    151 };
    152 
    153 void OpenBrowserUsingContextMenuOnRootWindow(aura::Window* root_window) {
    154   gfx::Point chrome_icon =
    155       GetChromeIconBoundsForRootWindow(root_window).CenterPoint();
    156   gfx::Point release_point = chrome_icon;
    157   release_point.Offset(50, -120);
    158   ui_controls::SendMouseMoveNotifyWhenDone(
    159       chrome_icon.x(), chrome_icon.y(),
    160       base::Bind(&WindowSizerContextMenuTest::Step1, release_point));
    161   base::MessageLoop::current()->Run();
    162 }
    163 
    164 }  // namespace
    165 
    166 IN_PROC_BROWSER_TEST_F(WindowSizerContextMenuTest,
    167                        MAYBE_OpenBrowserUsingContextMenuOnOtherDisplay) {
    168   // Don't shutdown when closing the last browser window.
    169   chrome::IncrementKeepAliveCount();
    170 
    171   views::MenuController::TurnOffMenuSelectionHoldForTest();
    172 
    173   aura::Window::Windows root_windows = ash::Shell::GetAllRootWindows();
    174 
    175   BrowserList* browser_list =
    176       BrowserList::GetInstance(chrome::HOST_DESKTOP_TYPE_ASH);
    177 
    178   ASSERT_EQ(1u, browser_list->size());
    179   EXPECT_EQ(root_windows[0], ash::Shell::GetTargetRootWindow());
    180   CloseBrowser(browser_list->get(0));
    181 
    182   OpenBrowserUsingContextMenuOnRootWindow(root_windows[1]);
    183 
    184   // A new browser must be created on 2nd display.
    185   ASSERT_EQ(1u, browser_list->size());
    186   EXPECT_EQ(root_windows[1],
    187             browser_list->get(0)->window()->GetNativeWindow()->GetRootWindow());
    188   EXPECT_EQ(root_windows[1], ash::Shell::GetTargetRootWindow());
    189 
    190   OpenBrowserUsingContextMenuOnRootWindow(root_windows[0]);
    191 
    192   // Next new browser must be created on 1st display.
    193   ASSERT_EQ(2u, browser_list->size());
    194   EXPECT_EQ(root_windows[0],
    195             browser_list->get(1)->window()->GetNativeWindow()->GetRootWindow());
    196   EXPECT_EQ(root_windows[0], ash::Shell::GetTargetRootWindow());
    197 
    198   // Balanced with the chrome::IncrementKeepAliveCount above.
    199   chrome::DecrementKeepAliveCount();
    200 }
    201