// 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/wm/drag_window_resizer.h"

#include "ash/display/mouse_cursor_event_filter.h"
#include "ash/public/cpp/shell_window_ids.h"
#include "ash/root_window_controller.h"
#include "ash/shelf/shelf_layout_manager.h"
#include "ash/shell.h"
#include "ash/test/ash_test_base.h"
#include "ash/wm/cursor_manager_test_api.h"
#include "ash/wm/drag_window_controller.h"
#include "ash/wm/window_positioning_utils.h"
#include "ash/wm/window_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/env.h"
#include "ui/aura/test/test_window_delegate.h"
#include "ui/base/hit_test.h"
#include "ui/base/ui_base_types.h"
#include "ui/compositor/layer_delegate.h"
#include "ui/compositor/layer_tree_owner.h"
#include "ui/display/display_layout.h"
#include "ui/display/display_layout_builder.h"
#include "ui/display/manager/display_manager.h"
#include "ui/gfx/geometry/insets.h"
#include "ui/views/widget/widget.h"
#include "ui/wm/core/window_util.h"

namespace ash {
namespace {

const int kRootHeight = 600;

// Used to test if the OnPaintLayer is called by DragWindowLayerDelegate.
class TestLayerDelegate : public ui::LayerDelegate {
 public:
  TestLayerDelegate() = default;
  ~TestLayerDelegate() override = default;

  int paint_count() const { return paint_count_; }

 private:
  // Paint content for the layer to the specified context.
  void OnPaintLayer(const ui::PaintContext& context) override {
    paint_count_++;
  }
  void OnDeviceScaleFactorChanged(float old_device_scale_factor,
                                  float new_device_scale_factor) override {}

  int paint_count_ = 0;

  DISALLOW_COPY_AND_ASSIGN(TestLayerDelegate);
};

}  // namespace

class DragWindowResizerTest : public AshTestBase {
 public:
  DragWindowResizerTest() : transient_child_(nullptr) {}
  ~DragWindowResizerTest() override = default;

  void SetUp() override {
    AshTestBase::SetUp();

    UpdateDisplay(base::StringPrintf("800x%d", kRootHeight));

    aura::Window* root = Shell::GetPrimaryRootWindow();
    gfx::Rect root_bounds(root->bounds());
    EXPECT_EQ(kRootHeight, root_bounds.height());
    EXPECT_EQ(800, root_bounds.width());
    window_.reset(new aura::Window(&delegate_));
    window_->SetType(aura::client::WINDOW_TYPE_NORMAL);
    window_->Init(ui::LAYER_NOT_DRAWN);
    ParentWindowInPrimaryRootWindow(window_.get());
    window_->set_id(1);

    always_on_top_window_.reset(new aura::Window(&delegate2_));
    always_on_top_window_->SetType(aura::client::WINDOW_TYPE_NORMAL);
    always_on_top_window_->SetProperty(aura::client::kAlwaysOnTopKey, true);
    always_on_top_window_->Init(ui::LAYER_NOT_DRAWN);
    ParentWindowInPrimaryRootWindow(always_on_top_window_.get());
    always_on_top_window_->set_id(2);

    system_modal_window_.reset(new aura::Window(&delegate3_));
    system_modal_window_->SetType(aura::client::WINDOW_TYPE_NORMAL);
    system_modal_window_->SetProperty(aura::client::kModalKey,
                                      ui::MODAL_TYPE_SYSTEM);
    system_modal_window_->Init(ui::LAYER_NOT_DRAWN);
    ParentWindowInPrimaryRootWindow(system_modal_window_.get());
    system_modal_window_->set_id(3);

    transient_child_ = new aura::Window(&delegate4_);
    transient_child_->SetType(aura::client::WINDOW_TYPE_NORMAL);
    transient_child_->Init(ui::LAYER_NOT_DRAWN);
    ParentWindowInPrimaryRootWindow(transient_child_);
    transient_child_->set_id(4);

    transient_parent_.reset(new aura::Window(&delegate5_));
    transient_parent_->SetType(aura::client::WINDOW_TYPE_NORMAL);
    transient_parent_->Init(ui::LAYER_NOT_DRAWN);
    ParentWindowInPrimaryRootWindow(transient_parent_.get());
    ::wm::AddTransientChild(transient_parent_.get(), transient_child_);
    transient_parent_->set_id(5);

    panel_window_.reset(new aura::Window(&delegate6_));
    panel_window_->SetType(aura::client::WINDOW_TYPE_PANEL);
    panel_window_->Init(ui::LAYER_NOT_DRAWN);
    ParentWindowInPrimaryRootWindow(panel_window_.get());
  }

