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