// 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/shell.h"
#include "ash/shell_window_ids.h"
#include "ash/test/ash_test_base.h"
#include "ash/test/shell_test_api.h"
#include "ash/test/test_activation_delegate.h"
#include "ash/wm/window_util.h"
#include "ui/aura/client/cursor_client_observer.h"
#include "ui/aura/client/focus_client.h"
#include "ui/aura/env.h"
#include "ui/aura/test/aura_test_base.h"
#include "ui/aura/test/test_window_delegate.h"
#include "ui/aura/test/test_windows.h"
#include "ui/base/cursor/cursor.h"
#include "ui/base/hit_test.h"
#include "ui/events/event.h"
#include "ui/events/event_processor.h"
#include "ui/events/event_utils.h"
#include "ui/events/test/event_generator.h"
#include "ui/events/test/test_event_handler.h"
#include "ui/gfx/screen.h"
#include "ui/wm/core/compound_event_filter.h"
#include "ui/wm/core/input_method_event_filter.h"
#include "ui/wm/public/activation_client.h"
#include "ui/wm/public/activation_delegate.h"

namespace {

class TestingCursorClientObserver : public aura::client::CursorClientObserver {
 public:
  TestingCursorClientObserver()
      : cursor_visibility_(false),
        did_visibility_change_(false) {}
  void reset() { cursor_visibility_ = did_visibility_change_ = false; }
  bool is_cursor_visible() const { return cursor_visibility_; }
  bool did_visibility_change() const { return did_visibility_change_; }

  // Overridden from aura::client::CursorClientObserver:
  void OnCursorVisibilityChanged(bool is_visible) override {
    cursor_visibility_ = is_visible;
    did_visibility_change_ = true;
  }

 private:
  bool cursor_visibility_;
  bool did_visibility_change_;

  DISALLOW_COPY_AND_ASSIGN(TestingCursorClientObserver);
};

base::TimeDelta getTime() {
  return ui::EventTimeForNow();
}

// A slightly changed TestEventHandler which can be configured to return a
// specified value for key/mouse event handling.
class CustomEventHandler : public ui::test::TestEventHandler {
 public:
  CustomEventHandler()
      : key_result_(ui::ER_UNHANDLED),
        mouse_result_(ui::ER_UNHANDLED) {
  }

  ~CustomEventHandler() override {}

  void set_key_event_handling_result(ui::EventResult result) {
    key_result_ = result;
  }

  void set_mouse_event_handling_result(ui::EventResult result) {
    mouse_result_ = result;
  }

  // Overridden from ui::EventHandler:
  void OnKeyEvent(ui::KeyEvent* event) override {
    ui::test::TestEventHandler::OnKeyEvent(event);
    if (key_result_ & ui::ER_HANDLED)
      event->SetHandled();
    if (key_result_ & ui::ER_CONSUMED)
      event->StopPropagation();
  }

  void OnMouseEvent(ui::MouseEvent* event) override {
    ui::test::TestEventHandler::OnMouseEvent(event);
    if (mouse_result_ & ui::ER_HANDLED)
      event->SetHandled();
    if (mouse_result_ & ui::ER_CONSUMED)
      event->StopPropagation();
  }

 private:
  ui::EventResult key_result_;
  ui::EventResult mouse_result_;

  DISALLOW_COPY_AND_ASSIGN(CustomEventHandler);
};

}  // namespace

namespace ash {

typedef test::AshTestBase WindowManagerTest;

class NonFocusableDelegate : public aura::test::TestWindowDelegate {
 public:
  NonFocusableDelegate() {}

 private:
  bool CanFocus() override { return false; }

  DISALLOW_COPY_AND_ASSIGN(NonFocusableDelegate);
};

class HitTestWindowDelegate : public aura::test::TestWindowDelegate {
 public:
  HitTestWindowDelegate()
      : hittest_code_(HTNOWHERE) {
  }
  ~HitTestWindowDelegate() override {}
  void set_hittest_code(int hittest_code) { hittest_code_ = hittest_code; }

 private:
  // Overridden from TestWindowDelegate:
  int GetNonClientComponent(const gfx::Point& point) const override {
    return hittest_code_;
  }

  int hittest_code_;

