ash_test_base.cc revision 7d4cd473f85ac64c3747c96c277f9e506a0d2246
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/test/ash_test_base.h" 6 7#include <string> 8#include <vector> 9 10#include "ash/ash_switches.h" 11#include "ash/display/display_controller.h" 12#include "ash/display/display_manager.h" 13#include "ash/shell.h" 14#include "ash/test/ash_test_helper.h" 15#include "ash/test/display_manager_test_api.h" 16#include "ash/test/test_session_state_delegate.h" 17#include "ash/test/test_shell_delegate.h" 18#include "ash/wm/coordinate_conversion.h" 19#include "base/command_line.h" 20#include "content/public/test/web_contents_tester.h" 21#include "ui/aura/client/aura_constants.h" 22#include "ui/aura/client/screen_position_client.h" 23#include "ui/aura/root_window.h" 24#include "ui/aura/test/event_generator.h" 25#include "ui/aura/test/test_window_delegate.h" 26#include "ui/aura/window.h" 27#include "ui/aura/window_delegate.h" 28#include "ui/base/ime/input_method_initializer.h" 29#include "ui/gfx/display.h" 30#include "ui/gfx/point.h" 31#include "ui/gfx/screen.h" 32 33#if defined(OS_WIN) 34#include "ash/test/test_metro_viewer_process_host.h" 35#include "base/test/test_process_killer_win.h" 36#include "base/win/metro.h" 37#include "base/win/windows_version.h" 38#include "ui/aura/remote_root_window_host_win.h" 39#include "ui/aura/root_window_host_win.h" 40#include "win8/test/test_registrar_constants.h" 41#endif 42 43namespace ash { 44namespace test { 45namespace { 46 47class AshEventGeneratorDelegate : public aura::test::EventGeneratorDelegate { 48 public: 49 AshEventGeneratorDelegate() {} 50 virtual ~AshEventGeneratorDelegate() {} 51 52 // aura::test::EventGeneratorDelegate overrides: 53 virtual aura::RootWindow* GetRootWindowAt( 54 const gfx::Point& point_in_screen) const OVERRIDE { 55 gfx::Screen* screen = Shell::GetScreen(); 56 gfx::Display display = screen->GetDisplayNearestPoint(point_in_screen); 57 return Shell::GetInstance()->display_controller()-> 58 GetRootWindowForDisplayId(display.id()); 59 } 60 61 virtual aura::client::ScreenPositionClient* GetScreenPositionClient( 62 const aura::Window* window) const OVERRIDE { 63 return aura::client::GetScreenPositionClient(window->GetRootWindow()); 64 } 65 66 private: 67 DISALLOW_COPY_AND_ASSIGN(AshEventGeneratorDelegate); 68}; 69 70} // namespace 71 72content::WebContents* AshTestViewsDelegate::CreateWebContents( 73 content::BrowserContext* browser_context, 74 content::SiteInstance* site_instance) { 75 return content::WebContentsTester::CreateTestWebContents(browser_context, 76 site_instance); 77} 78 79///////////////////////////////////////////////////////////////////////////// 80 81AshTestBase::AshTestBase() 82 : setup_called_(false), 83 teardown_called_(false) { 84 // Must initialize |ash_test_helper_| here because some tests rely on 85 // AshTestBase methods before they call AshTestBase::SetUp(). 86 ash_test_helper_.reset(new AshTestHelper(&message_loop_)); 87} 88 89AshTestBase::~AshTestBase() { 90 CHECK(setup_called_) 91 << "You have overridden SetUp but never called AshTestBase::SetUp"; 92 CHECK(teardown_called_) 93 << "You have overridden TearDown but never called AshTestBase::TearDown"; 94} 95 96void AshTestBase::SetUp() { 97 setup_called_ = true; 98 // TODO(jamescook): Can we do this without changing command line? 99 // Use the origin (1,1) so that it doesn't over 100 // lap with the native mouse cursor. 101 CommandLine::ForCurrentProcess()->AppendSwitchASCII( 102 switches::kAshHostWindowBounds, "1+1-800x600"); 103#if defined(OS_WIN) 104 aura::test::SetUsePopupAsRootWindowForTest(true); 105#endif 106 ui::InitializeInputMethodForTesting(); 107 108 ash_test_helper_->SetUp(); 109 110 Shell::GetPrimaryRootWindow()->Show(); 111 Shell::GetPrimaryRootWindow()->ShowRootWindow(); 112 // Move the mouse cursor to far away so that native events doesn't 113 // interfere test expectations. 114 Shell::GetPrimaryRootWindow()->MoveCursorTo(gfx::Point(-1000, -1000)); 115 ash::Shell::GetInstance()->cursor_manager()->EnableMouseEvents(); 116 117#if defined(OS_WIN) 118 if (base::win::GetVersion() >= base::win::VERSION_WIN8 && 119 !CommandLine::ForCurrentProcess()->HasSwitch( 120 ash::switches::kForceAshToDesktop)) { 121 ipc_thread_.reset(new base::Thread("test_metro_viewer_ipc_thread")); 122 base::Thread::Options options; 123 options.message_loop_type = base::MessageLoop::TYPE_IO; 124 ipc_thread_->StartWithOptions(options); 125 126 metro_viewer_host_.reset( 127 new TestMetroViewerProcessHost("viewer", 128 ipc_thread_->message_loop_proxy())); 129 CHECK(metro_viewer_host_->LaunchViewerAndWaitForConnection( 130 win8::test::kDefaultTestAppUserModelId)); 131 aura::RemoteRootWindowHostWin* root_window_host = 132 aura::RemoteRootWindowHostWin::Instance(); 133 CHECK(root_window_host != NULL); 134 } 135#endif 136} 137 138void AshTestBase::TearDown() { 139 teardown_called_ = true; 140 // Flush the message loop to finish pending release tasks. 141 RunAllPendingInMessageLoop(); 142 143#if defined(OS_WIN) 144 if (base::win::GetVersion() >= base::win::VERSION_WIN8 && 145 !CommandLine::ForCurrentProcess()->HasSwitch( 146 ash::switches::kForceAshToDesktop)) { 147 // Check that our viewer connection is still established. 148 CHECK(!metro_viewer_host_->closed_unexpectedly()); 149 } 150#endif 151 152 ash_test_helper_->TearDown(); 153 154 ui::ShutdownInputMethodForTesting(); 155#if defined(OS_WIN) 156 aura::test::SetUsePopupAsRootWindowForTest(false); 157 // Kill the viewer process if we spun one up. 158 metro_viewer_host_.reset(); 159 160 // Clean up any dangling viewer processes as the metro APIs sometimes leave 161 // zombies behind. A default browser process in metro will have the 162 // following command line arg so use that to avoid killing all processes named 163 // win8::test::kDefaultTestExePath. 164 const wchar_t kViewerProcessArgument[] = L"DefaultBrowserServer"; 165 base::KillAllNamedProcessesWithArgument(win8::test::kDefaultTestExePath, 166 kViewerProcessArgument); 167#endif 168 169 event_generator_.reset(); 170 // Some tests set an internal display id, 171 // reset it here, so other tests will continue in a clean environment. 172 gfx::Display::SetInternalDisplayId(gfx::Display::kInvalidDisplayID); 173} 174 175aura::test::EventGenerator& AshTestBase::GetEventGenerator() { 176 if (!event_generator_) { 177 event_generator_.reset( 178 new aura::test::EventGenerator(new AshEventGeneratorDelegate())); 179 } 180 return *event_generator_.get(); 181} 182 183// static 184bool AshTestBase::SupportsMultipleDisplays() { 185#if defined(OS_WIN) 186 return base::win::GetVersion() < base::win::VERSION_WIN8; 187#else 188 return true; 189#endif 190} 191 192void AshTestBase::UpdateDisplay(const std::string& display_specs) { 193 DisplayManagerTestApi display_manager_test_api( 194 Shell::GetInstance()->display_manager()); 195 display_manager_test_api.UpdateDisplay(display_specs); 196} 197 198aura::RootWindow* AshTestBase::CurrentContext() { 199 return ash_test_helper_->CurrentContext(); 200} 201 202aura::Window* AshTestBase::CreateTestWindowInShellWithId(int id) { 203 return CreateTestWindowInShellWithDelegate(NULL, id, gfx::Rect()); 204} 205 206aura::Window* AshTestBase::CreateTestWindowInShellWithBounds( 207 const gfx::Rect& bounds) { 208 return CreateTestWindowInShellWithDelegate(NULL, 0, bounds); 209} 210 211aura::Window* AshTestBase::CreateTestWindowInShell(SkColor color, 212 int id, 213 const gfx::Rect& bounds) { 214 return CreateTestWindowInShellWithDelegate( 215 new aura::test::ColorTestWindowDelegate(color), id, bounds); 216} 217 218aura::Window* AshTestBase::CreateTestWindowInShellWithDelegate( 219 aura::WindowDelegate* delegate, 220 int id, 221 const gfx::Rect& bounds) { 222 return CreateTestWindowInShellWithDelegateAndType( 223 delegate, 224 aura::client::WINDOW_TYPE_NORMAL, 225 id, 226 bounds); 227} 228 229aura::Window* AshTestBase::CreateTestWindowInShellWithDelegateAndType( 230 aura::WindowDelegate* delegate, 231 aura::client::WindowType type, 232 int id, 233 const gfx::Rect& bounds) { 234 aura::Window* window = new aura::Window(delegate); 235 window->set_id(id); 236 window->SetType(type); 237 window->Init(ui::LAYER_TEXTURED); 238 window->Show(); 239 240 if (bounds.IsEmpty()) { 241 SetDefaultParentByPrimaryRootWindow(window); 242 } else { 243 gfx::Display display = 244 ash::Shell::GetInstance()->display_manager()->GetDisplayMatching(bounds); 245 aura::RootWindow* root = ash::Shell::GetInstance()->display_controller()-> 246 GetRootWindowForDisplayId(display.id()); 247 gfx::Point origin = bounds.origin(); 248 wm::ConvertPointFromScreen(root, &origin); 249 window->SetBounds(gfx::Rect(origin, bounds.size())); 250 window->SetDefaultParentByRootWindow(root, bounds); 251 } 252 window->SetProperty(aura::client::kCanMaximizeKey, true); 253 return window; 254} 255 256void AshTestBase::SetDefaultParentByPrimaryRootWindow(aura::Window* window) { 257 window->SetDefaultParentByRootWindow( 258 Shell::GetPrimaryRootWindow(), gfx::Rect()); 259} 260 261void AshTestBase::RunAllPendingInMessageLoop() { 262 ash_test_helper_->RunAllPendingInMessageLoop(); 263} 264 265void AshTestBase::SetSessionStarted(bool session_started) { 266 ash_test_helper_->test_shell_delegate()->test_session_state_delegate()-> 267 SetActiveUserSessionStarted(session_started); 268} 269 270void AshTestBase::SetUserLoggedIn(bool user_logged_in) { 271 ash_test_helper_->test_shell_delegate()->test_session_state_delegate()-> 272 SetHasActiveUser(user_logged_in); 273} 274 275void AshTestBase::SetCanLockScreen(bool can_lock_screen) { 276 ash_test_helper_->test_shell_delegate()->test_session_state_delegate()-> 277 SetCanLockScreen(can_lock_screen); 278} 279 280} // namespace test 281} // namespace ash 282