// Copyright 2015 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ash/display/cursor_window_controller.h"
#include "base/memory/raw_ptr.h"

#include <cmath>
#include <utility>

#include "ash/accessibility/accessibility_controller.h"
#include "ash/constants/ash_constants.h"
#include "ash/constants/ash_pref_names.h"
#include "ash/display/display_util.h"
#include "ash/display/window_tree_host_manager.h"
#include "ash/session/session_controller_impl.h"
#include "ash/shell.h"
#include "ash/test/ash_test_base.h"
#include "base/command_line.h"
#include "base/notreached.h"
#include "base/strings/stringprintf.h"
#include "base/test/scoped_feature_list.h"
#include "components/prefs/pref_service.h"
#include "ui/accessibility/accessibility_features.h"
#include "ui/aura/client/cursor_shape_client.h"
#include "ui/aura/window.h"
#include "ui/aura/window_tree_host.h"
#include "ui/base/cursor/cursor.h"
#include "ui/base/cursor/mojom/cursor_type.mojom-shared.h"
#include "ui/base/resource/mock_resource_bundle_delegate.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/base/resource/resource_scale_factor.h"
#include "ui/display/display.h"
#include "ui/display/screen.h"
#include "ui/display/test/display_manager_test_api.h"
#include "ui/events/test/event_generator.h"
#include "ui/gfx/color_utils.h"
#include "ui/gfx/geometry/dip_util.h"
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/geometry/point_conversions.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/geometry/size_conversions.h"
#include "ui/gfx/geometry/skia_conversions.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/gfx/image/image_skia_rep.h"
#include "ui/gfx/image/image_skia_source.h"
#include "ui/gfx/image/image_unittest_util.h"
#include "ui/wm/core/cursor_manager.h"

namespace ash {

namespace {

float DistanceBetweenPoints(const gfx::Point& p1, const gfx::Point& p2) {
  float x_diff = p1.x() - p2.x();
  float y_diff = p1.y() - p2.y();
  return std::sqrt(x_diff * x_diff + y_diff * y_diff);
}

float DistanceBetweenSizes(const gfx::Size& s1, const gfx::Size& s2) {
  float width_diff = s1.width() - s2.width();
  float height_diff = s1.height() - s2.height();
  return std::sqrt(width_diff * width_diff + height_diff * height_diff);
}

}  // namespace

using ::ui::mojom::CursorType;

class CursorWindowControllerTest : public AshTestBase {
 public:
  CursorWindowControllerTest() = default;

  CursorWindowControllerTest(const CursorWindowControllerTest&) = delete;
  CursorWindowControllerTest& operator=(const CursorWindowControllerTest&) =
      delete;

  ~CursorWindowControllerTest() override = default;

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

    // Shell hides the cursor by default; show it for these tests.
    Shell::Get()->cursor_manager()->ShowCursor();

    SetCursorCompositionEnabled(true);
  }

  CursorType GetCursorType() const {
    return cursor_window_controller()->cursor_.type();
  }

  const gfx::Rect GetCursorBounds() const {
    return cursor_window_controller()->GetCursorBoundsInScreenForTest();
  }

  const gfx::Point& GetCursorHotPoint() const {
    return cursor_window_controller()->hot_point_;
  }

  const aura::Window* GetCursorHostWindow() const {
    return cursor_window_controller()->GetCursorHostWindowForTest();
  }

  const gfx::ImageSkia& GetCursorImage() const {
    return cursor_window_controller()->GetCursorImageForTest();
  }

  int64_t GetCursorDisplayId() const {
    return cursor_window_controller()->display_.id();
  }

  void SetCursorCompositionEnabled(bool enabled) {
    // Cursor compositing will be enabled when high contrast mode is turned on.
    // Cursor compositing will be disabled when high contrast mode is the only
    // feature using it and is turned off.
    Shell::Get()->accessibility_controller()->high_contrast().SetEnabled(
        enabled);
  }