  DISALLOW_COPY_AND_ASSIGN(HitTestWindowDelegate);
};

TEST_F(WindowManagerTest, Focus) {
  // The IME event filter interferes with the basic key event propagation we
  // attempt to do here, so we remove it.
  test::ShellTestApi shell_test(Shell::GetInstance());
  Shell::GetInstance()->RemovePreTargetHandler(
      shell_test.input_method_event_filter());

  aura::Window* root_window = Shell::GetPrimaryRootWindow();
  root_window->SetBounds(gfx::Rect(0, 0, 510, 510));

  // Supplied ids are negative so as not to collide with shell ids.
  // TODO(beng): maybe introduce a MAKE_SHELL_ID() macro that generates a safe
  //             id beyond shell id max?
  scoped_ptr<aura::Window> w1(CreateTestWindowInShell(
      SK_ColorWHITE, -1, gfx::Rect(10, 10, 500, 500)));
  scoped_ptr<aura::Window> w11(aura::test::CreateTestWindow(
      SK_ColorGREEN, -11, gfx::Rect(5, 5, 100, 100), w1.get()));
  scoped_ptr<aura::Window> w111(aura::test::CreateTestWindow(
      SK_ColorCYAN, -111, gfx::Rect(5, 5, 75, 75), w11.get()));
  scoped_ptr<aura::Window> w1111(aura::test::CreateTestWindow(
      SK_ColorRED, -1111, gfx::Rect(5, 5, 50, 50), w111.get()));
  scoped_ptr<aura::Window> w12(aura::test::CreateTestWindow(
      SK_ColorMAGENTA, -12, gfx::Rect(10, 420, 25, 25), w1.get()));
  aura::test::ColorTestWindowDelegate* w121delegate =
      new aura::test::ColorTestWindowDelegate(SK_ColorYELLOW);
  scoped_ptr<aura::Window> w121(aura::test::CreateTestWindowWithDelegate(
      w121delegate, -121, gfx::Rect(5, 5, 5, 5), w12.get()));
  aura::test::ColorTestWindowDelegate* w122delegate =
      new aura::test::ColorTestWindowDelegate(SK_ColorRED);
  scoped_ptr<aura::Window> w122(aura::test::CreateTestWindowWithDelegate(
      w122delegate, -122, gfx::Rect(10, 5, 5, 5), w12.get()));
  aura::test::ColorTestWindowDelegate* w123delegate =
      new aura::test::ColorTestWindowDelegate(SK_ColorRED);
  scoped_ptr<aura::Window> w123(aura::test::CreateTestWindowWithDelegate(
      w123delegate, -123, gfx::Rect(15, 5, 5, 5), w12.get()));
  scoped_ptr<aura::Window> w13(aura::test::CreateTestWindow(
      SK_ColorGRAY, -13, gfx::Rect(5, 470, 50, 50), w1.get()));

  // Click on a sub-window (w121) to focus it.
  ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow(), w121.get());
  generator.ClickLeftButton();

  aura::client::FocusClient* focus_client =
      aura::client::GetFocusClient(w121.get());
  EXPECT_EQ(w121.get(), focus_client->GetFocusedWindow());

  ui::EventProcessor* dispatcher = root_window->GetHost()->event_processor();

  // The key press should be sent to the focused sub-window.
  ui::KeyEvent keyev(ui::ET_KEY_PRESSED, ui::VKEY_E, ui::EF_NONE);
  ui::EventDispatchDetails details = dispatcher->OnEventFromSource(&keyev);
  ASSERT_FALSE(details.dispatcher_destroyed);
  EXPECT_EQ(ui::VKEY_E, w121delegate->last_key_code());

  // Touch on a sub-window (w122) to focus it.
  gfx::Point click_point = w122->bounds().CenterPoint();
  aura::Window::ConvertPointToTarget(w122->parent(), root_window, &click_point);
  ui::TouchEvent touchev(ui::ET_TOUCH_PRESSED, click_point, 0, getTime());
  details = dispatcher->OnEventFromSource(&touchev);
  ASSERT_FALSE(details.dispatcher_destroyed);
  focus_client = aura::client::GetFocusClient(w122.get());
  EXPECT_EQ(w122.get(), focus_client->GetFocusedWindow());