  void TearDown() override {
    window_.reset();
    always_on_top_window_.reset();
    system_modal_window_.reset();
    transient_parent_.reset();
    panel_window_.reset();
    AshTestBase::TearDown();
  }

 protected:
  gfx::Point CalculateDragPoint(const WindowResizer& resizer,
                                int delta_x,
                                int delta_y) const {
    gfx::Point location = resizer.GetInitialLocation();
    location.set_x(location.x() + delta_x);
    location.set_y(location.y() + delta_y);
    return location;
  }

  ShelfLayoutManager* shelf_layout_manager() {
    return Shell::GetPrimaryRootWindowController()->GetShelfLayoutManager();
  }

  static WindowResizer* CreateDragWindowResizer(
      aura::Window* window,
      const gfx::Point& point_in_parent,
      int window_component) {
    return CreateWindowResizer(window, point_in_parent, window_component,
                               ::wm::WINDOW_MOVE_SOURCE_MOUSE)
        .release();
  }

  bool TestIfMouseWarpsAt(const gfx::Point& point_in_screen) {
    return AshTestBase::TestIfMouseWarpsAt(GetEventGenerator(),
                                           point_in_screen);
  }

  aura::test::TestWindowDelegate delegate_;
  aura::test::TestWindowDelegate delegate2_;
  aura::test::TestWindowDelegate delegate3_;
  aura::test::TestWindowDelegate delegate4_;
  aura::test::TestWindowDelegate delegate5_;
  aura::test::TestWindowDelegate delegate6_;

  std::unique_ptr<aura::Window> window_;
  std::unique_ptr<aura::Window> always_on_top_window_;
  std::unique_ptr<aura::Window> system_modal_window_;
  std::unique_ptr<aura::Window> panel_window_;
  aura::Window* transient_child_;
  std::unique_ptr<aura::Window> transient_parent_;

