// 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/display/screen_position_controller.h"

#include <memory>

#include "ash/public/cpp/shell_window_ids.h"
#include "ash/screen_util.h"
#include "ash/shell.h"
#include "ash/shell_test_api.h"
#include "ash/test/ash_test_base.h"
#include "ash/window_factory.h"
#include "base/test/scoped_feature_list.h"
#include "ui/aura/env.h"
#include "ui/aura/test/test_window_delegate.h"
#include "ui/aura/window_tracker.h"
#include "ui/aura/window_tree_host.h"
#include "ui/base/layout.h"
#include "ui/display/display_layout.h"
#include "ui/display/display_switches.h"
#include "ui/display/manager/display_manager.h"
#include "ui/display/screen.h"
#include "ui/events/test/event_generator.h"

namespace ash {

namespace {

ScreenPositionController* GetScreenPositionController() {
  ShellTestApi test_api(Shell::Get());
  return test_api.screen_position_controller();
}

class ScreenPositionControllerTest : public AshTestBase {
 public:
  ScreenPositionControllerTest() = default;
  ~ScreenPositionControllerTest() override = default;

  void SetUp() override {
    AshTestBase::SetUp();
    window_ = window_factory::NewWindow(&window_delegate_);
    window_->SetType(aura::client::WINDOW_TYPE_NORMAL);
    window_->Init(ui::LAYER_NOT_DRAWN);
    ParentWindowInPrimaryRootWindow(window_.get());
    window_->set_id(1);
  }

  void TearDown() override {
    window_.reset();
    AshTestBase::TearDown();
  }

  // Converts a point (x, y) in host window's coordinate to screen and
  // returns its string representation.
  std::string ConvertHostPointToScreen(int x, int y) const {
    gfx::Point point(x, y);
    GetScreenPositionController()->ConvertHostPointToScreen(
        window_->GetRootWindow(), &point);
    return point.ToString();
  }

  void SetSecondaryDisplayLayout(display::DisplayPlacement::Position position) {
    std::unique_ptr<display::DisplayLayout> layout(
        display_manager()->GetCurrentDisplayLayout().Copy());
    layout->placement_list[0].position = position;
    display_manager()->SetLayoutForCurrentDisplays(std::move(layout));
  }

 protected:
  std::unique_ptr<aura::Window> window_;
  aura::test::TestWindowDelegate window_delegate_;