  // The key press should be sent to the focused sub-window.
  keyev = ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_E, ui::EF_NONE);
  details = dispatcher->OnEventFromSource(&keyev);
  ASSERT_FALSE(details.dispatcher_destroyed);
  EXPECT_EQ(ui::VKEY_E, w122delegate->last_key_code());

  // Hiding the focused window will set the focus to its parent if
  // it's focusable.
  w122->Hide();
  EXPECT_EQ(aura::client::GetFocusClient(w12.get()),
            aura::client::GetFocusClient(w122.get()));
  EXPECT_EQ(w12.get(),
            aura::client::GetFocusClient(w12.get())->GetFocusedWindow());

  // Sets the focus back to w122.
  w122->Show();
  w122->Focus();
  EXPECT_EQ(w122.get(),
            aura::client::GetFocusClient(w12.get())->GetFocusedWindow());

  // Removing the focused window from parent should set the focus to
  // its parent if it's focusable.
  w12->RemoveChild(w122.get());
  EXPECT_EQ(NULL, aura::client::GetFocusClient(w122.get()));
  EXPECT_EQ(w12.get(),
            aura::client::GetFocusClient(w12.get())->GetFocusedWindow());

  // Set the focus to w123, but make the w1 not activatable.
  test::TestActivationDelegate activation_delegate(false);
  w123->Focus();
  EXPECT_EQ(w123.get(),
            aura::client::GetFocusClient(w12.get())->GetFocusedWindow());
  aura::client::SetActivationDelegate(w1.get(), &activation_delegate);

  // Hiding the focused window will set the focus to NULL because
  // parent window is not focusable.
  w123->Hide();
  EXPECT_EQ(aura::client::GetFocusClient(w12.get()),
            aura::client::GetFocusClient(w123.get()));
  EXPECT_EQ(NULL, aura::client::GetFocusClient(w12.get())->GetFocusedWindow());
  keyev = ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_E, ui::EF_NONE);
  details = dispatcher->OnEventFromSource(&keyev);
  EXPECT_FALSE(keyev.handled() || details.dispatcher_destroyed);

  // Set the focus back to w123
  aura::client::SetActivationDelegate(w1.get(), NULL);
  w123->Show();
  w123->Focus();
  EXPECT_EQ(w123.get(),
            aura::client::GetFocusClient(w12.get())->GetFocusedWindow());
  aura::client::SetActivationDelegate(w1.get(), &activation_delegate);

  // Removing the focused window will set the focus to NULL because
  // parent window is not focusable.
  w12->RemoveChild(w123.get());
  EXPECT_EQ(NULL, aura::client::GetFocusClient(w123.get()));
  keyev = ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_E, ui::EF_NONE);
  details = dispatcher->OnEventFromSource(&keyev);
  EXPECT_FALSE(keyev.handled() || details.dispatcher_destroyed);
}

// Various assertion testing for activating windows.
TEST_F(WindowManagerTest, ActivateOnMouse) {
  aura::Window* root_window = Shell::GetPrimaryRootWindow();

  test::TestActivationDelegate d1;
  aura::test::TestWindowDelegate wd;
  scoped_ptr<aura::Window> w1(CreateTestWindowInShellWithDelegate(
      &wd, -1, gfx::Rect(10, 10, 50, 50)));
  d1.SetWindow(w1.get());
  test::TestActivationDelegate d2;
  scoped_ptr<aura::Window> w2(CreateTestWindowInShellWithDelegate(
      &wd, -2, gfx::Rect(70, 70, 50, 50)));
  d2.SetWindow(w2.get());

  aura::client::FocusClient* focus_client =
      aura::client::GetFocusClient(w1.get());

  d1.Clear();
  d2.Clear();

  // Activate window1.
  wm::ActivateWindow(w1.get());
  EXPECT_TRUE(wm::IsActiveWindow(w1.get()));
  EXPECT_EQ(w1.get(), focus_client->GetFocusedWindow());
  EXPECT_EQ(1, d1.activated_count());
  EXPECT_EQ(0, d1.lost_active_count());
  d1.Clear();

  {
    // Click on window2.
    ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow(), w2.get());
    generator.ClickLeftButton();

    // Window2 should have become active.
    EXPECT_TRUE(wm::IsActiveWindow(w2.get()));
    EXPECT_EQ(w2.get(), focus_client->GetFocusedWindow());
    EXPECT_EQ(0, d1.activated_count());
    EXPECT_EQ(1, d1.lost_active_count());
    EXPECT_EQ(1, d2.activated_count());
    EXPECT_EQ(0, d2.lost_active_count());
    d1.Clear();
    d2.Clear();
  }

  {
    // Click back on window1, but set it up so w1 doesn't activate on click.
    ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow(), w1.get());
    d1.set_activate(false);
    generator.ClickLeftButton();

    // Window2 should still be active and focused.
    EXPECT_TRUE(wm::IsActiveWindow(w2.get()));
    EXPECT_EQ(w2.get(), focus_client->GetFocusedWindow());
    EXPECT_EQ(0, d1.activated_count());
    EXPECT_EQ(0, d1.lost_active_count());
    EXPECT_EQ(0, d2.activated_count());
    EXPECT_EQ(0, d2.lost_active_count());
    d1.Clear();
    d2.Clear();
  }

  // Destroy window2, this should make window1 active.
  d1.set_activate(true);
  w2.reset();
  EXPECT_EQ(0, d2.activated_count());
  EXPECT_EQ(1, d2.lost_active_count());
  EXPECT_TRUE(wm::IsActiveWindow(w1.get()));
  EXPECT_EQ(w1.get(), focus_client->GetFocusedWindow());
  EXPECT_EQ(1, d1.activated_count());
  EXPECT_EQ(0, d1.lost_active_count());

  // Clicking an active window with a child shouldn't steal the
  // focus from the child.
  {
    scoped_ptr<aura::Window> w11(CreateTestWindowWithDelegate(
          &wd, -11, gfx::Rect(10, 10, 10, 10), w1.get()));
    ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
                                       w11.get());
    // First set the focus to the child |w11|.
    generator.ClickLeftButton();
    EXPECT_EQ(w11.get(), focus_client->GetFocusedWindow());
    EXPECT_EQ(w1.get(), wm::GetActiveWindow());

    // Then click the parent active window. The focus shouldn't move.
    gfx::Point left_top = w1->bounds().origin();
    aura::Window::ConvertPointToTarget(w1->parent(), root_window, &left_top);
    left_top.Offset(1, 1);
    generator.MoveMouseTo(left_top);
    generator.ClickLeftButton();
    EXPECT_EQ(w11.get(), focus_client->GetFocusedWindow());
    EXPECT_EQ(w1.get(), wm::GetActiveWindow());
  }

  // Clicking on a non-focusable window inside a background window should still
  // give focus to the background window.
  {
    NonFocusableDelegate nfd;
    scoped_ptr<aura::Window> w11(CreateTestWindowWithDelegate(
          &nfd, -1, gfx::Rect(10, 10, 10, 10), w1.get()));
    // Move focus to |w2| first.
    scoped_ptr<aura::Window> w2(CreateTestWindowInShellWithDelegate(
          &wd, -1, gfx::Rect(70, 70, 50, 50)));
    ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow(), w2.get());
    generator.ClickLeftButton();
    EXPECT_EQ(w2.get(), focus_client->GetFocusedWindow());
    EXPECT_FALSE(w11->CanFocus());

    // Click on |w11|. This should focus w1.
    generator.MoveMouseToCenterOf(w11.get());
    generator.ClickLeftButton();
    EXPECT_EQ(w1.get(), focus_client->GetFocusedWindow());
  }
}