 private:
  DISALLOW_COPY_AND_ASSIGN(DragWindowResizerTest);
};

// Verifies a window can be moved from the primary display to another.
TEST_F(DragWindowResizerTest, WindowDragWithMultiDisplays) {
  // The secondary display is logically on the right, but on the system (e.g. X)
  // layer, it's below the primary one. See UpdateDisplay() in ash_test_base.cc.
  UpdateDisplay("800x600,400x300");
  aura::Window::Windows root_windows = Shell::GetAllRootWindows();
  ASSERT_EQ(2U, root_windows.size());

  window_->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60),
                             display::Screen::GetScreen()->GetPrimaryDisplay());
  EXPECT_EQ(root_windows[0], window_->GetRootWindow());
  {
    // Grab (0, 0) of the window.
    std::unique_ptr<WindowResizer> resizer(
        CreateDragWindowResizer(window_.get(), gfx::Point(), HTCAPTION));
    ASSERT_TRUE(resizer.get());
    // Drag the pointer to the right. Once it reaches the right edge of the
    // primary display, it warps to the secondary.
    resizer->Drag(CalculateDragPoint(*resizer, 800, 10), 0);
    resizer->CompleteDrag();
    // The whole window is on the secondary display now. The parent should be
    // changed.
    EXPECT_EQ(root_windows[1], window_->GetRootWindow());
    EXPECT_EQ("0,10 50x60", window_->bounds().ToString());
  }

  window_->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60),
                             display::Screen::GetScreen()->GetPrimaryDisplay());
  EXPECT_EQ(root_windows[0], window_->GetRootWindow());
  {
    // Grab (0, 0) of the window and move the pointer to (775, 10).
    std::unique_ptr<WindowResizer> resizer(
        CreateDragWindowResizer(window_.get(), gfx::Point(), HTCAPTION));
    ASSERT_TRUE(resizer.get());
    resizer->Drag(CalculateDragPoint(*resizer, 795, 10), 0);
    // Window should be adjusted for minimum visibility (25px) during the drag.
    EXPECT_EQ("775,10 50x60", window_->bounds().ToString());
    resizer->CompleteDrag();
    // Since the pointer is still on the primary root window, the parent should
    // not be changed.
    // Window origin should be adjusted for minimum visibility (25px).
    EXPECT_EQ(root_windows[0], window_->GetRootWindow());
    EXPECT_EQ("775,10 50x60", window_->bounds().ToString());
  }

  window_->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60),
                             display::Screen::GetScreen()->GetPrimaryDisplay());
  EXPECT_EQ(root_windows[0], window_->GetRootWindow());
  {
    // Grab the top-right edge of the window and move the pointer to (0, 10)
    // in the secondary root window's coordinates.
    std::unique_ptr<WindowResizer> resizer(
        CreateDragWindowResizer(window_.get(), gfx::Point(49, 0), HTCAPTION));
    ASSERT_TRUE(resizer.get());
    resizer->Drag(CalculateDragPoint(*resizer, 751, 10), ui::EF_CONTROL_DOWN);
    resizer->CompleteDrag();
    // Since the pointer is on the secondary, the parent should be changed
    // even though only small fraction of the window is within the secondary
    // root window's bounds.
    EXPECT_EQ(root_windows[1], window_->GetRootWindow());
    // Window origin should be adjusted for minimum visibility (25px).
    int expected_x = -50 + wm::kMinimumOnScreenArea;

    EXPECT_EQ(base::IntToString(expected_x) + ",10 50x60",
              window_->bounds().ToString());
  }
  // Dropping a window that is larger than the destination work area
  // will shrink to fit to the work area.
  window_->SetBoundsInScreen(gfx::Rect(0, 0, 700, 500),
                             display::Screen::GetScreen()->GetPrimaryDisplay());
  EXPECT_EQ(root_windows[0], window_->GetRootWindow());
  {
    // Grab the top-right edge of the window and move the pointer to (0, 10)
    // in the secondary root window's coordinates.
    std::unique_ptr<WindowResizer> resizer(
        CreateDragWindowResizer(window_.get(), gfx::Point(699, 0), HTCAPTION));
    ASSERT_TRUE(resizer.get());
    resizer->Drag(CalculateDragPoint(*resizer, 101, 10), ui::EF_CONTROL_DOWN);
    resizer->CompleteDrag();
    EXPECT_EQ(root_windows[1], window_->GetRootWindow());
    // Window size should be adjusted to fit to the work area
    EXPECT_EQ(gfx::Size(400, 252).ToString(),
              window_->bounds().size().ToString());
    gfx::Rect window_bounds_in_screen = window_->GetBoundsInScreen();
    gfx::Rect intersect(window_->GetRootWindow()->GetBoundsInScreen());
    intersect.Intersect(window_bounds_in_screen);

    EXPECT_LE(10, intersect.width());
    EXPECT_LE(10, intersect.height());
    EXPECT_TRUE(window_bounds_in_screen.Contains(gfx::Point(800, 10)));
  }

  // Dropping a window that is larger than the destination work area
  // will shrink to fit to the work area.
  window_->SetBoundsInScreen(gfx::Rect(0, 0, 700, 500),
                             display::Screen::GetScreen()->GetPrimaryDisplay());
  EXPECT_EQ(root_windows[0], window_->GetRootWindow());
  {
    // Grab the top-left edge of the window and move the pointer to (150, 10)
    // in the secondary root window's coordinates. Make sure the window is
    // shrink in such a way that it keeps the cursor within.
    std::unique_ptr<WindowResizer> resizer(
        CreateDragWindowResizer(window_.get(), gfx::Point(0, 0), HTCAPTION));
    ASSERT_TRUE(resizer.get());
    resizer->Drag(CalculateDragPoint(*resizer, 799, 10), ui::EF_CONTROL_DOWN);
    resizer->Drag(CalculateDragPoint(*resizer, 850, 10), ui::EF_CONTROL_DOWN);
    resizer->CompleteDrag();
    EXPECT_EQ(root_windows[1], window_->GetRootWindow());
    // Window size should be adjusted to fit to the work area
    EXPECT_EQ(gfx::Size(400, 252).ToString(),
              window_->bounds().size().ToString());
    gfx::Rect window_bounds_in_screen = window_->GetBoundsInScreen();
    gfx::Rect intersect(window_->GetRootWindow()->GetBoundsInScreen());
    intersect.Intersect(window_bounds_in_screen);
    EXPECT_LE(10, intersect.width());
    EXPECT_LE(10, intersect.height());
    EXPECT_TRUE(window_bounds_in_screen.Contains(gfx::Point(850, 10)));
  }
}

