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/test/event_generator.h" 17 #include "ui/aura/window_event_dispatcher.h" 18 #include "ui/base/test/ui_controls.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 aura::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