blob: 2b0b32a5f2d8ae840966dfa12bce66a347d2c7da [file] [log] [blame]
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001// 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
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000010#include "ash/ash_switches.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000011#include "ash/display/display_controller.h"
Ben Murdoch7dbb3d52013-07-17 14:55:54 +010012#include "ash/screen_ash.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000013#include "ash/shell.h"
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010014#include "ash/test/ash_test_helper.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000015#include "ash/test/display_manager_test_api.h"
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010016#include "ash/test/test_session_state_delegate.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000017#include "ash/test/test_shell_delegate.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000018#include "ash/wm/coordinate_conversion.h"
19#include "base/command_line.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000020#include "content/public/test/web_contents_tester.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000021#include "ui/aura/client/aura_constants.h"
22#include "ui/aura/client/screen_position_client.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000023#include "ui/aura/root_window.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000024#include "ui/aura/test/event_generator.h"
25#include "ui/aura/test/test_window_delegate.h"
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010026#include "ui/aura/window.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000027#include "ui/aura/window_delegate.h"
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +010028#include "ui/base/ime/input_method_initializer.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000029#include "ui/gfx/display.h"
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010030#include "ui/gfx/point.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000031#include "ui/gfx/screen.h"
32
Ben Murdocheb525c52013-07-10 11:40:50 +010033#if defined(OS_CHROMEOS)
34#include "ash/system/chromeos/tray_display.h"
35#endif
36
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000037#if defined(OS_WIN)
38#include "ash/test/test_metro_viewer_process_host.h"
39#include "base/test/test_process_killer_win.h"
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010040#include "base/win/metro.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000041#include "base/win/windows_version.h"
42#include "ui/aura/remote_root_window_host_win.h"
43#include "ui/aura/root_window_host_win.h"
44#include "win8/test/test_registrar_constants.h"
45#endif
46
Torne (Richard Coles)58218062012-11-14 11:43:16 +000047namespace ash {
48namespace test {
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000049namespace {
50
51class AshEventGeneratorDelegate : public aura::test::EventGeneratorDelegate {
52 public:
53 AshEventGeneratorDelegate() {}
54 virtual ~AshEventGeneratorDelegate() {}
55
56 // aura::test::EventGeneratorDelegate overrides:
57 virtual aura::RootWindow* GetRootWindowAt(
58 const gfx::Point& point_in_screen) const OVERRIDE {
59 gfx::Screen* screen = Shell::GetScreen();
60 gfx::Display display = screen->GetDisplayNearestPoint(point_in_screen);
61 return Shell::GetInstance()->display_controller()->
62 GetRootWindowForDisplayId(display.id());
63 }
64
65 virtual aura::client::ScreenPositionClient* GetScreenPositionClient(
66 const aura::Window* window) const OVERRIDE {
67 return aura::client::GetScreenPositionClient(window->GetRootWindow());
68 }
69
70 private:
71 DISALLOW_COPY_AND_ASSIGN(AshEventGeneratorDelegate);
72};
73
74} // namespace
Torne (Richard Coles)58218062012-11-14 11:43:16 +000075
76content::WebContents* AshTestViewsDelegate::CreateWebContents(
77 content::BrowserContext* browser_context,
78 content::SiteInstance* site_instance) {
79 return content::WebContentsTester::CreateTestWebContents(browser_context,
80 site_instance);
81}
82
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010083/////////////////////////////////////////////////////////////////////////////
84
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000085AshTestBase::AshTestBase()
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010086 : setup_called_(false),
Ben Murdochbb1529c2013-08-08 10:24:53 +010087 teardown_called_(false),
88 start_session_(true) {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010089 // Must initialize |ash_test_helper_| here because some tests rely on
90 // AshTestBase methods before they call AshTestBase::SetUp().
Ben Murdocha3f7b4e2013-07-24 10:36:34 +010091 ash_test_helper_.reset(new AshTestHelper(base::MessageLoopForUI::current()));
Torne (Richard Coles)58218062012-11-14 11:43:16 +000092}
93
94AshTestBase::~AshTestBase() {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010095 CHECK(setup_called_)
96 << "You have overridden SetUp but never called AshTestBase::SetUp";
97 CHECK(teardown_called_)
98 << "You have overridden TearDown but never called AshTestBase::TearDown";
Torne (Richard Coles)58218062012-11-14 11:43:16 +000099}
100
101void AshTestBase::SetUp() {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100102 setup_called_ = true;
103 // TODO(jamescook): Can we do this without changing command line?
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000104 // Use the origin (1,1) so that it doesn't over
105 // lap with the native mouse cursor.
106 CommandLine::ForCurrentProcess()->AppendSwitchASCII(
107 switches::kAshHostWindowBounds, "1+1-800x600");
108#if defined(OS_WIN)
109 aura::test::SetUsePopupAsRootWindowForTest(true);
110#endif
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +0100111 ui::InitializeInputMethodForTesting();
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000112
Ben Murdochbb1529c2013-08-08 10:24:53 +0100113 ash_test_helper_->SetUp(start_session_);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000114
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000115 Shell::GetPrimaryRootWindow()->Show();
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000116 Shell::GetPrimaryRootWindow()->ShowRootWindow();
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000117 // Move the mouse cursor to far away so that native events doesn't
118 // interfere test expectations.
119 Shell::GetPrimaryRootWindow()->MoveCursorTo(gfx::Point(-1000, -1000));
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100120 ash::Shell::GetInstance()->cursor_manager()->EnableMouseEvents();
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000121
122#if defined(OS_WIN)
123 if (base::win::GetVersion() >= base::win::VERSION_WIN8 &&
124 !CommandLine::ForCurrentProcess()->HasSwitch(
125 ash::switches::kForceAshToDesktop)) {
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +0100126 ipc_thread_.reset(new base::Thread("test_metro_viewer_ipc_thread"));
127 base::Thread::Options options;
128 options.message_loop_type = base::MessageLoop::TYPE_IO;
129 ipc_thread_->StartWithOptions(options);
130
131 metro_viewer_host_.reset(
Ben Murdocheb525c52013-07-10 11:40:50 +0100132 new TestMetroViewerProcessHost(ipc_thread_->message_loop_proxy()));
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100133 CHECK(metro_viewer_host_->LaunchViewerAndWaitForConnection(
134 win8::test::kDefaultTestAppUserModelId));
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000135 aura::RemoteRootWindowHostWin* root_window_host =
136 aura::RemoteRootWindowHostWin::Instance();
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100137 CHECK(root_window_host != NULL);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000138 }
139#endif
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000140}
141
142void AshTestBase::TearDown() {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100143 teardown_called_ = true;
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000144 // Flush the message loop to finish pending release tasks.
145 RunAllPendingInMessageLoop();
146
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000147#if defined(OS_WIN)
148 if (base::win::GetVersion() >= base::win::VERSION_WIN8 &&
149 !CommandLine::ForCurrentProcess()->HasSwitch(
150 ash::switches::kForceAshToDesktop)) {
151 // Check that our viewer connection is still established.
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100152 CHECK(!metro_viewer_host_->closed_unexpectedly());
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000153 }
154#endif
155
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100156 ash_test_helper_->TearDown();
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000157
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +0100158 ui::ShutdownInputMethodForTesting();
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000159#if defined(OS_WIN)
160 aura::test::SetUsePopupAsRootWindowForTest(false);
161 // Kill the viewer process if we spun one up.
162 metro_viewer_host_.reset();
163
164 // Clean up any dangling viewer processes as the metro APIs sometimes leave
165 // zombies behind. A default browser process in metro will have the
166 // following command line arg so use that to avoid killing all processes named
167 // win8::test::kDefaultTestExePath.
168 const wchar_t kViewerProcessArgument[] = L"DefaultBrowserServer";
169 base::KillAllNamedProcessesWithArgument(win8::test::kDefaultTestExePath,
170 kViewerProcessArgument);
171#endif
172
173 event_generator_.reset();
174 // Some tests set an internal display id,
175 // reset it here, so other tests will continue in a clean environment.
176 gfx::Display::SetInternalDisplayId(gfx::Display::kInvalidDisplayID);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000177}
178
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000179aura::test::EventGenerator& AshTestBase::GetEventGenerator() {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100180 if (!event_generator_) {
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000181 event_generator_.reset(
182 new aura::test::EventGenerator(new AshEventGeneratorDelegate()));
183 }
184 return *event_generator_.get();
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000185}
186
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +0100187// static
188bool AshTestBase::SupportsMultipleDisplays() {
189#if defined(OS_WIN)
190 return base::win::GetVersion() < base::win::VERSION_WIN8;
191#else
192 return true;
193#endif
194}
195
Ben Murdocheb525c52013-07-10 11:40:50 +0100196// static
197bool AshTestBase::SupportsHostWindowResize() {
198#if defined(OS_WIN)
199 return base::win::GetVersion() < base::win::VERSION_WIN8;
200#else
201 return true;
202#endif
203}
204
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000205void AshTestBase::UpdateDisplay(const std::string& display_specs) {
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000206 DisplayManagerTestApi display_manager_test_api(
207 Shell::GetInstance()->display_manager());
208 display_manager_test_api.UpdateDisplay(display_specs);
209}
210
211aura::RootWindow* AshTestBase::CurrentContext() {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100212 return ash_test_helper_->CurrentContext();
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000213}
214
215aura::Window* AshTestBase::CreateTestWindowInShellWithId(int id) {
216 return CreateTestWindowInShellWithDelegate(NULL, id, gfx::Rect());
217}
218
219aura::Window* AshTestBase::CreateTestWindowInShellWithBounds(
220 const gfx::Rect& bounds) {
221 return CreateTestWindowInShellWithDelegate(NULL, 0, bounds);
222}
223
224aura::Window* AshTestBase::CreateTestWindowInShell(SkColor color,
225 int id,
226 const gfx::Rect& bounds) {
227 return CreateTestWindowInShellWithDelegate(
228 new aura::test::ColorTestWindowDelegate(color), id, bounds);
229}
230
231aura::Window* AshTestBase::CreateTestWindowInShellWithDelegate(
232 aura::WindowDelegate* delegate,
233 int id,
234 const gfx::Rect& bounds) {
235 return CreateTestWindowInShellWithDelegateAndType(
236 delegate,
237 aura::client::WINDOW_TYPE_NORMAL,
238 id,
239 bounds);
240}
241
242aura::Window* AshTestBase::CreateTestWindowInShellWithDelegateAndType(
243 aura::WindowDelegate* delegate,
244 aura::client::WindowType type,
245 int id,
246 const gfx::Rect& bounds) {
247 aura::Window* window = new aura::Window(delegate);
248 window->set_id(id);
249 window->SetType(type);
250 window->Init(ui::LAYER_TEXTURED);
251 window->Show();
252
253 if (bounds.IsEmpty()) {
254 SetDefaultParentByPrimaryRootWindow(window);
255 } else {
256 gfx::Display display =
Ben Murdoch7dbb3d52013-07-17 14:55:54 +0100257 Shell::GetScreen()->GetDisplayMatching(bounds);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000258 aura::RootWindow* root = ash::Shell::GetInstance()->display_controller()->
259 GetRootWindowForDisplayId(display.id());
260 gfx::Point origin = bounds.origin();
261 wm::ConvertPointFromScreen(root, &origin);
262 window->SetBounds(gfx::Rect(origin, bounds.size()));
263 window->SetDefaultParentByRootWindow(root, bounds);
264 }
265 window->SetProperty(aura::client::kCanMaximizeKey, true);
266 return window;
267}
268
269void AshTestBase::SetDefaultParentByPrimaryRootWindow(aura::Window* window) {
270 window->SetDefaultParentByRootWindow(
271 Shell::GetPrimaryRootWindow(), gfx::Rect());
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000272}
273
274void AshTestBase::RunAllPendingInMessageLoop() {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100275 ash_test_helper_->RunAllPendingInMessageLoop();
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000276}
277
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000278void AshTestBase::SetSessionStarted(bool session_started) {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100279 ash_test_helper_->test_shell_delegate()->test_session_state_delegate()->
280 SetActiveUserSessionStarted(session_started);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000281}
282
283void AshTestBase::SetUserLoggedIn(bool user_logged_in) {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100284 ash_test_helper_->test_shell_delegate()->test_session_state_delegate()->
285 SetHasActiveUser(user_logged_in);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000286}
287
288void AshTestBase::SetCanLockScreen(bool can_lock_screen) {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100289 ash_test_helper_->test_shell_delegate()->test_session_state_delegate()->
290 SetCanLockScreen(can_lock_screen);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000291}
292
Ben Murdochbbcdd452013-07-25 10:06:34 +0100293void AshTestBase::SetUserAddingScreenRunning(bool user_adding_screen_running) {
294 ash_test_helper_->test_shell_delegate()->test_session_state_delegate()->
295 SetUserAddingScreenRunning(user_adding_screen_running);
296}
297
298void AshTestBase::BlockUserSession(UserSessionBlockReason block_reason) {
299 switch (block_reason) {
300 case BLOCKED_BY_LOCK_SCREEN:
301 SetSessionStarted(true);
302 SetUserAddingScreenRunning(false);
303 Shell::GetInstance()->session_state_delegate()->LockScreen();
304 break;
305 case BLOCKED_BY_LOGIN_SCREEN:
306 SetUserAddingScreenRunning(false);
307 SetSessionStarted(false);
308 break;
309 case BLOCKED_BY_USER_ADDING_SCREEN:
310 SetUserAddingScreenRunning(true);
311 SetSessionStarted(true);
312 break;
313 default:
314 NOTREACHED();
315 break;
316 }
317}
318
319void AshTestBase::UnblockUserSession() {
320 Shell::GetInstance()->session_state_delegate()->UnlockScreen();
321 SetSessionStarted(true);
322 SetUserAddingScreenRunning(false);
323}
324
325
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000326} // namespace test
327} // namespace ash