// Verifies that dragging the active window to another display makes the new
// root window the active root window.
TEST_F(DragWindowResizerTest, WindowDragWithMultiDisplaysActiveRoot) {
  // The secondary display is logically on the right, but on the system (e.g. X)
  // layer, it's below the primary one. See UpdateDisplay() in ash_test_base.cc.
  UpdateDisplay("800x600,800x600");
  aura::Window::Windows root_windows = Shell::GetAllRootWindows();
  ASSERT_EQ(2U, root_windows.size());

  aura::test::TestWindowDelegate delegate;
  std::unique_ptr<aura::Window> window(new aura::Window(&delegate));
  window->SetType(aura::client::WINDOW_TYPE_NORMAL);
  window->Init(ui::LAYER_TEXTURED);
  ParentWindowInPrimaryRootWindow(window.get());
  window->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60),
                            display::Screen::GetScreen()->GetPrimaryDisplay());
  window->Show();
  EXPECT_TRUE(wm::CanActivateWindow(window.get()));
  wm::ActivateWindow(window.get());
  EXPECT_EQ(root_windows[0], window->GetRootWindow());
  EXPECT_EQ(root_windows[0], Shell::GetRootWindowForNewWindows());
  {
    // Grab (0, 0) of the window.
    std::unique_ptr<WindowResizer> resizer(
        CreateDragWindowResizer(window.get(), gfx::Point(), HTCAPTION));
    ASSERT_TRUE(resizer.get());
    // Drag the pointer to the right. Once it reaches the right edge of the
    // primary display, it warps to the secondary.
    resizer->Drag(CalculateDragPoint(*resizer, 800, 10), 0);
    resizer->CompleteDrag();
    // The whole window is on the secondary display now. The parent should be
    // changed.
    EXPECT_EQ(root_windows[1], window->GetRootWindow());
    EXPECT_EQ(root_windows[1], Shell::GetRootWindowForNewWindows());
  }
}

// Verifies a window can be moved from the secondary display to primary.
TEST_F(DragWindowResizerTest, WindowDragWithMultiDisplaysRightToLeft) {
  UpdateDisplay("800x600,800x600");
  aura::Window::Windows root_windows = Shell::GetAllRootWindows();
  ASSERT_EQ(2U, root_windows.size());

  window_->SetBoundsInScreen(
      gfx::Rect(800, 00, 50, 60),
      display::Screen::GetScreen()->GetDisplayNearestWindow(root_windows[1]));
  EXPECT_EQ(root_windows[1], window_->GetRootWindow());
  {
    // Grab (0, 0) of the window.
    std::unique_ptr<WindowResizer> resizer(
        CreateDragWindowResizer(window_.get(), gfx::Point(), HTCAPTION));
    ASSERT_TRUE(resizer.get());
    // Move the mouse near the right edge, (798, 0), of the primary display.
    resizer->Drag(CalculateDragPoint(*resizer, -2, 0), ui::EF_CONTROL_DOWN);
    resizer->CompleteDrag();
    EXPECT_EQ(root_windows[0], window_->GetRootWindow());
    // Window origin should be adjusted for minimum visibility (25px).
    EXPECT_EQ("775,0 50x60", window_->bounds().ToString());
  }
}