 private:
  DISALLOW_COPY_AND_ASSIGN(ScreenPositionControllerTest);
};

class ScreenPositionControllerWithUiScaleTest
    : public ScreenPositionControllerTest {
 public:
  ScreenPositionControllerWithUiScaleTest() = default;
  ~ScreenPositionControllerWithUiScaleTest() override = default;

  // ScreenPositionControllerTest
  void SetUp() override {
    scoped_feature_list_.InitAndDisableFeature(
        features::kEnableDisplayZoomSetting);
    ScreenPositionControllerTest::SetUp();
  }

 private:
  base::test::ScopedFeatureList scoped_feature_list_;

  DISALLOW_COPY_AND_ASSIGN(ScreenPositionControllerWithUiScaleTest);
};

}  // namespace

TEST_F(ScreenPositionControllerTest, ConvertHostPointToScreen) {
  // Make sure that the point is in host coordinates. (crbug.com/521919)
  UpdateDisplay("100+100-200x200,100+300-200x200");
  // The point 150,210 should be in host coords, and detected as outside.
  EXPECT_EQ("350,10", ConvertHostPointToScreen(150, 210));

  UpdateDisplay("100+100-200x200,100+500-200x200");

  aura::Window::Windows root_windows = Shell::Get()->GetAllRootWindows();
  EXPECT_EQ(
      "100,100",
      root_windows[0]->GetHost()->GetBoundsInPixels().origin().ToString());
  EXPECT_EQ("200x200",
            root_windows[0]->GetHost()->GetBoundsInPixels().size().ToString());
  EXPECT_EQ(
      "100,500",
      root_windows[1]->GetHost()->GetBoundsInPixels().origin().ToString());
  EXPECT_EQ("200x200",
            root_windows[1]->GetHost()->GetBoundsInPixels().size().ToString());

  const gfx::Point window_pos(100, 100);
  window_->SetBoundsInScreen(
      gfx::Rect(window_pos, gfx::Size(100, 100)),
      display::Screen::GetScreen()->GetDisplayNearestPoint(window_pos));
  SetSecondaryDisplayLayout(display::DisplayPlacement::RIGHT);
  // The point is on the primary root window.
  EXPECT_EQ("50,50", ConvertHostPointToScreen(50, 50));
  // The point is out of the all root windows.
  EXPECT_EQ("250,250", ConvertHostPointToScreen(250, 250));
  // The point is on the secondary display.
  EXPECT_EQ("250,0", ConvertHostPointToScreen(50, 400));

  SetSecondaryDisplayLayout(display::DisplayPlacement::BOTTOM);
  // The point is on the primary root window.
  EXPECT_EQ("50,50", ConvertHostPointToScreen(50, 50));
  // The point is out of the all root windows.
  EXPECT_EQ("250,250", ConvertHostPointToScreen(250, 250));
  // The point is on the secondary display.
  EXPECT_EQ("50,200", ConvertHostPointToScreen(50, 400));

  SetSecondaryDisplayLayout(display::DisplayPlacement::LEFT);
  // The point is on the primary root window.
  EXPECT_EQ("50,50", ConvertHostPointToScreen(50, 50));
  // The point is out of the all root windows.
  EXPECT_EQ("250,250", ConvertHostPointToScreen(250, 250));
  // The point is on the secondary display.
  EXPECT_EQ("-150,0", ConvertHostPointToScreen(50, 400));

  SetSecondaryDisplayLayout(display::DisplayPlacement::TOP);
  // The point is on the primary root window.
  EXPECT_EQ("50,50", ConvertHostPointToScreen(50, 50));
  // The point is out of the all root windows.
  EXPECT_EQ("250,250", ConvertHostPointToScreen(250, 250));
  // The point is on the secondary display.
  EXPECT_EQ("50,-200", ConvertHostPointToScreen(50, 400));

  SetSecondaryDisplayLayout(display::DisplayPlacement::RIGHT);
  const gfx::Point window_pos2(300, 100);
  window_->SetBoundsInScreen(
      gfx::Rect(window_pos2, gfx::Size(100, 100)),
      display::Screen::GetScreen()->GetDisplayNearestPoint(window_pos2));
  // The point is on the secondary display.
  EXPECT_EQ("250,50", ConvertHostPointToScreen(50, 50));
  // The point is out of the all root windows.
  EXPECT_EQ("450,250", ConvertHostPointToScreen(250, 250));
  // The point is on the primary root window.
  EXPECT_EQ("50,0", ConvertHostPointToScreen(50, -400));

  SetSecondaryDisplayLayout(display::DisplayPlacement::BOTTOM);
  // The point is on the secondary display.
  EXPECT_EQ("50,250", ConvertHostPointToScreen(50, 50));
  // The point is out of the all root windows.
  EXPECT_EQ("250,450", ConvertHostPointToScreen(250, 250));
  // The point is on the primary root window.
  EXPECT_EQ("50,0", ConvertHostPointToScreen(50, -400));

  SetSecondaryDisplayLayout(display::DisplayPlacement::LEFT);
  // The point is on the secondary display.
  EXPECT_EQ("-150,50", ConvertHostPointToScreen(50, 50));
  // The point is out of the all root windows.
  EXPECT_EQ("50,250", ConvertHostPointToScreen(250, 250));
  // The point is on the primary root window.
  EXPECT_EQ("50,0", ConvertHostPointToScreen(50, -400));

  SetSecondaryDisplayLayout(display::DisplayPlacement::TOP);
  // The point is on the secondary display.
  EXPECT_EQ("50,-150", ConvertHostPointToScreen(50, 50));
  // The point is out of the all root windows.
  EXPECT_EQ("250,50", ConvertHostPointToScreen(250, 250));
  // The point is on the primary root window.
  EXPECT_EQ("50,0", ConvertHostPointToScreen(50, -400));
}

TEST_F(ScreenPositionControllerTest, ConvertHostPointToScreenHiDPI) {
  UpdateDisplay("50+50-200x200*2,50+300-300x300");

  aura::Window::Windows root_windows = Shell::Get()->GetAllRootWindows();
  EXPECT_EQ("50,50 200x200",
            root_windows[0]->GetHost()->GetBoundsInPixels().ToString());
  EXPECT_EQ("50,300 300x300",
            root_windows[1]->GetHost()->GetBoundsInPixels().ToString());

  // Put |window_| to the primary 2x display.
  window_->SetBoundsInScreen(gfx::Rect(20, 20, 50, 50),
                             display::Screen::GetScreen()->GetPrimaryDisplay());
  // (30, 30) means the host coordinate, so the point is still on the primary
  // root window.  Since it's 2x, the specified native point was halved.
  EXPECT_EQ("15,15", ConvertHostPointToScreen(30, 30));
  // Similar to above but the point is out of the all root windows.
  EXPECT_EQ("200,200", ConvertHostPointToScreen(400, 400));
  // Similar to above but the point is on the secondary display.
  EXPECT_EQ("100,15", ConvertHostPointToScreen(200, 30));

  // On secondary display. The position on the 2nd host window is (150,200)
  // so the screen position is (100,0) + (150,200).
  EXPECT_EQ("250,200", ConvertHostPointToScreen(150, 450));

  // At the edge but still in the primary display.  Remaining of the primary
  // display is (50, 50) but adding ~100 since it's 2x-display.
  EXPECT_EQ("79,79", ConvertHostPointToScreen(158, 158));
  // At the edge of the secondary display.
  EXPECT_EQ("80,80", ConvertHostPointToScreen(160, 160));
}

TEST_F(ScreenPositionControllerTest, ConvertHostPointToScreenRotate) {
  // 1st display is rotated 90 clockise, and 2nd display is rotated
  // 270 clockwise.
  UpdateDisplay("100+100-200x200/r,100+500-200x200/l");
  // Put |window_| to the 1st.
  window_->SetBoundsInScreen(gfx::Rect(20, 20, 50, 50),
                             display::Screen::GetScreen()->GetPrimaryDisplay());

  // The point is on the 1st host.
  EXPECT_EQ("70,150", ConvertHostPointToScreen(50, 70));
  // The point is out of the host windows.
  EXPECT_EQ("250,-50", ConvertHostPointToScreen(250, 250));
  // The point is on the 2nd host. Point on 2nd host (30,150) -
  // rotate 270 clockwise -> (149, 30) - layout [+(200,0)] -> (349,30).
  EXPECT_EQ("350,30", ConvertHostPointToScreen(30, 450));

  // Move |window_| to the 2nd.
  window_->SetBoundsInScreen(gfx::Rect(300, 20, 50, 50),
                             display_manager()->GetSecondaryDisplay());
  aura::Window::Windows root_windows = Shell::Get()->GetAllRootWindows();
  EXPECT_EQ(root_windows[1], window_->GetRootWindow());

  // The point is on the 2nd host. (50,70) on 2n host -
  // roatate 270 clockwise -> (129,50) -layout [+(200,0)] -> (329,50)
  EXPECT_EQ("330,50", ConvertHostPointToScreen(50, 70));
  // The point is out of the host windows.
  EXPECT_EQ("450,50", ConvertHostPointToScreen(50, -50));
  // The point is on the 2nd host. Point on 2nd host (50,50) -
  // rotate 90 clockwise -> (50, 149)
  EXPECT_EQ("50,150", ConvertHostPointToScreen(50, -350));
}

TEST_F(ScreenPositionControllerTest, ConvertHostPointToScreenZoomScale) {
  // 1st display is 2x density with 1.5 UI scale.
  UpdateDisplay("100+100-200x200*2@0.8,100+500-200x200");
  // Put |window_| to the 1st.
  window_->SetBoundsInScreen(gfx::Rect(20, 20, 50, 50),
                             display::Screen::GetScreen()->GetPrimaryDisplay());

  // The point is on the 1st host.
  EXPECT_EQ("37,37", ConvertHostPointToScreen(60, 60));
  // The point is out of the host windows.
  EXPECT_EQ("37,187", ConvertHostPointToScreen(60, 300));
  // The point is on the 2nd host. Point on 2nd host (60,150) -
  // - screen [+(150,0)]
  EXPECT_EQ("184,49", ConvertHostPointToScreen(60, 450));

  // Move |window_| to the 2nd.
  window_->SetBoundsInScreen(gfx::Rect(300, 20, 50, 50),
                             display_manager()->GetSecondaryDisplay());
  aura::Window::Windows root_windows = Shell::Get()->GetAllRootWindows();
  EXPECT_EQ(root_windows[1], window_->GetRootWindow());

  // The point is on the 2nd host. (50,70) - ro
  EXPECT_EQ("185,70", ConvertHostPointToScreen(60, 70));
  // The point is out of the host windows.
  EXPECT_EQ("185,-50", ConvertHostPointToScreen(60, -50));
  // The point is on the 2nd host. Point on 1nd host (60, 60)
  // 1/2 * 1 / 0.8 = (45,45)
  EXPECT_EQ("37,37", ConvertHostPointToScreen(60, -340));
}

TEST_F(ScreenPositionControllerWithUiScaleTest,
       ConvertHostPointToScreenUIScale) {
  // 1st display is 2x density with 1.5 UI scale.
  UpdateDisplay("100+100-200x200*2@1.5,100+500-200x200");
  // Put |window_| to the 1st.
  window_->SetBoundsInScreen(gfx::Rect(20, 20, 50, 50),
                             display::Screen::GetScreen()->GetPrimaryDisplay());

  // The point is on the 1st host.
  EXPECT_EQ("45,45", ConvertHostPointToScreen(60, 60));
  // The point is out of the host windows.
  EXPECT_EQ("45,225", ConvertHostPointToScreen(60, 300));
  // The point is on the 2nd host. Point on 2nd host (60,150) -
  // - screen [+(150,0)]
  EXPECT_EQ("210,49", ConvertHostPointToScreen(60, 450));

  // Move |window_| to the 2nd.
  window_->SetBoundsInScreen(gfx::Rect(300, 20, 50, 50),
                             display_manager()->GetSecondaryDisplay());
  aura::Window::Windows root_windows = Shell::Get()->GetAllRootWindows();
  EXPECT_EQ(root_windows[1], window_->GetRootWindow());

  // The point is on the 2nd host. (50,70) - ro
  EXPECT_EQ("210,70", ConvertHostPointToScreen(60, 70));
  // The point is out of the host windows.
  EXPECT_EQ("210,-50", ConvertHostPointToScreen(60, -50));
  // The point is on the 2nd host. Point on 1nd host (60, 60)
  // 1/2 * 1.5 = (45,45)
  EXPECT_EQ("45,45", ConvertHostPointToScreen(60, -340));
}

namespace {

// EventHandler which tracks whether it got any MouseEvents whose location could
// not be converted to screen coordinates.
class ConvertToScreenEventHandler : public ui::EventHandler {
 public:
  ConvertToScreenEventHandler() : could_convert_to_screen_(true) {
    Shell::Get()->aura_env()->AddPreTargetHandler(this);
  }
  ~ConvertToScreenEventHandler() override {
    Shell::Get()->aura_env()->RemovePreTargetHandler(this);
  }

