// Copyright 2018 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/cros_display_config.h"

#include "ash/display/cros_display_config.h"
#include "ash/display/touch_calibrator_controller.h"
#include "ash/public/interfaces/cros_display_config.mojom.h"
#include "ash/shell.h"
#include "ash/test/ash_test_base.h"
#include "ash/touch/ash_touch_transform_controller.h"
#include "base/bind.h"
#include "base/command_line.h"
#include "base/stl_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/test/scoped_feature_list.h"
#include "mojo/public/cpp/bindings/associated_binding.h"
#include "services/ws/public/cpp/input_devices/input_device_client_test_api.h"
#include "ui/display/display_switches.h"
#include "ui/display/manager/display_manager.h"
#include "ui/display/manager/test/touch_transform_controller_test_api.h"
#include "ui/display/manager/touch_transform_setter.h"
#include "ui/display/test/display_manager_test_api.h"
#include "ui/events/devices/touch_device_transform.h"
#include "ui/events/devices/touchscreen_device.h"

namespace ash {

namespace {

void SetResult(mojom::DisplayConfigResult* result_ptr,
               base::OnceClosure callback,
               mojom::DisplayConfigResult result) {
  *result_ptr = result;
  std::move(callback).Run();
}

void InitExternalTouchDevices(int64_t display_id) {
  ui::TouchscreenDevice touchdevice(123, ui::InputDeviceType::INPUT_DEVICE_USB,
                                    std::string("test external touch device"),
                                    gfx::Size(1000, 1000), 1);
  ws::InputDeviceClientTestApi().SetTouchscreenDevices({touchdevice});

  std::vector<ui::TouchDeviceTransform> transforms;
  ui::TouchDeviceTransform touch_device_transform;
  touch_device_transform.display_id = display_id;
  touch_device_transform.device_id = touchdevice.id;
  transforms.push_back(touch_device_transform);
  display::test::TouchTransformControllerTestApi(
      ash::Shell::Get()->touch_transformer_controller())
      .touch_transform_setter()
      ->ConfigureTouchDevices(transforms);
}

class TestObserver : public mojom::CrosDisplayConfigObserver {
 public:
  TestObserver() = default;

  // mojom::CrosDisplayConfigObserver:
  void OnDisplayConfigChanged() override { display_changes_++; }

  int display_changes() const { return display_changes_; }
  void reset_display_changes() { display_changes_ = 0; }

 private:
  int display_changes_ = 0;

  DISALLOW_COPY_AND_ASSIGN(TestObserver);
};

class CrosDisplayConfigTest : public AshTestBase {
 public:
  CrosDisplayConfigTest() {}
  ~CrosDisplayConfigTest() override {}

  void SetUp() override {
    base::CommandLine::ForCurrentProcess()->AppendSwitch(
        switches::kUseFirstDisplayAsInternal);
    AshTestBase::SetUp();
    CHECK(display::Screen::GetScreen());
    cros_display_config_ = Shell::Get()->cros_display_config();
  }

  mojom::DisplayLayoutInfoPtr GetDisplayLayoutInfo() {
    mojom::DisplayLayoutInfoPtr display_layout_info;
    base::RunLoop run_loop;
    cros_display_config_->GetDisplayLayoutInfo(base::BindOnce(
        [](mojom::DisplayLayoutInfoPtr* result_ptr, base::OnceClosure callback,
           mojom::DisplayLayoutInfoPtr result) {
          *result_ptr = std::move(result);
          std::move(callback).Run();
        },
        &display_layout_info, run_loop.QuitClosure()));
    run_loop.Run();
    return display_layout_info;
  }

  mojom::DisplayConfigResult SetDisplayLayoutInfo(
      mojom::DisplayLayoutInfoPtr display_layout_info) {
    mojom::DisplayConfigResult result;
    base::RunLoop run_loop;
    cros_display_config_->SetDisplayLayoutInfo(
        std::move(display_layout_info),
        base::BindOnce(&SetResult, &result, run_loop.QuitClosure()));
    run_loop.Run();
    return result;
  }