TEST_F(WindowManagerTest, PanelActivation) {
  aura::test::TestWindowDelegate wd;
  scoped_ptr<aura::Window> w1(CreateTestWindowInShellWithDelegate(
      &wd, -1, gfx::Rect(10, 10, 50, 50)));
  aura::test::TestWindowDelegate pd;
  scoped_ptr<aura::Window> p1(CreateTestWindowInShellWithDelegateAndType(
      &pd, ui::wm::WINDOW_TYPE_PANEL, -1, gfx::Rect(10, 10, 50, 50)));
  aura::client::FocusClient* focus_client =
      aura::client::GetFocusClient(w1.get());

  // Activate w1.
  wm::ActivateWindow(w1.get());
  EXPECT_TRUE(wm::IsActiveWindow(w1.get()));

  // Activate p1.
  wm::ActivateWindow(p1.get());
  EXPECT_TRUE(wm::IsActiveWindow(p1.get()));
  EXPECT_EQ(p1.get(), focus_client->GetFocusedWindow());

  // Activate w1.
  wm::ActivateWindow(w1.get());
  EXPECT_TRUE(wm::IsActiveWindow(w1.get()));
  EXPECT_EQ(w1.get(), focus_client->GetFocusedWindow());

  // Clicking on a non-activatable window should not change the active window.
  {
    NonFocusableDelegate nfd;
    scoped_ptr<aura::Window> w3(CreateTestWindowInShellWithDelegate(
          &nfd, -1, gfx::Rect(70, 70, 50, 50)));
    ui::test::EventGenerator generator3(Shell::GetPrimaryRootWindow(),
                                        w3.get());
    wm::ActivateWindow(p1.get());
    EXPECT_TRUE(wm::IsActiveWindow(p1.get()));
    generator3.ClickLeftButton();
    EXPECT_TRUE(wm::IsActiveWindow(p1.get()));
  }
}