// Verifies the drag window is shown correctly.
TEST_F(DragWindowResizerTest, DragWindowController) {
  UpdateDisplay("800x600,800x600");
  aura::Window::Windows root_windows = Shell::GetAllRootWindows();
  ASSERT_EQ(2U, root_windows.size());

  TestLayerDelegate delegate;
  window_->layer()->set_delegate(&delegate);
  window_->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60),
                             display::Screen::GetScreen()->GetPrimaryDisplay());
  EXPECT_EQ(root_windows[0], window_->GetRootWindow());
  EXPECT_FLOAT_EQ(1.0f, window_->layer()->opacity());
  {
    // Hold the center of the window so that the window doesn't stick to the
    // edge when dragging around the edge of the display.
    std::unique_ptr<WindowResizer> resizer(
        CreateDragWindowResizer(window_.get(), gfx::Point(25, 30), HTCAPTION));
    ASSERT_TRUE(resizer.get());
    DragWindowResizer* drag_resizer = DragWindowResizer::instance_;
    ASSERT_TRUE(drag_resizer);
    EXPECT_FALSE(drag_resizer->drag_window_controller_.get());

    // The pointer is inside the primary root. The drag window controller
    // should be NULL.
    resizer->Drag(CalculateDragPoint(*resizer, 10, 10), 0);
    DragWindowController* controller =
        drag_resizer->drag_window_controller_.get();
    EXPECT_EQ(0, controller->GetDragWindowsCountForTest());

    // The window spans both root windows.
    resizer->Drag(CalculateDragPoint(*resizer, 773, 10), 0);
    EXPECT_EQ(1, controller->GetDragWindowsCountForTest());
    const aura::Window* drag_window = controller->GetDragWindowForTest(0);
    ASSERT_TRUE(drag_window);

    const ui::Layer* drag_layer = drag_window->layer();
    ASSERT_TRUE(drag_layer);
    // Check if |resizer->layer_| is properly set to the drag widget.
    const std::vector<ui::Layer*>& layers = drag_layer->children();
    EXPECT_FALSE(layers.empty());
    EXPECT_EQ(controller->GetDragLayerOwnerForTest(0)->root(), layers.back());

    // The paint request on a drag window should reach the original delegate.
    controller->RequestLayerPaintForTest();
    EXPECT_EQ(1, delegate.paint_count());

    // Invalidating the delegate on the original layer should prevent
    // calling the OnPaintLayer on the original delegate from new delegate.
    window_->layer()->set_delegate(nullptr);
    controller->RequestLayerPaintForTest();
    EXPECT_EQ(1, delegate.paint_count());

    // |window_| should be opaque since the pointer is still on the primary
    // root window. The drag window should be semi-transparent.
    EXPECT_FLOAT_EQ(1.0f, window_->layer()->opacity());
    EXPECT_GT(1.0f, drag_layer->opacity());

    // Enter the pointer to the secondary display.
    resizer->Drag(CalculateDragPoint(*resizer, 775, 10), 0);
    EXPECT_EQ(1, controller->GetDragWindowsCountForTest());
    // |window_| should be transparent, and the drag window should be opaque.
    EXPECT_GT(1.0f, window_->layer()->opacity());
    EXPECT_FLOAT_EQ(1.0f, drag_layer->opacity());

    resizer->CompleteDrag();
    EXPECT_EQ(root_windows[1], window_->GetRootWindow());
    EXPECT_FLOAT_EQ(1.0f, window_->layer()->opacity());
  }

  // Do the same test with RevertDrag().
  window_->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60),
                             display::Screen::GetScreen()->GetPrimaryDisplay());
  EXPECT_EQ(root_windows[0], window_->GetRootWindow());
  EXPECT_FLOAT_EQ(1.0f, window_->layer()->opacity());
  {
    std::unique_ptr<WindowResizer> resizer(
        CreateDragWindowResizer(window_.get(), gfx::Point(), HTCAPTION));
    ASSERT_TRUE(resizer.get());
    DragWindowResizer* drag_resizer = DragWindowResizer::instance_;
    DragWindowController* controller =
        drag_resizer->drag_window_controller_.get();
    ASSERT_TRUE(drag_resizer);
    EXPECT_FALSE(controller);

    resizer->Drag(CalculateDragPoint(*resizer, 0, 610), 0);
    resizer->RevertDrag();
    EXPECT_EQ(root_windows[0], window_->GetRootWindow());
    EXPECT_FLOAT_EQ(1.0f, window_->layer()->opacity());
  }
}