  CursorWindowController* cursor_window_controller() const {
    return Shell::Get()->window_tree_host_manager()->cursor_window_controller();
  }

 private:
  base::test::ScopedFeatureList scoped_feature_list_;
};

// Test that the composited cursor moves to another display when the real cursor
// moves to another display.
TEST_F(CursorWindowControllerTest, MoveToDifferentDisplay) {
  UpdateDisplay("300x200,300x200*2/r");

  WindowTreeHostManager* window_tree_host_manager =
      Shell::Get()->window_tree_host_manager();
  int64_t primary_display_id = window_tree_host_manager->GetPrimaryDisplayId();
  int64_t secondary_display_id =
      display::test::DisplayManagerTestApi(display_manager())
          .GetSecondaryDisplay()
          .id();
  aura::Window* primary_root =
      window_tree_host_manager->GetRootWindowForDisplayId(primary_display_id);
  aura::Window* secondary_root =
      window_tree_host_manager->GetRootWindowForDisplayId(secondary_display_id);

  ui::test::EventGenerator primary_generator(primary_root);
  primary_generator.MoveMouseToInHost(20, 50);

  EXPECT_TRUE(primary_root->Contains(GetCursorHostWindow()));
  EXPECT_EQ(primary_display_id, GetCursorDisplayId());
  EXPECT_EQ(CursorType::kNull, GetCursorType());
  gfx::Point hot_point = GetCursorHotPoint();
  EXPECT_EQ(gfx::Point(6, 4), hot_point);
  gfx::Rect cursor_bounds = GetCursorBounds();
  EXPECT_EQ(20, cursor_bounds.x() + hot_point.x());
  EXPECT_EQ(50, cursor_bounds.y() + hot_point.y());

  // The cursor can only be moved between displays via
  // WindowTreeHost::MoveCursorTo(). EventGenerator uses a hack to move the
  // cursor between displays.
  // Screen location: 220, 50
  // Root location: 20, 50
  secondary_root->MoveCursorTo(gfx::Point(20, 50));

  // Chrome relies on WindowTreeHost::MoveCursorTo() dispatching a mouse move
  // asynchronously. This is implemented in a platform specific way. Generate a
  // fake mouse move instead of waiting.
  gfx::Point new_cursor_position_in_host(20, 50);
  secondary_root->GetHost()->ConvertDIPToPixels(&new_cursor_position_in_host);
  ui::test::EventGenerator secondary_generator(secondary_root);
  secondary_generator.MoveMouseToInHost(new_cursor_position_in_host);

  EXPECT_TRUE(secondary_root->Contains(GetCursorHostWindow()));
  EXPECT_EQ(secondary_display_id, GetCursorDisplayId());
  EXPECT_EQ(CursorType::kNull, GetCursorType());
  hot_point = GetCursorHotPoint();
  EXPECT_EQ(gfx::Point(6, 4), hot_point);
  cursor_bounds = GetCursorBounds();
  EXPECT_EQ(320, cursor_bounds.x() + hot_point.x());
  EXPECT_EQ(50, cursor_bounds.y() + hot_point.y());
}

// Make sure that composition cursor inherits the visibility state.
TEST_F(CursorWindowControllerTest, VisibilityTest) {
  ASSERT_TRUE(GetCursorHostWindow());
  EXPECT_TRUE(GetCursorHostWindow()->IsVisible());
  aura::client::CursorClient* client = Shell::Get()->cursor_manager();
  client->HideCursor();
  ASSERT_TRUE(GetCursorHostWindow());
  EXPECT_FALSE(GetCursorHostWindow()->IsVisible());

  // Normal cursor should be in the correct state.
  SetCursorCompositionEnabled(false);
  ASSERT_FALSE(GetCursorHostWindow());
  ASSERT_FALSE(client->IsCursorVisible());

  // Cursor was hidden.
  SetCursorCompositionEnabled(true);
  ASSERT_TRUE(GetCursorHostWindow());
  EXPECT_FALSE(GetCursorHostWindow()->IsVisible());

  // Goback to normal cursor and show the cursor.
  SetCursorCompositionEnabled(false);
  ASSERT_FALSE(GetCursorHostWindow());
  ASSERT_FALSE(client->IsCursorVisible());
  client->ShowCursor();
  ASSERT_TRUE(client->IsCursorVisible());

  // Cursor was shown.
  SetCursorCompositionEnabled(true);
  ASSERT_TRUE(GetCursorHostWindow());
  EXPECT_TRUE(GetCursorHostWindow()->IsVisible());
}

