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