TEST_F(DragWindowResizerTest, DragWindowControllerAcrossThreeDisplays) {
  UpdateDisplay("400x600,400x600,800x600");
  aura::Window::Windows root_windows = Shell::GetAllRootWindows();

  // Layout so that all three displays touch each other.
  display::DisplayIdList list = display_manager()->GetCurrentDisplayIdList();
  ASSERT_EQ(3u, list.size());
  ASSERT_EQ(display::Screen::GetScreen()->GetPrimaryDisplay().id(), list[0]);
  display::DisplayLayoutBuilder builder(list[0]);
  builder.AddDisplayPlacement(list[1], list[0],
                              display::DisplayPlacement::RIGHT, 0);
  builder.AddDisplayPlacement(list[2], list[0],
                              display::DisplayPlacement::BOTTOM, 0);
  display_manager()->SetLayoutForCurrentDisplays(builder.Build());
  // Sanity check.
  ASSERT_EQ(gfx::Rect(0, 000, 400, 600),
            display_manager()->GetDisplayForId(list[0]).bounds());
  ASSERT_EQ(gfx::Rect(400, 0, 400, 600),
            display_manager()->GetDisplayForId(list[1]).bounds());
  ASSERT_EQ(gfx::Rect(0, 600, 800, 600),
            display_manager()->GetDisplayForId(list[2]).bounds());

  // Create a window on 2nd display.
  window_->SetBoundsInScreen(gfx::Rect(400, 0, 100, 100),
                             display_manager()->GetDisplayForId(list[1]));
  ASSERT_EQ(root_windows[1], window_->GetRootWindow());

  // Hold the center of the window so that the window doesn't stick to the edge
  // when dragging around the edge of the display.
  std::unique_ptr<WindowResizer> resizer(
      CreateDragWindowResizer(window_.get(), gfx::Point(50, 50), HTCAPTION));
  ASSERT_TRUE(resizer.get());
  DragWindowResizer* drag_resizer = DragWindowResizer::instance_;
  ASSERT_TRUE(drag_resizer);
  EXPECT_FALSE(drag_resizer->drag_window_controller_.get());
  resizer->Drag(CalculateDragPoint(*resizer, -50, 0), 0);
  DragWindowController* controller =
      drag_resizer->drag_window_controller_.get();
  ASSERT_TRUE(controller);
  ASSERT_EQ(1, controller->GetDragWindowsCountForTest());
  const aura::Window* drag_window0 = controller->GetDragWindowForTest(0);
  ASSERT_TRUE(drag_window0);
  const ui::Layer* drag_layer0 = drag_window0->layer();
  EXPECT_EQ(root_windows[0], drag_window0->GetRootWindow());

  // |window_| should be opaque since the pointer is still on the primary
  // root window. The drag window should be semi-transparent.
  EXPECT_FLOAT_EQ(1.0f, window_->layer()->opacity());
  EXPECT_GT(1.0f, drag_layer0->opacity());

  // The window spans across 3 displays, dragging to 3rd display.
  resizer->Drag(CalculateDragPoint(*resizer, -50, 549), 0);
  ASSERT_EQ(2, controller->GetDragWindowsCountForTest());
  drag_window0 = controller->GetDragWindowForTest(0);
  const aura::Window* drag_window1 = controller->GetDragWindowForTest(1);
  drag_layer0 = drag_window0->layer();
  const ui::Layer* drag_layer1 = drag_window1->layer();
  EXPECT_EQ(root_windows[0], drag_window0->GetRootWindow());
  EXPECT_EQ(root_windows[2], drag_window1->GetRootWindow());

  // |window_| should be opaque since the pointer is still on the 2nd
  // root window. The drag window should be semi-transparent.
  EXPECT_FLOAT_EQ(1.0f, window_->layer()->opacity());
  EXPECT_GT(1.0f, drag_layer0->opacity());
  EXPECT_GT(1.0f, drag_layer1->opacity());

  resizer->Drag(CalculateDragPoint(*resizer, -51, 549), 0);
  ASSERT_EQ(2, controller->GetDragWindowsCountForTest());
  drag_window0 = controller->GetDragWindowForTest(0);
  drag_window1 = controller->GetDragWindowForTest(1);
  drag_layer0 = drag_window0->layer();
  drag_layer1 = drag_window1->layer();
  EXPECT_EQ(root_windows[0], drag_window0->GetRootWindow());
  EXPECT_EQ(root_windows[2], drag_window1->GetRootWindow());

  // |window_| should be transparent since the pointer is still on the primary
  // root window. The drag window should be semi-transparent.
  EXPECT_GT(1.0f, window_->layer()->opacity());
  EXPECT_FLOAT_EQ(1.0f, drag_layer0->opacity());
  EXPECT_GT(1.0f, drag_layer1->opacity());

  // Enter the pointer to the 3rd. Since it's bottom, the window snaps and
  // no drag windwos are created.
  resizer->Drag(CalculateDragPoint(*resizer, -51, 551), 0);
  ASSERT_EQ(1, controller->GetDragWindowsCountForTest());
  drag_window0 = controller->GetDragWindowForTest(0);
  drag_layer0 = drag_window0->layer();
  EXPECT_EQ(root_windows[2], drag_window0->GetRootWindow());

  // |window_| should be transparent, and the drag window should be opaque.
  EXPECT_FLOAT_EQ(0.0f, window_->layer()->opacity());
  EXPECT_FLOAT_EQ(1.0f, drag_layer0->opacity());

  resizer->CompleteDrag();
  EXPECT_EQ(root_windows[2], window_->GetRootWindow());
  EXPECT_FLOAT_EQ(1.0f, window_->layer()->opacity());
}

// Verifies if the resizer sets and resets
// MouseCursorEventFilter::mouse_warp_mode_ as expected.
TEST_F(DragWindowResizerTest, WarpMousePointer) {
  MouseCursorEventFilter* event_filter = Shell::Get()->mouse_cursor_filter();
  ASSERT_TRUE(event_filter);
  window_->SetBounds(gfx::Rect(0, 0, 50, 60));

  EXPECT_TRUE(event_filter->mouse_warp_enabled_);
  {
    std::unique_ptr<WindowResizer> resizer(
        CreateDragWindowResizer(window_.get(), gfx::Point(), HTCAPTION));
    // While dragging a window, warp should be allowed.
    EXPECT_TRUE(event_filter->mouse_warp_enabled_);
    resizer->CompleteDrag();
  }
  EXPECT_TRUE(event_filter->mouse_warp_enabled_);

  {
    std::unique_ptr<WindowResizer> resizer(
        CreateDragWindowResizer(window_.get(), gfx::Point(), HTCAPTION));
    EXPECT_TRUE(event_filter->mouse_warp_enabled_);
    resizer->RevertDrag();
  }
  EXPECT_TRUE(event_filter->mouse_warp_enabled_);

  {
    std::unique_ptr<WindowResizer> resizer(
        CreateDragWindowResizer(window_.get(), gfx::Point(), HTRIGHT));
    // While resizing a window, warp should NOT be allowed.
    EXPECT_FALSE(event_filter->mouse_warp_enabled_);
    resizer->CompleteDrag();
  }
  EXPECT_TRUE(event_filter->mouse_warp_enabled_);

  {
    std::unique_ptr<WindowResizer> resizer(
        CreateDragWindowResizer(window_.get(), gfx::Point(), HTRIGHT));
    EXPECT_FALSE(event_filter->mouse_warp_enabled_);
    resizer->RevertDrag();
  }
  EXPECT_TRUE(event_filter->mouse_warp_enabled_);
}