  bool could_convert_to_screen() const { return could_convert_to_screen_; }

 private:
  void OnMouseEvent(ui::MouseEvent* event) override {
    if (event->type() == ui::ET_MOUSE_CAPTURE_CHANGED)
      return;

    aura::Window* root =
        static_cast<aura::Window*>(event->target())->GetRootWindow();
    if (!aura::client::GetScreenPositionClient(root))
      could_convert_to_screen_ = false;
  }

  bool could_convert_to_screen_;

  DISALLOW_COPY_AND_ASSIGN(ConvertToScreenEventHandler);
};

}  // namespace

// Test that events are only dispatched when a ScreenPositionClient is available
// to convert the event to screen coordinates. The ScreenPositionClient is
// detached from the root window prior to the root window being destroyed. Test
// that no events are dispatched at this time.
TEST_F(ScreenPositionControllerTest,
       ConvertToScreenWhileRemovingSecondaryDisplay) {
  UpdateDisplay("600x600,600x600");
  RunAllPendingInMessageLoop();

  // Create a window on the secondary display.
  window_->SetBoundsInScreen(gfx::Rect(600, 0, 400, 400),
                             display_manager()->GetSecondaryDisplay());

  // Move the mouse cursor over |window_|. Synthetic mouse moves are dispatched
  // asynchronously when a window which contains the mouse cursor is destroyed.
  // We want to check that none of these synthetic events are dispatched after
  // ScreenPositionClient has been detached from the root window.
  GetEventGenerator()->MoveMouseTo(800, 200);
  EXPECT_TRUE(window_->GetBoundsInScreen().Contains(
      Shell::Get()->aura_env()->last_mouse_location()));

  aura::Window::Windows root_windows = Shell::Get()->GetAllRootWindows();
  aura::WindowTracker tracker;
  tracker.Add(root_windows[1]);
  std::unique_ptr<ConvertToScreenEventHandler> event_handler(
      new ConvertToScreenEventHandler);

  // Remove the secondary monitor.
  UpdateDisplay("600x600");

  // The secondary root window is not immediately destroyed.
  EXPECT_TRUE(tracker.Contains(root_windows[1]));

  RunAllPendingInMessageLoop();

  // Check that we waited long enough and that the secondary root window was
  // destroyed.
  EXPECT_FALSE(tracker.Contains(root_windows[1]));

  // Check that we could convert all of the mouse events we got to screen
  // coordinates.
  EXPECT_TRUE(event_handler->could_convert_to_screen());
}

}  // namespace ash