// Essentially the same as ActivateOnMouse, but for touch events.
TEST_F(WindowManagerTest, ActivateOnTouch) {
  aura::Window* root_window = Shell::GetPrimaryRootWindow();

  test::TestActivationDelegate d1;
  aura::test::TestWindowDelegate wd;
  scoped_ptr<aura::Window> w1(CreateTestWindowInShellWithDelegate(
      &wd, -1, gfx::Rect(10, 10, 50, 50)));
  d1.SetWindow(w1.get());
  test::TestActivationDelegate d2;
  scoped_ptr<aura::Window> w2(CreateTestWindowInShellWithDelegate(
      &wd, -2, gfx::Rect(70, 70, 50, 50)));
  d2.SetWindow(w2.get());

  aura::client::FocusClient* focus_client =
      aura::client::GetFocusClient(w1.get());

  d1.Clear();
  d2.Clear();

  // Activate window1.
  wm::ActivateWindow(w1.get());
  EXPECT_TRUE(wm::IsActiveWindow(w1.get()));
  EXPECT_EQ(w1.get(), focus_client->GetFocusedWindow());
  EXPECT_EQ(1, d1.activated_count());
  EXPECT_EQ(0, d1.lost_active_count());
  d1.Clear();

  // Touch window2.
  gfx::Point press_point = w2->bounds().CenterPoint();
  aura::Window::ConvertPointToTarget(w2->parent(), root_window, &press_point);
  ui::TouchEvent touchev1(ui::ET_TOUCH_PRESSED, press_point, 0, getTime());

  ui::EventProcessor* dispatcher = root_window->GetHost()->event_processor();
  ui::EventDispatchDetails details = dispatcher->OnEventFromSource(&touchev1);
  ASSERT_FALSE(details.dispatcher_destroyed);

  // Window2 should have become active.
  EXPECT_TRUE(wm::IsActiveWindow(w2.get()));
  EXPECT_EQ(w2.get(), focus_client->GetFocusedWindow());
  EXPECT_EQ(0, d1.activated_count());
  EXPECT_EQ(1, d1.lost_active_count());
  EXPECT_EQ(1, d2.activated_count());
  EXPECT_EQ(0, d2.lost_active_count());
  d1.Clear();
  d2.Clear();

  // Touch window1, but set it up so w1 doesn't activate on touch.
  press_point = w1->bounds().CenterPoint();
  aura::Window::ConvertPointToTarget(w1->parent(), root_window, &press_point);
  d1.set_activate(false);
  ui::TouchEvent touchev2(ui::ET_TOUCH_PRESSED, press_point, 1, getTime());
  details = dispatcher->OnEventFromSource(&touchev2);
  ASSERT_FALSE(details.dispatcher_destroyed);

  // Window2 should still be active and focused.
  EXPECT_TRUE(wm::IsActiveWindow(w2.get()));
  EXPECT_EQ(w2.get(), focus_client->GetFocusedWindow());
  EXPECT_EQ(0, d1.activated_count());
  EXPECT_EQ(0, d1.lost_active_count());
  EXPECT_EQ(0, d2.activated_count());
  EXPECT_EQ(0, d2.lost_active_count());
  d1.Clear();
  d2.Clear();

  // Destroy window2, this should make window1 active.
  d1.set_activate(true);
  w2.reset();
  EXPECT_EQ(0, d2.activated_count());
  EXPECT_EQ(1, d2.lost_active_count());
  EXPECT_TRUE(wm::IsActiveWindow(w1.get()));
  EXPECT_EQ(w1.get(), focus_client->GetFocusedWindow());
  EXPECT_EQ(1, d1.activated_count());
  EXPECT_EQ(0, d1.lost_active_count());
}

TEST_F(WindowManagerTest, MouseEventCursors) {
  aura::Window* root_window = Shell::GetPrimaryRootWindow();

  // Create a window.
  const int kWindowLeft = 123;
  const int kWindowTop = 45;
  HitTestWindowDelegate window_delegate;
  scoped_ptr<aura::Window> window(CreateTestWindowInShellWithDelegate(
    &window_delegate,
    -1,
    gfx::Rect(kWindowLeft, kWindowTop, 640, 480)));

  // Create two mouse movement events we can switch between.
  gfx::Point point1(kWindowLeft, kWindowTop);
  aura::Window::ConvertPointToTarget(window->parent(), root_window, &point1);

  gfx::Point point2(kWindowLeft + 1, kWindowTop + 1);
  aura::Window::ConvertPointToTarget(window->parent(), root_window, &point2);

  aura::WindowTreeHost* host = root_window->GetHost();
  ui::EventProcessor* dispatcher = host->event_processor();

  // Cursor starts as a pointer (set during Shell::Init()).
  EXPECT_EQ(ui::kCursorPointer, host->last_cursor().native_type());

  {
    // Resize edges and corners show proper cursors.
    window_delegate.set_hittest_code(HTBOTTOM);
    ui::MouseEvent move1(ui::ET_MOUSE_MOVED, point1, point1, 0, 0);
    ui::EventDispatchDetails details = dispatcher->OnEventFromSource(&move1);
    ASSERT_FALSE(details.dispatcher_destroyed);
    EXPECT_EQ(ui::kCursorSouthResize, host->last_cursor().native_type());
  }

  {
    window_delegate.set_hittest_code(HTBOTTOMLEFT);
    ui::MouseEvent move2(ui::ET_MOUSE_MOVED, point2, point2, 0, 0);
    ui::EventDispatchDetails details = dispatcher->OnEventFromSource(&move2);
    ASSERT_FALSE(details.dispatcher_destroyed);
    EXPECT_EQ(ui::kCursorSouthWestResize, host->last_cursor().native_type());
  }

  {
    window_delegate.set_hittest_code(HTBOTTOMRIGHT);
    ui::MouseEvent move1(ui::ET_MOUSE_MOVED, point1, point1, 0, 0);
    ui::EventDispatchDetails details = dispatcher->OnEventFromSource(&move1);
    ASSERT_FALSE(details.dispatcher_destroyed);
    EXPECT_EQ(ui::kCursorSouthEastResize, host->last_cursor().native_type());
  }

  {
    window_delegate.set_hittest_code(HTLEFT);
    ui::MouseEvent move2(ui::ET_MOUSE_MOVED, point2, point2, 0, 0);
    ui::EventDispatchDetails details = dispatcher->OnEventFromSource(&move2);
    ASSERT_FALSE(details.dispatcher_destroyed);
    EXPECT_EQ(ui::kCursorWestResize, host->last_cursor().native_type());
  }

  {
    window_delegate.set_hittest_code(HTRIGHT);
    ui::MouseEvent move1(ui::ET_MOUSE_MOVED, point1, point1, 0, 0);
    ui::EventDispatchDetails details = dispatcher->OnEventFromSource(&move1);
    ASSERT_FALSE(details.dispatcher_destroyed);
    EXPECT_EQ(ui::kCursorEastResize, host->last_cursor().native_type());
  }

  {
    window_delegate.set_hittest_code(HTTOP);
    ui::MouseEvent move2(ui::ET_MOUSE_MOVED, point2, point2, 0, 0);
    ui::EventDispatchDetails details = dispatcher->OnEventFromSource(&move2);
    ASSERT_FALSE(details.dispatcher_destroyed);
    EXPECT_EQ(ui::kCursorNorthResize, host->last_cursor().native_type());
  }

  {
    window_delegate.set_hittest_code(HTTOPLEFT);
    ui::MouseEvent move1(ui::ET_MOUSE_MOVED, point1, point1, 0, 0);
    ui::EventDispatchDetails details = dispatcher->OnEventFromSource(&move1);
    ASSERT_FALSE(details.dispatcher_destroyed);
    EXPECT_EQ(ui::kCursorNorthWestResize, host->last_cursor().native_type());
  }

  {
    window_delegate.set_hittest_code(HTTOPRIGHT);
    ui::MouseEvent move2(ui::ET_MOUSE_MOVED, point2, point2, 0, 0);
    ui::EventDispatchDetails details = dispatcher->OnEventFromSource(&move2);
    ASSERT_FALSE(details.dispatcher_destroyed);
    EXPECT_EQ(ui::kCursorNorthEastResize, host->last_cursor().native_type());
  }

  {
    // Client area uses null cursor.
    window_delegate.set_hittest_code(HTCLIENT);
    ui::MouseEvent move1(ui::ET_MOUSE_MOVED, point1, point1, 0, 0);
    ui::EventDispatchDetails details = dispatcher->OnEventFromSource(&move1);
    ASSERT_FALSE(details.dispatcher_destroyed);
    EXPECT_EQ(ui::kCursorNull, host->last_cursor().native_type());
  }
}