// Verifies cursor's device scale factor is updated whe a window is moved across
// root windows with different device scale factors (http://crbug.com/154183).
TEST_F(DragWindowResizerTest, CursorDeviceScaleFactor) {
  // The secondary display is logically on the right, but on the system (e.g. X)
  // layer, it's below the primary one. See UpdateDisplay() in ash_test_base.cc.
  UpdateDisplay("400x400,800x800*2");
  aura::Window::Windows root_windows = Shell::GetAllRootWindows();
  ASSERT_EQ(2U, root_windows.size());

  CursorManagerTestApi cursor_test_api(Shell::Get()->cursor_manager());
  // Move window from the root window with 1.0 device scale factor to the root
  // window with 2.0 device scale factor.
  {
    window_->SetBoundsInScreen(
        gfx::Rect(0, 0, 50, 60),
        display::Screen::GetScreen()->GetPrimaryDisplay());
    EXPECT_EQ(root_windows[0], window_->GetRootWindow());
    // Grab (0, 0) of the window.
    std::unique_ptr<WindowResizer> resizer(
        CreateDragWindowResizer(window_.get(), gfx::Point(), HTCAPTION));
    EXPECT_EQ(1.0f, cursor_test_api.GetCurrentCursor().device_scale_factor());
    ASSERT_TRUE(resizer.get());
    resizer->Drag(CalculateDragPoint(*resizer, 399, 200), 0);
    TestIfMouseWarpsAt(gfx::Point(399, 200));
    EXPECT_EQ(2.0f, cursor_test_api.GetCurrentCursor().device_scale_factor());
    resizer->CompleteDrag();
    EXPECT_EQ(2.0f, cursor_test_api.GetCurrentCursor().device_scale_factor());
  }

  // Move window from the root window with 2.0 device scale factor to the root
  // window with 1.0 device scale factor.
  {
    // Make sure the window is on the default container first.
    aura::Window* default_container =
        RootWindowController::ForWindow(root_windows[1])
            ->GetContainer(kShellWindowId_DefaultContainer);
    default_container->AddChild(window_.get());
    window_->SetBoundsInScreen(
        gfx::Rect(600, 0, 50, 60),
        display::Screen::GetScreen()->GetDisplayNearestWindow(root_windows[1]));
    EXPECT_EQ(root_windows[1], window_->GetRootWindow());
    // Grab (0, 0) of the window.
    std::unique_ptr<WindowResizer> resizer(
        CreateDragWindowResizer(window_.get(), gfx::Point(), HTCAPTION));
    EXPECT_EQ(2.0f, cursor_test_api.GetCurrentCursor().device_scale_factor());
    ASSERT_TRUE(resizer.get());
    resizer->Drag(CalculateDragPoint(*resizer, -200, 200), 0);
    TestIfMouseWarpsAt(gfx::Point(400, 200));
    EXPECT_EQ(1.0f, cursor_test_api.GetCurrentCursor().device_scale_factor());
    resizer->CompleteDrag();
    EXPECT_EQ(1.0f, cursor_test_api.GetCurrentCursor().device_scale_factor());
  }
}

