Home | History | Annotate | Download | only in test
      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/screen_ash.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_CHROMEOS)
     34 #include "ash/system/chromeos/tray_display.h"
     35 #endif
     36 
     37 #if defined(OS_WIN)
     38 #include "ash/test/test_metro_viewer_process_host.h"
     39 #include "base/test/test_process_killer_win.h"
     40 #include "base/win/metro.h"
     41 #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 
     47 namespace ash {
     48 namespace test {
     49 namespace {
     50 
     51 class 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
     75 
     76 content::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 
     83 /////////////////////////////////////////////////////////////////////////////
     84 
     85 AshTestBase::AshTestBase()
     86     : setup_called_(false),
     87       teardown_called_(false),
     88       start_session_(true) {
     89   // Must initialize |ash_test_helper_| here because some tests rely on
     90   // AshTestBase methods before they call AshTestBase::SetUp().
     91   ash_test_helper_.reset(new AshTestHelper(base::MessageLoopForUI::current()));
     92 }
     93 
     94 AshTestBase::~AshTestBase() {
     95   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";
     99 }
    100 
    101 void AshTestBase::SetUp() {
    102   setup_called_ = true;
    103   // TODO(jamescook): Can we do this without changing command line?
    104   // 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
    111   ui::InitializeInputMethodForTesting();
    112 
    113   ash_test_helper_->SetUp(start_session_);
    114 
    115   Shell::GetPrimaryRootWindow()->Show();
    116   Shell::GetPrimaryRootWindow()->ShowRootWindow();
    117   // 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));
    120   ash::Shell::GetInstance()->cursor_manager()->EnableMouseEvents();
    121 
    122 #if defined(OS_WIN)
    123   if (base::win::GetVersion() >= base::win::VERSION_WIN8 &&
    124       !CommandLine::ForCurrentProcess()->HasSwitch(
    125           ash::switches::kForceAshToDesktop)) {
    126     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(
    132         new TestMetroViewerProcessHost(ipc_thread_->message_loop_proxy()));
    133     CHECK(metro_viewer_host_->LaunchViewerAndWaitForConnection(
    134         win8::test::kDefaultTestAppUserModelId));
    135     aura::RemoteRootWindowHostWin* root_window_host =
    136         aura::RemoteRootWindowHostWin::Instance();
    137     CHECK(root_window_host != NULL);
    138   }
    139 #endif
    140 }
    141 
    142 void AshTestBase::TearDown() {
    143   teardown_called_ = true;
    144   // Flush the message loop to finish pending release tasks.
    145   RunAllPendingInMessageLoop();
    146 
    147 #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.
    152     CHECK(!metro_viewer_host_->closed_unexpectedly());
    153   }
    154 #endif
    155 
    156   ash_test_helper_->TearDown();
    157 
    158   ui::ShutdownInputMethodForTesting();
    159 #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);
    177 }
    178 
    179 aura::test::EventGenerator& AshTestBase::GetEventGenerator() {
    180   if (!event_generator_) {
    181     event_generator_.reset(
    182         new aura::test::EventGenerator(new AshEventGeneratorDelegate()));
    183   }
    184   return *event_generator_.get();
    185 }
    186 
    187 // static
    188 bool 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 
    196 // static
    197 bool 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 
    205 void AshTestBase::UpdateDisplay(const std::string& display_specs) {
    206   DisplayManagerTestApi display_manager_test_api(
    207       Shell::GetInstance()->display_manager());
    208   display_manager_test_api.UpdateDisplay(display_specs);
    209 }
    210 
    211 aura::RootWindow* AshTestBase::CurrentContext() {
    212   return ash_test_helper_->CurrentContext();
    213 }
    214 
    215 aura::Window* AshTestBase::CreateTestWindowInShellWithId(int id) {
    216   return CreateTestWindowInShellWithDelegate(NULL, id, gfx::Rect());
    217 }
    218 
    219 aura::Window* AshTestBase::CreateTestWindowInShellWithBounds(
    220     const gfx::Rect& bounds) {
    221   return CreateTestWindowInShellWithDelegate(NULL, 0, bounds);
    222 }
    223 
    224 aura::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 
    231 aura::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 
    242 aura::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 =
    257         Shell::GetScreen()->GetDisplayMatching(bounds);
    258     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 
    269 void AshTestBase::SetDefaultParentByPrimaryRootWindow(aura::Window* window) {
    270   window->SetDefaultParentByRootWindow(
    271       Shell::GetPrimaryRootWindow(), gfx::Rect());
    272 }
    273 
    274 void AshTestBase::RunAllPendingInMessageLoop() {
    275   ash_test_helper_->RunAllPendingInMessageLoop();
    276 }
    277 
    278 void AshTestBase::SetSessionStarted(bool session_started) {
    279   ash_test_helper_->test_shell_delegate()->test_session_state_delegate()->
    280       SetActiveUserSessionStarted(session_started);
    281 }
    282 
    283 void AshTestBase::SetUserLoggedIn(bool user_logged_in) {
    284   ash_test_helper_->test_shell_delegate()->test_session_state_delegate()->
    285       SetHasActiveUser(user_logged_in);
    286 }
    287 
    288 void AshTestBase::SetCanLockScreen(bool can_lock_screen) {
    289   ash_test_helper_->test_shell_delegate()->test_session_state_delegate()->
    290       SetCanLockScreen(can_lock_screen);
    291 }
    292 
    293 void 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 
    298 void 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 
    319 void AshTestBase::UnblockUserSession() {
    320   Shell::GetInstance()->session_state_delegate()->UnlockScreen();
    321   SetSessionStarted(true);
    322   SetUserAddingScreenRunning(false);
    323 }
    324 
    325 
    326 }  // namespace test
    327 }  // namespace ash
    328