#if defined(OS_WIN)
#define MAYBE_TransformActivate DISABLED_TransformActivate
#else
#define MAYBE_TransformActivate TransformActivate
#endif
TEST_F(WindowManagerTest, MAYBE_TransformActivate) {
  aura::Window* root_window = Shell::GetPrimaryRootWindow();
  gfx::Size size = root_window->bounds().size();
  EXPECT_EQ(gfx::Rect(size).ToString(),
            Shell::GetScreen()->GetDisplayNearestPoint(
                gfx::Point()).bounds().ToString());

  // Rotate it clock-wise 90 degrees.
  gfx::Transform transform;
  transform.Translate(size.width(), 0);
  transform.Rotate(90.0f);
  root_window->GetHost()->SetRootTransform(transform);

  test::TestActivationDelegate d1;
  aura::test::TestWindowDelegate wd;
  scoped_ptr<aura::Window> w1(
      CreateTestWindowInShellWithDelegate(&wd, 1, gfx::Rect(0, 15, 50, 50)));
  d1.SetWindow(w1.get());
  w1->Show();

  gfx::Point miss_point(5, 5);
  transform.TransformPoint(&miss_point);
  ui::MouseEvent mouseev1(ui::ET_MOUSE_PRESSED,
                          miss_point,
                          miss_point,
                          ui::EF_LEFT_MOUSE_BUTTON,
                          ui::EF_LEFT_MOUSE_BUTTON);
  ui::EventProcessor* dispatcher = root_window->GetHost()->event_processor();
  ui::EventDispatchDetails details = dispatcher->OnEventFromSource(&mouseev1);
  ASSERT_FALSE(details.dispatcher_destroyed);
  EXPECT_EQ(NULL, aura::client::GetFocusClient(w1.get())->GetFocusedWindow());
  ui::MouseEvent mouseup(ui::ET_MOUSE_RELEASED,
                         miss_point,
                         miss_point,
                         ui::EF_LEFT_MOUSE_BUTTON,
                         ui::EF_LEFT_MOUSE_BUTTON);
  details = dispatcher->OnEventFromSource(&mouseup);
  ASSERT_FALSE(details.dispatcher_destroyed);

  gfx::Point hit_point(5, 15);
  transform.TransformPoint(&hit_point);
  ui::MouseEvent mouseev2(ui::ET_MOUSE_PRESSED,
                          hit_point,
                          hit_point,
                          ui::EF_LEFT_MOUSE_BUTTON,
                          ui::EF_LEFT_MOUSE_BUTTON);
  details = dispatcher->OnEventFromSource(&mouseev2);
  ASSERT_FALSE(details.dispatcher_destroyed);
  EXPECT_TRUE(wm::IsActiveWindow(w1.get()));
  EXPECT_EQ(w1.get(),
            aura::client::GetFocusClient(w1.get())->GetFocusedWindow());
}