// Verifies several kinds of windows can be moved across displays.
TEST_F(DragWindowResizerTest, MoveWindowAcrossDisplays) {
  // The secondary display is logically on the right, but on the system (e.g. X)
  // layer, it's below the primary one. See UpdateDisplay() in ash_test_base.cc.
  UpdateDisplay("400x400,400x400");

  aura::Window::Windows root_windows = Shell::GetAllRootWindows();
  ASSERT_EQ(2U, root_windows.size());

  // Normal window can be moved across display.
  {
    aura::Window* window = window_.get();
    window->SetBoundsInScreen(
        gfx::Rect(0, 0, 50, 60),
        display::Screen::GetScreen()->GetPrimaryDisplay());
    // Grab (0, 0) of the window.
    std::unique_ptr<WindowResizer> resizer(
        CreateDragWindowResizer(window, gfx::Point(), HTCAPTION));
    ASSERT_TRUE(resizer.get());
    resizer->Drag(CalculateDragPoint(*resizer, 399, 200), 0);
    EXPECT_TRUE(TestIfMouseWarpsAt(gfx::Point(399, 200)));
    EXPECT_EQ("401,200",
              aura::Env::GetInstance()->last_mouse_location().ToString());
    resizer->CompleteDrag();
  }

  // Always on top window can be moved across display.
  {
    aura::Window* window = always_on_top_window_.get();
    window->SetBoundsInScreen(
        gfx::Rect(0, 0, 50, 60),
        display::Screen::GetScreen()->GetPrimaryDisplay());
    // Grab (0, 0) of the window.
    std::unique_ptr<WindowResizer> resizer(
        CreateDragWindowResizer(window, gfx::Point(), HTCAPTION));
    ASSERT_TRUE(resizer.get());
    resizer->Drag(CalculateDragPoint(*resizer, 399, 200), 0);
    EXPECT_TRUE(TestIfMouseWarpsAt(gfx::Point(399, 200)));
    EXPECT_EQ("401,200",
              aura::Env::GetInstance()->last_mouse_location().ToString());
    resizer->CompleteDrag();
  }

  // System modal window can be moved across display.
  {
    aura::Window* window = system_modal_window_.get();
    window->SetBoundsInScreen(
        gfx::Rect(0, 0, 50, 60),
        display::Screen::GetScreen()->GetPrimaryDisplay());
    aura::Env::GetInstance()->SetLastMouseLocation(gfx::Point(0, 0));
    // Grab (0, 0) of the window.
    std::unique_ptr<WindowResizer> resizer(
        CreateDragWindowResizer(window, gfx::Point(), HTCAPTION));
    ASSERT_TRUE(resizer.get());
    resizer->Drag(CalculateDragPoint(*resizer, 399, 200), 0);
    EXPECT_TRUE(TestIfMouseWarpsAt(gfx::Point(399, 200)));
    EXPECT_EQ("401,200",
              aura::Env::GetInstance()->last_mouse_location().ToString());
    resizer->CompleteDrag();
  }

  // Transient window cannot be moved across display.
  {
    aura::Window* window = transient_child_;
    window->SetBoundsInScreen(
        gfx::Rect(0, 0, 50, 60),
        display::Screen::GetScreen()->GetPrimaryDisplay());
    // Grab (0, 0) of the window.
    std::unique_ptr<WindowResizer> resizer(
        CreateDragWindowResizer(window, gfx::Point(), HTCAPTION));
    ASSERT_TRUE(resizer.get());
    resizer->Drag(CalculateDragPoint(*resizer, 399, 200), 0);
    EXPECT_FALSE(TestIfMouseWarpsAt(gfx::Point(399, 200)));
    EXPECT_EQ("399,200",
              aura::Env::GetInstance()->last_mouse_location().ToString());
    resizer->CompleteDrag();
  }

  // The parent of transient window can be moved across display.
  {
    aura::Window* window = transient_parent_.get();
    window->SetBoundsInScreen(
        gfx::Rect(0, 0, 50, 60),
        display::Screen::GetScreen()->GetPrimaryDisplay());
    // Grab (0, 0) of the window.
    std::unique_ptr<WindowResizer> resizer(
        CreateDragWindowResizer(window, gfx::Point(), HTCAPTION));
    ASSERT_TRUE(resizer.get());
    resizer->Drag(CalculateDragPoint(*resizer, 399, 200), 0);
    EXPECT_TRUE(TestIfMouseWarpsAt(gfx::Point(399, 200)));
    EXPECT_EQ("401,200",
              aura::Env::GetInstance()->last_mouse_location().ToString());
    resizer->CompleteDrag();
  }

  // Panel window can be moved across display.
  {
    aura::Window* window = panel_window_.get();
    window->SetBoundsInScreen(
        gfx::Rect(0, 0, 50, 60),
        display::Screen::GetScreen()->GetPrimaryDisplay());
    // Grab (0, 0) of the window.
    std::unique_ptr<WindowResizer> resizer(
        CreateDragWindowResizer(window, gfx::Point(), HTCAPTION));
    ASSERT_TRUE(resizer.get());
    resizer->Drag(CalculateDragPoint(*resizer, 399, 200), 0);
    EXPECT_TRUE(TestIfMouseWarpsAt(gfx::Point(399, 200)));
    EXPECT_EQ("401,200",
              aura::Env::GetInstance()->last_mouse_location().ToString());
    resizer->CompleteDrag();
  }
}

}  // namespace ash