// Test different properties of the composited cursor with different device
// scale factors and zoom levels.
TEST_F(CursorWindowControllerTest, DSF) {
  const auto& cursor_shape_client = aura::client::GetCursorShapeClient();

  auto cursor_test = [&](ui::Cursor cursor, float large_cursor_size_in_dip) {
    const float dsf =
        display::Screen::Get()->GetPrimaryDisplay().device_scale_factor();
    SCOPED_TRACE(testing::Message()
                 << cursor.type() << " at scale " << dsf << " and size "
                 << large_cursor_size_in_dip);

    cursor_window_controller()->SetCursor(cursor);
    const std::optional<ui::CursorData> cursor_data =
        cursor_shape_client.GetCursorData(cursor);
    DCHECK(cursor_data);

    // Software cursors look blurry if they are resized by the window they are
    // rendered in, instead of by `ImageSkia`. Make sure
    // `CursorWindowController` creates the cursor in a way that a
    // representation for the display's device scale factor can be directly
    // obtained.
    const gfx::ImageSkiaRep& rep = GetCursorImage().GetRepresentation(dsf);
    EXPECT_EQ(rep.scale(), dsf);

    const gfx::Size original_cursor_size_in_dip =
        // ImageSkiaRep::GetWidth() uses static_cast<int>.
        gfx::ToFlooredSize(gfx::ConvertSizeToDips(
            gfx::SkISizeToSize(cursor_data->bitmaps[0].dimensions()),
            cursor_data->scale_factor));
    const gfx::Size cursor_size_in_dip =
        large_cursor_size_in_dip != 0
            ? gfx::Size(large_cursor_size_in_dip, large_cursor_size_in_dip)
            : original_cursor_size_in_dip;
    // Scaling operations and conversions between dp and px can cause rounding
    // errors. We accept rounding errors <= sqrt(1+1).
    EXPECT_LE(DistanceBetweenSizes(GetCursorImage().size(), cursor_size_in_dip),
              sqrt(2));

    // TODO(hferreiro): the cursor hotspot for non-custom cursors cannot be
    // checked, since the software cursor uses
    // `ui::GetSupportedResourceScaleFactorForRescale`, and
    // `CursorLoader::GetCursorData` uses `ui::GetSupportedResourceScaleFactor`,
    // and 2x cursor hotspots are not just twice the 1x hotspots.
    if (cursor.type() == CursorType::kCustom) {
      const gfx::Point hotspot_in_dip =
          gfx::ToFlooredPoint(gfx::ConvertPointToDips(
              cursor_data->hotspot, cursor_data->scale_factor));
      const float rescale = static_cast<float>(cursor_size_in_dip.height()) /
                            original_cursor_size_in_dip.height();
      // Scaling operations and conversions between dp and px can cause rounding
      // errors. We accept rounding errors <= sqrt(1+1).
      ASSERT_LE(DistanceBetweenPoints(
                    GetCursorHotPoint(),
                    gfx::ScaleToCeiledPoint(hotspot_in_dip, rescale)),
                sqrt(2));
    }

    // The cursor window should have the same size as the cursor.
    EXPECT_EQ(GetCursorBounds().size(), GetCursorImage().size());
  };

  auto* const cursor_manager = Shell::Get()->cursor_manager();
  DCHECK(cursor_manager);

  for (const float device_scale_factor : {1.0f, 1.5f, 2.0f, 2.5f}) {
    for (const float zoom : {0.8f, 1.0f, 1.25f}) {
      UpdateDisplay(
          base::StringPrintf("1000x500*%f@%f", device_scale_factor, zoom));
      const float dsf =
          display::Screen::Get()->GetPrimaryDisplay().device_scale_factor();

      for (const int large_cursor_size_in_dip : {0, 32, 64, 128}) {
        cursor_manager->SetCursorSize(large_cursor_size_in_dip == 0
                                          ? ui::CursorSize::kNormal
                                          : ui::CursorSize::kLarge);
        Shell::Get()->SetLargeCursorSizeInDip(large_cursor_size_in_dip);

        // Default cursor.
        cursor_test(CursorType::kPointer, large_cursor_size_in_dip);

        // Custom cursor. Custom cursors are always scaled at the device scale
        // factor. See `WebCursor::GetNativeCursor`.
        cursor_test(ui::Cursor::NewCustom(gfx::test::CreateBitmap(/*size=*/20),
                                          gfx::Point(10, 10), dsf),
                    large_cursor_size_in_dip);
      }
    }
  }
}