  std::vector<mojom::DisplayUnitInfoPtr> GetDisplayUnitInfoList() {
    std::vector<mojom::DisplayUnitInfoPtr> display_info_list;
    base::RunLoop run_loop;
    cros_display_config_->GetDisplayUnitInfoList(
        /*single_unified=*/false,
        base::BindOnce(
            [](std::vector<mojom::DisplayUnitInfoPtr>* result_ptr,
               base::OnceClosure callback,
               std::vector<mojom::DisplayUnitInfoPtr> result) {
              *result_ptr = std::move(result);
              std::move(callback).Run();
            },
            &display_info_list, run_loop.QuitClosure()));
    run_loop.Run();
    return display_info_list;
  }

  mojom::DisplayConfigResult SetDisplayProperties(
      const std::string& id,
      mojom::DisplayConfigPropertiesPtr properties) {
    mojom::DisplayConfigResult result;
    base::RunLoop run_loop;
    cros_display_config_->SetDisplayProperties(
        id, std::move(properties), mojom::DisplayConfigSource::kUser,
        base::BindOnce(&SetResult, &result, run_loop.QuitClosure()));
    run_loop.Run();
    return result;
  }

  bool OverscanCalibration(int64_t id,
                           mojom::DisplayConfigOperation op,
                           const base::Optional<gfx::Insets>& delta) {
    mojom::DisplayConfigResult result;
    base::RunLoop run_loop;
    cros_display_config()->OverscanCalibration(
        base::NumberToString(id), op, delta,
        base::BindOnce(&SetResult, &result, run_loop.QuitClosure()));
    run_loop.Run();
    return result == mojom::DisplayConfigResult::kSuccess;
  }

  bool DisplayExists(int64_t display_id) {
    const display::Display& display =
        display_manager()->GetDisplayForId(display_id);
    return display.id() != display::kInvalidDisplayId;
  }

  mojom::TouchCalibrationPtr GetDefaultCalibration() {
    auto calibration = mojom::TouchCalibration::New();
    for (int i = 0; i < 4; ++i)
      calibration->pairs.emplace_back(mojom::TouchCalibrationPair::New());
    return calibration;
  }

  bool StartTouchCalibration(const std::string& display_id) {
    return CallTouchCalibration(
        display_id, ash::mojom::DisplayConfigOperation::kStart, nullptr);
  }

  bool CompleteCustomTouchCalibration(const std::string& display_id,
                                      mojom::TouchCalibrationPtr calibration) {
    return CallTouchCalibration(display_id,
                                ash::mojom::DisplayConfigOperation::kComplete,
                                std::move(calibration));
  }

  bool CallTouchCalibration(const std::string& id,
                            ash::mojom::DisplayConfigOperation op,
                            ash::mojom::TouchCalibrationPtr calibration) {
    mojom::DisplayConfigResult result;
    base::RunLoop run_loop;
    cros_display_config_->TouchCalibration(
        id, op, std::move(calibration),
        base::BindOnce(&SetResult, &result, run_loop.QuitClosure()));
    run_loop.Run();
    return result == mojom::DisplayConfigResult::kSuccess;
  }

  bool IsTouchCalibrationActive() {
    TouchCalibratorController* touch_calibrator =
        cros_display_config_->touch_calibrator_for_test();
    return touch_calibrator && touch_calibrator->IsCalibrating();
  }

  CrosDisplayConfig* cros_display_config() { return cros_display_config_; }

 private:
  CrosDisplayConfig* cros_display_config_ = nullptr;

