root/ash/test/ash_test_base.cc

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. GetHostAt
  2. GetScreenPositionClient
  3. CreateWebContents
  4. start_session_
  5. SetUp
  6. TearDown
  7. GetEventGenerator
  8. SupportsMultipleDisplays
  9. SupportsHostWindowResize
  10. UpdateDisplay
  11. CurrentContext
  12. CreateTestWindowInShellWithId
  13. CreateTestWindowInShellWithBounds
  14. CreateTestWindowInShell
  15. CreateTestWindowInShellWithDelegate
  16. CreateTestWindowInShellWithDelegateAndType
  17. ParentWindowInPrimaryRootWindow
  18. RunAllPendingInMessageLoop
  19. GetScreenshotDelegate
  20. GetSystemTrayDelegate
  21. SetSessionStarted
  22. SetUserLoggedIn
  23. SetCanLockScreen
  24. SetShouldLockScreenBeforeSuspending
  25. SetUserAddingScreenRunning
  26. BlockUserSession
  27. UnblockUserSession

// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ash/test/ash_test_base.h"

#include <string>
#include <vector>

#include "ash/ash_switches.h"
#include "ash/display/display_controller.h"
#include "ash/shell.h"
#include "ash/shell/toplevel_window.h"
#include "ash/test/ash_test_helper.h"
#include "ash/test/display_manager_test_api.h"
#include "ash/test/test_session_state_delegate.h"
#include "ash/test/test_shell_delegate.h"
#include "ash/test/test_system_tray_delegate.h"
#include "ash/wm/coordinate_conversion.h"
#include "ash/wm/window_positioner.h"
#include "base/command_line.h"
#include "content/public/test/web_contents_tester.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/client/screen_position_client.h"
#include "ui/aura/client/window_tree_client.h"
#include "ui/aura/test/event_generator.h"
#include "ui/aura/test/test_window_delegate.h"
#include "ui/aura/window.h"
#include "ui/aura/window_delegate.h"
#include "ui/aura/window_tree_host.h"
#include "ui/base/ime/input_method_initializer.h"
#include "ui/events/gestures/gesture_configuration.h"
#include "ui/gfx/display.h"
#include "ui/gfx/point.h"
#include "ui/gfx/screen.h"

#if defined(OS_CHROMEOS)
#include "ash/system/chromeos/tray_display.h"
#endif

#if defined(OS_WIN)
#include "ash/test/test_metro_viewer_process_host.h"
#include "base/test/test_process_killer_win.h"
#include "base/win/metro.h"
#include "base/win/windows_version.h"
#include "ui/aura/remote_window_tree_host_win.h"
#include "ui/aura/window_tree_host_win.h"
#include "win8/test/test_registrar_constants.h"
#endif

#if defined(USE_X11)
#include <X11/Xlib.h>
#endif

namespace ash {
namespace test {
namespace {

class AshEventGeneratorDelegate : public aura::test::EventGeneratorDelegate {
 public:
  AshEventGeneratorDelegate() {}
  virtual ~AshEventGeneratorDelegate() {}

  // aura::test::EventGeneratorDelegate overrides:
  virtual aura::WindowTreeHost* GetHostAt(
      const gfx::Point& point_in_screen) const OVERRIDE {
    gfx::Screen* screen = Shell::GetScreen();
    gfx::Display display = screen->GetDisplayNearestPoint(point_in_screen);
    return Shell::GetInstance()->display_controller()->
        GetRootWindowForDisplayId(display.id())->GetHost();
  }