// Test that cursor compositing is enabled if at least one of the features that
// use it is enabled.
TEST_F(CursorWindowControllerTest, ShouldEnableCursorCompositing) {
  PrefService* prefs =
      Shell::Get()->session_controller()->GetActivePrefService();
  display::Display display = display::Screen::Get()->GetPrimaryDisplay();
  const float dsf = 2.0f;
  display.set_device_scale_factor(dsf);
  display.set_maximum_cursor_size(gfx::Size(128, 128));
  const gfx::SizeF display_maximum_cursor_size_in_dip =
      gfx::ConvertSizeToDips(display.maximum_cursor_size(), dsf);

  // Cursor compositing is disabled by default.
  SetCursorCompositionEnabled(false);
  EXPECT_FALSE(cursor_window_controller()->is_cursor_compositing_enabled());

  // Enable high contrast feature, cursor compositing should be enabled.
  prefs->SetBoolean(prefs::kAccessibilityHighContrastEnabled, true);
  EXPECT_TRUE(cursor_window_controller()->is_cursor_compositing_enabled());

  // Disable high contrast feature, cursor compositing should be disabled.
  prefs->SetBoolean(prefs::kAccessibilityHighContrastEnabled, false);
  EXPECT_FALSE(cursor_window_controller()->is_cursor_compositing_enabled());

  // Enable docked magnifier feature, cursor compositing should be enabled.
  prefs->SetBoolean(prefs::kDockedMagnifierEnabled, true);
  EXPECT_TRUE(cursor_window_controller()->is_cursor_compositing_enabled());

  // Disable docked magnifier feature, cursor compositing should be disabled.
  prefs->SetBoolean(prefs::kDockedMagnifierEnabled, false);
  EXPECT_FALSE(cursor_window_controller()->is_cursor_compositing_enabled());

  // Enable large cursor, cursor compositing should be enabled only if
  // the target large cursor size is larger than current display's maximum
  // cursor size.
  cursor_window_controller()->SetDisplay(display);
  cursor_window_controller()->SetLargeCursorSizeInDip(
      display_maximum_cursor_size_in_dip.height() + 1);
  prefs->SetBoolean(prefs::kAccessibilityLargeCursorEnabled, true);
  EXPECT_TRUE(cursor_window_controller()->is_cursor_compositing_enabled());

  // Disable large cursor, cursor compositing should be disabled.
  prefs->SetBoolean(prefs::kAccessibilityLargeCursorEnabled, false);
  EXPECT_FALSE(cursor_window_controller()->is_cursor_compositing_enabled());

  // Re-enable large cursor, since large cursor size is smaller than display's
  // maximum cursor size, cursor should use hardware compositing instead of
  // software compositing.
  cursor_window_controller()->SetDisplay(display);
  cursor_window_controller()->SetLargeCursorSizeInDip(
      display_maximum_cursor_size_in_dip.height() - 1);
  prefs->SetBoolean(prefs::kAccessibilityLargeCursorEnabled, true);
  EXPECT_FALSE(cursor_window_controller()->is_cursor_compositing_enabled());
}