  DISALLOW_COPY_AND_ASSIGN(CrosDisplayConfigTest);
};

}  // namespace

TEST_F(CrosDisplayConfigTest, OnDisplayConfigChanged) {
  TestObserver observer;
  mojom::CrosDisplayConfigObserverAssociatedPtr observer_ptr;
  mojo::AssociatedBinding<mojom::CrosDisplayConfigObserver> binding(
      &observer, mojo::MakeRequestAssociatedWithDedicatedPipe(&observer_ptr));
  cros_display_config()->AddObserver(observer_ptr.PassInterface());
  base::RunLoop().RunUntilIdle();

  // Adding one display should trigger one notification.
  UpdateDisplay("500x400");
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(1, observer.display_changes());
  observer.reset_display_changes();

  // Adding two displays should trigger two notification.
  UpdateDisplay("500x400,500x400");
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(2, observer.display_changes());
}

TEST_F(CrosDisplayConfigTest, GetDisplayLayoutInfo) {
  UpdateDisplay("500x400,500x400,500x400");
  std::vector<display::Display> displays =
      display::Screen::GetScreen()->GetAllDisplays();
  ASSERT_EQ(3u, displays.size());

  mojom::DisplayLayoutInfoPtr display_layout_info = GetDisplayLayoutInfo();

  ASSERT_TRUE(display_layout_info);
  const std::vector<mojom::DisplayLayoutPtr>& layouts =
      *display_layout_info->layouts;
  ASSERT_EQ(2u, layouts.size());

  EXPECT_EQ(base::NumberToString(displays[1].id()), layouts[0]->id);
  EXPECT_EQ(base::NumberToString(displays[0].id()), layouts[0]->parent_id);
  EXPECT_EQ(mojom::DisplayLayoutPosition::kRight, layouts[0]->position);
  EXPECT_EQ(0, layouts[0]->offset);

  EXPECT_EQ(base::NumberToString(displays[2].id()), layouts[1]->id);
  EXPECT_EQ(layouts[0]->id, layouts[1]->parent_id);
  EXPECT_EQ(mojom::DisplayLayoutPosition::kRight, layouts[1]->position);
  EXPECT_EQ(0, layouts[1]->offset);
}

TEST_F(CrosDisplayConfigTest, SetLayoutUnified) {
  UpdateDisplay("500x400,500x400");
  EXPECT_FALSE(display_manager()->IsInUnifiedMode());

  // Enable unified desktop. Enables unified mode.
  cros_display_config()->SetUnifiedDesktopEnabled(true);
  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(display_manager()->IsInUnifiedMode());

  // Disable unified mode.
  auto properties = mojom::DisplayLayoutInfo::New();
  properties->layout_mode = mojom::DisplayLayoutMode::kNormal;
  mojom::DisplayConfigResult result =
      SetDisplayLayoutInfo(std::move(properties));
  EXPECT_EQ(mojom::DisplayConfigResult::kSuccess, result);
  EXPECT_FALSE(display_manager()->IsInUnifiedMode());

  // Enable unified mode.
  properties = mojom::DisplayLayoutInfo::New();
  properties->layout_mode = mojom::DisplayLayoutMode::kUnified;
  result = SetDisplayLayoutInfo(std::move(properties));
  EXPECT_EQ(mojom::DisplayConfigResult::kSuccess, result);
  EXPECT_TRUE(display_manager()->IsInUnifiedMode());

  // Restore extended mode.
  cros_display_config()->SetUnifiedDesktopEnabled(false);
  EXPECT_FALSE(display_manager()->IsInUnifiedMode());
}

TEST_F(CrosDisplayConfigTest, SetLayoutMirroredDefault) {
  UpdateDisplay("500x400,500x400,500x400");

  auto properties = mojom::DisplayLayoutInfo::New();
  properties->layout_mode = mojom::DisplayLayoutMode::kMirrored;
  mojom::DisplayConfigResult result =
      SetDisplayLayoutInfo(std::move(properties));
  EXPECT_EQ(mojom::DisplayConfigResult::kSuccess, result);
  EXPECT_TRUE(display_manager()->IsInMirrorMode());
  display::DisplayIdList id_list =
      display_manager()->GetMirroringDestinationDisplayIdList();
  ASSERT_EQ(2u, id_list.size());

  properties = mojom::DisplayLayoutInfo::New();
  properties->layout_mode = mojom::DisplayLayoutMode::kNormal;
  result = SetDisplayLayoutInfo(std::move(properties));
  EXPECT_EQ(mojom::DisplayConfigResult::kSuccess, result);
  EXPECT_FALSE(display_manager()->IsInMirrorMode());
}

TEST_F(CrosDisplayConfigTest, SetLayoutMirroredMixed) {
  UpdateDisplay("500x400,500x400,500x400,500x400");

  std::vector<display::Display> displays =
      display::Screen::GetScreen()->GetAllDisplays();
  ASSERT_EQ(4u, displays.size());

  auto properties = mojom::DisplayLayoutInfo::New();
  properties->layout_mode = mojom::DisplayLayoutMode::kMirrored;
  properties->mirror_source_id = base::NumberToString(displays[0].id());
  properties->mirror_destination_ids =
      base::make_optional<std::vector<std::string>>(
          {base::NumberToString(displays[1].id()),
           base::NumberToString(displays[3].id())});
  mojom::DisplayConfigResult result =
      SetDisplayLayoutInfo(std::move(properties));
  EXPECT_EQ(mojom::DisplayConfigResult::kSuccess, result);
  EXPECT_TRUE(display_manager()->IsInMirrorMode());
  display::DisplayIdList id_list =
      display_manager()->GetMirroringDestinationDisplayIdList();
  ASSERT_EQ(2u, id_list.size());
  EXPECT_TRUE(base::ContainsValue(id_list, displays[1].id()));
  EXPECT_TRUE(base::ContainsValue(id_list, displays[3].id()));
}

TEST_F(CrosDisplayConfigTest, GetDisplayUnitInfoListBasic) {
  UpdateDisplay("500x600,400x520");
  std::vector<mojom::DisplayUnitInfoPtr> result = GetDisplayUnitInfoList();
  ASSERT_EQ(2u, result.size());

  int64_t display_id;
  ASSERT_TRUE(base::StringToInt64(result[0]->id, &display_id));
  ASSERT_TRUE(DisplayExists(display_id));
  const mojom::DisplayUnitInfo& info_0 = *result[0];
  EXPECT_TRUE(info_0.is_primary);
  EXPECT_TRUE(info_0.is_internal);
  EXPECT_TRUE(info_0.is_enabled);
  EXPECT_FALSE(info_0.is_tablet_mode);
  EXPECT_FALSE(info_0.has_touch_support);
  EXPECT_FALSE(info_0.has_accelerometer_support);
  EXPECT_EQ(96, info_0.dpi_x);
  EXPECT_EQ(96, info_0.dpi_y);
  EXPECT_EQ(display::Display::ROTATE_0, info_0.rotation);
  EXPECT_EQ("0,0 500x600", info_0.bounds.ToString());
  EXPECT_EQ("0,0,0,0", info_0.overscan.ToString());

  ASSERT_TRUE(base::StringToInt64(result[1]->id, &display_id));
  ASSERT_TRUE(DisplayExists(display_id));
  const mojom::DisplayUnitInfo& info_1 = *result[1];
  EXPECT_EQ(display_manager()->GetDisplayNameForId(display_id), info_1.name);
  // Second display is left of the primary display whose width 500.
  EXPECT_EQ("500,0 400x520", info_1.bounds.ToString());
  EXPECT_EQ("0,0,0,0", info_1.overscan.ToString());
  EXPECT_EQ(display::Display::ROTATE_0, info_1.rotation);
  EXPECT_FALSE(info_1.is_primary);
  EXPECT_FALSE(info_1.is_internal);
  EXPECT_TRUE(info_1.is_enabled);
  EXPECT_EQ(96, info_1.dpi_x);
  EXPECT_EQ(96, info_1.dpi_y);
}

TEST_F(CrosDisplayConfigTest, GetDisplayUnitInfoListZoomFactor) {
  UpdateDisplay("1024x512,1024x512");
  std::vector<mojom::DisplayUnitInfoPtr> result = GetDisplayUnitInfoList();
  ASSERT_EQ(2u, result.size());

  const mojom::DisplayUnitInfo& info_0 = *result[0];
  EXPECT_EQ(1.0, info_0.display_zoom_factor);
  const std::vector<double>& zoom_factors =
      info_0.available_display_zoom_factors;
  EXPECT_EQ(9u, zoom_factors.size());
  EXPECT_FLOAT_EQ(0.90f, zoom_factors[0]);
  EXPECT_FLOAT_EQ(0.95f, zoom_factors[1]);
  EXPECT_FLOAT_EQ(1.f, zoom_factors[2]);
  EXPECT_FLOAT_EQ(1.05f, zoom_factors[3]);
  EXPECT_FLOAT_EQ(1.10f, zoom_factors[4]);
  EXPECT_FLOAT_EQ(1.15f, zoom_factors[5]);
  EXPECT_FLOAT_EQ(1.20f, zoom_factors[6]);
  EXPECT_FLOAT_EQ(1.25f, zoom_factors[7]);
  EXPECT_FLOAT_EQ(1.30f, zoom_factors[8]);
}

TEST_F(CrosDisplayConfigTest, SetDisplayPropertiesPrimary) {
  UpdateDisplay("1200x600,600x1000");
  int64_t primary_id = display::Screen::GetScreen()->GetPrimaryDisplay().id();
  int64_t secondary_id = display_manager()->GetSecondaryDisplay().id();
  ASSERT_NE(primary_id, secondary_id);

  auto properties = mojom::DisplayConfigProperties::New();
  properties->set_primary = true;
  mojom::DisplayConfigResult result = SetDisplayProperties(
      base::NumberToString(secondary_id), std::move(properties));
  EXPECT_EQ(mojom::DisplayConfigResult::kSuccess, result);

  // secondary display should now be primary.
  primary_id = display::Screen::GetScreen()->GetPrimaryDisplay().id();
  EXPECT_EQ(primary_id, secondary_id);
}

TEST_F(CrosDisplayConfigTest, SetDisplayPropertiesOverscan) {
  UpdateDisplay("1200x600,600x1000*2");
  const display::Display& secondary = display_manager()->GetSecondaryDisplay();

  auto properties = mojom::DisplayConfigProperties::New();
  properties->overscan = gfx::Insets({199, 20, 51, 130});
  mojom::DisplayConfigResult result = SetDisplayProperties(
      base::NumberToString(secondary.id()), std::move(properties));
  EXPECT_EQ(mojom::DisplayConfigResult::kSuccess, result);
  EXPECT_EQ("1200,0 150x250", secondary.bounds().ToString());
  const gfx::Insets overscan =
      display_manager()->GetOverscanInsets(secondary.id());
  EXPECT_EQ(199, overscan.top());
  EXPECT_EQ(20, overscan.left());
  EXPECT_EQ(51, overscan.bottom());
  EXPECT_EQ(130, overscan.right());
}

TEST_F(CrosDisplayConfigTest, SetDisplayPropertiesRotation) {
  UpdateDisplay("1200x600,600x1000*2");
  const display::Display& secondary = display_manager()->GetSecondaryDisplay();

  mojom::DisplayConfigResult result;

  auto properties = mojom::DisplayConfigProperties::New();
  properties->rotation =
      mojom::DisplayRotation::New(display::Display::ROTATE_90);
  result = SetDisplayProperties(base::NumberToString(secondary.id()),
                                std::move(properties));
  EXPECT_EQ(mojom::DisplayConfigResult::kSuccess, result);
  EXPECT_EQ("1200,0 500x300", secondary.bounds().ToString());
  EXPECT_EQ(display::Display::ROTATE_90, secondary.rotation());

  properties = mojom::DisplayConfigProperties::New();
  properties->rotation =
      mojom::DisplayRotation::New(display::Display::ROTATE_270);
  result = SetDisplayProperties(base::NumberToString(secondary.id()),
                                std::move(properties));
  EXPECT_EQ(mojom::DisplayConfigResult::kSuccess, result);
  EXPECT_EQ("1200,0 500x300", secondary.bounds().ToString());
  EXPECT_EQ(display::Display::ROTATE_270, secondary.rotation());

  // Test setting primary and rotating.
  properties = mojom::DisplayConfigProperties::New();
  properties->set_primary = true;
  properties->rotation =
      mojom::DisplayRotation::New(display::Display::ROTATE_180);
  result = SetDisplayProperties(base::NumberToString(secondary.id()),
                                std::move(properties));
  EXPECT_EQ(mojom::DisplayConfigResult::kSuccess, result);
  const display::Display& primary =
      display::Screen::GetScreen()->GetPrimaryDisplay();
  EXPECT_EQ(secondary.id(), primary.id());
  EXPECT_EQ("0,0 300x500", primary.bounds().ToString());
  EXPECT_EQ(display::Display::ROTATE_180, primary.rotation());
}

TEST_F(CrosDisplayConfigTest, SetDisplayPropertiesBoundsOrigin) {
  UpdateDisplay("1200x600,520x400");
  const display::Display& secondary = display_manager()->GetSecondaryDisplay();

  mojom::DisplayConfigResult result;

  auto properties = mojom::DisplayConfigProperties::New();
  properties->bounds_origin = gfx::Point({-520, 50});
  result = SetDisplayProperties(base::NumberToString(secondary.id()),
                                std::move(properties));
  EXPECT_EQ(mojom::DisplayConfigResult::kSuccess, result);
  EXPECT_EQ("-520,50 520x400", secondary.bounds().ToString());

  properties = mojom::DisplayConfigProperties::New();
  properties->bounds_origin = gfx::Point({1200, 100});
  result = SetDisplayProperties(base::NumberToString(secondary.id()),
                                std::move(properties));
  EXPECT_EQ(mojom::DisplayConfigResult::kSuccess, result);
  EXPECT_EQ("1200,100 520x400", secondary.bounds().ToString());

  properties = mojom::DisplayConfigProperties::New();
  properties->bounds_origin = gfx::Point({1100, -400});
  result = SetDisplayProperties(base::NumberToString(secondary.id()),
                                std::move(properties));
  EXPECT_EQ(mojom::DisplayConfigResult::kSuccess, result);
  EXPECT_EQ("1100,-400 520x400", secondary.bounds().ToString());

  properties = mojom::DisplayConfigProperties::New();
  properties->bounds_origin = gfx::Point({-350, 600});
  result = SetDisplayProperties(base::NumberToString(secondary.id()),
                                std::move(properties));
  EXPECT_EQ(mojom::DisplayConfigResult::kSuccess, result);
  EXPECT_EQ("-350,600 520x400", secondary.bounds().ToString());
}

TEST_F(CrosDisplayConfigTest, SetDisplayPropertiesDisplayZoomFactor) {
  UpdateDisplay("1200x600, 1600x1000#1600x1000");
  display::DisplayIdList display_id_list =
      display_manager()->GetCurrentDisplayIdList();

  const float zoom_factor_1 = 1.23f;
  const float zoom_factor_2 = 2.34f;

  display_manager()->UpdateZoomFactor(display_id_list[0], zoom_factor_2);
  display_manager()->UpdateZoomFactor(display_id_list[1], zoom_factor_1);

  EXPECT_EQ(
      zoom_factor_2,
      display_manager()->GetDisplayInfo(display_id_list[0]).zoom_factor());
  EXPECT_EQ(
      zoom_factor_1,
      display_manager()->GetDisplayInfo(display_id_list[1]).zoom_factor());

  // Set zoom factor for display 0, should not affect display 1.
  auto properties = mojom::DisplayConfigProperties::New();
  properties->display_zoom_factor = zoom_factor_1;
  mojom::DisplayConfigResult result = SetDisplayProperties(
      base::NumberToString(display_id_list[0]), std::move(properties));
  EXPECT_EQ(mojom::DisplayConfigResult::kSuccess, result);
  EXPECT_EQ(
      zoom_factor_1,
      display_manager()->GetDisplayInfo(display_id_list[0]).zoom_factor());
  EXPECT_EQ(
      zoom_factor_1,
      display_manager()->GetDisplayInfo(display_id_list[1]).zoom_factor());

  // Set zoom factor for display 1.
  properties = mojom::DisplayConfigProperties::New();
  properties->display_zoom_factor = zoom_factor_2;
  result = SetDisplayProperties(base::NumberToString(display_id_list[1]),
                                std::move(properties));
  EXPECT_EQ(mojom::DisplayConfigResult::kSuccess, result);
  EXPECT_EQ(
      zoom_factor_1,
      display_manager()->GetDisplayInfo(display_id_list[0]).zoom_factor());
  EXPECT_EQ(
      zoom_factor_2,
      display_manager()->GetDisplayInfo(display_id_list[1]).zoom_factor());

  // Invalid zoom factor should fail.
  const float invalid_zoom_factor = 0.01f;
  properties = mojom::DisplayConfigProperties::New();
  properties->display_zoom_factor = invalid_zoom_factor;
  result = SetDisplayProperties(base::NumberToString(display_id_list[1]),
                                std::move(properties));
  EXPECT_EQ(mojom::DisplayConfigResult::kPropertyValueOutOfRangeError, result);
  EXPECT_EQ(
      zoom_factor_2,
      display_manager()->GetDisplayInfo(display_id_list[1]).zoom_factor());
}

TEST_F(CrosDisplayConfigTest, SetDisplayMode) {
  UpdateDisplay("1024x512,1024x512");
  std::vector<mojom::DisplayUnitInfoPtr> result = GetDisplayUnitInfoList();
  ASSERT_EQ(2u, result.size());
  // Internal display has just one mode.
  EXPECT_EQ(0, result[0]->selected_display_mode_index);
  ASSERT_EQ(1u, result[0]->available_display_modes.size());

  auto properties = mojom::DisplayConfigProperties::New();
  auto display_mode = result[0]->available_display_modes[0].Clone();
  properties->display_mode = std::move(display_mode);
  ASSERT_EQ(mojom::DisplayConfigResult::kSuccess,
            SetDisplayProperties(result[0]->id, std::move(properties)));

  result = GetDisplayUnitInfoList();
  ASSERT_EQ(2u, result.size());
  EXPECT_EQ(0, result[0]->selected_display_mode_index);
}

TEST_F(CrosDisplayConfigTest, OverscanCalibration) {
  UpdateDisplay("1200x600");
  int64_t id = display::Screen::GetScreen()->GetPrimaryDisplay().id();
  ASSERT_NE(display::kInvalidDisplayId, id);

  // Test that kAdjust succeeds after kComplete call.
  EXPECT_TRUE(OverscanCalibration(id, mojom::DisplayConfigOperation::kStart,
                                  base::nullopt));
  EXPECT_EQ(gfx::Insets(0, 0, 0, 0), display_manager()->GetOverscanInsets(id));

  gfx::Insets insets(10, 10, 10, 10);
  EXPECT_TRUE(
      OverscanCalibration(id, mojom::DisplayConfigOperation::kAdjust, insets));
  // Adjust has no effect until Complete.
  EXPECT_EQ(gfx::Insets(0, 0, 0, 0), display_manager()->GetOverscanInsets(id));

  EXPECT_TRUE(OverscanCalibration(id, mojom::DisplayConfigOperation::kComplete,
                                  base::nullopt));
  gfx::Insets overscan = display_manager()->GetOverscanInsets(id);
  EXPECT_EQ(insets, overscan)
      << "Overscan: " << overscan.ToString() << " != " << insets.ToString();

  // Test that kReset clears restores previous insets.

  // Start clears any overscan values.
  EXPECT_TRUE(OverscanCalibration(id, mojom::DisplayConfigOperation::kStart,
                                  base::nullopt));
  EXPECT_EQ(gfx::Insets(0, 0, 0, 0), display_manager()->GetOverscanInsets(id));

  // Reset + Complete restores previously set insets.
  EXPECT_TRUE(OverscanCalibration(id, mojom::DisplayConfigOperation::kReset,
                                  base::nullopt));
  EXPECT_EQ(gfx::Insets(0, 0, 0, 0), display_manager()->GetOverscanInsets(id));
  EXPECT_TRUE(OverscanCalibration(id, mojom::DisplayConfigOperation::kComplete,
                                  base::nullopt));
  EXPECT_EQ(insets, display_manager()->GetOverscanInsets(id));

  // Additional complete call should fail.
  EXPECT_FALSE(OverscanCalibration(id, mojom::DisplayConfigOperation::kComplete,
                                   base::nullopt));
}

TEST_F(CrosDisplayConfigTest, CustomTouchCalibrationInternal) {
  UpdateDisplay("1200x600,600x1000*2");
  const int64_t internal_display_id =
      display::test::DisplayManagerTestApi(display_manager())
          .SetFirstDisplayAsInternalDisplay();

  InitExternalTouchDevices(internal_display_id);

  EXPECT_FALSE(
      StartTouchCalibration(base::NumberToString(internal_display_id)));
  EXPECT_FALSE(IsTouchCalibrationActive());
}

TEST_F(CrosDisplayConfigTest, CustomTouchCalibrationWithoutStart) {
  UpdateDisplay("1200x600,600x1000*2");
  EXPECT_FALSE(IsTouchCalibrationActive());
}

TEST_F(CrosDisplayConfigTest, CustomTouchCalibrationNonTouchDisplay) {
  UpdateDisplay("1200x600,600x1000*2");

  const int64_t internal_display_id =
      display::test::DisplayManagerTestApi(display_manager())
          .SetFirstDisplayAsInternalDisplay();

  display::DisplayIdList display_id_list =
      display_manager()->GetCurrentDisplayIdList();

  // Pick the non internal display Id.
  const int64_t display_id = display_id_list[0] == internal_display_id
                                 ? display_id_list[1]
                                 : display_id_list[0];

  ws::InputDeviceClientTestApi().SetTouchscreenDevices({});
  std::string id = base::NumberToString(display_id);

  // Since no external touch devices are present, the calibration should fail.
  EXPECT_FALSE(StartTouchCalibration(id));

  // If an external touch device is present, the calibration should proceed.
  InitExternalTouchDevices(display_id);
  EXPECT_TRUE(StartTouchCalibration(id));
  EXPECT_TRUE(IsTouchCalibrationActive());
}

TEST_F(CrosDisplayConfigTest, CustomTouchCalibrationInvalidPoints) {
  UpdateDisplay("1200x600,600x1000*2");

  const int64_t internal_display_id =
      display::test::DisplayManagerTestApi(display_manager())
          .SetFirstDisplayAsInternalDisplay();

  display::DisplayIdList display_id_list =
      display_manager()->GetCurrentDisplayIdList();

  // Pick the non internal display Id.
  const int64_t display_id = display_id_list[0] == internal_display_id
                                 ? display_id_list[1]
                                 : display_id_list[0];

  InitExternalTouchDevices(display_id);

  std::string id = base::NumberToString(display_id);

  EXPECT_TRUE(StartTouchCalibration(id));
  mojom::TouchCalibrationPtr calibration = GetDefaultCalibration();
  calibration->pairs[0]->display_point.set_x(-1);
  EXPECT_FALSE(CompleteCustomTouchCalibration(id, std::move(calibration)));

  EXPECT_TRUE(StartTouchCalibration(id));
  calibration = GetDefaultCalibration();
  calibration->bounds.set_width(1);
  calibration->pairs[0]->display_point.set_x(2);
  EXPECT_FALSE(CompleteCustomTouchCalibration(id, std::move(calibration)));
}

TEST_F(CrosDisplayConfigTest, CustomTouchCalibrationSuccess) {
  UpdateDisplay("1200x600,600x1000*2");

  const int64_t internal_display_id =
      display::test::DisplayManagerTestApi(display_manager())
          .SetFirstDisplayAsInternalDisplay();

  display::DisplayIdList display_id_list =
      display_manager()->GetCurrentDisplayIdList();

  // Pick the non internal display Id.
  const int64_t display_id = display_id_list[0] == internal_display_id
                                 ? display_id_list[1]
                                 : display_id_list[0];

  InitExternalTouchDevices(display_id);

  std::string id = base::NumberToString(display_id);

  EXPECT_TRUE(StartTouchCalibration(id));
  EXPECT_TRUE(IsTouchCalibrationActive());
  mojom::TouchCalibrationPtr calibration = GetDefaultCalibration();
  EXPECT_TRUE(CompleteCustomTouchCalibration(id, std::move(calibration)));
}

}  // namespace ash