TEST_F(WindowManagerTest, AdditionalFilters) {
  // The IME event filter interferes with the basic key event propagation we
  // attempt to do here, so we remove it.
  test::ShellTestApi shell_test(Shell::GetInstance());
  Shell::GetInstance()->RemovePreTargetHandler(
      shell_test.input_method_event_filter());

  aura::Window* root_window = Shell::GetPrimaryRootWindow();

  // Creates a window and make it active
  scoped_ptr<aura::Window> w1(CreateTestWindowInShell(
      SK_ColorWHITE, -1, gfx::Rect(0, 0, 100, 100)));
  wm::ActivateWindow(w1.get());

  // Creates two addition filters
  scoped_ptr<CustomEventHandler> f1(new CustomEventHandler);
  scoped_ptr<CustomEventHandler> f2(new CustomEventHandler);

  // Adds them to root window event filter.
  ::wm::CompoundEventFilter* env_filter =
      Shell::GetInstance()->env_filter();
  env_filter->AddHandler(f1.get());
  env_filter->AddHandler(f2.get());

  // Dispatches mouse and keyboard events.
  ui::KeyEvent key_event(ui::ET_KEY_PRESSED, ui::VKEY_A, ui::EF_NONE);
  ui::EventProcessor* dispatcher = root_window->GetHost()->event_processor();
  ui::EventDispatchDetails details = dispatcher->OnEventFromSource(&key_event);
  ASSERT_FALSE(details.dispatcher_destroyed);
  ui::MouseEvent mouse_pressed(
      ui::ET_MOUSE_PRESSED, gfx::Point(0, 0), gfx::Point(0, 0), 0, 0);
  details = dispatcher->OnEventFromSource(&mouse_pressed);
  ASSERT_FALSE(details.dispatcher_destroyed);

  // Both filters should get the events.
  EXPECT_EQ(1, f1->num_key_events());
  EXPECT_EQ(1, f1->num_mouse_events());
  EXPECT_EQ(1, f2->num_key_events());
  EXPECT_EQ(1, f2->num_mouse_events());

  f1->Reset();
  f2->Reset();

  // Makes f1 consume events.
  f1->set_key_event_handling_result(ui::ER_CONSUMED);
  f1->set_mouse_event_handling_result(ui::ER_CONSUMED);

  // Dispatches events.
  details = dispatcher->OnEventFromSource(&key_event);
  ASSERT_FALSE(details.dispatcher_destroyed);
  ui::MouseEvent mouse_released(
      ui::ET_MOUSE_RELEASED, gfx::Point(0, 0), gfx::Point(0, 0), 0, 0);
  details = dispatcher->OnEventFromSource(&mouse_released);
  ASSERT_FALSE(details.dispatcher_destroyed);

  // f1 should still get the events but f2 no longer gets them.
  EXPECT_EQ(1, f1->num_key_events());
  EXPECT_EQ(1, f1->num_mouse_events());
  EXPECT_EQ(0, f2->num_key_events());
  EXPECT_EQ(0, f2->num_mouse_events());

  f1->Reset();
  f2->Reset();

  // Remove f1 from additonal filters list.
  env_filter->RemoveHandler(f1.get());

  // Dispatches events.
  details = dispatcher->OnEventFromSource(&key_event);
  ASSERT_FALSE(details.dispatcher_destroyed);
  details = dispatcher->OnEventFromSource(&mouse_pressed);
  ASSERT_FALSE(details.dispatcher_destroyed);

  // f1 should get no events since it's out and f2 should get them.
  EXPECT_EQ(0, f1->num_key_events());
  EXPECT_EQ(0, f1->num_mouse_events());
  EXPECT_EQ(1, f2->num_key_events());
  EXPECT_EQ(1, f2->num_mouse_events());

  env_filter->RemoveHandler(f2.get());
}

#if defined(OS_CHROMEOS) || defined(OS_WIN)
// Touch visually hides the cursor on ChromeOS and Windows
TEST_F(WindowManagerTest, UpdateCursorVisibility) {
  ui::test::EventGenerator& generator = GetEventGenerator();
  ::wm::CursorManager* cursor_manager =
      ash::Shell::GetInstance()->cursor_manager();

  generator.MoveMouseTo(gfx::Point(0, 0));
  EXPECT_TRUE(cursor_manager->IsCursorVisible());
  EXPECT_TRUE(cursor_manager->IsMouseEventsEnabled());
  generator.PressTouch();
  EXPECT_FALSE(cursor_manager->IsCursorVisible());
  EXPECT_FALSE(cursor_manager->IsMouseEventsEnabled());
  generator.MoveMouseTo(gfx::Point(0, 0));
  EXPECT_TRUE(cursor_manager->IsCursorVisible());
  EXPECT_TRUE(cursor_manager->IsMouseEventsEnabled());
  generator.ReleaseTouch();
  EXPECT_TRUE(cursor_manager->IsCursorVisible());
  EXPECT_TRUE(cursor_manager->IsMouseEventsEnabled());
}
#endif  // defined(OS_CHROMEOS) || defined(OS_WIN)