// Test that cursor color works correctly when large cursor is enabled.
TEST_F(CursorWindowControllerTest, LargeCursorColoringSpotCheck) {
  // Enable large cursor, cursor compositing should be enabled and thus
  // colored cursor should also be composited cursor.
  PrefService* prefs =
      Shell::Get()->session_controller()->GetActivePrefService();
  prefs->SetBoolean(prefs::kAccessibilityLargeCursorEnabled, true);
  ASSERT_TRUE(cursor_window_controller()->is_cursor_compositing_enabled());

  // Try a few colors to ensure colorizing is working appropriately.
  const struct {
    SkColor cursor_color;  // Set the cursor to this color.
    SkColor not_found;     // Spot-check: This color shouldn't be in the cursor.
    SkColor found;         // Spot-check: This color should be in the cursor.
    CursorType cursor_type;
  } kColorTestCases[] = {
      // Cursors should not have black because the black cursor body should be
      // replaced by other colors.
      {SK_ColorRED, SK_ColorBLACK, SK_ColorWHITE, CursorType::kPointer},
      {SK_ColorRED, SK_ColorBLACK, SK_ColorWHITE, CursorType::kCell},

      // Cursors should not have white because the white cursor body should be
      // replaced by other colors.
      {SK_ColorMAGENTA, SK_ColorWHITE, SK_ColorBLACK, CursorType::kHand},

      // Also cursors should still have transparent.
      {SK_ColorRED, SK_ColorGREEN, SK_ColorTRANSPARENT, CursorType::kPointer},

      // The no drop cursor has red in it, check it's still there:
      // Cursor body should be colored, but the red part shouldn't be
      // re-colored.
      {SK_ColorBLUE, SK_ColorGREEN, SkColorSetRGB(181, 70, 72),
       CursorType::kNoDrop},

      // Similarly, the copy cursor has a green part in it which should not be
      // re-colored.
      {SK_ColorBLUE, SK_ColorRED, SkColorSetRGB(57, 149, 88),
       CursorType::kCopy},
  };

  for (const auto& test : kColorTestCases) {
    cursor_window_controller()->SetCursorColor(test.cursor_color);
    cursor_window_controller()->SetCursor(test.cursor_type);
    const SkBitmap* bitmap = GetCursorImage().bitmap();
    // We should find `cursor_color` and `found` color pixels in the cursor, but
    // no |not_found| color pixels.
    bool has_color = false;
    bool has_not_found_color = false;
    bool has_found_color = false;
    for (int x = 0; x < bitmap->width(); ++x) {
      for (int y = 0; y < bitmap->height(); ++y) {
        SkColor color = bitmap->getColor(x, y);
        if (color == test.cursor_color)
          has_color = true;
        else if (color == test.not_found)
          has_not_found_color = true;
        else if (color == test.found)
          has_found_color = true;
      }
    }
    EXPECT_TRUE(has_color) << color_utils::SkColorToRgbaString(
        test.cursor_color);
    EXPECT_TRUE(has_found_color)
        << color_utils::SkColorToRgbaString(test.found);
    EXPECT_FALSE(has_not_found_color)
        << color_utils::SkColorToRgbaString(test.not_found);
  }

  // Set back to the default color and ensure cursor compositing is disabled.
  prefs->SetBoolean(prefs::kAccessibilityLargeCursorEnabled, false);
  SetCursorCompositionEnabled(false);
}

}  // namespace ash