  virtual aura::client::ScreenPositionClient* GetScreenPositionClient(
      const aura::Window* window) const OVERRIDE {
    return aura::client::GetScreenPositionClient(window->GetRootWindow());
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(AshEventGeneratorDelegate);
};

}  // namespace

content::WebContents* AshTestViewsDelegate::CreateWebContents(
    content::BrowserContext* browser_context,
    content::SiteInstance* site_instance) {
  return content::WebContentsTester::CreateTestWebContents(browser_context,
                                                           site_instance);
}

/////////////////////////////////////////////////////////////////////////////

AshTestBase::AshTestBase()
    : setup_called_(false),
      teardown_called_(false),
      start_session_(true) {
#if defined(USE_X11)
  // This is needed for tests which use this base class but are run in browser
  // test binaries so don't get the default initialization in the unit test
  // suite.
  XInitThreads();
#endif

  thread_bundle_.reset(new content::TestBrowserThreadBundle);
  // Must initialize |ash_test_helper_| here because some tests rely on
  // AshTestBase methods before they call AshTestBase::SetUp().
  ash_test_helper_.reset(new AshTestHelper(base::MessageLoopForUI::current()));
}

AshTestBase::~AshTestBase() {
  CHECK(setup_called_)
      << "You have overridden SetUp but never called AshTestBase::SetUp";
  CHECK(teardown_called_)
      << "You have overridden TearDown but never called AshTestBase::TearDown";
}

void AshTestBase::SetUp() {
  setup_called_ = true;

  // Clears the saved state so that test doesn't use on the wrong
  // default state.
  shell::ToplevelWindow::ClearSavedStateForTest();

  // TODO(jamescook): Can we do this without changing command line?
  // Use the origin (1,1) so that it doesn't over
  // lap with the native mouse cursor.
  CommandLine* command_line = CommandLine::ForCurrentProcess();
  if (!command_line->HasSwitch(switches::kAshHostWindowBounds)) {
    command_line->AppendSwitchASCII(
        switches::kAshHostWindowBounds, "1+1-800x600");
  }
#if defined(OS_WIN)
  aura::test::SetUsePopupAsRootWindowForTest(true);
#endif
  ash_test_helper_->SetUp(start_session_);

  Shell::GetPrimaryRootWindow()->Show();
  Shell::GetPrimaryRootWindow()->GetHost()->Show();
  // Move the mouse cursor to far away so that native events doesn't
  // interfere test expectations.
  Shell::GetPrimaryRootWindow()->MoveCursorTo(gfx::Point(-1000, -1000));
  ash::Shell::GetInstance()->cursor_manager()->EnableMouseEvents();

  // Changing GestureConfiguration shouldn't make tests fail.
  ui::GestureConfiguration::set_max_touch_move_in_pixels_for_click(5);

#if defined(OS_WIN)
  if (!command_line->HasSwitch(ash::switches::kForceAshToDesktop)) {
    if (base::win::GetVersion() >= base::win::VERSION_WIN8) {
      ipc_thread_.reset(new base::Thread("test_metro_viewer_ipc_thread"));
      base::Thread::Options options;
      options.message_loop_type = base::MessageLoop::TYPE_IO;
      ipc_thread_->StartWithOptions(options);
      metro_viewer_host_.reset(
          new TestMetroViewerProcessHost(ipc_thread_->message_loop_proxy()));
      CHECK(metro_viewer_host_->LaunchViewerAndWaitForConnection(
          win8::test::kDefaultTestAppUserModelId));
      aura::RemoteWindowTreeHostWin* window_tree_host =
          aura::RemoteWindowTreeHostWin::Instance();
      CHECK(window_tree_host != NULL);
    }
    ash::WindowPositioner::SetMaximizeFirstWindow(true);
  }
#endif
}

void AshTestBase::TearDown() {
  teardown_called_ = true;
  // Flush the message loop to finish pending release tasks.
  RunAllPendingInMessageLoop();

#if defined(OS_WIN)
  if (base::win::GetVersion() >= base::win::VERSION_WIN8 &&
      !CommandLine::ForCurrentProcess()->HasSwitch(
          ash::switches::kForceAshToDesktop)) {
    // Check that our viewer connection is still established.
    CHECK(!metro_viewer_host_->closed_unexpectedly());
  }
#endif

  ash_test_helper_->TearDown();
#if defined(OS_WIN)
  aura::test::SetUsePopupAsRootWindowForTest(false);
  // Kill the viewer process if we spun one up.
  metro_viewer_host_.reset();

  // Clean up any dangling viewer processes as the metro APIs sometimes leave
  // zombies behind. A default browser process in metro will have the
  // following command line arg so use that to avoid killing all processes named
  // win8::test::kDefaultTestExePath.
  const wchar_t kViewerProcessArgument[] = L"DefaultBrowserServer";
  base::KillAllNamedProcessesWithArgument(win8::test::kDefaultTestExePath,
                                          kViewerProcessArgument);
#endif

  event_generator_.reset();
  // Some tests set an internal display id,
  // reset it here, so other tests will continue in a clean environment.
  gfx::Display::SetInternalDisplayId(gfx::Display::kInvalidDisplayID);
}

aura::test::EventGenerator& AshTestBase::GetEventGenerator() {
  if (!event_generator_) {
    event_generator_.reset(
        new aura::test::EventGenerator(new AshEventGeneratorDelegate()));
  }
  return *event_generator_.get();
}

// static
bool AshTestBase::SupportsMultipleDisplays() {
#if defined(OS_WIN)
  return base::win::GetVersion() < base::win::VERSION_WIN8;
#else
  return true;
#endif
}

// static
bool AshTestBase::SupportsHostWindowResize() {
#if defined(OS_WIN)
  return base::win::GetVersion() < base::win::VERSION_WIN8;
#else
  return true;
#endif
}

void AshTestBase::UpdateDisplay(const std::string& display_specs) {
  DisplayManagerTestApi display_manager_test_api(
      Shell::GetInstance()->display_manager());
  display_manager_test_api.UpdateDisplay(display_specs);
}

aura::Window* AshTestBase::CurrentContext() {
  return ash_test_helper_->CurrentContext();
}

aura::Window* AshTestBase::CreateTestWindowInShellWithId(int id) {
  return CreateTestWindowInShellWithDelegate(NULL, id, gfx::Rect());
}

aura::Window* AshTestBase::CreateTestWindowInShellWithBounds(
    const gfx::Rect& bounds) {
  return CreateTestWindowInShellWithDelegate(NULL, 0, bounds);
}

aura::Window* AshTestBase::CreateTestWindowInShell(SkColor color,
                                                   int id,
                                                   const gfx::Rect& bounds) {
  return CreateTestWindowInShellWithDelegate(
      new aura::test::ColorTestWindowDelegate(color), id, bounds);
}

aura::Window* AshTestBase::CreateTestWindowInShellWithDelegate(
    aura::WindowDelegate* delegate,
    int id,
    const gfx::Rect& bounds) {
  return CreateTestWindowInShellWithDelegateAndType(
      delegate, ui::wm::WINDOW_TYPE_NORMAL, id, bounds);
}

aura::Window* AshTestBase::CreateTestWindowInShellWithDelegateAndType(
    aura::WindowDelegate* delegate,
    ui::wm::WindowType type,
    int id,
    const gfx::Rect& bounds) {
  aura::Window* window = new aura::Window(delegate);
  window->set_id(id);
  window->SetType(type);
  window->Init(aura::WINDOW_LAYER_TEXTURED);
  window->Show();

  if (bounds.IsEmpty()) {
    ParentWindowInPrimaryRootWindow(window);
  } else {
    gfx::Display display =
        Shell::GetScreen()->GetDisplayMatching(bounds);
    aura::Window* root = ash::Shell::GetInstance()->display_controller()->
        GetRootWindowForDisplayId(display.id());
    gfx::Point origin = bounds.origin();
    wm::ConvertPointFromScreen(root, &origin);
    window->SetBounds(gfx::Rect(origin, bounds.size()));
    aura::client::ParentWindowWithContext(window, root, bounds);
  }
  window->SetProperty(aura::client::kCanMaximizeKey, true);
  return window;
}

void AshTestBase::ParentWindowInPrimaryRootWindow(aura::Window* window) {
  aura::client::ParentWindowWithContext(
      window, Shell::GetPrimaryRootWindow(), gfx::Rect());
}

void AshTestBase::RunAllPendingInMessageLoop() {
  ash_test_helper_->RunAllPendingInMessageLoop();
}

TestScreenshotDelegate* AshTestBase::GetScreenshotDelegate() {
  return ash_test_helper_->test_screenshot_delegate();
}

TestSystemTrayDelegate* AshTestBase::GetSystemTrayDelegate() {
  return static_cast<TestSystemTrayDelegate*>(
      Shell::GetInstance()->system_tray_delegate());
}

void AshTestBase::SetSessionStarted(bool session_started) {
  ash_test_helper_->test_shell_delegate()->test_session_state_delegate()->
      SetActiveUserSessionStarted(session_started);
}

void AshTestBase::SetUserLoggedIn(bool user_logged_in) {
  ash_test_helper_->test_shell_delegate()->test_session_state_delegate()->
      SetHasActiveUser(user_logged_in);
}

void AshTestBase::SetCanLockScreen(bool can_lock_screen) {
  ash_test_helper_->test_shell_delegate()->test_session_state_delegate()->
      SetCanLockScreen(can_lock_screen);
}

void AshTestBase::SetShouldLockScreenBeforeSuspending(bool should_lock) {
  ash_test_helper_->test_shell_delegate()->test_session_state_delegate()->
      SetShouldLockScreenBeforeSuspending(should_lock);
}

void AshTestBase::SetUserAddingScreenRunning(bool user_adding_screen_running) {
  ash_test_helper_->test_shell_delegate()->test_session_state_delegate()->
      SetUserAddingScreenRunning(user_adding_screen_running);
}

void AshTestBase::BlockUserSession(UserSessionBlockReason block_reason) {
  switch (block_reason) {
    case BLOCKED_BY_LOCK_SCREEN:
      SetSessionStarted(true);
      SetUserAddingScreenRunning(false);
      Shell::GetInstance()->session_state_delegate()->LockScreen();
      break;
    case BLOCKED_BY_LOGIN_SCREEN:
      SetUserAddingScreenRunning(false);
      SetSessionStarted(false);
      break;
    case BLOCKED_BY_USER_ADDING_SCREEN:
      SetUserAddingScreenRunning(true);
      SetSessionStarted(true);
      break;
    default:
      NOTREACHED();
      break;
  }
}

void AshTestBase::UnblockUserSession() {
  Shell::GetInstance()->session_state_delegate()->UnlockScreen();
  SetSessionStarted(true);
  SetUserAddingScreenRunning(false);
}


}  // namespace test
}  // namespace ash

/* [<][>][^][v][top][bottom][index][help] */