#if defined(OS_CHROMEOS)
// ChromeOS is the only platform for which the cursor is hidden on keypress
// (crbug.com/304296).
TEST_F(WindowManagerTest, UpdateCursorVisibilityOnKeyEvent) {
  ui::test::EventGenerator& generator = GetEventGenerator();
  ::wm::CursorManager* cursor_manager =
      ash::Shell::GetInstance()->cursor_manager();

  // Pressing a key hides the cursor but does not disable mouse events.
  generator.PressKey(ui::VKEY_A, ui::EF_NONE);
  EXPECT_FALSE(cursor_manager->IsCursorVisible());
  EXPECT_TRUE(cursor_manager->IsMouseEventsEnabled());
  // Moving mouse shows the cursor.
  generator.MoveMouseTo(gfx::Point(0, 0));
  EXPECT_TRUE(cursor_manager->IsCursorVisible());
  EXPECT_TRUE(cursor_manager->IsMouseEventsEnabled());
  // Releasing a key also hides the cursor but does not disable mouse events.
  generator.ReleaseKey(ui::VKEY_A, ui::EF_NONE);
  EXPECT_FALSE(cursor_manager->IsCursorVisible());
  EXPECT_TRUE(cursor_manager->IsMouseEventsEnabled());
  // Moving mouse shows the cursor again.
  generator.MoveMouseTo(gfx::Point(0, 0));
  EXPECT_TRUE(cursor_manager->IsCursorVisible());
  EXPECT_TRUE(cursor_manager->IsMouseEventsEnabled());
}

TEST_F(WindowManagerTest, TestCursorClientObserver) {
  ui::test::EventGenerator& generator = GetEventGenerator();
  ::wm::CursorManager* cursor_manager =
      ash::Shell::GetInstance()->cursor_manager();

  scoped_ptr<aura::Window> w1(CreateTestWindowInShell(
      SK_ColorWHITE, -1, gfx::Rect(0, 0, 100, 100)));
  wm::ActivateWindow(w1.get());

  // Add two observers. Both should have OnCursorVisibilityChanged()
  // invoked when an event changes the visibility of the cursor.
  TestingCursorClientObserver observer_a;
  TestingCursorClientObserver observer_b;
  cursor_manager->AddObserver(&observer_a);
  cursor_manager->AddObserver(&observer_b);

  // Initial state before any events have been sent.
  observer_a.reset();
  observer_b.reset();
  EXPECT_FALSE(observer_a.did_visibility_change());
  EXPECT_FALSE(observer_b.did_visibility_change());
  EXPECT_FALSE(observer_a.is_cursor_visible());
  EXPECT_FALSE(observer_b.is_cursor_visible());

  // Keypress should hide the cursor.
  generator.PressKey(ui::VKEY_A, ui::EF_NONE);
  EXPECT_TRUE(observer_a.did_visibility_change());
  EXPECT_TRUE(observer_b.did_visibility_change());
  EXPECT_FALSE(observer_a.is_cursor_visible());
  EXPECT_FALSE(observer_b.is_cursor_visible());

  // Mouse move should show the cursor.
  observer_a.reset();
  observer_b.reset();
  generator.MoveMouseTo(50, 50);
  EXPECT_TRUE(observer_a.did_visibility_change());
  EXPECT_TRUE(observer_b.did_visibility_change());
  EXPECT_TRUE(observer_a.is_cursor_visible());
  EXPECT_TRUE(observer_b.is_cursor_visible());

  // Remove observer_b. Its OnCursorVisibilityChanged() should
  // not be invoked past this point.
  cursor_manager->RemoveObserver(&observer_b);

  // Gesture tap should hide the cursor.
  observer_a.reset();
  observer_b.reset();
  generator.GestureTapAt(gfx::Point(25, 25));
  EXPECT_TRUE(observer_a.did_visibility_change());
  EXPECT_FALSE(observer_b.did_visibility_change());
  EXPECT_FALSE(observer_a.is_cursor_visible());

  // Mouse move should show the cursor.
  observer_a.reset();
  observer_b.reset();
  generator.MoveMouseTo(50, 50);
  EXPECT_TRUE(observer_a.did_visibility_change());
  EXPECT_FALSE(observer_b.did_visibility_change());
  EXPECT_TRUE(observer_a.is_cursor_visible());
}
#endif  // defined(OS_CHROMEOS)

}  // namespace ash
