// 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 "ui/display/manager/display_manager.h"

#include "ash/accelerators/accelerator_commands.h"
#include "ash/accelerometer/accelerometer_reader.h"
#include "ash/accelerometer/accelerometer_types.h"
#include "ash/app_list/app_list_controller_impl.h"
#include "ash/display/cursor_window_controller.h"
#include "ash/display/display_configuration_controller.h"
#include "ash/display/display_util.h"
#include "ash/display/mirror_window_controller.h"
#include "ash/display/mirror_window_test_api.h"
#include "ash/display/screen_orientation_controller.h"
#include "ash/display/screen_orientation_controller_test_api.h"
#include "ash/display/window_tree_host_manager.h"
#include "ash/public/cpp/app_types.h"
#include "ash/public/cpp/ash_switches.h"
#include "ash/root_window_controller.h"
#include "ash/screen_util.h"
#include "ash/shelf/shelf.h"
#include "ash/shell.h"
#include "ash/strings/grit/ash_strings.h"
#include "ash/test/ash_test_base.h"
#include "ash/wm/tablet_mode/tablet_mode_controller.h"
#include "ash/wm/window_state.h"
#include "ash/wm/window_util.h"
#include "base/command_line.h"
#include "base/format_macros.h"
#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "base/test/scoped_feature_list.h"
#include "build/build_config.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/env.h"
#include "ui/aura/window_observer.h"
#include "ui/aura/window_tree_host.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/display/display.h"
#include "ui/display/display_layout.h"
#include "ui/display/display_layout_builder.h"
#include "ui/display/display_observer.h"
#include "ui/display/display_switches.h"
#include "ui/display/manager/display_change_observer.h"
#include "ui/display/manager/display_layout_store.h"
#include "ui/display/manager/display_manager_utilities.h"
#include "ui/display/manager/display_util.h"
#include "ui/display/manager/fake_display_snapshot.h"
#include "ui/display/manager/managed_display_info.h"
#include "ui/display/manager/test/touch_device_manager_test_api.h"
#include "ui/display/screen.h"
#include "ui/display/test/display_manager_test_api.h"
#include "ui/events/devices/touchscreen_device.h"
#include "ui/events/test/event_generator.h"
#include "ui/gfx/font_render_params.h"

namespace ash {

using std::string;
using std::vector;

using base::StringPrintf;

namespace {

std::string ToDisplayName(int64_t id) {
  return "x-" + base::NumberToString(id);
}

}  // namespace

class DisplayManagerTest : public AshTestBase,
                           public display::DisplayObserver,
                           public aura::WindowObserver {
 public:
  DisplayManagerTest() = default;
  ~DisplayManagerTest() override = default;

  void SetUp() override {
    AshTestBase::SetUp();
    display::Screen::GetScreen()->AddObserver(this);
    Shell::GetPrimaryRootWindow()->AddObserver(this);
  }
  void TearDown() override {
    Shell::GetPrimaryRootWindow()->RemoveObserver(this);
    display::Screen::GetScreen()->RemoveObserver(this);
    AshTestBase::TearDown();
  }

  const vector<display::Display>& changed() const { return changed_; }
  const vector<display::Display>& added() const { return added_; }
  uint32_t changed_metrics() const { return changed_metrics_; }

  string GetCountSummary() const {
    return StringPrintf("%" PRIuS " %" PRIuS " %" PRIuS " %" PRIuS " %" PRIuS,
                        changed_.size(), added_.size(), removed_count_,
                        will_process_count_, did_process_count_);
  }

  void reset() {
    changed_.clear();
    added_.clear();
    removed_count_ = will_process_count_ = did_process_count_ = 0U;
    changed_metrics_ = 0U;
    root_window_destroyed_ = false;
  }

  bool root_window_destroyed() const { return root_window_destroyed_; }

  const display::ManagedDisplayInfo& GetDisplayInfo(
      const display::Display& display) {
    return display_manager()->GetDisplayInfo(display.id());
  }

  const display::ManagedDisplayInfo& GetDisplayInfoAt(int index) {
    return GetDisplayInfo(display_manager()->GetDisplayAt(index));
  }

  const display::Display& GetDisplayForId(int64_t id) {
    return display_manager()->GetDisplayForId(id);
  }

  const display::ManagedDisplayInfo& GetDisplayInfoForId(int64_t id) {
    return GetDisplayInfo(display_manager()->GetDisplayForId(id));
  }

  // aura::DisplayObserver overrides:
  void OnWillProcessDisplayChanges() override { ++will_process_count_; }
  void OnDidProcessDisplayChanges() override { ++did_process_count_; }
  void OnDisplayMetricsChanged(const display::Display& display,
                               uint32_t changed_metrics) override {
    changed_.push_back(display);
    changed_metrics_ |= changed_metrics;
  }
  void OnDisplayAdded(const display::Display& new_display) override {
    added_.push_back(new_display);
  }
  void OnDisplayRemoved(const display::Display& old_display) override {
    ++removed_count_;
  }

  // aura::WindowObserver overrides:
  void OnWindowDestroying(aura::Window* window) override {
    ASSERT_EQ(Shell::GetPrimaryRootWindow(), window);
    root_window_destroyed_ = true;
  }

  // Returns true if there exists any overlapping mirroring displays.
  bool OverlappingMirroringDisplaysExist() {
    const auto& mirroring_displays =
        display_manager()->software_mirroring_display_list();
    for (size_t i = 0; i < mirroring_displays.size() - 1; ++i) {
      for (size_t j = i + 1; j < mirroring_displays.size(); ++j) {
        const gfx::Rect& bounds_1 = mirroring_displays[i].bounds();
        const gfx::Rect& bounds_2 = mirroring_displays[j].bounds();
        if (bounds_1.Intersects(bounds_2))
          return true;
      }
    }

    return false;
  }

  void SetSoftwareMirrorMode(bool active) {
    display_manager()->SetMirrorMode(
        active ? display::MirrorMode::kNormal : display::MirrorMode::kOff,
        base::nullopt);
    base::RunLoop().RunUntilIdle();
  }

 private:
  vector<display::Display> changed_;
  vector<display::Display> added_;
  size_t removed_count_ = 0u;
  size_t will_process_count_ = 0u;
  size_t did_process_count_ = 0u;
  bool root_window_destroyed_ = false;
  uint32_t changed_metrics_ = 0u;

  DISALLOW_COPY_AND_ASSIGN(DisplayManagerTest);
};

TEST_F(DisplayManagerTest, UpdateDisplayTest) {
  EXPECT_EQ(1U, display_manager()->GetNumDisplays());

  // Update primary and add seconary.
  UpdateDisplay("100+0-500x500,0+501-400x400");
  EXPECT_EQ(2U, display_manager()->GetNumDisplays());
  EXPECT_EQ("0,0 500x500",
            display_manager()->GetDisplayAt(0).bounds().ToString());

  EXPECT_EQ("2 1 0 1 1", GetCountSummary());
  // Metrics change immediately when new displays set shelf work area insets.
  // After that, DisplayManager::OnNativeDisplaysChanged trigger changes of the
  // primary display's metrics. So the observed order of changes is [1, 0].
  EXPECT_EQ(display_manager()->GetDisplayAt(0).id(), changed()[1].id());
  EXPECT_EQ(display_manager()->GetDisplayAt(1).id(), changed()[0].id());
  EXPECT_EQ(display_manager()->GetDisplayAt(1).id(), added()[0].id());
  EXPECT_EQ("0,0 500x500", changed()[1].bounds().ToString());
  EXPECT_EQ("500,0 400x400", changed()[0].bounds().ToString());
  // Secondary display is on right.
  EXPECT_EQ("500,0 400x400", added()[0].bounds().ToString());
  EXPECT_EQ("0,501 400x400",
            GetDisplayInfo(added()[0]).bounds_in_native().ToString());
  reset();

  // Delete secondary.
  UpdateDisplay("100+0-500x500");
  EXPECT_EQ("0 0 1 1 1", GetCountSummary());
  reset();

  // Change primary.
  UpdateDisplay("1+1-1000x600");
  EXPECT_EQ("1 0 0 1 1", GetCountSummary());
  EXPECT_EQ(display_manager()->GetDisplayAt(0).id(), changed()[0].id());
  EXPECT_EQ("0,0 1000x600", changed()[0].bounds().ToString());
  reset();

  // Add secondary.
  UpdateDisplay("1+1-1000x600,1002+0-600x400");
  EXPECT_EQ(2U, display_manager()->GetNumDisplays());
  EXPECT_EQ("1 1 0 1 1", GetCountSummary());
  EXPECT_EQ(display_manager()->GetDisplayAt(1).id(), changed()[0].id());
  EXPECT_EQ(display_manager()->GetDisplayAt(1).id(), added()[0].id());
  // Secondary display is on right.
  EXPECT_EQ("1000,0 600x400", added()[0].bounds().ToString());
  EXPECT_EQ("1002,0 600x400",
            GetDisplayInfo(added()[0]).bounds_in_native().ToString());
  reset();

  // Secondary removed, primary changed.
  UpdateDisplay("1+1-800x300");
  EXPECT_EQ(1U, display_manager()->GetNumDisplays());
  EXPECT_EQ("1 0 1 1 1", GetCountSummary());
  EXPECT_EQ(display_manager()->GetDisplayAt(0).id(), changed()[0].id());
  EXPECT_EQ("0,0 800x300", changed()[0].bounds().ToString());
  reset();

  // # of display can go to zero when screen is off.
  const vector<display::ManagedDisplayInfo> empty;
  display_manager()->OnNativeDisplaysChanged(empty);
  EXPECT_EQ(1U, display_manager()->GetNumDisplays());
  // Going to 0 displays doesn't actually change the list and is effectively
  // ignored.
  EXPECT_EQ("0 0 0 0 0", GetCountSummary());
  EXPECT_FALSE(root_window_destroyed());
  // Display configuration stays the same
  EXPECT_EQ("0,0 800x300",
            display_manager()->GetDisplayAt(0).bounds().ToString());
  reset();

  // Connect to display again
  UpdateDisplay("100+100-500x400");
  EXPECT_EQ(1U, display_manager()->GetNumDisplays());
  EXPECT_EQ("1 0 0 1 1", GetCountSummary());
  EXPECT_FALSE(root_window_destroyed());
  EXPECT_EQ("0,0 500x400", changed()[0].bounds().ToString());
  EXPECT_EQ("100,100 500x400",
            GetDisplayInfo(changed()[0]).bounds_in_native().ToString());
  reset();

  // Go back to zero and wake up with multiple displays.
  display_manager()->OnNativeDisplaysChanged(empty);
  EXPECT_EQ(1U, display_manager()->GetNumDisplays());
  EXPECT_FALSE(root_window_destroyed());
  reset();

  // Add secondary.
  UpdateDisplay("0+0-1000x600,1000+1000-600x400");
  EXPECT_EQ(2U, display_manager()->GetNumDisplays());
  EXPECT_EQ("0,0 1000x600",
            display_manager()->GetDisplayAt(0).bounds().ToString());
  // Secondary display is on right.
  EXPECT_EQ("1000,0 600x400",
            display_manager()->GetDisplayAt(1).bounds().ToString());
  EXPECT_EQ("1000,1000 600x400",
            GetDisplayInfoAt(1).bounds_in_native().ToString());
  reset();

  // Changing primary will update secondary as well.
  UpdateDisplay("0+0-800x600,1000+1000-600x400");
  EXPECT_EQ("2 0 0 1 1", GetCountSummary());
  reset();
  EXPECT_EQ("0,0 800x600",
            display_manager()->GetDisplayAt(0).bounds().ToString());
  EXPECT_EQ("800,0 600x400",
            display_manager()->GetDisplayAt(1).bounds().ToString());
}

TEST_F(DisplayManagerTest, ScaleOnlyChange) {
  display_manager()->ToggleDisplayScaleFactor();
  EXPECT_TRUE(changed_metrics() &
              display::DisplayObserver::DISPLAY_METRIC_BOUNDS);
  EXPECT_TRUE(changed_metrics() &
              display::DisplayObserver::DISPLAY_METRIC_WORK_AREA);
}

// Test in emulation mode (use_fullscreen_host_window=false)
TEST_F(DisplayManagerTest, EmulatorTest) {
  EXPECT_EQ(1U, display_manager()->GetNumDisplays());

  display_manager()->AddRemoveDisplay();
  // Update primary and add seconary.
  EXPECT_EQ(2U, display_manager()->GetNumDisplays());
  EXPECT_EQ("1 1 0 1 1", GetCountSummary());
  reset();

  display_manager()->AddRemoveDisplay();
  EXPECT_EQ(1U, display_manager()->GetNumDisplays());
  EXPECT_EQ("0 0 1 1 1", GetCountSummary());
  reset();

  display_manager()->AddRemoveDisplay();
  EXPECT_EQ(2U, display_manager()->GetNumDisplays());
  EXPECT_EQ("1 1 0 1 1", GetCountSummary());
}

// Tests support for 3 displays.
TEST_F(DisplayManagerTest, UpdateThreeDisplaysWithDefaultLayout) {
  EXPECT_EQ(1U, display_manager()->GetNumDisplays());

  // Test with three displays. Native origin will not affect ash
  // display layout.
  UpdateDisplay("0+0-640x480,1000+0-320x200,2000+0-400x300");

  EXPECT_EQ(3U, display_manager()->GetNumDisplays());
  EXPECT_EQ("0,0 640x480",
            display_manager()->GetDisplayAt(0).bounds().ToString());
  EXPECT_EQ("640,0 320x200",
            display_manager()->GetDisplayAt(1).bounds().ToString());
  EXPECT_EQ("960,0 400x300",
            display_manager()->GetDisplayAt(2).bounds().ToString());

  EXPECT_EQ("3 2 0 1 1", GetCountSummary());
  // Metrics change immediately when new displays set shelf work area insets.
  // After that, DisplayManager::OnNativeDisplaysChanged trigger changes of the
  // primary display's metrics. So the observed order of changes is [1, 2, 0].
  EXPECT_EQ(display_manager()->GetDisplayAt(0).id(), changed()[2].id());
  EXPECT_EQ(display_manager()->GetDisplayAt(1).id(), changed()[0].id());
  EXPECT_EQ(display_manager()->GetDisplayAt(2).id(), changed()[1].id());
  EXPECT_EQ(display_manager()->GetDisplayAt(1).id(), added()[0].id());
  EXPECT_EQ(display_manager()->GetDisplayAt(2).id(), added()[1].id());
  EXPECT_EQ("0,0 640x480", changed()[2].bounds().ToString());
  EXPECT_EQ("640,0 320x200", changed()[0].bounds().ToString());
  EXPECT_EQ("960,0 400x300", changed()[1].bounds().ToString());
  // Secondary and terniary displays are on right.
  EXPECT_EQ("640,0 320x200", added()[0].bounds().ToString());
  EXPECT_EQ("1000,0 320x200",
            GetDisplayInfo(added()[0]).bounds_in_native().ToString());
  EXPECT_EQ("960,0 400x300", added()[1].bounds().ToString());
  EXPECT_EQ("2000,0 400x300",
            GetDisplayInfo(added()[1]).bounds_in_native().ToString());

  // Verify calling ReconfigureDisplays doesn't change anything.
  display_manager()->ReconfigureDisplays();
  EXPECT_EQ(3U, display_manager()->GetNumDisplays());
  EXPECT_EQ("0,0 640x480",
            display_manager()->GetDisplayAt(0).bounds().ToString());
  EXPECT_EQ("640,0 320x200",
            display_manager()->GetDisplayAt(1).bounds().ToString());
  EXPECT_EQ("960,0 400x300",
            display_manager()->GetDisplayAt(2).bounds().ToString());

  display::DisplayPlacement default_placement(display::DisplayPlacement::BOTTOM,
                                              10);
  display_manager()->layout_store()->SetDefaultDisplayPlacement(
      default_placement);

  // Test with new displays.
  UpdateDisplay("640x480");
  UpdateDisplay("640x480,320x200,400x300");

  EXPECT_EQ("0,0 640x480",
            display_manager()->GetDisplayAt(0).bounds().ToString());
  EXPECT_EQ("10,480 320x200",
            display_manager()->GetDisplayAt(1).bounds().ToString());
  EXPECT_EQ("20,680 400x300",
            display_manager()->GetDisplayAt(2).bounds().ToString());
}

TEST_F(DisplayManagerTest, LayoutMorethanThreeDisplaysTest) {
  int64_t primary_id = display::Screen::GetScreen()->GetPrimaryDisplay().id();
  display::DisplayIdList list = display::test::CreateDisplayIdListN(
      3, primary_id, primary_id + 1, primary_id + 2);
  {
    // Layout: [2]
    //         [1][P]
    display::DisplayLayoutBuilder builder(primary_id);
    builder.AddDisplayPlacement(list[1], primary_id,
                                display::DisplayPlacement::LEFT, 10);
    builder.AddDisplayPlacement(list[2], list[1],
                                display::DisplayPlacement::TOP, 10);
    display_manager()->layout_store()->RegisterLayoutForDisplayIdList(
        list, builder.Build());

    UpdateDisplay("640x480,320x200,400x300");

    EXPECT_EQ(3U, display_manager()->GetNumDisplays());

    EXPECT_EQ("0,0 640x480",
              display_manager()->GetDisplayAt(0).bounds().ToString());
    EXPECT_EQ("-320,10 320x200",
              display_manager()->GetDisplayAt(1).bounds().ToString());

    // The above layout causes an overlap between [P] and [2], making [2]'s
    // bounds be "-310,-290 400x300" if the overlap is not fixed. The overlap
    // must be detected and fixed and [2] is shifted up to remove the overlap.
    EXPECT_EQ("-310,-300 400x300",
              display_manager()->GetDisplayAt(2).bounds().ToString());
  }
  {
    // Layout: [1]
    //         [P][2]
    display::DisplayLayoutBuilder builder(primary_id);
    builder.AddDisplayPlacement(list[1], primary_id,
                                display::DisplayPlacement::TOP, 10);
    builder.AddDisplayPlacement(list[2], primary_id,
                                display::DisplayPlacement::RIGHT, 10);
    display_manager()->layout_store()->RegisterLayoutForDisplayIdList(
        list, builder.Build());

    UpdateDisplay("640x480,320x200,400x300");

    EXPECT_EQ(3U, display_manager()->GetNumDisplays());

    EXPECT_EQ("0,0 640x480",
              display_manager()->GetDisplayAt(0).bounds().ToString());
    EXPECT_EQ("10,-200 320x200",
              display_manager()->GetDisplayAt(1).bounds().ToString());
    EXPECT_EQ("640,10 400x300",
              display_manager()->GetDisplayAt(2).bounds().ToString());
  }
  {
    // Layout: [P]
    //         [2]
    //         [1]
    display::DisplayLayoutBuilder builder(primary_id);
    builder.AddDisplayPlacement(list[1], list[2],
                                display::DisplayPlacement::BOTTOM, 10);
    builder.AddDisplayPlacement(list[2], primary_id,
                                display::DisplayPlacement::BOTTOM, 10);
    display_manager()->layout_store()->RegisterLayoutForDisplayIdList(
        list, builder.Build());

    UpdateDisplay("640x480,320x200,400x300");

    EXPECT_EQ(3U, display_manager()->GetNumDisplays());

    EXPECT_EQ("0,0 640x480",
              display_manager()->GetDisplayAt(0).bounds().ToString());
    EXPECT_EQ("20,780 320x200",
              display_manager()->GetDisplayAt(1).bounds().ToString());
    EXPECT_EQ("10,480 400x300",
              display_manager()->GetDisplayAt(2).bounds().ToString());
  }

  {
    list = display::test::CreateDisplayIdListN(5, primary_id, primary_id + 1,
                                               primary_id + 2, primary_id + 3,
                                               primary_id + 4);
    // Layout: [P][2]
    //      [3][4]
    //      [1]
    display::DisplayLayoutBuilder builder(primary_id);
    builder.AddDisplayPlacement(list[2], primary_id,
                                display::DisplayPlacement::RIGHT, 10);
    builder.AddDisplayPlacement(list[1], list[3],
                                display::DisplayPlacement::BOTTOM, 10);
    builder.AddDisplayPlacement(list[3], list[4],
                                display::DisplayPlacement::LEFT, 10);
    builder.AddDisplayPlacement(list[4], primary_id,
                                display::DisplayPlacement::BOTTOM, 10);
    display_manager()->layout_store()->RegisterLayoutForDisplayIdList(
        list, builder.Build());

    UpdateDisplay("640x480,320x200,400x300,300x200,200x100");

    EXPECT_EQ(5U, display_manager()->GetNumDisplays());

    EXPECT_EQ("0,0 640x480",
              display_manager()->GetDisplayAt(0).bounds().ToString());
    // 2nd is right of the primary.
    EXPECT_EQ("640,10 400x300",
              display_manager()->GetDisplayAt(2).bounds().ToString());
    // 4th is bottom of the primary.
    EXPECT_EQ("10,480 200x100",
              display_manager()->GetDisplayAt(4).bounds().ToString());
    // 3rd is the left of 4th.
    EXPECT_EQ("-290,480 300x200",
              display_manager()->GetDisplayAt(3).bounds().ToString());
    // 1st is the bottom of 3rd.
    EXPECT_EQ("-280,680 320x200",
              display_manager()->GetDisplayAt(1).bounds().ToString());
  }
}

// Makes sure that layouts with overlapped displays are detected and fixed when
// applied.
TEST_F(DisplayManagerTest, NoOverlappedDisplays) {
  int64_t primary_id = display::Screen::GetScreen()->GetPrimaryDisplay().id();
  {
    // Layout with multiple overlaps and special cases:
    //
    //            +-----+
    //       +----+-+6  |
    //       |  5 | |   |
    //  +----+----+ |   |
    //  | 7  |    | |   |
    //  +----+----+-+---+---+-+---------+
    //       |      |   P   | |   2     |
    //       +------+       | |         +----------+
    //              |       | |         |     3    |
    //              |       | |         |          |
    //              +--+----+-+-+-+-----+--+       |
    //                 |    1   | |   4 |  |       |
    //                 |        | |     +--+-------+
    //                 |        | |        |
    //                 +--------+ +--------+

    display::DisplayIdList list = display::test::CreateDisplayIdListN(
        8, primary_id, primary_id + 1, primary_id + 2, primary_id + 3,
        primary_id + 4, primary_id + 5, primary_id + 6, primary_id + 7);
    display::DisplayLayoutBuilder builder(primary_id);
    builder.AddDisplayPlacement(list[1], primary_id,
                                display::DisplayPlacement::BOTTOM, 50);
    builder.AddDisplayPlacement(list[2], list[1],
                                display::DisplayPlacement::TOP, 300);
    builder.AddDisplayPlacement(list[3], list[2],
                                display::DisplayPlacement::RIGHT, 30);
    builder.AddDisplayPlacement(list[4], list[2],
                                display::DisplayPlacement::BOTTOM, 400);
    builder.AddDisplayPlacement(list[5], primary_id,
                                display::DisplayPlacement::LEFT, -300);
    builder.AddDisplayPlacement(list[6], primary_id,
                                display::DisplayPlacement::TOP, -250);
    builder.AddDisplayPlacement(list[7], list[6],
                                display::DisplayPlacement::LEFT, 250);
    display_manager()->layout_store()->RegisterLayoutForDisplayIdList(
        list, builder.Build());

    UpdateDisplay(
        "480x400,480x400,480x400,480x400,480x400,480x400,480x400,530x150");

    // The resulting layout after overlaps had been removed:
    //
    //
    //  +---------+
    //  | 7       +-----+
    //  +-+-------+  6  |
    //    |   5   |     |
    //    |       |     |
    //    |       |     |
    //    |       |-+---+----+---------+
    //    |       | |   P    |   2     |
    //    +-------+ |        |         +----------+
    //              |        |         |     3    |
    //              |        |         |          |
    //              +--+-----+-+-------+          |
    //                 |   1   |       |          |
    //                 |       |  +----+---+------+
    //                 |       |  |   4    |
    //                 +-------+  |        |
    //                            |        |
    //                            +--------+

    EXPECT_EQ(8U, display_manager()->GetNumDisplays());

    EXPECT_EQ(gfx::Rect(0, 0, 480, 400),
              display_manager()->GetDisplayAt(0).bounds());
    EXPECT_EQ(gfx::Rect(50, 400, 480, 400),
              display_manager()->GetDisplayAt(1).bounds());
    EXPECT_EQ(gfx::Rect(480, 0, 480, 400),
              display_manager()->GetDisplayAt(2).bounds());
    EXPECT_EQ(gfx::Rect(960, 30, 480, 400),
              display_manager()->GetDisplayAt(3).bounds());
    EXPECT_EQ(gfx::Rect(730, 430, 480, 400),
              display_manager()->GetDisplayAt(4).bounds());
    EXPECT_EQ(gfx::Rect(-730, -300, 480, 400),
              display_manager()->GetDisplayAt(5).bounds());
    EXPECT_EQ(gfx::Rect(-250, -400, 480, 400),
              display_manager()->GetDisplayAt(6).bounds());
    EXPECT_EQ(gfx::Rect(-780, -450, 530, 150),
              display_manager()->GetDisplayAt(7).bounds());

    // Expect that the displays have been reparented correctly, such that a
    // child is always touching its parent.
    display::DisplayLayoutBuilder expected_layout_builder(primary_id);
    expected_layout_builder.AddDisplayPlacement(
        list[1], primary_id, display::DisplayPlacement::BOTTOM, 50);
    expected_layout_builder.AddDisplayPlacement(
        list[2], list[1], display::DisplayPlacement::TOP, 430);
    expected_layout_builder.AddDisplayPlacement(
        list[3], list[2], display::DisplayPlacement::RIGHT, 30);
    // [4] became a child of [3] instead of [2] as they no longer touch.
    expected_layout_builder.AddDisplayPlacement(
        list[4], list[3], display::DisplayPlacement::BOTTOM, -230);
    // [5] became a child of [6] instead of [P] as they no longer touch.
    expected_layout_builder.AddDisplayPlacement(
        list[5], list[6], display::DisplayPlacement::LEFT, 100);
    expected_layout_builder.AddDisplayPlacement(
        list[6], primary_id, display::DisplayPlacement::TOP, -250);
    expected_layout_builder.AddDisplayPlacement(
        list[7], list[6], display::DisplayPlacement::LEFT, -50);

    const display::DisplayLayout& layout =
        display_manager()->GetCurrentResolvedDisplayLayout();

    EXPECT_TRUE(
        layout.HasSamePlacementList(*(expected_layout_builder.Build())));
  }

  {
    // The following is a special case where a child display is closer to the
    // origin than its parent. Test that we can handle it successfully without
    // introducing a circular dependency.
    //
    // +---------+
    // |    P    |    +---------+
    // |         |    |    3    |
    // |         |    |         |
    // |         |    |         |
    // +------+--+----+         |
    // |    1 |  | 2  +---------+
    // |      |  |    |
    // |      |  |    |
    // |      |  |    |
    // +------+--+----+
    //

    display::DisplayIdList list = display::test::CreateDisplayIdListN(
        4, primary_id, primary_id + 1, primary_id + 2, primary_id + 3);
    display::DisplayLayoutBuilder builder(primary_id);
    builder.AddDisplayPlacement(list[1], primary_id,
                                display::DisplayPlacement::BOTTOM, 0);
    builder.AddDisplayPlacement(list[2], primary_id,
                                display::DisplayPlacement::BOTTOM, 464);
    builder.AddDisplayPlacement(list[3], list[2],
                                display::DisplayPlacement::RIGHT, -700);
    display_manager()->layout_store()->RegisterLayoutForDisplayIdList(
        list, builder.Build());
    UpdateDisplay("696x800,696x800,300x800,696x800");

    // The expected layout should be:
    //
    // +---------+
    // |    P    |       +---------+
    // |         |       |    3    |
    // |         |       |         |
    // |         |       |         |
    // +---------+-------+         |
    // |    1    |   2   +---------+
    // |         |       |
    // |         |       |
    // |         |       |
    // +---------+-------+
    //
    //

    EXPECT_EQ(4U, display_manager()->GetNumDisplays());
    EXPECT_EQ(gfx::Rect(0, 0, 696, 800),
              display_manager()->GetDisplayAt(0).bounds());
    EXPECT_EQ(gfx::Rect(0, 800, 696, 800),
              display_manager()->GetDisplayAt(1).bounds());
    EXPECT_EQ(gfx::Rect(696, 800, 300, 800),
              display_manager()->GetDisplayAt(2).bounds());
    EXPECT_EQ(gfx::Rect(996, 100, 696, 800),
              display_manager()->GetDisplayAt(3).bounds());

    // This case if not handled correctly might lead to a cyclic dependency.
    // Make sure this doesn't happen.
    display::DisplayLayoutBuilder expected_layout_builder(primary_id);
    expected_layout_builder.AddDisplayPlacement(
        list[1], primary_id, display::DisplayPlacement::BOTTOM, 0);
    expected_layout_builder.AddDisplayPlacement(
        list[2], primary_id, display::DisplayPlacement::BOTTOM, 696);
    expected_layout_builder.AddDisplayPlacement(
        list[3], list[2], display::DisplayPlacement::RIGHT, -700);

    const display::DisplayLayout& layout =
        display_manager()->GetCurrentResolvedDisplayLayout();
    EXPECT_TRUE(
        layout.HasSamePlacementList(*(expected_layout_builder.Build())));
  }

  {
    // The following is a layout with an overlap to the left of the primary
    // display.
    //
    // +---------+---------+
    // |    1    |    P    |
    // |         |         |
    // +---------+         |
    // |         |         |
    // +---------+---------+
    // |    2    |
    // |         |
    // +---------+

    display::DisplayIdList list = display::test::CreateDisplayIdListN(
        3, primary_id, primary_id + 1, primary_id + 2);
    display::DisplayLayoutBuilder builder(primary_id);
    builder.AddDisplayPlacement(list[1], primary_id,
                                display::DisplayPlacement::LEFT, 0);
    builder.AddDisplayPlacement(list[2], primary_id,
                                display::DisplayPlacement::LEFT, 250);
    display_manager()->layout_store()->RegisterLayoutForDisplayIdList(
        list, builder.Build());
    UpdateDisplay("696x500,696x500,696x500");

    // The expected layout should be:
    //
    // +---------+---------+
    // |    1    |    P    |
    // |         |         |
    // |         |         |
    // |         |         |
    // +---------+---------+
    // |    2    |
    // |         |
    // |         |
    // |         |
    // +---------+

    EXPECT_EQ(3U, display_manager()->GetNumDisplays());
    EXPECT_EQ(gfx::Rect(0, 0, 696, 500),
              display_manager()->GetDisplayAt(0).bounds());
    EXPECT_EQ(gfx::Rect(-696, 0, 696, 500),
              display_manager()->GetDisplayAt(1).bounds());
    EXPECT_EQ(gfx::Rect(-696, 500, 696, 500),
              display_manager()->GetDisplayAt(2).bounds());
  }

  {
    // The following is a layout with an overlap occurring above the primary
    // display.
    //
    //    +------+--+------+
    //    |  2   |  | 1    |
    //    |      |  |      |
    //    |      |  |      |
    //    |      |  |      |
    //    +------+--+------+
    //           |    P    |
    //           |         |
    //           |         |
    //           |         |
    //           +---------+
    //

    display::DisplayIdList list = display::test::CreateDisplayIdListN(
        3, primary_id, primary_id + 1, primary_id + 2);
    display::DisplayLayoutBuilder builder(primary_id);
    builder.AddDisplayPlacement(list[1], primary_id,
                                display::DisplayPlacement::TOP, 0);
    builder.AddDisplayPlacement(list[2], primary_id,
                                display::DisplayPlacement::TOP, -348);
    display_manager()->layout_store()->RegisterLayoutForDisplayIdList(
        list, builder.Build());
    UpdateDisplay("696x500,696x500,696x500");

    // The expected layout should be:
    //
    // +---------+---------+
    // |    2    |    1    |
    // |         |         |
    // |         |         |
    // |         |         |
    // +---------+---------+
    //           |    P    |
    //           |         |
    //           |         |
    //           |         |
    //           +---------+
    //

    EXPECT_EQ(3U, display_manager()->GetNumDisplays());
    EXPECT_EQ(gfx::Rect(0, 0, 696, 500),
              display_manager()->GetDisplayAt(0).bounds());
    EXPECT_EQ(gfx::Rect(0, -500, 696, 500),
              display_manager()->GetDisplayAt(1).bounds());
    EXPECT_EQ(gfx::Rect(-696, -500, 696, 500),
              display_manager()->GetDisplayAt(2).bounds());
  }
}

TEST_F(DisplayManagerTest, NoOverlappedDisplaysNotFitBetweenTwo) {
  //    +------+--+----+--+------+
  //    |  1   |  |  2 |  |  3   |
  //    |      |  |    |  |      |
  //    |      |  |    |  |      |
  //    |      |  |    |  |      |
  //    +-+----+--+----+--+---+--+
  //      |         P         |
  //      |                   |
  //      |                   |
  //      |                   |
  //      +-------------------+
  //

  int64_t primary_id = display::Screen::GetScreen()->GetPrimaryDisplay().id();
  display::DisplayIdList list = display::test::CreateDisplayIdListN(
      4, primary_id, primary_id + 1, primary_id + 2, primary_id + 3);
  display::DisplayLayoutBuilder builder(primary_id);
  builder.AddDisplayPlacement(list[1], primary_id,
                              display::DisplayPlacement::TOP, -110);
  builder.AddDisplayPlacement(list[2], primary_id,
                              display::DisplayPlacement::TOP, 300);
  builder.AddDisplayPlacement(list[3], primary_id,
                              display::DisplayPlacement::TOP, 600);
  display_manager()->layout_store()->RegisterLayoutForDisplayIdList(
      list, builder.Build());
  UpdateDisplay("1200x500,600x500,600x500,600x500");

  // The expected layout should be:
  //
  //    +---------+---------+---------+
  //    |    1    |    2    |    3    |
  //    |         |         |         |
  //    |         |         |         |
  //    |         |         |         |
  //    +-+-------+---------+-+-------+
  //      |         P         |
  //      |                   |
  //      |                   |
  //      |                   |
  //      +-------------------+
  //

  EXPECT_EQ(4U, display_manager()->GetNumDisplays());
  EXPECT_EQ(gfx::Rect(0, 0, 1200, 500),
            display_manager()->GetDisplayAt(0).bounds());
  EXPECT_EQ(gfx::Rect(-110, -500, 600, 500),
            display_manager()->GetDisplayAt(1).bounds());
  EXPECT_EQ(gfx::Rect(490, -500, 600, 500),
            display_manager()->GetDisplayAt(2).bounds());
  EXPECT_EQ(gfx::Rect(1090, -500, 600, 500),
            display_manager()->GetDisplayAt(3).bounds());
}

TEST_F(DisplayManagerTest, NoOverlappedDisplaysAfterResolutionChange) {
  // Starting with a good layout with no overlaps, test that if the resolution
  // of one of the displays is changed, it won't result in any overlaps.
  //
  //         +-------------------+
  //         |         4         |
  //         |                   |
  //         |                   |
  //         |                   |
  //    +----+----+---------+----+----+
  //    |    1    |    2    |    3    |
  //    |         |         |         |
  //    |         |         |         |
  //    |         |         |         |
  //    +----+----+---------+----+----+
  //         |         p         |
  //         |                   |
  //         |                   |
  //         |                   |
  //         +-------------------+
  //

  int64_t primary_id = display::Screen::GetScreen()->GetPrimaryDisplay().id();
  display::DisplayIdList list = display::test::CreateDisplayIdListN(
      5, primary_id, primary_id + 1, primary_id + 2, primary_id + 3,
      primary_id + 4);
  display::DisplayLayoutBuilder builder(primary_id);
  builder.AddDisplayPlacement(list[1], primary_id,
                              display::DisplayPlacement::TOP, -250);
  builder.AddDisplayPlacement(list[2], primary_id,
                              display::DisplayPlacement::TOP, 250);
  builder.AddDisplayPlacement(list[3], primary_id,
                              display::DisplayPlacement::TOP, 750);
  builder.AddDisplayPlacement(list[4], list[1], display::DisplayPlacement::TOP,
                              250);
  display_manager()->layout_store()->RegisterLayoutForDisplayIdList(
      list, builder.Build());
  UpdateDisplay("1000x500,500x500,500x500,500x500,1000x500");

  // There should be no overlap at all.
  EXPECT_EQ(5U, display_manager()->GetNumDisplays());
  EXPECT_EQ(gfx::Rect(0, 0, 1000, 500),
            display_manager()->GetDisplayAt(0).bounds());
  EXPECT_EQ(gfx::Rect(-250, -500, 500, 500),
            display_manager()->GetDisplayAt(1).bounds());
  EXPECT_EQ(gfx::Rect(250, -500, 500, 500),
            display_manager()->GetDisplayAt(2).bounds());
  EXPECT_EQ(gfx::Rect(750, -500, 500, 500),
            display_manager()->GetDisplayAt(3).bounds());
  EXPECT_EQ(gfx::Rect(0, -1000, 1000, 500),
            display_manager()->GetDisplayAt(4).bounds());

  // Change the resolution of display (2) and expect the following layout.
  //
  //         +-------------------+
  //         |         4         |
  //         |                   |
  //         |                   |
  //         |                   |
  //         +----+-------------++
  //              |      2      |
  //    +---------+             +---------+
  //    |    1    |             |    3    |
  //    |         |             |         |
  //    |         |             |         |
  //    |         |             |         |
  //    +----+----+-------------++--------+
  //         |         p         |
  //         |                   |
  //         |                   |
  //         |                   |
  //         +-------------------+
  //

  UpdateDisplay("1000x500,500x500,600x600,500x500,1000x500");

  EXPECT_EQ(5U, display_manager()->GetNumDisplays());
  EXPECT_EQ(gfx::Rect(0, 0, 1000, 500),
            display_manager()->GetDisplayAt(0).bounds());
  EXPECT_EQ(gfx::Rect(-250, -500, 500, 500),
            display_manager()->GetDisplayAt(1).bounds());
  EXPECT_EQ(gfx::Rect(250, -600, 600, 600),
            display_manager()->GetDisplayAt(2).bounds());
  EXPECT_EQ(gfx::Rect(850, -500, 500, 500),
            display_manager()->GetDisplayAt(3).bounds());
  EXPECT_EQ(gfx::Rect(0, -1100, 1000, 500),
            display_manager()->GetDisplayAt(4).bounds());
}

TEST_F(DisplayManagerTest, NoOverlappedDisplaysWithDetachedDisplays) {
  // Detached displays that intersect other non-detached displays.
  //
  //    +---------+---------+---------+
  //    |    1    |    2    |    3    |
  //    |         |         |         |
  //    |         |         |         |
  //    |         |         |         |
  //    +----+----+-----+---+----+----+
  //         |  4, 5    | P      |
  //         | detached |        |
  //         |          |        |
  //         +----------+        |
  //         +-------------------+
  //

  int64_t primary_id = display::Screen::GetScreen()->GetPrimaryDisplay().id();
  display::DisplayIdList list = display::test::CreateDisplayIdListN(
      6, primary_id, primary_id + 1, primary_id + 2, primary_id + 3,
      primary_id + 4, primary_id + 5);
  display::DisplayLayoutBuilder builder(primary_id);
  builder.AddDisplayPlacement(list[1], primary_id,
                              display::DisplayPlacement::TOP, -250);
  builder.AddDisplayPlacement(list[2], primary_id,
                              display::DisplayPlacement::TOP, 250);
  builder.AddDisplayPlacement(list[3], primary_id,
                              display::DisplayPlacement::TOP, 750);
  display_manager()->layout_store()->RegisterLayoutForDisplayIdList(
      list, builder.Build());
  UpdateDisplay("1000x500,500x500,500x500,500x500,500x400,500x400");

  // Detached displays will be de-intersected and reparented appropriately.
  //
  //    +---------+---------+---------+
  //    |    1    |    2    |    3    |
  //    |         |         |         |
  //    |         |         |         |
  //    |         |         |         |
  //    +----+----+---------+----+----+
  //         |         P         |
  //         |                   |
  //         |                   |
  //         |                   |
  //         +----------+--------+
  //         |     4    |
  //         |          |
  //         |          |
  //         +----------+
  //         |     5    |
  //         |          |
  //         |          |
  //         +----------+
  //

  EXPECT_EQ(6U, display_manager()->GetNumDisplays());
  EXPECT_EQ(gfx::Rect(0, 0, 1000, 500),
            display_manager()->GetDisplayAt(0).bounds());
  EXPECT_EQ(gfx::Rect(-250, -500, 500, 500),
            display_manager()->GetDisplayAt(1).bounds());
  EXPECT_EQ(gfx::Rect(250, -500, 500, 500),
            display_manager()->GetDisplayAt(2).bounds());
  EXPECT_EQ(gfx::Rect(750, -500, 500, 500),
            display_manager()->GetDisplayAt(3).bounds());
  EXPECT_EQ(gfx::Rect(0, 500, 500, 400),
            display_manager()->GetDisplayAt(4).bounds());
  EXPECT_EQ(gfx::Rect(0, 900, 500, 400),
            display_manager()->GetDisplayAt(5).bounds());

  // This case if not handled correctly might lead to a cyclic dependency.
  // Make sure this doesn't happen.
  display::DisplayLayoutBuilder expected_layout_builder(primary_id);
  expected_layout_builder.AddDisplayPlacement(
      list[1], primary_id, display::DisplayPlacement::TOP, -250);
  expected_layout_builder.AddDisplayPlacement(
      list[2], primary_id, display::DisplayPlacement::TOP, 250);
  expected_layout_builder.AddDisplayPlacement(
      list[3], primary_id, display::DisplayPlacement::TOP, 750);
  expected_layout_builder.AddDisplayPlacement(
      list[4], primary_id, display::DisplayPlacement::BOTTOM, 0);
  expected_layout_builder.AddDisplayPlacement(
      list[5], list[4], display::DisplayPlacement::BOTTOM, 0);

  const display::DisplayLayout& layout =
      display_manager()->GetCurrentResolvedDisplayLayout();
  EXPECT_TRUE(layout.HasSamePlacementList(*(expected_layout_builder.Build())));
}

TEST_F(DisplayManagerTest, OverscanInsetsTest) {
  UpdateDisplay("0+0-500x500,0+501-400x400");
  reset();
  ASSERT_EQ(2u, display_manager()->GetNumDisplays());
  const display::ManagedDisplayInfo display_info1 = GetDisplayInfoAt(0);
  const display::ManagedDisplayInfo display_info2 = GetDisplayInfoAt(1);

  display_manager()->SetOverscanInsets(display_info2.id(),
                                       gfx::Insets(13, 12, 11, 10));

  std::vector<display::Display> changed_displays = changed();
  ASSERT_EQ(1u, changed_displays.size());
  EXPECT_EQ(display_info2.id(), changed_displays[0].id());
  EXPECT_EQ("0,0 500x500", GetDisplayInfoAt(0).bounds_in_native().ToString());
  display::ManagedDisplayInfo updated_display_info2 = GetDisplayInfoAt(1);
  EXPECT_EQ("0,501 400x400",
            updated_display_info2.bounds_in_native().ToString());
  EXPECT_EQ("378x376", updated_display_info2.size_in_pixel().ToString());
  EXPECT_EQ("13,12,11,10",
            updated_display_info2.overscan_insets_in_dip().ToString());
  EXPECT_EQ("500,0 378x376",
            display_manager()->GetSecondaryDisplay().bounds().ToString());

  // Make sure that SetOverscanInsets() is idempotent.
  display_manager()->SetOverscanInsets(display_info1.id(), gfx::Insets());
  display_manager()->SetOverscanInsets(display_info2.id(),
                                       gfx::Insets(13, 12, 11, 10));
  EXPECT_EQ("0,0 500x500", GetDisplayInfoAt(0).bounds_in_native().ToString());
  updated_display_info2 = GetDisplayInfoAt(1);
  EXPECT_EQ("0,501 400x400",
            updated_display_info2.bounds_in_native().ToString());
  EXPECT_EQ("378x376", updated_display_info2.size_in_pixel().ToString());
  EXPECT_EQ("13,12,11,10",
            updated_display_info2.overscan_insets_in_dip().ToString());

  display_manager()->SetOverscanInsets(display_info2.id(),
                                       gfx::Insets(10, 11, 12, 13));
  EXPECT_EQ("0,0 500x500", GetDisplayInfoAt(0).bounds_in_native().ToString());
  EXPECT_EQ("376x378", GetDisplayInfoAt(1).size_in_pixel().ToString());
  EXPECT_EQ("10,11,12,13",
            GetDisplayInfoAt(1).overscan_insets_in_dip().ToString());

  // Recreate a new 2nd display. It won't apply the overscan inset because the
  // new display has a different ID.
  UpdateDisplay("0+0-500x500");
  UpdateDisplay("0+0-500x500,0+501-400x400");
  EXPECT_EQ("0,0 500x500", GetDisplayInfoAt(0).bounds_in_native().ToString());
  EXPECT_EQ("0,501 400x400", GetDisplayInfoAt(1).bounds_in_native().ToString());

  // Recreate the displays with the same ID.  It should apply the overscan
  // inset.
  UpdateDisplay("0+0-500x500");

  std::vector<display::ManagedDisplayInfo> display_info_list;
  display_info_list.push_back(display_info1);
  display_info_list.push_back(display_info2);

  display_manager()->OnNativeDisplaysChanged(display_info_list);
  EXPECT_EQ("0,0 500x500", GetDisplayInfoAt(0).bounds_in_native().ToString());
  updated_display_info2 = GetDisplayInfoAt(1);
  EXPECT_EQ("376x378", updated_display_info2.size_in_pixel().ToString());
  EXPECT_EQ("10,11,12,13",
            updated_display_info2.overscan_insets_in_dip().ToString());

  // HiDPI but overscan display. The specified insets size should be doubled.
  UpdateDisplay("0+0-500x500,0+501-400x400*2");
  display_manager()->SetOverscanInsets(display_manager()->GetDisplayAt(1).id(),
                                       gfx::Insets(4, 5, 6, 7));
  EXPECT_EQ("0,0 500x500", GetDisplayInfoAt(0).bounds_in_native().ToString());
  updated_display_info2 = GetDisplayInfoAt(1);
  EXPECT_EQ("0,501 400x400",
            updated_display_info2.bounds_in_native().ToString());
  EXPECT_EQ("376x380", updated_display_info2.size_in_pixel().ToString());
  EXPECT_EQ("4,5,6,7",
            updated_display_info2.overscan_insets_in_dip().ToString());
  EXPECT_EQ("8,10,12,14",
            updated_display_info2.GetOverscanInsetsInPixel().ToString());

  // Make sure switching primary display applies the overscan offset only once.
  ash::Shell::Get()->window_tree_host_manager()->SetPrimaryDisplayId(
      display_manager()->GetSecondaryDisplay().id());
  EXPECT_EQ("-500,0 500x500",
            display_manager()->GetSecondaryDisplay().bounds().ToString());
  EXPECT_EQ("0,0 500x500",
            GetDisplayInfo(display_manager()->GetSecondaryDisplay())
                .bounds_in_native()
                .ToString());
  EXPECT_EQ("0,501 400x400",
            GetDisplayInfo(display::Screen::GetScreen()->GetPrimaryDisplay())
                .bounds_in_native()
                .ToString());
  EXPECT_EQ(
      "0,0 188x190",
      display::Screen::GetScreen()->GetPrimaryDisplay().bounds().ToString());

  // Make sure just moving the overscan area should property notify observers.
  UpdateDisplay("0+0-500x500");
  int64_t primary_id = display::Screen::GetScreen()->GetPrimaryDisplay().id();
  display_manager()->SetOverscanInsets(primary_id, gfx::Insets(0, 0, 20, 20));
  EXPECT_EQ(
      "0,0 480x480",
      display::Screen::GetScreen()->GetPrimaryDisplay().bounds().ToString());
  reset();
  display_manager()->SetOverscanInsets(primary_id, gfx::Insets(10, 10, 10, 10));
  EXPECT_TRUE(changed_metrics() &
              display::DisplayObserver::DISPLAY_METRIC_BOUNDS);
  EXPECT_TRUE(changed_metrics() &
              display::DisplayObserver::DISPLAY_METRIC_WORK_AREA);
  EXPECT_EQ(
      "0,0 480x480",
      display::Screen::GetScreen()->GetPrimaryDisplay().bounds().ToString());
  reset();
  display_manager()->SetOverscanInsets(primary_id, gfx::Insets(0, 0, 0, 0));
  EXPECT_TRUE(changed_metrics() &
              display::DisplayObserver::DISPLAY_METRIC_BOUNDS);
  EXPECT_TRUE(changed_metrics() &
              display::DisplayObserver::DISPLAY_METRIC_WORK_AREA);
  EXPECT_EQ(
      "0,0 500x500",
      display::Screen::GetScreen()->GetPrimaryDisplay().bounds().ToString());
}

TEST_F(DisplayManagerTest, ZeroOverscanInsets) {
  // Make sure the display change events is emitted for overscan inset changes.
  UpdateDisplay("0+0-500x500,0+501-400x400");
  ASSERT_EQ(2u, display_manager()->GetNumDisplays());
  int64_t display2_id = display_manager()->GetDisplayAt(1).id();

  reset();
  display_manager()->SetOverscanInsets(display2_id, gfx::Insets(0, 0, 0, 0));
  EXPECT_EQ(0u, changed().size());

  reset();
  display_manager()->SetOverscanInsets(display2_id, gfx::Insets(1, 0, 0, 0));
  ASSERT_EQ(1u, changed().size());
  EXPECT_EQ(display2_id, changed()[0].id());

  reset();
  display_manager()->SetOverscanInsets(display2_id, gfx::Insets(0, 0, 0, 0));
  ASSERT_EQ(1u, changed().size());
  EXPECT_EQ(display2_id, changed()[0].id());
}

TEST_F(DisplayManagerTest, TouchCalibrationTest) {
  UpdateDisplay("0+0-500x500,0+501-1024x600");
  reset();
  display::TouchDeviceManager* touch_device_manager =
      display_manager()->touch_device_manager();
  display::test::TouchDeviceManagerTestApi tdm_test_api(touch_device_manager);

  const ui::TouchscreenDevice touchdevice(
      11, ui::InputDeviceType::INPUT_DEVICE_USB,
      std::string("test touch device"), gfx::Size(123, 456), 1);
  const display::TouchDeviceIdentifier touch_device_identifier_2 =
      display::TouchDeviceIdentifier::FromDevice(touchdevice);

  ASSERT_EQ(2u, display_manager()->GetNumDisplays());
  const display::ManagedDisplayInfo display_info1 = GetDisplayInfoAt(0);
  const display::ManagedDisplayInfo display_info2 = GetDisplayInfoAt(1);

  EXPECT_FALSE(tdm_test_api.GetTouchDeviceCount(display_info2));

  const display::TouchCalibrationData::CalibrationPointPairQuad
      point_pair_quad = {
          {std::make_pair(gfx::Point(50, 50), gfx::Point(43, 51)),
           std::make_pair(gfx::Point(950, 50), gfx::Point(975, 45)),
           std::make_pair(gfx::Point(50, 550), gfx::Point(48, 534)),
           std::make_pair(gfx::Point(950, 550), gfx::Point(967, 574))}};
  const gfx::Size bounds_at_calibration(display_info2.size_in_pixel());
  const display::TouchCalibrationData touch_data(point_pair_quad,
                                                 bounds_at_calibration);

  // Set the touch calibration data for the secondary display.
  display_manager()->SetTouchCalibrationData(
      display_info2.id(), point_pair_quad, bounds_at_calibration,
      touch_device_identifier_2);

  EXPECT_TRUE(tdm_test_api.GetTouchDeviceCount(display_info2));
  EXPECT_EQ(touch_data, touch_device_manager->GetCalibrationData(
                            touchdevice, display_info2.id()));

  // Clearing touch calibration data from the secondary display.
  touch_device_manager->ClearTouchCalibrationData(touch_device_identifier_2,
                                                  GetDisplayInfoAt(1).id());

  EXPECT_TRUE(touch_device_manager
                  ->GetCalibrationData(touchdevice, GetDisplayInfoAt(1).id())
                  .IsEmpty());

  // Make sure that SetTouchCalibrationData() is idempotent.
  display::TouchCalibrationData::CalibrationPointPairQuad point_pair_quad_2 =
      point_pair_quad;
  point_pair_quad_2[1] =
      std::make_pair(gfx::Point(950, 50), gfx::Point(975, 53));
  display::TouchCalibrationData touch_data_2(point_pair_quad_2,
                                             bounds_at_calibration);
  display_manager()->SetTouchCalibrationData(
      display_info2.id(), point_pair_quad_2, bounds_at_calibration,
      touch_device_identifier_2);

  EXPECT_EQ(touch_data_2, touch_device_manager->GetCalibrationData(
                              touchdevice, GetDisplayInfoAt(1).id()));

  // Recreate a new 2nd display. It won't apply the touhc calibration data
  // because the new display has a different ID.
  UpdateDisplay("0+0-500x500");
  UpdateDisplay("0+0-500x500,0+501-400x400");
  tdm_test_api.ResetTouchDeviceManager();

  // Recreate the displays with the same ID.  It should apply the touch
  // calibration associated data.
  UpdateDisplay("0+0-500x500");
  std::vector<display::ManagedDisplayInfo> display_info_list;
  display_info_list.push_back(display_info1);
  display_info_list.push_back(display_info2);
  display_manager()->OnNativeDisplaysChanged(display_info_list);

  // Make sure multiple touch devices works.
  display_manager()->SetTouchCalibrationData(
      display_info2.id(), point_pair_quad, bounds_at_calibration,
      touch_device_identifier_2);

  EXPECT_EQ(touch_data, touch_device_manager->GetCalibrationData(
                            touchdevice, GetDisplayInfoAt(1).id()));

  const ui::TouchscreenDevice touchdevice_2(
      12, ui::InputDeviceType::INPUT_DEVICE_USB,
      std::string("test touch device 2"), gfx::Size(234, 567), 1);
  display::TouchDeviceIdentifier touch_device_identifier_2_2 =
      display::TouchDeviceIdentifier::FromDevice(touchdevice_2);

  display_manager()->SetTouchCalibrationData(
      display_info2.id(), point_pair_quad_2, bounds_at_calibration,
      touch_device_identifier_2_2);
  EXPECT_EQ(touch_data_2, touch_device_manager->GetCalibrationData(
                              touchdevice_2, GetDisplayInfoAt(1).id()));
  EXPECT_EQ(touch_data, touch_device_manager->GetCalibrationData(
                            touchdevice, GetDisplayInfoAt(1).id()));
}

TEST_F(DisplayManagerTest, UpdateDisplayZoomTest) {
  // Initialize a display pair.
  UpdateDisplay("1920x1080#1280x720|640x480%60, 600x400*2#600x400");
  reset();

  // The second display has a device scale factor of 2 set.
  constexpr float display_2_dsf = 2.0f;

  ASSERT_EQ(2u, display_manager()->GetNumDisplays());
  const display::ManagedDisplayInfo& info_1 = GetDisplayInfoAt(0);

  // The display should have 2 display modes based on the initialization spec.
  ASSERT_EQ(2u, info_1.display_modes().size());

  const display::ManagedDisplayInfo::ManagedDisplayModeList& modes =
      info_1.display_modes();

  // Set the display mode.
  display::test::SetDisplayResolution(display_manager(), info_1.id(),
                                      modes[0].size());
  display_manager()->UpdateDisplays();

  // Since no zoom factor or device scale factor has been set on the display,
  // the total/effective device scale factor on the display is 1.
  EXPECT_EQ(
      display_manager()->GetDisplayForId(info_1.id()).device_scale_factor(),
      1.f);

  float zoom_factor_1 = 2.0f;
  display_manager()->UpdateZoomFactor(info_1.id(), zoom_factor_1);
  EXPECT_EQ(display_manager()->GetDisplayInfo(info_1.id()).zoom_factor(),
            zoom_factor_1);

  // With the zoom factor set for the display. The effective zoom factor
  // returned should have the display zoom taken into consideration.
  EXPECT_EQ(
      display_manager()->GetDisplayForId(info_1.id()).device_scale_factor(),
      zoom_factor_1);

  // Update the zoom factor for a different display mode.
  float zoom_factor_2 = 1.5f;
  display_manager()->UpdateZoomFactor(info_1.id(), zoom_factor_2);

  EXPECT_EQ(display_manager()->GetDisplayInfo(info_1.id()).zoom_factor(),
            zoom_factor_2);

  // Change the display mode of the device.
  display::test::SetDisplayResolution(display_manager(), info_1.id(),
                                      modes[1].size());
  display_manager()->UpdateDisplays();

  // Since the display mode was changed, the zoom factor for the display is
  // reset to the default of 1.
  EXPECT_EQ(
      display_manager()->GetDisplayForId(info_1.id()).device_scale_factor(),
      1.f);

  // When setting the display mode back to the old one, the final effective
  // device scale factor should be using the correct zoom factor.
  display::test::SetDisplayResolution(display_manager(), info_1.id(),
                                      modes[0].size());
  display_manager()->UpdateDisplays();

  // Set the zoom factor back to |zoom_factor_2| for first display.
  display_manager()->UpdateZoomFactor(info_1.id(), zoom_factor_2);
  EXPECT_EQ(display_manager()->GetDisplayInfo(info_1.id()).zoom_factor(),
            zoom_factor_2);
  EXPECT_EQ(
      display_manager()->GetDisplayForId(info_1.id()).device_scale_factor(),
      zoom_factor_2);

  // Update the zoom factor for the second display.
  float zoom_factor_3 = 1.5f;
  const display::ManagedDisplayInfo& info_2 = GetDisplayInfoAt(1);
  display_manager()->UpdateZoomFactor(info_2.id(), zoom_factor_3);
  EXPECT_EQ(display_manager()->GetDisplayInfo(info_2.id()).zoom_factor(),
            zoom_factor_3);
  EXPECT_EQ(
      display_manager()->GetDisplayForId(info_2.id()).device_scale_factor(),
      zoom_factor_3 * display_2_dsf);

  // Modifying zoom factor for a display should not effect zoom factors of
  // other displays.
  EXPECT_EQ(display_manager()->GetDisplayInfo(info_1.id()).zoom_factor(),
            zoom_factor_2);

  // Update the zoom factor for display to see if it gets reflected.
  display_manager()->UpdateZoomFactor(info_1.id(), zoom_factor_3);

  EXPECT_EQ(display_manager()->GetDisplayInfo(info_1.id()).zoom_factor(),
            zoom_factor_3);
  display::test::SetDisplayResolution(display_manager(), info_1.id(),
                                      modes[0].size());
  display_manager()->UpdateDisplays();

  EXPECT_EQ(
      display_manager()->GetDisplayForId(info_1.id()).device_scale_factor(),
      1.f);
  EXPECT_EQ(
      display_manager()->GetDisplayForId(info_2.id()).device_scale_factor(),
      zoom_factor_3 * display_2_dsf);
}

TEST_F(DisplayManagerTest, ZoomDisplay) {
  // Initialize a display pair.
  UpdateDisplay("1920x1080#1920x1080|1280x720%60, 2560x1440*2#2560x1440");
  reset();

  ASSERT_EQ(2u, display_manager()->GetNumDisplays());

  const display::ManagedDisplayInfo& info_1 = GetDisplayInfoAt(0);
  const display::ManagedDisplayInfo::ManagedDisplayModeList& modes_1 =
      info_1.display_modes();

  const display::ManagedDisplayInfo& info_2 = GetDisplayInfoAt(1);
  const display::ManagedDisplayInfo::ManagedDisplayModeList& modes_2 =
      info_2.display_modes();

  // Set the display mode for each display.
  display::test::SetDisplayResolution(display_manager(), info_1.id(),
                                      modes_1[0].size());
  display::test::SetDisplayResolution(display_manager(), info_2.id(),
                                      modes_2[0].size());
  display_manager()->UpdateDisplays();

  // Enumerate the zoom factors for display.
  const std::vector<float> zoom_factors_1 =
      display::GetDisplayZoomFactors(modes_1[0]);

  // Set the zoom factor to one of the enumerated zoom factors for the said
  // display.
  const std::size_t zoom_factor_idx_1 = 0;
  display_manager()->UpdateZoomFactor(info_1.id(),
                                      zoom_factors_1[zoom_factor_idx_1]);

  // Make sure the chage was successful.
  EXPECT_FLOAT_EQ(display_manager()->GetDisplayInfo(info_1.id()).zoom_factor(),
                  zoom_factors_1[zoom_factor_idx_1]);

  // Zoom out the display. This should have no effect, since the display is
  // already at the minimum zoom level.
  display_manager()->ZoomDisplay(info_1.id(), true /* up */);
  EXPECT_FLOAT_EQ(display_manager()->GetDisplayInfo(info_1.id()).zoom_factor(),
                  zoom_factors_1[zoom_factor_idx_1]);

  // Ensure that this call did not modify the zoom value for the other display.
  EXPECT_FLOAT_EQ(display_manager()->GetDisplayInfo(info_2.id()).zoom_factor(),
                  1.f);

  // Zoom in the display.
  display_manager()->ZoomDisplay(info_1.id(), false /* up */);

  // The zoom factor for the display should be set to the next zoom factor in
  // list.
  EXPECT_FLOAT_EQ(display_manager()->GetDisplayInfo(info_1.id()).zoom_factor(),
                  zoom_factors_1[zoom_factor_idx_1 + 1]);

  // Zoom out the display.
  display_manager()->ZoomDisplay(info_1.id(), true /* up */);

  // The zoom level should decrease from the previous level.
  EXPECT_FLOAT_EQ(display_manager()->GetDisplayInfo(info_1.id()).zoom_factor(),
                  zoom_factors_1[zoom_factor_idx_1]);

  // Enumerate the zoom factors for display.
  const std::vector<float> zoom_factors_2 =
      display::GetDisplayZoomFactors(modes_2[0]);

  // Set the zoom factor to one of the enumerated zoom factors for the said
  // display.
  const std::size_t zoom_factor_idx_2 = zoom_factors_2.size() - 1;
  display_manager()->UpdateZoomFactor(info_2.id(),
                                      zoom_factors_2[zoom_factor_idx_2]);

  // Make sure the chage was successful.
  EXPECT_FLOAT_EQ(display_manager()->GetDisplayInfo(info_2.id()).zoom_factor(),
                  zoom_factors_2[zoom_factor_idx_2]);

  // Zoom in the display. This should have no effect since we are already at
  // maximum zoom.
  display_manager()->ZoomDisplay(info_2.id(), false /* up */);
  EXPECT_FLOAT_EQ(display_manager()->GetDisplayInfo(info_2.id()).zoom_factor(),
                  zoom_factors_2[zoom_factor_idx_2]);

  // Zoom out the display
  display_manager()->ZoomDisplay(info_2.id(), true /* up */);
  EXPECT_FLOAT_EQ(display_manager()->GetDisplayInfo(info_2.id()).zoom_factor(),
                  zoom_factors_2[zoom_factor_idx_2 - 1]);

  // Ensure that this call did not modify the zoom value for the other display.
  EXPECT_FLOAT_EQ(display_manager()->GetDisplayInfo(info_1.id()).zoom_factor(),
                  zoom_factors_1[zoom_factor_idx_1]);

  // Reset the zoom value for displays.
  display_manager()->ResetDisplayZoom(info_1.id());
  EXPECT_FLOAT_EQ(display_manager()->GetDisplayInfo(info_1.id()).zoom_factor(),
                  1.f);
  // Resetting the zoom level of one display should not effect the other display
  EXPECT_FLOAT_EQ(display_manager()->GetDisplayInfo(info_2.id()).zoom_factor(),
                  zoom_factors_2[zoom_factor_idx_2 - 1]);

  // Now reset the zoom value for other display.
  display_manager()->ResetDisplayZoom(info_2.id());
  EXPECT_FLOAT_EQ(display_manager()->GetDisplayInfo(info_2.id()).zoom_factor(),
                  1.f);
  EXPECT_FLOAT_EQ(display_manager()->GetDisplayInfo(info_1.id()).zoom_factor(),
                  1.f);
}

TEST_F(DisplayManagerTest, TestDeviceScaleOnlyChange) {
  UpdateDisplay("1000x600");
  aura::WindowTreeHost* host = Shell::GetPrimaryRootWindow()->GetHost();
  EXPECT_EQ(1, host->compositor()->device_scale_factor());
  EXPECT_EQ("1000x600",
            Shell::GetPrimaryRootWindow()->bounds().size().ToString());
  EXPECT_EQ("1 0 0 1 1", GetCountSummary());

  UpdateDisplay("1000x600*2");
  EXPECT_EQ(2, host->compositor()->device_scale_factor());
  EXPECT_EQ("2 0 0 2 2", GetCountSummary());
  EXPECT_EQ("500x300",
            Shell::GetPrimaryRootWindow()->bounds().size().ToString());
}

TEST_F(DisplayManagerTest, TestNativeDisplaysChanged) {
  // Disable restoring mirror mode to prevent interference from previous
  // display configuration.
  display_manager()->set_disable_restoring_mirror_mode_for_test(true);

  const int64_t internal_display_id =
      display::test::DisplayManagerTestApi(display_manager())
          .SetFirstDisplayAsInternalDisplay();
  const int external_id = 10;
  const int mirror_id = 11;
  const int64_t invalid_id = display::kInvalidDisplayId;
  const display::ManagedDisplayInfo internal_display_info =
      display::CreateDisplayInfo(internal_display_id,
                                 gfx::Rect(0, 0, 500, 500));
  const display::ManagedDisplayInfo external_display_info =
      display::CreateDisplayInfo(external_id, gfx::Rect(1, 1, 100, 100));
  const display::ManagedDisplayInfo mirroring_display_info =
      display::CreateDisplayInfo(mirror_id, gfx::Rect(0, 0, 500, 500));

  EXPECT_EQ(1U, display_manager()->GetNumDisplays());
  EXPECT_EQ(1U, display_manager()->num_connected_displays());
  std::string default_bounds =
      display_manager()->GetDisplayAt(0).bounds().ToString();

  std::vector<display::ManagedDisplayInfo> display_info_list;
  // Primary disconnected.
  display_manager()->OnNativeDisplaysChanged(display_info_list);
  EXPECT_EQ(1U, display_manager()->GetNumDisplays());
  EXPECT_EQ(default_bounds,
            display_manager()->GetDisplayAt(0).bounds().ToString());
  EXPECT_EQ(1U, display_manager()->num_connected_displays());
  EXPECT_FALSE(display_manager()->IsInMirrorMode());

  // External connected while primary was disconnected.
  display_info_list.push_back(external_display_info);
  display_manager()->OnNativeDisplaysChanged(display_info_list);
  EXPECT_EQ(1U, display_manager()->GetNumDisplays());

  EXPECT_EQ(invalid_id, GetDisplayForId(internal_display_id).id());
  EXPECT_EQ("1,1 100x100",
            GetDisplayInfoForId(external_id).bounds_in_native().ToString());
  EXPECT_EQ(1U, display_manager()->num_connected_displays());
  EXPECT_FALSE(display_manager()->IsInMirrorMode());
  EXPECT_EQ(external_id,
            display::Screen::GetScreen()->GetPrimaryDisplay().id());

  EXPECT_EQ(internal_display_id, display::Display::InternalDisplayId());

  // Primary connected, with different bounds.
  display_info_list.clear();
  display_info_list.push_back(internal_display_info);
  display_info_list.push_back(external_display_info);
  display_manager()->OnNativeDisplaysChanged(display_info_list);
  EXPECT_EQ(2U, display_manager()->GetNumDisplays());
  EXPECT_EQ(internal_display_id,
            display::Screen::GetScreen()->GetPrimaryDisplay().id());

  // This combinatino is new, so internal display becomes primary.
  EXPECT_EQ("0,0 500x500",
            GetDisplayForId(internal_display_id).bounds().ToString());
  EXPECT_EQ("1,1 100x100",
            GetDisplayInfoForId(10).bounds_in_native().ToString());
  EXPECT_EQ(2U, display_manager()->num_connected_displays());
  EXPECT_FALSE(display_manager()->IsInMirrorMode());
  EXPECT_EQ(ToDisplayName(internal_display_id),
            display_manager()->GetDisplayNameForId(internal_display_id));

  // Emulate suspend.
  display_info_list.clear();
  display_manager()->OnNativeDisplaysChanged(display_info_list);
  EXPECT_EQ(2U, display_manager()->GetNumDisplays());
  EXPECT_EQ("0,0 500x500",
            GetDisplayForId(internal_display_id).bounds().ToString());
  EXPECT_EQ("1,1 100x100",
            GetDisplayInfoForId(10).bounds_in_native().ToString());
  EXPECT_EQ(2U, display_manager()->num_connected_displays());
  EXPECT_FALSE(display_manager()->IsInMirrorMode());
  EXPECT_EQ(ToDisplayName(internal_display_id),
            display_manager()->GetDisplayNameForId(internal_display_id));

  // External display has disconnected then resumed.
  display_info_list.push_back(internal_display_info);
  display_manager()->OnNativeDisplaysChanged(display_info_list);
  EXPECT_EQ(1U, display_manager()->GetNumDisplays());
  EXPECT_EQ("0,0 500x500",
            GetDisplayForId(internal_display_id).bounds().ToString());
  EXPECT_EQ(1U, display_manager()->num_connected_displays());
  EXPECT_FALSE(display_manager()->IsInMirrorMode());

  // External display was changed during suspend.
  display_info_list.push_back(external_display_info);
  display_manager()->OnNativeDisplaysChanged(display_info_list);
  EXPECT_EQ(2U, display_manager()->GetNumDisplays());
  EXPECT_EQ(2U, display_manager()->num_connected_displays());
  EXPECT_FALSE(display_manager()->IsInMirrorMode());

  // suspend...
  display_info_list.clear();
  display_manager()->OnNativeDisplaysChanged(display_info_list);
  EXPECT_EQ(2U, display_manager()->GetNumDisplays());
  EXPECT_EQ(2U, display_manager()->num_connected_displays());
  EXPECT_FALSE(display_manager()->IsInMirrorMode());

  // and resume with different external display.
  display_info_list.push_back(internal_display_info);
  display_info_list.push_back(
      display::CreateDisplayInfo(12, gfx::Rect(1, 1, 100, 100)));
  display_manager()->OnNativeDisplaysChanged(display_info_list);
  EXPECT_EQ(2U, display_manager()->GetNumDisplays());
  EXPECT_EQ(2U, display_manager()->num_connected_displays());
  EXPECT_FALSE(display_manager()->IsInMirrorMode());
  EXPECT_FALSE(display_manager()->IsInMirrorMode());

  // mirrored...
  display_info_list.clear();
  display_info_list.push_back(internal_display_info);
  display_info_list.push_back(mirroring_display_info);
  display_manager()->OnNativeDisplaysChanged(display_info_list);
  EXPECT_EQ(1U, display_manager()->GetNumDisplays());
  EXPECT_EQ("0,0 500x500",
            GetDisplayForId(internal_display_id).bounds().ToString());
  EXPECT_EQ(2U, display_manager()->num_connected_displays());
  EXPECT_EQ(11U, display_manager()->GetMirroringDestinationDisplayIdList()[0]);
  EXPECT_TRUE(display_manager()->IsInMirrorMode());

  // Test display name.
  EXPECT_EQ(ToDisplayName(internal_display_id),
            display_manager()->GetDisplayNameForId(internal_display_id));
  EXPECT_EQ("x-10", display_manager()->GetDisplayNameForId(10));
  EXPECT_EQ("x-11", display_manager()->GetDisplayNameForId(11));
  EXPECT_EQ("x-12", display_manager()->GetDisplayNameForId(12));
  // Default name for the id that doesn't exist.
  EXPECT_EQ("Display 100", display_manager()->GetDisplayNameForId(100));

  // and exit mirroring.
  display_info_list.clear();
  display_info_list.push_back(internal_display_info);
  display_info_list.push_back(external_display_info);
  display_manager()->OnNativeDisplaysChanged(display_info_list);
  EXPECT_EQ(2U, display_manager()->GetNumDisplays());
  EXPECT_EQ(2U, display_manager()->num_connected_displays());
  EXPECT_FALSE(display_manager()->IsInMirrorMode());
  EXPECT_EQ("0,0 500x500",
            GetDisplayForId(internal_display_id).bounds().ToString());
  EXPECT_EQ("500,0 100x100", GetDisplayForId(10).bounds().ToString());

  // Turn off internal
  display_info_list.clear();
  display_info_list.push_back(external_display_info);
  display_manager()->OnNativeDisplaysChanged(display_info_list);
  EXPECT_EQ(1U, display_manager()->GetNumDisplays());
  EXPECT_EQ(invalid_id, GetDisplayForId(internal_display_id).id());
  EXPECT_EQ("1,1 100x100",
            GetDisplayInfoForId(external_id).bounds_in_native().ToString());
  EXPECT_EQ(1U, display_manager()->num_connected_displays());
  EXPECT_FALSE(display_manager()->IsInMirrorMode());

  // Switched to another display
  display_info_list.clear();
  display_info_list.push_back(internal_display_info);
  display_manager()->OnNativeDisplaysChanged(display_info_list);
  EXPECT_EQ(1U, display_manager()->GetNumDisplays());
  EXPECT_EQ(
      "0,0 500x500",
      GetDisplayInfoForId(internal_display_id).bounds_in_native().ToString());
  EXPECT_EQ(1U, display_manager()->num_connected_displays());
  EXPECT_FALSE(display_manager()->IsInMirrorMode());

  display_manager()->set_disable_restoring_mirror_mode_for_test(false);
}

// Make sure crash does not happen if add and remove happens at the same time.
// See: crbug.com/414394
TEST_F(DisplayManagerTest, DisplayAddRemoveAtTheSameTime) {
  UpdateDisplay("100+0-500x500,0+501-400x400");

  const int64_t primary_id = WindowTreeHostManager::GetPrimaryDisplayId();
  const int64_t secondary_id = display_manager()->GetSecondaryDisplay().id();

  display::ManagedDisplayInfo primary_info =
      display_manager()->GetDisplayInfo(primary_id);
  display::ManagedDisplayInfo secondary_info =
      display_manager()->GetDisplayInfo(secondary_id);

  // An id which is different from primary and secondary.
  const int64_t third_id = secondary_id + 1;

  display::ManagedDisplayInfo third_info =
      display::CreateDisplayInfo(third_id, gfx::Rect(0, 0, 600, 600));

  std::vector<display::ManagedDisplayInfo> display_info_list;
  display_info_list.push_back(third_info);
  display_info_list.push_back(secondary_info);
  display_manager()->OnNativeDisplaysChanged(display_info_list);

  // Secondary seconary_id becomes the primary as it has smaller output index.
  EXPECT_EQ(secondary_id, WindowTreeHostManager::GetPrimaryDisplayId());
  EXPECT_EQ(third_id, display_manager()->GetSecondaryDisplay().id());
  EXPECT_EQ("600x600", GetDisplayForId(third_id).size().ToString());
}

TEST_F(DisplayManagerTest, TestNativeDisplaysChangedNoInternal) {
  EXPECT_EQ(1U, display_manager()->GetNumDisplays());

  // Don't change the display info if all displays are disconnected.
  std::vector<display::ManagedDisplayInfo> display_info_list;
  display_manager()->OnNativeDisplaysChanged(display_info_list);
  EXPECT_EQ(1U, display_manager()->GetNumDisplays());

  // Connect another display which will become primary.
  const display::ManagedDisplayInfo external_display_info =
      display::CreateDisplayInfo(10, gfx::Rect(1, 1, 100, 100));
  display_info_list.push_back(external_display_info);
  display_manager()->OnNativeDisplaysChanged(display_info_list);
  EXPECT_EQ(1U, display_manager()->GetNumDisplays());
  EXPECT_EQ("1,1 100x100",
            GetDisplayInfoForId(10).bounds_in_native().ToString());
  EXPECT_EQ("100x100", ash::Shell::GetPrimaryRootWindow()
                           ->GetHost()
                           ->GetBoundsInPixels()
                           .size()
                           .ToString());
}

TEST_F(DisplayManagerTest, NativeDisplaysChangedAfterPrimaryChange) {
  const int64_t internal_display_id =
      display::test::DisplayManagerTestApi(display_manager())
          .SetFirstDisplayAsInternalDisplay();
  const display::ManagedDisplayInfo native_display_info =
      display::CreateDisplayInfo(internal_display_id,
                                 gfx::Rect(0, 0, 500, 500));
  const display::ManagedDisplayInfo secondary_display_info =
      display::CreateDisplayInfo(10, gfx::Rect(1, 1, 100, 100));

  std::vector<display::ManagedDisplayInfo> display_info_list;
  display_info_list.push_back(native_display_info);
  display_info_list.push_back(secondary_display_info);
  display_manager()->OnNativeDisplaysChanged(display_info_list);
  EXPECT_EQ(2U, display_manager()->GetNumDisplays());
  EXPECT_EQ("0,0 500x500",
            GetDisplayForId(internal_display_id).bounds().ToString());
  EXPECT_EQ("500,0 100x100", GetDisplayForId(10).bounds().ToString());

  ash::Shell::Get()->window_tree_host_manager()->SetPrimaryDisplayId(
      secondary_display_info.id());
  EXPECT_EQ("-500,0 500x500",
            GetDisplayForId(internal_display_id).bounds().ToString());
  EXPECT_EQ("0,0 100x100", GetDisplayForId(10).bounds().ToString());

  // OnNativeDisplaysChanged may change the display bounds.  Here makes sure
  // nothing changed if the exactly same displays are specified.
  display_manager()->OnNativeDisplaysChanged(display_info_list);
  EXPECT_EQ("-500,0 500x500",
            GetDisplayForId(internal_display_id).bounds().ToString());
  EXPECT_EQ("0,0 100x100", GetDisplayForId(10).bounds().ToString());
}

TEST_F(DisplayManagerTest, DontRememberBestResolution) {
  int display_id = 1000;
  display::ManagedDisplayInfo native_display_info =
      display::CreateDisplayInfo(display_id, gfx::Rect(0, 0, 1000, 500));
  display::ManagedDisplayInfo::ManagedDisplayModeList display_modes;
  display_modes.push_back(
      display::ManagedDisplayMode(gfx::Size(1000, 500), 58.0f, false, true));
  display_modes.push_back(
      display::ManagedDisplayMode(gfx::Size(800, 300), 59.0f, false, false));
  display_modes.push_back(
      display::ManagedDisplayMode(gfx::Size(400, 500), 60.0f, false, false));

  native_display_info.SetManagedDisplayModes(display_modes);

  std::vector<display::ManagedDisplayInfo> display_info_list;
  display_info_list.push_back(native_display_info);
  display_manager()->OnNativeDisplaysChanged(display_info_list);

  display::ManagedDisplayMode expected_mode(gfx::Size(1000, 500), 0.0f, false,
                                            false);

  display::ManagedDisplayMode mode;
  EXPECT_FALSE(
      display_manager()->GetSelectedModeForDisplayId(display_id, &mode));
  display::ManagedDisplayMode active_mode;
  EXPECT_TRUE(
      display_manager()->GetActiveModeForDisplayId(display_id, &active_mode));
  EXPECT_TRUE(expected_mode.IsEquivalent(active_mode));

  // Unsupported resolution.
  display::test::SetDisplayResolution(display_manager(), display_id,
                                      gfx::Size(800, 4000));
  EXPECT_FALSE(
      display_manager()->GetSelectedModeForDisplayId(display_id, &mode));
  EXPECT_TRUE(
      display_manager()->GetActiveModeForDisplayId(display_id, &active_mode));
  EXPECT_TRUE(expected_mode.IsEquivalent(active_mode));

  // Supported resolution.
  display::test::SetDisplayResolution(display_manager(), display_id,
                                      gfx::Size(800, 300));
  EXPECT_TRUE(
      display_manager()->GetSelectedModeForDisplayId(display_id, &mode));
  EXPECT_EQ("800x300", mode.size().ToString());
  EXPECT_EQ(59.0f, mode.refresh_rate());
  EXPECT_FALSE(mode.native());

  expected_mode =
      display::ManagedDisplayMode(gfx::Size(800, 300), 0.0f, false, false);

  EXPECT_TRUE(
      display_manager()->GetActiveModeForDisplayId(display_id, &active_mode));
  EXPECT_TRUE(expected_mode.IsEquivalent(active_mode));

  // Best resolution.
  display::test::SetDisplayResolution(display_manager(), display_id,
                                      gfx::Size(1000, 500));
  EXPECT_TRUE(
      display_manager()->GetSelectedModeForDisplayId(display_id, &mode));
  EXPECT_EQ("1000x500", mode.size().ToString());
  EXPECT_EQ(58.0f, mode.refresh_rate());
  EXPECT_TRUE(mode.native());

  expected_mode =
      display::ManagedDisplayMode(gfx::Size(1000, 500), 0.0f, false, false);

  EXPECT_TRUE(
      display_manager()->GetActiveModeForDisplayId(display_id, &active_mode));
  EXPECT_TRUE(expected_mode.IsEquivalent(active_mode));
}

TEST_F(DisplayManagerTest, ResolutionFallback) {
  int display_id = 1000;
  display::ManagedDisplayInfo native_display_info =
      display::CreateDisplayInfo(display_id, gfx::Rect(0, 0, 1000, 500));
  display::ManagedDisplayInfo::ManagedDisplayModeList display_modes;
  display_modes.push_back(
      display::ManagedDisplayMode(gfx::Size(1000, 500), 58.0f, false, true));
  display_modes.push_back(
      display::ManagedDisplayMode(gfx::Size(800, 300), 59.0f, false, false));
  display_modes.push_back(
      display::ManagedDisplayMode(gfx::Size(400, 500), 60.0f, false, false));

  display::ManagedDisplayInfo::ManagedDisplayModeList copy = display_modes;
  native_display_info.SetManagedDisplayModes(copy);

  std::vector<display::ManagedDisplayInfo> display_info_list;
  display_info_list.push_back(native_display_info);
  display_manager()->OnNativeDisplaysChanged(display_info_list);
  {
    display::test::SetDisplayResolution(display_manager(), display_id,
                                        gfx::Size(800, 300));
    display::ManagedDisplayInfo new_native_display_info =
        display::CreateDisplayInfo(display_id, gfx::Rect(0, 0, 400, 500));
    copy = display_modes;
    new_native_display_info.SetManagedDisplayModes(copy);
    std::vector<display::ManagedDisplayInfo> new_display_info_list;
    new_display_info_list.push_back(new_native_display_info);
    display_manager()->OnNativeDisplaysChanged(new_display_info_list);

    display::ManagedDisplayMode mode;
    EXPECT_TRUE(
        display_manager()->GetSelectedModeForDisplayId(display_id, &mode));
    EXPECT_EQ("400x500", mode.size().ToString());
    EXPECT_EQ(60.0f, mode.refresh_rate());
    EXPECT_FALSE(mode.native());
  }
  {
    // Best resolution should find itself on the resolutions list.
    display::test::SetDisplayResolution(display_manager(), display_id,
                                        gfx::Size(800, 300));
    display::ManagedDisplayInfo new_native_display_info =
        display::CreateDisplayInfo(display_id, gfx::Rect(0, 0, 1000, 500));
    display::ManagedDisplayInfo::ManagedDisplayModeList copy = display_modes;
    new_native_display_info.SetManagedDisplayModes(copy);
    std::vector<display::ManagedDisplayInfo> new_display_info_list;
    new_display_info_list.push_back(new_native_display_info);
    display_manager()->OnNativeDisplaysChanged(new_display_info_list);

    display::ManagedDisplayMode mode;
    EXPECT_TRUE(
        display_manager()->GetSelectedModeForDisplayId(display_id, &mode));
    EXPECT_EQ("1000x500", mode.size().ToString());
    EXPECT_EQ(58.0f, mode.refresh_rate());
    EXPECT_TRUE(mode.native());
  }
}

TEST_F(DisplayManagerTest, DisplayRemovedOnlyOnceWhenEnteringDockedMode) {
  // Create two displays, one internal, and one external, such that the full ID
  // of the internal display is *greater* than the full ID of the external
  // display, but the port-index part (least significant 8-bit) of the ID of the
  // internal display is *less* than the port-index part of the external
  // display.
  constexpr int64_t kInternalDisplayId = 0x4D10DBEBF24802LL;
  constexpr int64_t kExternalDisplayId = 0x4CABEF61B95735LL;
  const auto internal_info = display::ManagedDisplayInfo::CreateFromSpecWithID(
      "0+0-400x400", kInternalDisplayId);
  const auto external_info = display::ManagedDisplayInfo::CreateFromSpecWithID(
      "401+0-600x600", kExternalDisplayId);
  vector<display::ManagedDisplayInfo> display_info_list{internal_info,
                                                        external_info};
  display_manager()->OnNativeDisplaysChanged(display_info_list);
  display::test::DisplayManagerTestApi(display_manager())
      .SetFirstDisplayAsInternalDisplay();

  // Switching to docked mode in this configuration should result in only a
  // single display removal, and no new display additions.
  // https://crbug.com/921275.
  reset();
  display_info_list.clear();
  display_info_list.emplace_back(external_info);
  display_manager()->OnNativeDisplaysChanged(display_info_list);

  // There should only be 1 display change, 0 adds, and 1 removal.
  EXPECT_EQ("1 0 1 1 1", GetCountSummary());
  const unsigned int expected_changed_metrics =
      display::DisplayObserver::DISPLAY_METRIC_BOUNDS |
      display::DisplayObserver::DISPLAY_METRIC_WORK_AREA |
      display::DisplayObserver::DISPLAY_METRIC_PRIMARY;
  EXPECT_EQ(expected_changed_metrics, changed_metrics());

  // Exit docked mode by re-adding the internal display again.
  reset();
  display_info_list.clear();
  display_info_list.emplace_back(internal_info);
  display_info_list.emplace_back(external_info);
  display_manager()->OnNativeDisplaysChanged(display_info_list);

  // Expect that we get a "primary" change notification.
  EXPECT_EQ("5 1 0 1 1", GetCountSummary());
  EXPECT_EQ(expected_changed_metrics, changed_metrics());
}

TEST_F(DisplayManagerTest, Rotate) {
  UpdateDisplay("100x200/r,300x400/l");
  EXPECT_EQ("1,1 100x200", GetDisplayInfoAt(0).bounds_in_native().ToString());
  EXPECT_EQ("200x100", GetDisplayInfoAt(0).size_in_pixel().ToString());

  EXPECT_EQ("1,201 300x400", GetDisplayInfoAt(1).bounds_in_native().ToString());
  EXPECT_EQ("400x300", GetDisplayInfoAt(1).size_in_pixel().ToString());
  reset();
  UpdateDisplay("100x200/b,300x400");
  EXPECT_EQ("2 0 0 1 1", GetCountSummary());
  reset();

  EXPECT_EQ("1,1 100x200", GetDisplayInfoAt(0).bounds_in_native().ToString());
  EXPECT_EQ("100x200", GetDisplayInfoAt(0).size_in_pixel().ToString());

  EXPECT_EQ("1,201 300x400", GetDisplayInfoAt(1).bounds_in_native().ToString());
  EXPECT_EQ("300x400", GetDisplayInfoAt(1).size_in_pixel().ToString());

  // Just Rotating display will change the bounds on both display.
  UpdateDisplay("100x200/l,300x400");
  EXPECT_EQ("2 0 0 1 1", GetCountSummary());
  reset();

  // Updating to the same configuration should report no changes. A will/did
  // change is still sent.
  UpdateDisplay("100x200/l,300x400");
  EXPECT_EQ("0 0 0 1 1", GetCountSummary());
  reset();

  // Rotating 180 degrees should report one change.
  UpdateDisplay("100x200/r,300x400");
  EXPECT_EQ("1 0 0 1 1", GetCountSummary());
  reset();

  UpdateDisplay("200x200");
  EXPECT_EQ("1 0 1 1 1", GetCountSummary());
  reset();

  // Rotating 180 degrees should report one change.
  UpdateDisplay("200x200/u");
  EXPECT_EQ("1 0 0 1 1", GetCountSummary());
  reset();

  UpdateDisplay("200x200/l");
  EXPECT_EQ("1 0 0 1 1", GetCountSummary());

  // Having the internal display deactivated should restore user rotation. Newly
  // set rotations should be applied.
  UpdateDisplay("200x200, 200x200");
  const int64_t internal_display_id =
      display::test::DisplayManagerTestApi(display_manager())
          .SetFirstDisplayAsInternalDisplay();

  display_manager()->SetDisplayRotation(internal_display_id,
                                        display::Display::ROTATE_90,
                                        display::Display::RotationSource::USER);
  display_manager()->SetDisplayRotation(
      internal_display_id, display::Display::ROTATE_0,
      display::Display::RotationSource::ACTIVE);

  const display::ManagedDisplayInfo info =
      GetDisplayInfoForId(internal_display_id);
  EXPECT_EQ(display::Display::ROTATE_0, info.GetActiveRotation());

  // Deactivate internal display to simulate Docked Mode.
  vector<display::ManagedDisplayInfo> secondary_only;
  secondary_only.push_back(GetDisplayInfoAt(1));
  display_manager()->OnNativeDisplaysChanged(secondary_only);

  const display::ManagedDisplayInfo& post_removal_info =
      display::test::DisplayManagerTestApi(display_manager())
          .GetInternalManagedDisplayInfo(internal_display_id);
  EXPECT_NE(info.GetActiveRotation(), post_removal_info.GetActiveRotation());
  EXPECT_EQ(display::Display::ROTATE_90, post_removal_info.GetActiveRotation());

  display_manager()->SetDisplayRotation(
      internal_display_id, display::Display::ROTATE_180,
      display::Display::RotationSource::ACTIVE);
  const display::ManagedDisplayInfo& post_rotation_info =
      display::test::DisplayManagerTestApi(display_manager())
          .GetInternalManagedDisplayInfo(internal_display_id);
  EXPECT_NE(info.GetActiveRotation(), post_rotation_info.GetActiveRotation());
  EXPECT_EQ(display::Display::ROTATE_180,
            post_rotation_info.GetActiveRotation());
}

TEST_F(DisplayManagerTest, FHD125DefaultsTo08UIScaling) {
  int64_t display_id = display::Screen::GetScreen()->GetPrimaryDisplay().id();

  display_id++;
  display::test::ScopedSetInternalDisplayId set_internal(display_manager(),
                                                         display_id);

  // Setup the display modes with UI-scale.
  display::ManagedDisplayInfo native_display_info =
      display::CreateDisplayInfo(display_id, gfx::Rect(0, 0, 1920, 1080));
  native_display_info.set_device_scale_factor(1.25);

  const display::ManagedDisplayMode base_mode(gfx::Size(1920, 1080), 60.0f,
                                              false, false);
  display::ManagedDisplayInfo::ManagedDisplayModeList mode_list =
      CreateInternalManagedDisplayModeList(base_mode);
  native_display_info.SetManagedDisplayModes(mode_list);

  std::vector<display::ManagedDisplayInfo> display_info_list;
  display_info_list.push_back(native_display_info);

  display_manager()->OnNativeDisplaysChanged(display_info_list);

  EXPECT_EQ(1.25f, GetDisplayInfoAt(0).GetEffectiveDeviceScaleFactor());
}

TEST_F(DisplayManagerTest, ResolutionChangeInUnifiedMode) {
  // Don't check root window destruction in unified mode.
  Shell::GetPrimaryRootWindow()->RemoveObserver(this);

  display_manager()->SetUnifiedDesktopEnabled(true);

  UpdateDisplay("200x200, 400x400");

  int64_t unified_id = display::Screen::GetScreen()->GetPrimaryDisplay().id();
  display::ManagedDisplayInfo info =
      display_manager()->GetDisplayInfo(unified_id);
  ASSERT_EQ(2u, info.display_modes().size());
  EXPECT_EQ("400x200", info.display_modes()[0].size().ToString());
  EXPECT_TRUE(info.display_modes()[0].native());
  EXPECT_EQ("800x400", info.display_modes()[1].size().ToString());
  EXPECT_FALSE(info.display_modes()[1].native());
  EXPECT_EQ(
      "400x200",
      display::Screen::GetScreen()->GetPrimaryDisplay().size().ToString());
  display::ManagedDisplayMode active_mode;
  EXPECT_TRUE(
      display_manager()->GetActiveModeForDisplayId(unified_id, &active_mode));
  EXPECT_EQ("400x200", active_mode.size().ToString());

  EXPECT_TRUE(display::test::SetDisplayResolution(display_manager(), unified_id,
                                                  gfx::Size(800, 400)));
  EXPECT_EQ(
      "800x400",
      display::Screen::GetScreen()->GetPrimaryDisplay().size().ToString());

  EXPECT_TRUE(
      display_manager()->GetActiveModeForDisplayId(unified_id, &active_mode));
  EXPECT_EQ("800x400", active_mode.size().ToString());

  // resolution change will not persist in unified desktop mode.
  UpdateDisplay("600x600, 200x200");
  EXPECT_EQ(
      "1200x600",
      display::Screen::GetScreen()->GetPrimaryDisplay().size().ToString());
  EXPECT_TRUE(
      display_manager()->GetActiveModeForDisplayId(unified_id, &active_mode));
  EXPECT_TRUE(active_mode.native());
  EXPECT_EQ("1200x600", active_mode.size().ToString());
}

TEST_F(DisplayManagerTest, UpdateMouseCursorAfterRotateZoom) {
  // Make sure just rotating will not change native location.
  UpdateDisplay("300x200,200x150");
  aura::Window::Windows root_windows = Shell::GetAllRootWindows();
  aura::Env* env = Shell::Get()->aura_env();

  ui::test::EventGenerator generator1(root_windows[0]);
  ui::test::EventGenerator generator2(root_windows[1]);

  // Test on 1st display.
  generator1.MoveMouseToInHost(150, 50);
  EXPECT_EQ("150,50", env->last_mouse_location().ToString());
  UpdateDisplay("300x200/r,200x150");
  EXPECT_EQ("50,150", env->last_mouse_location().ToString());

  // Test on 2nd display.
  generator2.MoveMouseToInHost(50, 100);
  EXPECT_EQ("250,100", env->last_mouse_location().ToString());
  UpdateDisplay("300x200/r,200x150/l");
  EXPECT_EQ("250,50", env->last_mouse_location().ToString());

  // The native location is now outside, so move to the center
  // of closest display.
  UpdateDisplay("300x200/r,100x50/l");
  EXPECT_EQ("225,50", env->last_mouse_location().ToString());

  // Make sure just zooming will not change native location.
  UpdateDisplay("600x400*2,400x300");

  // Test on 1st display.
  generator1.MoveMouseToInHost(200, 300);
  EXPECT_EQ("100,150", env->last_mouse_location().ToString());
  UpdateDisplay("600x400*2@1.5,400x300");
  EXPECT_EQ("66,100", env->last_mouse_location().ToString());

  // Test on 2nd display.
  UpdateDisplay("600x400,400x300*2");
  generator2.MoveMouseToInHost(200, 250);
  EXPECT_EQ("700,125", env->last_mouse_location().ToString());
  UpdateDisplay("600x400,400x300*2@1.5");
  EXPECT_EQ("666,83", env->last_mouse_location().ToString());

  // The native location is now outside, so move to the
  // center of closest display.
  UpdateDisplay("600x400,400x200*2@1.5");
  EXPECT_EQ("666,67", env->last_mouse_location().ToString());
}

class TestDisplayObserver : public display::DisplayObserver {
 public:
  TestDisplayObserver() : changed_(false) {}
  ~TestDisplayObserver() override = default;

  // display::DisplayObserver overrides:
  void OnDisplayMetricsChanged(const display::Display&, uint32_t) override {}
  void OnDisplayAdded(const display::Display& new_display) override {
    // Mirror window should already be delete before restoring
    // the external display.
    EXPECT_TRUE(test_api.GetHosts().empty());
    changed_ = true;
  }
  void OnDisplayRemoved(const display::Display& old_display) override {
    // Mirror window should not be created until the external display
    // is removed.
    EXPECT_TRUE(test_api.GetHosts().empty());
    changed_ = true;
  }

  bool changed_and_reset() {
    bool changed = changed_;
    changed_ = false;
    return changed;
  }

 private:
  MirrorWindowTestApi test_api;
  bool changed_;

  DISALLOW_COPY_AND_ASSIGN(TestDisplayObserver);
};

TEST_F(DisplayManagerTest, SoftwareMirroring) {
  UpdateDisplay("300x400,400x500");

  MirrorWindowTestApi test_api;
  EXPECT_TRUE(test_api.GetHosts().empty());

  TestDisplayObserver display_observer;
  display::Screen::GetScreen()->AddObserver(&display_observer);

  display_manager()->SetMultiDisplayMode(display::DisplayManager::MIRRORING);
  display_manager()->UpdateDisplays();
  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(display_observer.changed_and_reset());
  EXPECT_EQ(1U, display_manager()->GetNumDisplays());
  EXPECT_EQ(
      "0,0 300x400",
      display::Screen::GetScreen()->GetPrimaryDisplay().bounds().ToString());
  std::vector<aura::WindowTreeHost*> hosts = test_api.GetHosts();
  ASSERT_EQ(1U, hosts.size());
  EXPECT_EQ("400x500", hosts[0]->GetBoundsInPixels().size().ToString());
  EXPECT_EQ("300x400", hosts[0]->window()->bounds().size().ToString());
  EXPECT_TRUE(display_manager()->IsInMirrorMode());

  SetSoftwareMirrorMode(false);
  EXPECT_TRUE(display_observer.changed_and_reset());
  EXPECT_TRUE(test_api.GetHosts().empty());
  EXPECT_EQ(2U, display_manager()->GetNumDisplays());
  EXPECT_FALSE(display_manager()->IsInMirrorMode());

  // Make sure the mirror window has the pixel size of the
  // source display.
  SetSoftwareMirrorMode(true);
  EXPECT_TRUE(display_observer.changed_and_reset());

  UpdateDisplay("300x400@0.5,400x500");
  EXPECT_FALSE(display_observer.changed_and_reset());
  EXPECT_EQ("300x400",
            test_api.GetHosts()[0]->window()->bounds().size().ToString());

  UpdateDisplay("310x410*2,400x500");
  EXPECT_FALSE(display_observer.changed_and_reset());
  EXPECT_EQ("310x410",
            test_api.GetHosts()[0]->window()->bounds().size().ToString());

  UpdateDisplay("320x420/r,400x500");
  EXPECT_FALSE(display_observer.changed_and_reset());
  EXPECT_EQ("320x420",
            test_api.GetHosts()[0]->window()->bounds().size().ToString());

  UpdateDisplay("330x440/r,400x500");
  EXPECT_FALSE(display_observer.changed_and_reset());
  EXPECT_EQ("330x440",
            test_api.GetHosts()[0]->window()->bounds().size().ToString());

  // Overscan insets are ignored.
  UpdateDisplay("400x600/o,600x800/o");
  EXPECT_FALSE(display_observer.changed_and_reset());
  EXPECT_EQ("400x600",
            test_api.GetHosts()[0]->window()->bounds().size().ToString());

  display::Screen::GetScreen()->RemoveObserver(&display_observer);
}

TEST_F(DisplayManagerTest, RotateInSoftwareMirroring) {
  UpdateDisplay("600x400,500x300");
  SetSoftwareMirrorMode(true);

  EXPECT_EQ(1U, display_manager()->GetNumDisplays());
  int64_t primary_id = display::Screen::GetScreen()->GetPrimaryDisplay().id();
  display_manager()->SetDisplayRotation(
      primary_id, display::Display::ROTATE_180,
      display::Display::RotationSource::ACTIVE);
  SetSoftwareMirrorMode(false);
}

TEST_F(DisplayManagerTest, InvertLayout) {
  EXPECT_EQ("left, 0",
            display::DisplayPlacement(display::DisplayPlacement::RIGHT, 0)
                .Swap()
                .ToString());
  EXPECT_EQ("left, -100",
            display::DisplayPlacement(display::DisplayPlacement::RIGHT, 100)
                .Swap()
                .ToString());
  EXPECT_EQ("left, 50",
            display::DisplayPlacement(display::DisplayPlacement::RIGHT, -50)
                .Swap()
                .ToString());

  EXPECT_EQ("right, 0",
            display::DisplayPlacement(display::DisplayPlacement::LEFT, 0)
                .Swap()
                .ToString());
  EXPECT_EQ("right, -90",
            display::DisplayPlacement(display::DisplayPlacement::LEFT, 90)
                .Swap()
                .ToString());
  EXPECT_EQ("right, 60",
            display::DisplayPlacement(display::DisplayPlacement::LEFT, -60)
                .Swap()
                .ToString());

  EXPECT_EQ("bottom, 0",
            display::DisplayPlacement(display::DisplayPlacement::TOP, 0)
                .Swap()
                .ToString());
  EXPECT_EQ("bottom, -80",
            display::DisplayPlacement(display::DisplayPlacement::TOP, 80)
                .Swap()
                .ToString());
  EXPECT_EQ("bottom, 70",
            display::DisplayPlacement(display::DisplayPlacement::TOP, -70)
                .Swap()
                .ToString());

  EXPECT_EQ("top, 0",
            display::DisplayPlacement(display::DisplayPlacement::BOTTOM, 0)
                .Swap()
                .ToString());
  EXPECT_EQ("top, -70",
            display::DisplayPlacement(display::DisplayPlacement::BOTTOM, 70)
                .Swap()
                .ToString());
  EXPECT_EQ("top, 80",
            display::DisplayPlacement(display::DisplayPlacement::BOTTOM, -80)
                .Swap()
                .ToString());
}

TEST_F(DisplayManagerTest, NotifyPrimaryChange) {
  UpdateDisplay("500x500,500x500");
  SwapPrimaryDisplay();
  reset();
  UpdateDisplay("500x500");
  EXPECT_FALSE(changed_metrics() &
               display::DisplayObserver::DISPLAY_METRIC_BOUNDS);
  EXPECT_FALSE(changed_metrics() &
               display::DisplayObserver::DISPLAY_METRIC_WORK_AREA);
  EXPECT_TRUE(changed_metrics() &
              display::DisplayObserver::DISPLAY_METRIC_PRIMARY);

  UpdateDisplay("500x500,500x500");
  SwapPrimaryDisplay();
  UpdateDisplay("500x400");
  EXPECT_TRUE(changed_metrics() &
              display::DisplayObserver::DISPLAY_METRIC_BOUNDS);
  EXPECT_TRUE(changed_metrics() &
              display::DisplayObserver::DISPLAY_METRIC_WORK_AREA);
  EXPECT_TRUE(changed_metrics() &
              display::DisplayObserver::DISPLAY_METRIC_PRIMARY);
}

TEST_F(DisplayManagerTest, NotifyPrimaryChangeUndock) {
  // Assume the default display is an external display, and
  // emulates undocking by switching to another display.
  display::ManagedDisplayInfo another_display_info =
      display::CreateDisplayInfo(1, gfx::Rect(0, 0, 1280, 800));
  std::vector<display::ManagedDisplayInfo> info_list;
  info_list.push_back(another_display_info);
  reset();
  display_manager()->OnNativeDisplaysChanged(info_list);
  EXPECT_TRUE(changed_metrics() &
              display::DisplayObserver::DISPLAY_METRIC_BOUNDS);
  EXPECT_TRUE(changed_metrics() &
              display::DisplayObserver::DISPLAY_METRIC_WORK_AREA);
  EXPECT_TRUE(changed_metrics() &
              display::DisplayObserver::DISPLAY_METRIC_PRIMARY);
}

TEST_F(DisplayManagerTest, UpdateDisplayWithHostOrigin) {
  UpdateDisplay("100x200,300x400");
  ASSERT_EQ(2, display::Screen::GetScreen()->GetNumDisplays());
  aura::Window::Windows root_windows = Shell::Get()->GetAllRootWindows();
  ASSERT_EQ(2U, root_windows.size());
  aura::WindowTreeHost* host0 = root_windows[0]->GetHost();
  aura::WindowTreeHost* host1 = root_windows[1]->GetHost();

  EXPECT_EQ("1,1", host0->GetBoundsInPixels().origin().ToString());
  EXPECT_EQ("100x200", host0->GetBoundsInPixels().size().ToString());
  // UpdateDisplay set the origin if it's not set.
  EXPECT_NE("1,1", host1->GetBoundsInPixels().origin().ToString());
  EXPECT_EQ("300x400", host1->GetBoundsInPixels().size().ToString());

  UpdateDisplay("100x200,200+300-300x400");
  ASSERT_EQ(2, display::Screen::GetScreen()->GetNumDisplays());
  EXPECT_EQ("0,0", host0->GetBoundsInPixels().origin().ToString());
  EXPECT_EQ("100x200", host0->GetBoundsInPixels().size().ToString());
  EXPECT_EQ("200,300", host1->GetBoundsInPixels().origin().ToString());
  EXPECT_EQ("300x400", host1->GetBoundsInPixels().size().ToString());

  UpdateDisplay("400+500-200x300,300x400");
  ASSERT_EQ(2, display::Screen::GetScreen()->GetNumDisplays());
  EXPECT_EQ("400,500", host0->GetBoundsInPixels().origin().ToString());
  EXPECT_EQ("200x300", host0->GetBoundsInPixels().size().ToString());
  EXPECT_EQ("0,0", host1->GetBoundsInPixels().origin().ToString());
  EXPECT_EQ("300x400", host1->GetBoundsInPixels().size().ToString());

  UpdateDisplay("100+200-100x200,300+500-200x300");
  ASSERT_EQ(2, display::Screen::GetScreen()->GetNumDisplays());
  EXPECT_EQ("100,200", host0->GetBoundsInPixels().origin().ToString());
  EXPECT_EQ("100x200", host0->GetBoundsInPixels().size().ToString());
  EXPECT_EQ("300,500", host1->GetBoundsInPixels().origin().ToString());
  EXPECT_EQ("200x300", host1->GetBoundsInPixels().size().ToString());
}

TEST_F(DisplayManagerTest, UnifiedDesktopBasic) {
  // Don't check root window destruction in unified mode.
  Shell::GetPrimaryRootWindow()->RemoveObserver(this);

  UpdateDisplay("400x500,300x200");

  // Enable after extended mode.
  display_manager()->SetUnifiedDesktopEnabled(true);

  // Defaults to the unified desktop.
  display::Screen* screen = display::Screen::GetScreen();
  // The 2nd display is scaled so that it has the same height as 1st display.
  // 300 * 500 / 200  + 400 = 1150.
  EXPECT_EQ(gfx::Size(1150, 500), screen->GetPrimaryDisplay().size());

  SetSoftwareMirrorMode(true);
  EXPECT_EQ(gfx::Size(400, 500), screen->GetPrimaryDisplay().size());

  SetSoftwareMirrorMode(false);
  EXPECT_EQ(gfx::Size(1150, 500), screen->GetPrimaryDisplay().size());

  // Switch to single desktop.
  UpdateDisplay("500x300");
  EXPECT_EQ(gfx::Size(500, 300), screen->GetPrimaryDisplay().size());

  // Switch to unified desktop.
  UpdateDisplay("500x300,400x500");
  // 400 * 300 / 500 + 500 ~= 739.
  EXPECT_EQ(gfx::Size(739, 300), screen->GetPrimaryDisplay().size());

  // The default should fit to the internal display.
  std::vector<display::ManagedDisplayInfo> display_info_list;
  display_info_list.push_back(
      display::CreateDisplayInfo(10, gfx::Rect(0, 0, 500, 300)));
  display_info_list.push_back(
      display::CreateDisplayInfo(11, gfx::Rect(500, 0, 400, 500)));
  {
    display::test::ScopedSetInternalDisplayId set_internal(display_manager(),
                                                           11);
    display_manager()->OnNativeDisplaysChanged(display_info_list);
    // 500 * 500 / 300 + 400 ~= 1233.
    EXPECT_EQ(gfx::Size(1233, 500), screen->GetPrimaryDisplay().size());
  }

  // Switch to 3 displays.
  UpdateDisplay("500x300,400x500,500x300");
  EXPECT_EQ(gfx::Size(1239, 300), screen->GetPrimaryDisplay().size());

  // Switch back to extended desktop.
  display_manager()->SetUnifiedDesktopEnabled(false);
  EXPECT_EQ(gfx::Size(500, 300), screen->GetPrimaryDisplay().size());
  EXPECT_EQ(gfx::Size(400, 500),
            display_manager()->GetSecondaryDisplay().size());
  EXPECT_EQ(
      gfx::Size(500, 300),
      display_manager()
          ->GetDisplayForId(display_manager()->GetSecondaryDisplay().id() + 1)
          .size());
}

TEST_F(DisplayManagerTest, UnifiedDesktopWithHardwareMirroring) {
  // Don't check root window destruction in unified mode.
  Shell::GetPrimaryRootWindow()->RemoveObserver(this);

  // Enter to hardware mirroring.
  display::ManagedDisplayInfo d1(1, "", false);
  d1.SetBounds(gfx::Rect(0, 0, 500, 500));
  display::ManagedDisplayInfo d2(2, "", false);
  d2.SetBounds(gfx::Rect(0, 0, 500, 500));
  std::vector<display::ManagedDisplayInfo> display_info_list;
  display_info_list.push_back(d1);
  display_info_list.push_back(d2);
  display_manager()->OnNativeDisplaysChanged(display_info_list);
  ASSERT_TRUE(display_manager()->IsInHardwareMirrorMode());
  display_manager()->SetUnifiedDesktopEnabled(true);
  EXPECT_TRUE(display_manager()->IsInHardwareMirrorMode());

  // The display manager automatically switches to software mirroring if
  // hardware mirroring is no longer available, because previous mirror mode
  // enforces current display mode to be mirror mode.
  display::DisplayIdList list = display::test::CreateDisplayIdList2(1, 2);
  display::DisplayLayoutBuilder builder(
      display_manager()->layout_store()->GetRegisteredDisplayLayout(list));
  display_manager()->layout_store()->RegisterLayoutForDisplayIdList(
      list, builder.Build());
  d2.SetBounds(gfx::Rect(0, 500, 500, 500));
  display_info_list.clear();
  display_info_list.push_back(d1);
  display_info_list.push_back(d2);
  display_manager()->OnNativeDisplaysChanged(display_info_list);
  EXPECT_TRUE(display_manager()->IsInSoftwareMirrorMode());
  EXPECT_FALSE(display_manager()->IsInUnifiedMode());

  // Exit software mirroring and enter unified desktop mode after mirror mode is
  // turned off.
  SetSoftwareMirrorMode(false);
  EXPECT_FALSE(display_manager()->IsInMirrorMode());
  EXPECT_TRUE(display_manager()->IsInUnifiedMode());
}

TEST_F(DisplayManagerTest, UnifiedDesktopEnabledWithExtended) {
  // Don't check root window destruction in unified mode.
  Shell::GetPrimaryRootWindow()->RemoveObserver(this);

  UpdateDisplay("400x500,300x200");
  display::DisplayIdList list = display_manager()->GetCurrentDisplayIdList();
  display::DisplayLayoutBuilder builder(
      display_manager()->layout_store()->GetRegisteredDisplayLayout(list));
  builder.SetDefaultUnified(false);
  display_manager()->layout_store()->RegisterLayoutForDisplayIdList(
      list, builder.Build());
  display_manager()->SetUnifiedDesktopEnabled(true);
  EXPECT_FALSE(display_manager()->IsInUnifiedMode());
}

TEST_F(DisplayManagerTest, UnifiedDesktopWith2xDSF) {
  // Don't check root window destruction in unified mode.
  Shell::GetPrimaryRootWindow()->RemoveObserver(this);

  display_manager()->SetUnifiedDesktopEnabled(true);
  display::Screen* screen = display::Screen::GetScreen();

  // 2nd display is 2x.
  UpdateDisplay("400x500,1000x800*2");
  display::ManagedDisplayInfo info =
      display_manager()->GetDisplayInfo(screen->GetPrimaryDisplay().id());
  ASSERT_EQ(2u, info.display_modes().size());
  EXPECT_EQ("1640x800", info.display_modes()[0].size().ToString());
  EXPECT_EQ(2.0f, info.display_modes()[0].device_scale_factor());
  EXPECT_EQ("1025x500", info.display_modes()[1].size().ToString());
  EXPECT_EQ(1.0f, info.display_modes()[1].device_scale_factor());

  // For 1x, 400 + 500 / 800 * 100 = 1025.
  EXPECT_EQ("1025x500", screen->GetPrimaryDisplay().size().ToString());
  EXPECT_EQ("1025x500",
            Shell::GetPrimaryRootWindow()->bounds().size().ToString());
  accelerators::ZoomDisplay(false);
  // (800 / 500 * 400 + 500) /2 = 820
  EXPECT_EQ("820x400", screen->GetPrimaryDisplay().size().ToString());
  EXPECT_EQ("820x400",
            Shell::GetPrimaryRootWindow()->bounds().size().ToString());

  // 1st display is 2x.
  UpdateDisplay("1200x800*2,1000x1000");
  info = display_manager()->GetDisplayInfo(screen->GetPrimaryDisplay().id());
  ASSERT_EQ(2u, info.display_modes().size());
  EXPECT_EQ("2000x800", info.display_modes()[0].size().ToString());
  EXPECT_EQ(2.0f, info.display_modes()[0].device_scale_factor());
  EXPECT_EQ("2500x1000", info.display_modes()[1].size().ToString());
  EXPECT_EQ(1.0f, info.display_modes()[1].device_scale_factor());

  // For 2x, (800 / 1000 * 1000 + 1200) / 2 = 1000
  EXPECT_EQ("1000x400", screen->GetPrimaryDisplay().size().ToString());
  EXPECT_EQ("1000x400",
            Shell::GetPrimaryRootWindow()->bounds().size().ToString());
  accelerators::ZoomDisplay(true);
  // 1000 / 800 * 1200 + 1000 = 2500
  EXPECT_EQ("2500x1000", screen->GetPrimaryDisplay().size().ToString());
  EXPECT_EQ("2500x1000",
            Shell::GetPrimaryRootWindow()->bounds().size().ToString());

  // Both displays are 2x.
  // 1st display is 2x.
  UpdateDisplay("1200x800*2,1000x1000*2");
  info = display_manager()->GetDisplayInfo(screen->GetPrimaryDisplay().id());
  ASSERT_EQ(2u, info.display_modes().size());
  EXPECT_EQ("2000x800", info.display_modes()[0].size().ToString());
  EXPECT_EQ(2.0f, info.display_modes()[0].device_scale_factor());
  EXPECT_EQ("2500x1000", info.display_modes()[1].size().ToString());
  EXPECT_EQ(2.0f, info.display_modes()[1].device_scale_factor());

  EXPECT_EQ("1000x400", screen->GetPrimaryDisplay().size().ToString());
  EXPECT_EQ("1000x400",
            Shell::GetPrimaryRootWindow()->bounds().size().ToString());
  accelerators::ZoomDisplay(true);
  EXPECT_EQ("1250x500", screen->GetPrimaryDisplay().size().ToString());
  EXPECT_EQ("1250x500",
            Shell::GetPrimaryRootWindow()->bounds().size().ToString());

  // Both displays have the same physical height, with the first display
  // being 2x.
  UpdateDisplay("1000x800*2,300x800");
  info = display_manager()->GetDisplayInfo(screen->GetPrimaryDisplay().id());
  ASSERT_EQ(2u, info.display_modes().size());
  EXPECT_EQ("1300x800", info.display_modes()[0].size().ToString());
  EXPECT_EQ(2.0f, info.display_modes()[0].device_scale_factor());
  EXPECT_EQ("1300x800", info.display_modes()[1].size().ToString());
  EXPECT_EQ(1.0f, info.display_modes()[1].device_scale_factor());

  EXPECT_EQ("650x400", screen->GetPrimaryDisplay().size().ToString());
  EXPECT_EQ("650x400",
            Shell::GetPrimaryRootWindow()->bounds().size().ToString());
  accelerators::ZoomDisplay(true);
  EXPECT_EQ("1300x800", screen->GetPrimaryDisplay().size().ToString());
  EXPECT_EQ("1300x800",
            Shell::GetPrimaryRootWindow()->bounds().size().ToString());

  // Both displays have the same physical height, with the second display
  // being 2x.
  UpdateDisplay("1000x800,300x800*2");
  ASSERT_EQ(2u, info.display_modes().size());
  EXPECT_EQ("1300x800", info.display_modes()[0].size().ToString());
  EXPECT_EQ(2.0f, info.display_modes()[0].device_scale_factor());
  EXPECT_EQ("1300x800", info.display_modes()[1].size().ToString());
  EXPECT_EQ(1.0f, info.display_modes()[1].device_scale_factor());

  EXPECT_EQ("1300x800", screen->GetPrimaryDisplay().size().ToString());
  EXPECT_EQ("1300x800",
            Shell::GetPrimaryRootWindow()->bounds().size().ToString());
  accelerators::ZoomDisplay(false);
  EXPECT_EQ("650x400", screen->GetPrimaryDisplay().size().ToString());
  EXPECT_EQ("650x400",
            Shell::GetPrimaryRootWindow()->bounds().size().ToString());
}

// Updating displays again in unified desktop mode should not crash.
// crbug.com/491094.
TEST_F(DisplayManagerTest, ConfigureUnifiedTwice) {
  // Don't check root window destruction in unified mode.
  Shell::GetPrimaryRootWindow()->RemoveObserver(this);

  UpdateDisplay("300x200,400x500");
  // Mirror windows are created in a posted task.
  base::RunLoop().RunUntilIdle();

  UpdateDisplay("300x250,400x550");
  base::RunLoop().RunUntilIdle();
}

TEST_F(DisplayManagerTest, NoRotateUnifiedDesktop) {
  display_manager()->SetUnifiedDesktopEnabled(true);

  // Don't check root window destruction in unified mode.
  Shell::GetPrimaryRootWindow()->RemoveObserver(this);

  UpdateDisplay("400x500,300x200");

  display::Screen* screen = display::Screen::GetScreen();
  const display::Display& display = screen->GetPrimaryDisplay();
  EXPECT_EQ("1150x500", display.size().ToString());
  display_manager()->SetDisplayRotation(
      display.id(), display::Display::ROTATE_90,
      display::Display::RotationSource::ACTIVE);
  EXPECT_EQ("1150x500", screen->GetPrimaryDisplay().size().ToString());
  display_manager()->SetDisplayRotation(
      display.id(), display::Display::ROTATE_0,
      display::Display::RotationSource::ACTIVE);
  EXPECT_EQ("1150x500", screen->GetPrimaryDisplay().size().ToString());

  UpdateDisplay("400x500");
  EXPECT_EQ("400x500", screen->GetPrimaryDisplay().size().ToString());
}

// Validate that setting an invalid matrix will fall back to the default
// horizontal unified desktop layout.
TEST_F(DisplayManagerTest, UnifiedDesktopInvalidMatrices) {
  // Don't check root window destruction in unified mode.
  Shell::GetPrimaryRootWindow()->RemoveObserver(this);

  UpdateDisplay("400x500,300x200");
  display_manager()->SetUnifiedDesktopEnabled(true);
  display::Screen* screen = display::Screen::GetScreen();

  display::DisplayIdList list = display_manager()->GetCurrentDisplayIdList();
  ASSERT_EQ(2u, list.size());
  {
    // Create an empty matrix.
    display::UnifiedDesktopLayoutMatrix matrix;
    display_manager()->SetUnifiedDesktopMatrix(matrix);
    // The result is still a valid default horizontal layout.
    EXPECT_EQ(gfx::Size(1150, 500), screen->GetPrimaryDisplay().size());

    // 2 x 1 empty matrix.
    matrix.resize(2u);
    display_manager()->SetUnifiedDesktopMatrix(matrix);
    // The result is still a valid default horizontal layout.
    EXPECT_EQ(gfx::Size(1150, 500), screen->GetPrimaryDisplay().size());
  }

  {
    // 2 x 1 vertical matrix with invalid IDs.
    display::UnifiedDesktopLayoutMatrix matrix;
    matrix.resize(2u);
    matrix[0].emplace_back(list[0]);
    matrix[1].emplace_back(-100);
    display_manager()->SetUnifiedDesktopMatrix(matrix);
    // The result is still a valid default horizontal layout.
    EXPECT_EQ(gfx::Size(1150, 500), screen->GetPrimaryDisplay().size());
  }

  {
    // Matrix with a missing ID.
    display::UnifiedDesktopLayoutMatrix matrix;
    matrix.resize(2u);
    matrix[0].emplace_back(list[0]);
    display_manager()->SetUnifiedDesktopMatrix(matrix);
    // The result is still a valid default horizontal layout.
    EXPECT_EQ(gfx::Size(1150, 500), screen->GetPrimaryDisplay().size());
  }

  // Switch to 3 displays.
  UpdateDisplay("500x300,400x500,500x300");
  list = display_manager()->GetCurrentDisplayIdList();
  ASSERT_EQ(3u, list.size());
  {
    // Create a matrix with unequal rows
    display::UnifiedDesktopLayoutMatrix matrix;
    matrix.resize(3u);
    matrix[0].emplace_back(list[0]);
    matrix[1].emplace_back(list[1]);
    matrix[1].emplace_back(list[2]);  // Typo; meant to say matrix[2].
    display_manager()->SetUnifiedDesktopMatrix(matrix);
    // The result is still a valid default horizontal layout.
    EXPECT_EQ(gfx::Size(1239, 300), screen->GetPrimaryDisplay().size());
  }

  {
    // Create a matrix with repeated IDs.
    display::UnifiedDesktopLayoutMatrix matrix;
    matrix.resize(3u);
    matrix[0].emplace_back(list[0]);
    matrix[1].emplace_back(list[1]);
    matrix[2].emplace_back(list[1]);  // Typo; meant to say list[2].
    display_manager()->SetUnifiedDesktopMatrix(matrix);
    // The result is still a valid default horizontal layout.
    EXPECT_EQ(gfx::Size(1239, 300), screen->GetPrimaryDisplay().size());
  }
}

TEST_F(DisplayManagerTest, UnifiedDesktopVerticalLayout2x1) {
  // Don't check root window destruction in unified mode.
  Shell::GetPrimaryRootWindow()->RemoveObserver(this);

  UpdateDisplay("400x500,300x200");
  display_manager()->SetUnifiedDesktopEnabled(true);
  display::Screen* screen = display::Screen::GetScreen();
  // This is still a horizontal layout.
  EXPECT_EQ(gfx::Size(1150, 500), screen->GetPrimaryDisplay().size());

  display::DisplayIdList list = display_manager()->GetCurrentDisplayIdList();
  ASSERT_EQ(2u, list.size());
  {
    // Create a 2 x 1 vertical layout matrix and set it.
    // [400 x 500]
    // [300 x 200]
    display::UnifiedDesktopLayoutMatrix matrix;
    matrix.resize(2u);
    matrix[0].emplace_back(list[0]);
    matrix[1].emplace_back(list[1]);
    display_manager()->SetUnifiedDesktopMatrix(matrix);
    // 500 + 400 * 200 / 300 ~= 766.
    EXPECT_EQ(gfx::Size(400, 766), screen->GetPrimaryDisplay().size());
    // Default shelf alignment is bottom. Display in bottom-left cell is
    // considered the primary mirroring display.
    EXPECT_EQ(list[1], Shell::Get()
                           ->display_configuration_controller()
                           ->GetPrimaryMirroringDisplayForUnifiedDesktop()
                           .id());

    // Validate display rows and max heights.
    EXPECT_EQ(0, display_manager()->GetMirroringDisplayRowIndexInUnifiedMatrix(
                     list[0]));
    EXPECT_EQ(1, display_manager()->GetMirroringDisplayRowIndexInUnifiedMatrix(
                     list[1]));
    EXPECT_EQ(500, display_manager()->GetUnifiedDesktopRowMaxHeight(0));
    EXPECT_EQ(400 * 200 / 300,
              display_manager()->GetUnifiedDesktopRowMaxHeight(1));
    EXPECT_FALSE(OverlappingMirroringDisplaysExist());
  }

  {
    // Change the order of the displays such that the [300 x 200] is on top,
    // which should make its bounds used for the default mode.
    // [300 x 200]
    // [400 x 500]
    display::UnifiedDesktopLayoutMatrix matrix;
    matrix.resize(2u);
    matrix[0].emplace_back(list[1]);
    matrix[1].emplace_back(list[0]);
    display_manager()->SetUnifiedDesktopMatrix(matrix);
    // 200 + 300 * 500 / 400 ~= 574 (Note that we actually scale the max unified
    // bounds).
    EXPECT_EQ(gfx::Size(300, 574), screen->GetPrimaryDisplay().size());
    // Display in bottom-left cell is considered primary.
    EXPECT_EQ(list[0], Shell::Get()
                           ->display_configuration_controller()
                           ->GetPrimaryMirroringDisplayForUnifiedDesktop()
                           .id());

    // Validate display rows and max heights.
    EXPECT_EQ(1, display_manager()->GetMirroringDisplayRowIndexInUnifiedMatrix(
                     list[0]));
    EXPECT_EQ(0, display_manager()->GetMirroringDisplayRowIndexInUnifiedMatrix(
                     list[1]));
    EXPECT_EQ(199, display_manager()->GetUnifiedDesktopRowMaxHeight(0));
    // 300 * 500 / 400.
    EXPECT_EQ(375, display_manager()->GetUnifiedDesktopRowMaxHeight(1));
    EXPECT_FALSE(OverlappingMirroringDisplaysExist());
  }

  {
    // Revert to the first matrix, but mark the [300 x 200] display as internal.
    // [400 x 500]
    // [300 x 200] : Internal
    display::UnifiedDesktopLayoutMatrix matrix;
    matrix.resize(2u);
    matrix[0].emplace_back(list[0]);
    matrix[1].emplace_back(list[1]);
    display_manager()->SetUnifiedDesktopMatrix(matrix);
    std::vector<display::ManagedDisplayInfo> display_info_list;
    display_info_list.emplace_back(
        display::CreateDisplayInfo(list[0], gfx::Rect(0, 0, 400, 500)));
    display_info_list.emplace_back(
        display::CreateDisplayInfo(list[1], gfx::Rect(400, 0, 300, 200)));
    display::test::ScopedSetInternalDisplayId set_internal(display_manager(),
                                                           list[1]);
    display_manager()->OnNativeDisplaysChanged(display_info_list);
    EXPECT_EQ(gfx::Size(300, 574), screen->GetPrimaryDisplay().size());
    // Display in bottom-left cell is considered primary.
    EXPECT_EQ(list[1], Shell::Get()
                           ->display_configuration_controller()
                           ->GetPrimaryMirroringDisplayForUnifiedDesktop()
                           .id());

    // Validate display rows and max heights.
    EXPECT_EQ(0, display_manager()->GetMirroringDisplayRowIndexInUnifiedMatrix(
                     list[0]));
    EXPECT_EQ(1, display_manager()->GetMirroringDisplayRowIndexInUnifiedMatrix(
                     list[1]));
    // 300 * 500 / 400.
    EXPECT_EQ(375, display_manager()->GetUnifiedDesktopRowMaxHeight(0));
    EXPECT_EQ(199, display_manager()->GetUnifiedDesktopRowMaxHeight(1));
    EXPECT_FALSE(OverlappingMirroringDisplaysExist());
  }
}

TEST_F(DisplayManagerTest, UnifiedDesktopVerticalLayout3x1) {
  // Don't check root window destruction in unified mode.
  Shell::GetPrimaryRootWindow()->RemoveObserver(this);

  UpdateDisplay("500x300,400x500,500x300");
  display_manager()->SetUnifiedDesktopEnabled(true);
  display::Screen* screen = display::Screen::GetScreen();

  display::DisplayIdList list = display_manager()->GetCurrentDisplayIdList();
  ASSERT_EQ(3u, list.size());
  {
    // Create a 3 x 1 vertical layout matrix and set it.
    // [500 x 300]
    // [400 x 500]
    // [500 x 300]
    display::UnifiedDesktopLayoutMatrix matrix;
    matrix.resize(3u);
    matrix[0].emplace_back(list[0]);
    matrix[1].emplace_back(list[1]);
    matrix[2].emplace_back(list[2]);
    display_manager()->SetUnifiedDesktopMatrix(matrix);
    EXPECT_EQ(gfx::Size(500, 1225), screen->GetPrimaryDisplay().size());
    // Display in bottom-left cell is considered primary.
    EXPECT_EQ(list[2], Shell::Get()
                           ->display_configuration_controller()
                           ->GetPrimaryMirroringDisplayForUnifiedDesktop()
                           .id());

    // Validate display rows and max heights.
    EXPECT_EQ(0, display_manager()->GetMirroringDisplayRowIndexInUnifiedMatrix(
                     list[0]));
    EXPECT_EQ(1, display_manager()->GetMirroringDisplayRowIndexInUnifiedMatrix(
                     list[1]));
    EXPECT_EQ(2, display_manager()->GetMirroringDisplayRowIndexInUnifiedMatrix(
                     list[2]));
    EXPECT_EQ(300, display_manager()->GetUnifiedDesktopRowMaxHeight(0));
    // 500 * 500 / 400 = 625.
    EXPECT_EQ(625, display_manager()->GetUnifiedDesktopRowMaxHeight(1));
    EXPECT_EQ(300, display_manager()->GetUnifiedDesktopRowMaxHeight(2));
    EXPECT_FALSE(OverlappingMirroringDisplaysExist());
  }

  {
    // We can change the order however we want.
    // [400 x 500]
    // [500 x 300]
    // [500 x 300]
    display::UnifiedDesktopLayoutMatrix matrix;
    matrix.resize(3u);
    matrix[0].emplace_back(list[1]);
    matrix[1].emplace_back(list[0]);
    matrix[2].emplace_back(list[2]);
    display_manager()->SetUnifiedDesktopMatrix(matrix);
    EXPECT_EQ(gfx::Size(400, 980), screen->GetPrimaryDisplay().size());
    // Display in bottom-left cell is considered primary.
    EXPECT_EQ(list[2], Shell::Get()
                           ->display_configuration_controller()
                           ->GetPrimaryMirroringDisplayForUnifiedDesktop()
                           .id());

    // Validate display rows and max heights.
    EXPECT_EQ(1, display_manager()->GetMirroringDisplayRowIndexInUnifiedMatrix(
                     list[0]));
    EXPECT_EQ(0, display_manager()->GetMirroringDisplayRowIndexInUnifiedMatrix(
                     list[1]));
    EXPECT_EQ(2, display_manager()->GetMirroringDisplayRowIndexInUnifiedMatrix(
                     list[2]));
    EXPECT_EQ(500, display_manager()->GetUnifiedDesktopRowMaxHeight(0));
    // 400 * 300 / 500 = 240.
    EXPECT_EQ(240, display_manager()->GetUnifiedDesktopRowMaxHeight(1));
    EXPECT_EQ(240, display_manager()->GetUnifiedDesktopRowMaxHeight(2));
    EXPECT_FALSE(OverlappingMirroringDisplaysExist());
  }
}

TEST_F(DisplayManagerTest, UnifiedDesktopGridLayout2x2) {
  // Don't check root window destruction in unified mode.
  Shell::GetPrimaryRootWindow()->RemoveObserver(this);

  UpdateDisplay("500x300,400x500,300x600,200x300");
  display_manager()->SetUnifiedDesktopEnabled(true);
  display::Screen* screen = display::Screen::GetScreen();

  display::DisplayIdList list = display_manager()->GetCurrentDisplayIdList();
  ASSERT_EQ(4u, list.size());
  // Create a 2 x 2 vertical layout matrix and set it.
  // [500 x 300] [400 x 500]
  // [300 x 600] [200 x 300]
  display::UnifiedDesktopLayoutMatrix matrix;
  matrix.resize(2u);
  matrix[0].emplace_back(list[0]);
  matrix[0].emplace_back(list[1]);
  matrix[1].emplace_back(list[2]);
  matrix[1].emplace_back(list[3]);
  display_manager()->SetUnifiedDesktopMatrix(matrix);
  EXPECT_EQ(gfx::Size(739, 933), screen->GetPrimaryDisplay().size());

  // Default shelf alignment is bottom.
  Shelf* shelf = Shell::GetPrimaryRootWindowController()->shelf();
  EXPECT_EQ(shelf->alignment(), SHELF_ALIGNMENT_BOTTOM);

  // Display in bottom-left cell is considered the primary mirroring display.
  EXPECT_EQ(list[2], Shell::Get()
                         ->display_configuration_controller()
                         ->GetPrimaryMirroringDisplayForUnifiedDesktop()
                         .id());

  // Validate display rows and max heights.
  EXPECT_EQ(0, display_manager()->GetMirroringDisplayRowIndexInUnifiedMatrix(
                   list[0]));
  EXPECT_EQ(0, display_manager()->GetMirroringDisplayRowIndexInUnifiedMatrix(
                   list[1]));
  EXPECT_EQ(1, display_manager()->GetMirroringDisplayRowIndexInUnifiedMatrix(
                   list[2]));
  EXPECT_EQ(1, display_manager()->GetMirroringDisplayRowIndexInUnifiedMatrix(
                   list[3]));
  EXPECT_EQ(300, display_manager()->GetUnifiedDesktopRowMaxHeight(0));
  EXPECT_EQ(633, display_manager()->GetUnifiedDesktopRowMaxHeight(1));
  EXPECT_FALSE(OverlappingMirroringDisplaysExist());

  // Change the shelf alignment to left, and expect that the primary mirroring
  // display in the top-left display in the matrix.
  shelf->SetAlignment(SHELF_ALIGNMENT_LEFT);
  EXPECT_EQ(list[0], Shell::Get()
                         ->display_configuration_controller()
                         ->GetPrimaryMirroringDisplayForUnifiedDesktop()
                         .id());

  // Change the shelf alignment to right, and expect that the primary mirroring
  // display in the top-right display in the matrix.
  shelf->SetAlignment(SHELF_ALIGNMENT_RIGHT);
  EXPECT_EQ(list[1], Shell::Get()
                         ->display_configuration_controller()
                         ->GetPrimaryMirroringDisplayForUnifiedDesktop()
                         .id());
}

TEST_F(DisplayManagerTest, UnifiedDesktopGridLayout3x2) {
  // Don't check root window destruction in unified mode.
  Shell::GetPrimaryRootWindow()->RemoveObserver(this);

  UpdateDisplay("500x300,400x500,300x600,200x300,700x200,350x480");
  display_manager()->SetUnifiedDesktopEnabled(true);
  display::Screen* screen = display::Screen::GetScreen();

  display::DisplayIdList list = display_manager()->GetCurrentDisplayIdList();
  ASSERT_EQ(6u, list.size());
  // Create a 3 x 2 vertical layout matrix and set it.
  // [500 x 300] [400 x 500]
  // [300 x 600] [200 x 300]
  // [700 x 200] [350 x 480]
  display::UnifiedDesktopLayoutMatrix matrix;
  matrix.resize(3u);
  matrix[0].emplace_back(list[0]);
  matrix[0].emplace_back(list[1]);
  matrix[1].emplace_back(list[2]);
  matrix[1].emplace_back(list[3]);
  matrix[2].emplace_back(list[4]);
  matrix[2].emplace_back(list[5]);
  display_manager()->SetUnifiedDesktopMatrix(matrix);
  EXPECT_EQ(gfx::Size(739, 1108), screen->GetPrimaryDisplay().size());

  // Default shelf alignment is bottom.
  Shelf* shelf = Shell::GetPrimaryRootWindowController()->shelf();
  EXPECT_EQ(shelf->alignment(), SHELF_ALIGNMENT_BOTTOM);

  // Display in bottom-left cell is considered the primary mirroring display.
  EXPECT_EQ(list[4], Shell::Get()
                         ->display_configuration_controller()
                         ->GetPrimaryMirroringDisplayForUnifiedDesktop()
                         .id());

  // Validate display rows and max heights.
  EXPECT_EQ(0, display_manager()->GetMirroringDisplayRowIndexInUnifiedMatrix(
                   list[0]));
  EXPECT_EQ(0, display_manager()->GetMirroringDisplayRowIndexInUnifiedMatrix(
                   list[1]));
  EXPECT_EQ(1, display_manager()->GetMirroringDisplayRowIndexInUnifiedMatrix(
                   list[2]));
  EXPECT_EQ(1, display_manager()->GetMirroringDisplayRowIndexInUnifiedMatrix(
                   list[3]));
  EXPECT_EQ(2, display_manager()->GetMirroringDisplayRowIndexInUnifiedMatrix(
                   list[4]));
  EXPECT_EQ(2, display_manager()->GetMirroringDisplayRowIndexInUnifiedMatrix(
                   list[5]));
  EXPECT_EQ(300, display_manager()->GetUnifiedDesktopRowMaxHeight(0));
  EXPECT_EQ(633, display_manager()->GetUnifiedDesktopRowMaxHeight(1));
  EXPECT_EQ(175, display_manager()->GetUnifiedDesktopRowMaxHeight(2));
  EXPECT_FALSE(OverlappingMirroringDisplaysExist());

  // Change the shelf alignment to left, and expect that the primary mirroring
  // display in the top-left display in the matrix.
  shelf->SetAlignment(SHELF_ALIGNMENT_LEFT);
  EXPECT_EQ(list[0], Shell::Get()
                         ->display_configuration_controller()
                         ->GetPrimaryMirroringDisplayForUnifiedDesktop()
                         .id());

  // Change the shelf alignment to right, and expect that the primary mirroring
  // display in the top-right display in the matrix.
  shelf->SetAlignment(SHELF_ALIGNMENT_RIGHT);
  EXPECT_EQ(list[1], Shell::Get()
                         ->display_configuration_controller()
                         ->GetPrimaryMirroringDisplayForUnifiedDesktop()
                         .id());
}

TEST_F(DisplayManagerTest, UnifiedDesktopTabletMode) {
  // Don't check root window destruction in unified mode.
  Shell::GetPrimaryRootWindow()->RemoveObserver(this);

  UpdateDisplay("400x300,800x800");
  base::RunLoop().RunUntilIdle();

  // Set the first display as internal display so that the tablet mode can be
  // enabled.
  display::test::DisplayManagerTestApi(display_manager())
      .SetFirstDisplayAsInternalDisplay();

  display_manager()->SetUnifiedDesktopEnabled(true);
  EXPECT_TRUE(display_manager()->IsInUnifiedMode());

  // Turn on tablet mode, expect that we switch to mirror mode without any
  // crashes.
  Shell::Get()->tablet_mode_controller()->EnableTabletModeWindowManager(true);
  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(display_manager()->IsInSoftwareMirrorMode());

  // The Home Launcher should be created and shown, not dismissed as a result of
  // the destruction of the Unified host when we switched to mirror mode
  // asynchronously.
  auto* app_list_controller = Shell::Get()->app_list_controller();
  auto* tablet_mode_controller = Shell::Get()->tablet_mode_controller();
  EXPECT_TRUE(tablet_mode_controller->IsTabletModeWindowManagerEnabled());
  EXPECT_TRUE(app_list_controller->IsVisible());

  // Exiting tablet mode should exit mirror mode and return back to Unified
  // mode.
  Shell::Get()->tablet_mode_controller()->EnableTabletModeWindowManager(false);
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(display_manager()->IsInSoftwareMirrorMode());
  EXPECT_TRUE(display_manager()->IsInUnifiedMode());

  // Home Launcher should be dismissed.
  EXPECT_FALSE(tablet_mode_controller->IsTabletModeWindowManagerEnabled());
  EXPECT_FALSE(app_list_controller->IsVisible());
}

TEST_F(DisplayManagerTest, DisplayPrefsAndForcedMirrorMode) {
  UpdateDisplay("400x300,800x800");
  base::RunLoop().RunUntilIdle();

  // Set the first display as internal display so that the tablet mode can be
  // enabled.
  display::test::DisplayManagerTestApi(display_manager())
      .SetFirstDisplayAsInternalDisplay();

  // Initially we can save display prefs ...
  EXPECT_TRUE(Shell::Get()->ShouldSaveDisplaySettings());
  // ... and there are no external displays that are candidates for mirror
  // restore.
  EXPECT_TRUE(display_manager()->external_display_mirror_info().empty());

  // Turn on tablet mode, and expect that it's not possible to persist the
  // display prefs while forced mirror mode is active.
  Shell::Get()->tablet_mode_controller()->EnableTabletModeWindowManager(true);
  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(display_manager()->IsInSoftwareMirrorMode());
  EXPECT_TRUE(
      display_manager()->layout_store()->forced_mirror_mode_for_tablet());
  EXPECT_FALSE(Shell::Get()->ShouldSaveDisplaySettings());
  // Forced mirror mode does not add external displays as candidates for mirror
  // restore.
  EXPECT_TRUE(display_manager()->external_display_mirror_info().empty());

  // Exit tablet mode and expect everything is back to normal.
  Shell::Get()->tablet_mode_controller()->EnableTabletModeWindowManager(false);
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(display_manager()->IsInSoftwareMirrorMode());
  EXPECT_FALSE(
      display_manager()->layout_store()->forced_mirror_mode_for_tablet());
  EXPECT_TRUE(Shell::Get()->ShouldSaveDisplaySettings());
  EXPECT_TRUE(display_manager()->external_display_mirror_info().empty());
}

TEST_F(DisplayManagerTest, DockMode) {
  const int64_t internal_id = 1;
  const int64_t external_id = 2;

  const display::ManagedDisplayInfo internal_display_info =
      display::CreateDisplayInfo(internal_id, gfx::Rect(0, 0, 500, 500));
  const display::ManagedDisplayInfo external_display_info =
      display::CreateDisplayInfo(external_id, gfx::Rect(1, 1, 100, 100));
  std::vector<display::ManagedDisplayInfo> display_info_list;

  // software mirroring.
  display_info_list.push_back(internal_display_info);
  display_info_list.push_back(external_display_info);
  display_manager()->OnNativeDisplaysChanged(display_info_list);
  const int64_t internal_display_id =
      display::test::DisplayManagerTestApi(display_manager())
          .SetFirstDisplayAsInternalDisplay();
  EXPECT_EQ(internal_id, internal_display_id);

  display_info_list.clear();
  display_info_list.push_back(external_display_info);
  display_manager()->OnNativeDisplaysChanged(display_info_list);
  EXPECT_EQ(1U, display_manager()->active_display_list().size());

  EXPECT_TRUE(display_manager()->IsActiveDisplayId(external_id));
  EXPECT_FALSE(display_manager()->IsActiveDisplayId(internal_id));
}

// Make sure that bad layout information is ignored and does not crash.
TEST_F(DisplayManagerTest, DontRegisterBadConfig) {
  display::DisplayIdList list = display::test::CreateDisplayIdList2(1, 2);
  display::DisplayLayoutBuilder builder(1);
  builder.AddDisplayPlacement(2, 1, display::DisplayPlacement::LEFT, 0);
  builder.AddDisplayPlacement(3, 1, display::DisplayPlacement::BOTTOM, 0);

  display_manager()->layout_store()->RegisterLayoutForDisplayIdList(
      list, builder.Build());
}

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

  void TearDown() override {
    display::Screen* orig_screen = display::Screen::GetScreen();
    AshTestBase::TearDown();
    display::Screen* screen = display::Screen::GetScreen();
    EXPECT_NE(orig_screen, screen);
    EXPECT_EQ(2, screen->GetNumDisplays());
    EXPECT_EQ("500x300", screen->GetPrimaryDisplay().size().ToString());
    std::vector<display::Display> all = screen->GetAllDisplays();
    EXPECT_EQ("500x300", all[0].size().ToString());
    EXPECT_EQ("800x400", all[1].size().ToString());
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(ScreenShutdownTest);
};

TEST_F(ScreenShutdownTest, ScreenAfterShutdown) {
  UpdateDisplay("500x300,800x400");
}

namespace {

// A helper class that sets the display configuration and starts ash.
// This is to make sure the font configuration happens during ash
// initialization process.
class FontTestHelper : public AshTestBase {
 public:
  enum DisplayType { INTERNAL, EXTERNAL };

  FontTestHelper(float scale, DisplayType display_type) {
    gfx::ClearFontRenderParamsCacheForTest();
    base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
    if (display_type == INTERNAL)
      command_line->AppendSwitch(::switches::kUseFirstDisplayAsInternal);
    command_line->AppendSwitchASCII(::switches::kHostWindowBounds,
                                    StringPrintf("1000x800*%f", scale));
    SetUp();
  }

  ~FontTestHelper() override { TearDown(); }

  // AshTestBase:
  void TestBody() override { NOTREACHED(); }

 private:
  DISALLOW_COPY_AND_ASSIGN(FontTestHelper);
};

bool IsTextSubpixelPositioningEnabled() {
  gfx::FontRenderParams params =
      gfx::GetFontRenderParams(gfx::FontRenderParamsQuery(), nullptr);
  return params.subpixel_positioning;
}

gfx::FontRenderParams::Hinting GetFontHintingParams() {
  gfx::FontRenderParams params =
      gfx::GetFontRenderParams(gfx::FontRenderParamsQuery(), nullptr);
  return params.hinting;
}

}  // namespace

using DisplayManagerFontTest = testing::Test;

TEST_F(DisplayManagerFontTest, TextSubpixelPositioningWithDsf100Internal) {
  FontTestHelper helper(1.0f, FontTestHelper::INTERNAL);
  ASSERT_DOUBLE_EQ(
      1.0f,
      display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor());
  EXPECT_FALSE(IsTextSubpixelPositioningEnabled());
  EXPECT_NE(gfx::FontRenderParams::HINTING_NONE, GetFontHintingParams());
}

TEST_F(DisplayManagerFontTest, TextSubpixelPositioningWithDsf200Internal) {
  FontTestHelper helper(2.0f, FontTestHelper::INTERNAL);
  ASSERT_DOUBLE_EQ(
      2.0f,
      display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor());
  EXPECT_FALSE(IsTextSubpixelPositioningEnabled());
  EXPECT_NE(gfx::FontRenderParams::HINTING_NONE, GetFontHintingParams());

  helper.display_manager()->UpdateZoomFactor(
      display::Screen::GetScreen()->GetPrimaryDisplay().id(), 0.5f);

  ASSERT_DOUBLE_EQ(
      1.0f,
      display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor());
  EXPECT_FALSE(IsTextSubpixelPositioningEnabled());
  EXPECT_NE(gfx::FontRenderParams::HINTING_NONE, GetFontHintingParams());
}

TEST_F(DisplayManagerFontTest, TextSubpixelPositioningWithDsf100External) {
  FontTestHelper helper(1.0f, FontTestHelper::EXTERNAL);
  ASSERT_DOUBLE_EQ(
      1.0f,
      display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor());
  EXPECT_FALSE(IsTextSubpixelPositioningEnabled());
  EXPECT_NE(gfx::FontRenderParams::HINTING_NONE, GetFontHintingParams());
}

TEST_F(DisplayManagerFontTest, TextSubpixelPositioningWithDsf125External) {
  FontTestHelper helper(1.25f, FontTestHelper::EXTERNAL);
  ASSERT_DOUBLE_EQ(
      1.25f,
      display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor());
  EXPECT_TRUE(IsTextSubpixelPositioningEnabled());
  EXPECT_EQ(gfx::FontRenderParams::HINTING_NONE, GetFontHintingParams());
}

TEST_F(DisplayManagerFontTest, TextSubpixelPositioningWithDsf200External) {
  FontTestHelper helper(2.0f, FontTestHelper::EXTERNAL);
  ASSERT_DOUBLE_EQ(
      2.0f,
      display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor());
  EXPECT_FALSE(IsTextSubpixelPositioningEnabled());
  EXPECT_NE(gfx::FontRenderParams::HINTING_NONE, GetFontHintingParams());
}

TEST_F(DisplayManagerFontTest,
       TextSubpixelPositioningWithDsf125InternalWithScaling) {
  FontTestHelper helper(1.25f, FontTestHelper::INTERNAL);

  ASSERT_DOUBLE_EQ(
      1.25f,
      display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor());
  EXPECT_TRUE(IsTextSubpixelPositioningEnabled());
  EXPECT_EQ(gfx::FontRenderParams::HINTING_NONE, GetFontHintingParams());

  helper.display_manager()->UpdateZoomFactor(
      display::Screen::GetScreen()->GetPrimaryDisplay().id(), 0.8f);

  ASSERT_DOUBLE_EQ(
      1.f,
      display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor());
  EXPECT_FALSE(IsTextSubpixelPositioningEnabled());
  EXPECT_NE(gfx::FontRenderParams::HINTING_NONE, GetFontHintingParams());
}

TEST_F(DisplayManagerTest, SubsequentInitializationOfDisplayZoom) {
  int64_t id = display_manager()->GetDisplayAt(0).id();
  const float zoom_factor = 1.5f;
  // Negative value of ui scale means that this is not the first boot with
  // display zoom enabled.
  display_manager()->RegisterDisplayProperty(id, display::Display::ROTATE_0,
                                             -1000, nullptr, gfx::Size(), 1.f,
                                             zoom_factor, 60.f, false);

  const display::ManagedDisplayInfo& info =
      display_manager()->GetDisplayInfo(id);

  EXPECT_FLOAT_EQ(info.zoom_factor(), zoom_factor);
}

TEST_F(DisplayManagerTest, CheckInitializationOfRotationProperty) {
  int64_t id = display_manager()->GetDisplayAt(0).id();
  display_manager()->RegisterDisplayProperty(id, display::Display::ROTATE_90,
                                             1.0f, nullptr, gfx::Size(), 1.0f,
                                             1.0f, 60.f, false);

  const display::ManagedDisplayInfo& info =
      display_manager()->GetDisplayInfo(id);

  EXPECT_EQ(display::Display::ROTATE_90,
            info.GetRotation(display::Display::RotationSource::USER));
  EXPECT_EQ(display::Display::ROTATE_90,
            info.GetRotation(display::Display::RotationSource::ACTIVE));
}

TEST_F(DisplayManagerTest, RejectInvalidLayoutData) {
  display::DisplayLayoutStore* layout_store = display_manager()->layout_store();
  int64_t id1 = 10001;
  int64_t id2 = 10002;
  ASSERT_TRUE(display::CompareDisplayIds(id1, id2));
  display::DisplayLayoutBuilder good_builder(id1);
  good_builder.SetSecondaryPlacement(id2, display::DisplayPlacement::LEFT, 0);
  std::unique_ptr<display::DisplayLayout> good(good_builder.Build());

  display::DisplayIdList good_list =
      display::test::CreateDisplayIdList2(id1, id2);
  layout_store->RegisterLayoutForDisplayIdList(good_list, good->Copy());

  display::DisplayLayoutBuilder bad(id1);
  bad.SetSecondaryPlacement(id2, display::DisplayPlacement::BOTTOM, 0);

  display::DisplayIdList bad_list(2);
  bad_list[0] = id2;
  bad_list[1] = id1;
  layout_store->RegisterLayoutForDisplayIdList(bad_list, bad.Build());

  EXPECT_EQ(good->ToString(),
            layout_store->GetRegisteredDisplayLayout(good_list).ToString());
}

TEST_F(DisplayManagerTest, GuessDisplayIdFieldsInDisplayLayout) {
  int64_t id1 = 10001;
  int64_t id2 = 10002;

  std::unique_ptr<display::DisplayLayout> old_layout(
      new display::DisplayLayout);
  old_layout->placement_list.emplace_back(display::DisplayPlacement::BOTTOM, 0);
  old_layout->primary_id = id1;

  display::DisplayLayoutStore* layout_store = display_manager()->layout_store();
  display::DisplayIdList list = display::test::CreateDisplayIdList2(id1, id2);
  layout_store->RegisterLayoutForDisplayIdList(list, std::move(old_layout));
  const display::DisplayLayout& stored =
      layout_store->GetRegisteredDisplayLayout(list);

  EXPECT_EQ(id1, stored.placement_list[0].parent_display_id);
  EXPECT_EQ(id2, stored.placement_list[0].display_id);
}

TEST_F(DisplayManagerTest, AccelerometerSupport) {
  display::test::DisplayManagerTestApi(display_manager())
      .SetFirstDisplayAsInternalDisplay();
  display::Screen* screen = display::Screen::GetScreen();
  EXPECT_EQ(display::Display::AccelerometerSupport::UNAVAILABLE,
            screen->GetPrimaryDisplay().accelerometer_support());

  display_manager()->set_internal_display_has_accelerometer(true);
  display_manager()->UpdateDisplays();
  EXPECT_EQ(display::Display::AccelerometerSupport::AVAILABLE,
            screen->GetPrimaryDisplay().accelerometer_support());

  UpdateDisplay("1000x1000,800x800");
  EXPECT_EQ(display::Display::AccelerometerSupport::AVAILABLE,
            screen->GetPrimaryDisplay().accelerometer_support());
  EXPECT_EQ(display::Display::AccelerometerSupport::UNAVAILABLE,
            display_manager()->GetSecondaryDisplay().accelerometer_support());

  // Secondary is now primary and should not have accelerometer support.
  std::vector<display::ManagedDisplayInfo> display_info_list;
  display_info_list.push_back(
      display::CreateDisplayInfo(display_manager()->GetSecondaryDisplay().id(),
                                 gfx::Rect(1, 1, 100, 100)));
  display_manager()->OnNativeDisplaysChanged(display_info_list);
  EXPECT_EQ(display::Display::AccelerometerSupport::UNAVAILABLE,
            screen->GetPrimaryDisplay().accelerometer_support());

  // Re-enable internal display.
  display_info_list.clear();
  display_info_list.push_back(display::CreateDisplayInfo(
      display::Display::InternalDisplayId(), gfx::Rect(1, 1, 100, 100)));
  display_manager()->OnNativeDisplaysChanged(display_info_list);
  EXPECT_EQ(display::Display::AccelerometerSupport::AVAILABLE,
            screen->GetPrimaryDisplay().accelerometer_support());
}

namespace {

std::unique_ptr<display::DisplayMode> MakeDisplayMode() {
  return std::make_unique<display::DisplayMode>(gfx::Size(1366, 768), false,
                                                60);
}

}  // namespace

TEST_F(DisplayManagerTest, DisconnectedInternalDisplayShouldUpdateDisplayInfo) {
  constexpr int64_t external_id = 123;
  const int64_t internal_id =
      display::test::DisplayManagerTestApi(display_manager())
          .SetFirstDisplayAsInternalDisplay();
  display::Screen* screen = display::Screen::GetScreen();
  DCHECK(screen);
  Shell* shell = Shell::Get();
  display::DisplayChangeObserver observer(shell->display_manager());
  display::DisplayConfigurator::DisplayStateList outputs;
  std::unique_ptr<display::DisplaySnapshot> internal_snapshot =
      display::FakeDisplaySnapshot::Builder()
          .SetId(internal_id)
          .SetType(display::DISPLAY_CONNECTION_TYPE_INTERNAL)
          .SetDPI(210)  // 1.6f
          .SetNativeMode(MakeDisplayMode())
          .Build();
  EXPECT_FALSE(internal_snapshot->current_mode());

  outputs.push_back(internal_snapshot.get());
  std::unique_ptr<display::DisplaySnapshot> external_snapshot =
      display::FakeDisplaySnapshot::Builder()
          .SetId(external_id)
          .SetNativeMode(MakeDisplayMode())
          .AddMode(MakeDisplayMode())
          .SetOrigin({0, 1000})
          .Build();
  // "Connectd display" has the current mode.
  external_snapshot->set_current_mode(external_snapshot->native_mode());

  outputs.push_back(external_snapshot.get());

  // Update the display manager through DisplayChangeObserver.
  observer.GetStateForDisplayIds(outputs);
  observer.OnDisplayModeChanged(outputs);

  EXPECT_EQ(1u, display_manager()->GetNumDisplays());
  EXPECT_TRUE(display_manager()->IsActiveDisplayId(external_id));
  EXPECT_FALSE(display_manager()->IsActiveDisplayId(internal_id));

  const display::ManagedDisplayInfo& display_info =
      display_manager()->GetDisplayInfo(internal_id);
  EXPECT_EQ(1.6f, display_info.device_scale_factor());
  ASSERT_EQ(1u, display_info.display_modes().size());
  EXPECT_EQ(1.6f, display_info.display_modes()[0].device_scale_factor());
}

TEST_F(DisplayManagerTest, UpdateInternalDisplayNativeBounds) {
  constexpr int64_t external_id = 123;
  const int64_t internal_id =
      display::test::DisplayManagerTestApi(display_manager())
          .SetFirstDisplayAsInternalDisplay();
  display::Screen* screen = display::Screen::GetScreen();
  DCHECK(screen);
  display::DisplayChangeObserver observer(display_manager());
  display::DisplayConfigurator::DisplayStateList outputs;
  std::unique_ptr<display::DisplaySnapshot> internal_snapshot =
      display::FakeDisplaySnapshot::Builder()
          .SetId(internal_id)
          .SetType(display::DISPLAY_CONNECTION_TYPE_INTERNAL)
          .SetDPI(210)  // 1.6f
          .SetNativeMode(MakeDisplayMode())
          .Build();
  internal_snapshot->set_current_mode(internal_snapshot->native_mode());
  outputs.push_back(internal_snapshot.get());

  observer.GetStateForDisplayIds(outputs);
  observer.OnDisplayModeChanged(outputs);
  EXPECT_EQ(1u, display_manager()->GetNumDisplays());

  internal_snapshot->set_origin({0, 1000});

  std::unique_ptr<display::DisplaySnapshot> external_snapshot =
      display::FakeDisplaySnapshot::Builder()
          .SetId(external_id)
          .SetNativeMode(MakeDisplayMode())
          .AddMode(MakeDisplayMode())
          .Build();
  // "Connectd display" has the current mode.
  external_snapshot->set_current_mode(external_snapshot->native_mode());
  outputs.push_back(external_snapshot.get());

  reset();
  observer.GetStateForDisplayIds(outputs);
  observer.OnDisplayModeChanged(outputs);

  EXPECT_EQ(2u, display_manager()->GetNumDisplays());
  EXPECT_TRUE(changed_metrics() &
              display::DisplayObserver::DISPLAY_METRIC_BOUNDS);
}

// It's difficult to test with full stack due to crbug.com/771178.
// Improve the coverage once it is fixed.
TEST_F(DisplayManagerTest, ForcedMirrorMode) {
  // Disable restoring mirror mode to prevent interference from previous
  // display configuration.
  display_manager()->set_disable_restoring_mirror_mode_for_test(true);

  constexpr int64_t id1 = 1;
  constexpr int64_t id2 = 2;
  display::Screen* screen = display::Screen::GetScreen();
  DCHECK(screen);
  display::DisplayChangeObserver observer(display_manager());
  display::DisplayConfigurator::DisplayStateList outputs;
  std::unique_ptr<display::DisplaySnapshot> snapshot1 =
      display::FakeDisplaySnapshot::Builder()
          .SetId(id1)
          .SetNativeMode(MakeDisplayMode())
          .Build();
  std::unique_ptr<display::DisplaySnapshot> snapshot2 =
      display::FakeDisplaySnapshot::Builder()
          .SetId(id2)
          .SetNativeMode(MakeDisplayMode())
          .SetOrigin({0, 1000})
          .Build();
  snapshot1->set_current_mode(snapshot1->native_mode());
  snapshot2->set_current_mode(snapshot2->native_mode());

  outputs.push_back(snapshot1.get());
  outputs.push_back(snapshot2.get());

  EXPECT_EQ(display::MULTIPLE_DISPLAY_STATE_MULTI_EXTENDED,
            observer.GetStateForDisplayIds(outputs));

  display_manager()->layout_store()->set_forced_mirror_mode_for_tablet(true);

  observer.OnDisplayModeChanged(outputs);

  const display::DisplayIdList current_list =
      display_manager()->GetCurrentDisplayIdList();
  display_manager()->layout_store()->UpdateDefaultUnified(current_list,
                                                          false /* unified */);
  EXPECT_EQ(display::MULTIPLE_DISPLAY_STATE_MULTI_MIRROR,
            observer.GetStateForDisplayIds(outputs));

  display_manager()->layout_store()->set_forced_mirror_mode_for_tablet(false);

  EXPECT_EQ(display::MULTIPLE_DISPLAY_STATE_MULTI_EXTENDED,
            observer.GetStateForDisplayIds(outputs));

  display_manager()->set_disable_restoring_mirror_mode_for_test(false);
}

namespace {

class DisplayManagerOrientationTest : public DisplayManagerTest {
 public:
  DisplayManagerOrientationTest() = default;
  ~DisplayManagerOrientationTest() override = default;

  void SetUp() override {
    DisplayManagerTest::SetUp();
    const float kMeanGravity = 9.8066f;
    portrait_primary->Set(ACCELEROMETER_SOURCE_SCREEN, -kMeanGravity, 0.f, 0.f);
    portrait_secondary->Set(ACCELEROMETER_SOURCE_SCREEN, kMeanGravity, 0.f,
                            0.f);
    landscape_primary->Set(ACCELEROMETER_SOURCE_SCREEN, 0, -kMeanGravity, 0.f);
  }

 protected:
  scoped_refptr<AccelerometerUpdate> portrait_primary =
      new AccelerometerUpdate();
  scoped_refptr<AccelerometerUpdate> portrait_secondary =
      new AccelerometerUpdate();
  scoped_refptr<AccelerometerUpdate> landscape_primary =
      new AccelerometerUpdate();

 private:
  DISALLOW_COPY_AND_ASSIGN(DisplayManagerOrientationTest);
};

class TestObserver : public ScreenOrientationController::Observer {
 public:
  TestObserver() = default;
  ~TestObserver() override = default;

  void OnUserRotationLockChanged() override { count_++; }

  int countAndReset() {
    int tmp = count_;
    count_ = 0;
    return tmp;
  }

 private:
  int count_ = 0;
};

}  // namespace

TEST_F(DisplayManagerOrientationTest, SaveRestoreUserRotationLock) {
  Shell* shell = Shell::Get();
  display::DisplayManager* display_manager = shell->display_manager();
  display::test::DisplayManagerTestApi(display_manager)
      .SetFirstDisplayAsInternalDisplay();
  ScreenOrientationController* orientation_controller =
      shell->screen_orientation_controller();
  ScreenOrientationControllerTestApi test_api(orientation_controller);
  TestObserver test_observer;
  orientation_controller->AddObserver(&test_observer);

  // Set up windows with portrait,lanscape and any.
  aura::Window* window_a = CreateTestWindowInShellWithId(0);
  {
    window_a->SetProperty(aura::client::kAppType,
                          static_cast<int>(AppType::CHROME_APP));
    orientation_controller->LockOrientationForWindow(window_a,
                                                     OrientationLockType::kAny);
  }
  aura::Window* window_p = CreateTestWindowInShellWithId(0);
  {
    window_p->SetProperty(aura::client::kAppType,
                          static_cast<int>(AppType::CHROME_APP));
    orientation_controller->LockOrientationForWindow(
        window_p, OrientationLockType::kPortrait);
  }
  aura::Window* window_l = CreateTestWindowInShellWithId(0);
  {
    window_l->SetProperty(aura::client::kAppType,
                          static_cast<int>(AppType::CHROME_APP));
    orientation_controller->LockOrientationForWindow(
        window_l, OrientationLockType::kLandscape);
  }

  DisplayConfigurationController* configuration_controller =
      shell->display_configuration_controller();
  display::Screen* screen = display::Screen::GetScreen();

  // Rotate to portrait in clamshell.
  configuration_controller->SetDisplayRotation(
      screen->GetPrimaryDisplay().id(), display::Display::ROTATE_270,
      display::Display::RotationSource::USER);
  EXPECT_EQ(display::Display::ROTATE_270,
            screen->GetPrimaryDisplay().rotation());
  EXPECT_FALSE(display_manager->registered_internal_display_rotation_lock());

  EXPECT_EQ(0, test_observer.countAndReset());
  // Just enabling will not save the lock.
  Shell::Get()->tablet_mode_controller()->EnableTabletModeWindowManager(true);
  EXPECT_EQ(1, test_observer.countAndReset());

  EXPECT_EQ(display::Display::ROTATE_0, screen->GetPrimaryDisplay().rotation());
  EXPECT_FALSE(display_manager->registered_internal_display_rotation_lock());
  EXPECT_EQ(OrientationLockType::kLandscapePrimary,
            test_api.GetCurrentOrientation());

  // Enable lock at 0.
  orientation_controller->ToggleUserRotationLock();
  EXPECT_EQ(1, test_observer.countAndReset());

  EXPECT_TRUE(display_manager->registered_internal_display_rotation_lock());
  EXPECT_EQ(display::Display::ROTATE_0,
            display_manager->registered_internal_display_rotation());

  // Application can overwwrite the locked orientation.
  wm::ActivateWindow(window_p);
  EXPECT_EQ(display::Display::ROTATE_270,
            screen->GetPrimaryDisplay().rotation());
  EXPECT_EQ(display::Display::ROTATE_0,
            display_manager->registered_internal_display_rotation());
  EXPECT_EQ(0, test_observer.countAndReset());
  EXPECT_EQ(OrientationLockType::kPortraitPrimary,
            test_api.GetCurrentOrientation());

  // Any will rotate to the locked rotation.
  wm::ActivateWindow(window_a);
  EXPECT_EQ(display::Display::ROTATE_0, screen->GetPrimaryDisplay().rotation());
  EXPECT_TRUE(display_manager->registered_internal_display_rotation_lock());
  EXPECT_EQ(display::Display::ROTATE_0,
            display_manager->registered_internal_display_rotation());
  EXPECT_EQ(0, test_observer.countAndReset());

  wm::ActivateWindow(window_l);
  EXPECT_EQ(display::Display::ROTATE_0, screen->GetPrimaryDisplay().rotation());
  EXPECT_TRUE(display_manager->registered_internal_display_rotation_lock());
  EXPECT_EQ(display::Display::ROTATE_0,
            display_manager->registered_internal_display_rotation());
  EXPECT_EQ(0, test_observer.countAndReset());

  // Exit tablet mode reset to clamshell's rotation, which is 90.
  Shell::Get()->tablet_mode_controller()->EnableTabletModeWindowManager(false);
  EXPECT_EQ(1, test_observer.countAndReset());
  EXPECT_EQ(display::Display::ROTATE_270,
            screen->GetPrimaryDisplay().rotation());
  // Activate Any.
  wm::ActivateWindow(window_a);
  Shell::Get()->tablet_mode_controller()->EnableTabletModeWindowManager(true);
  EXPECT_EQ(1, test_observer.countAndReset());
  // Entering with active ANY will lock again to landscape.
  EXPECT_EQ(display::Display::ROTATE_0, screen->GetPrimaryDisplay().rotation());

  wm::ActivateWindow(window_p);
  EXPECT_EQ(display::Display::ROTATE_270,
            screen->GetPrimaryDisplay().rotation());
  EXPECT_EQ(0, test_observer.countAndReset());
  orientation_controller->ToggleUserRotationLock();
  orientation_controller->ToggleUserRotationLock();
  EXPECT_EQ(2, test_observer.countAndReset());

  EXPECT_TRUE(display_manager->registered_internal_display_rotation_lock());
  EXPECT_EQ(display::Display::ROTATE_270,
            display_manager->registered_internal_display_rotation());

  wm::ActivateWindow(window_l);
  EXPECT_EQ(display::Display::ROTATE_0, screen->GetPrimaryDisplay().rotation());
  EXPECT_EQ(display::Display::ROTATE_270,
            display_manager->registered_internal_display_rotation());

  // ANY will rotate to locked ortation.
  wm::ActivateWindow(window_a);
  EXPECT_EQ(display::Display::ROTATE_270,
            screen->GetPrimaryDisplay().rotation());

  orientation_controller->RemoveObserver(&test_observer);
}

TEST_F(DisplayManagerOrientationTest, UserRotationLockReverse) {
  Shell* shell = Shell::Get();
  display::DisplayManager* display_manager = shell->display_manager();
  display::test::DisplayManagerTestApi test_api(display_manager);
  test_api.SetFirstDisplayAsInternalDisplay();
  ScreenOrientationController* orientation_controller =
      shell->screen_orientation_controller();

  // Set up windows with portrait,lanscape and any.
  aura::Window* window = CreateTestWindowInShellWithId(0);
  window->SetProperty(aura::client::kAppType,
                      static_cast<int>(AppType::CHROME_APP));
  display::Screen* screen = display::Screen::GetScreen();

  // Just enabling will not save the lock.
  Shell::Get()->tablet_mode_controller()->EnableTabletModeWindowManager(true);

  orientation_controller->LockOrientationForWindow(
      window, OrientationLockType::kPortrait);
  EXPECT_EQ(display::Display::ROTATE_270,
            screen->GetPrimaryDisplay().rotation());

  orientation_controller->OnAccelerometerUpdated(portrait_secondary);

  EXPECT_EQ(display::Display::ROTATE_90,
            screen->GetPrimaryDisplay().rotation());

  orientation_controller->OnAccelerometerUpdated(portrait_primary);
  EXPECT_EQ(display::Display::ROTATE_270,
            screen->GetPrimaryDisplay().rotation());

  // Enable lock at 270.
  orientation_controller->ToggleUserRotationLock();
  EXPECT_TRUE(display_manager->registered_internal_display_rotation_lock());
  EXPECT_EQ(display::Display::ROTATE_270,
            display_manager->registered_internal_display_rotation());

  orientation_controller->OnAccelerometerUpdated(portrait_secondary);

  EXPECT_EQ(display::Display::ROTATE_270,
            screen->GetPrimaryDisplay().rotation());
}

TEST_F(DisplayManagerOrientationTest, LockToSpecificOrientation) {
  Shell* shell = Shell::Get();
  display::DisplayManager* display_manager = shell->display_manager();
  display::test::DisplayManagerTestApi(display_manager)
      .SetFirstDisplayAsInternalDisplay();
  ScreenOrientationController* orientation_controller =
      shell->screen_orientation_controller();
  ScreenOrientationControllerTestApi test_api(orientation_controller);

  aura::Window* window_a = CreateTestWindowInShellWithId(0);
  {
    window_a->SetProperty(aura::client::kAppType,
                          static_cast<int>(AppType::CHROME_APP));
    orientation_controller->LockOrientationForWindow(window_a,
                                                     OrientationLockType::kAny);
  }
  wm::ActivateWindow(window_a);
  Shell::Get()->tablet_mode_controller()->EnableTabletModeWindowManager(true);

  orientation_controller->OnAccelerometerUpdated(portrait_primary);

  EXPECT_EQ(OrientationLockType::kPortraitPrimary,
            test_api.GetCurrentOrientation());

  orientation_controller->OnAccelerometerUpdated(portrait_secondary);

  aura::Window* window_lsc = CreateTestWindowInShellWithId(1);
  window_lsc->SetProperty(aura::client::kAppType,
                          static_cast<int>(AppType::CHROME_APP));

  aura::Window* window_psc = CreateTestWindowInShellWithId(1);
  window_psc->SetProperty(aura::client::kAppType,
                          static_cast<int>(AppType::CHROME_APP));

  orientation_controller->LockOrientationForWindow(
      window_psc, OrientationLockType::kPortraitSecondary);
  orientation_controller->LockOrientationForWindow(
      window_psc, OrientationLockType::kCurrent);
  wm::ActivateWindow(window_psc);

  orientation_controller->LockOrientationForWindow(
      window_lsc, OrientationLockType::kLandscapeSecondary);
  orientation_controller->LockOrientationForWindow(
      window_lsc, OrientationLockType::kCurrent);

  EXPECT_EQ(OrientationLockType::kPortraitSecondary,
            test_api.GetCurrentOrientation());

  // The orientation should stay portrait secondary.
  orientation_controller->OnAccelerometerUpdated(portrait_primary);
  EXPECT_EQ(OrientationLockType::kPortraitSecondary,
            test_api.GetCurrentOrientation());
  wm::ActivateWindow(window_lsc);

  EXPECT_EQ(OrientationLockType::kLandscapeSecondary,
            test_api.GetCurrentOrientation());

  // The orientation should stay landscape secondary.
  orientation_controller->OnAccelerometerUpdated(landscape_primary);
  EXPECT_EQ(OrientationLockType::kLandscapeSecondary,
            test_api.GetCurrentOrientation());

  wm::ActivateWindow(window_a);
  orientation_controller->OnAccelerometerUpdated(portrait_primary);

  // Swtching to |window_a| enables rotation.
  EXPECT_EQ(OrientationLockType::kPortraitPrimary,
            test_api.GetCurrentOrientation());

  // The orientation has alraedy been locked to secondary once, so
  // it should swtich back to the portrait secondary.
  wm::ActivateWindow(window_psc);
  EXPECT_EQ(OrientationLockType::kPortraitSecondary,
            test_api.GetCurrentOrientation());
}

// crbug.com/734107
TEST_F(DisplayManagerOrientationTest, DisplayChangeShouldNotSaveUserRotation) {
  Shell* shell = Shell::Get();
  display::DisplayManager* display_manager = shell->display_manager();
  display::test::DisplayManagerTestApi test_api(display_manager);
  test_api.SetFirstDisplayAsInternalDisplay();
  display::Screen* screen = display::Screen::GetScreen();

  Shell::Get()->tablet_mode_controller()->EnableTabletModeWindowManager(true);
  // Emulate that Animator is calling this async when animation is completed.
  display_manager->SetDisplayRotation(
      screen->GetPrimaryDisplay().id(), display::Display::ROTATE_90,
      display::Display::RotationSource::ACCELEROMETER);
  EXPECT_EQ(display::Display::ROTATE_90,
            screen->GetPrimaryDisplay().rotation());

  Shell::Get()->tablet_mode_controller()->EnableTabletModeWindowManager(false);
  EXPECT_EQ(display::Display::ROTATE_0, screen->GetPrimaryDisplay().rotation());
}

TEST_F(DisplayManagerTest, HardwareMirrorMode) {
  // Create three displays with the same origin in frame buffer.
  const int64_t internal_display_id =
      display::test::DisplayManagerTestApi(display_manager())
          .SetFirstDisplayAsInternalDisplay();
  constexpr int64_t first_mirror_id = 11;
  constexpr int64_t second_mirror_id = 12;
  std::vector<display::ManagedDisplayInfo> display_info_list;
  display_info_list.push_back(display::CreateDisplayInfo(
      internal_display_id, gfx::Rect(0, 0, 500, 500)));
  display_info_list.push_back(
      display::CreateDisplayInfo(first_mirror_id, gfx::Rect(0, 0, 500, 500)));
  display_info_list.push_back(
      display::CreateDisplayInfo(second_mirror_id, gfx::Rect(0, 0, 500, 500)));

  // mirrored across 3 displays...
  display_manager()->OnNativeDisplaysChanged(display_info_list);
  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(1U, display_manager()->GetNumDisplays());
  EXPECT_EQ(3U, display_manager()->num_connected_displays());

  EXPECT_EQ(internal_display_id, display_manager()->mirroring_source_id());
  EXPECT_EQ(gfx::Rect(0, 0, 500, 500),
            GetDisplayForId(internal_display_id).bounds());

  const display::DisplayIdList id_list =
      display_manager()->GetMirroringDestinationDisplayIdList();
  ASSERT_EQ(2U, id_list.size());
  EXPECT_EQ(11U, id_list[0]);
  EXPECT_EQ(12U, id_list[1]);

  EXPECT_FALSE(display_manager()->IsInSoftwareMirrorMode());
  EXPECT_TRUE(display_manager()->IsInHardwareMirrorMode());
}

TEST_F(DisplayManagerTest, SoftwareMirrorModeBasics) {
  UpdateDisplay("300x400,400x500,500x600");

  // There's not mirror window by default.
  MirrorWindowTestApi test_api;
  EXPECT_TRUE(test_api.GetHosts().empty());

  TestDisplayObserver display_observer;
  display::Screen::GetScreen()->AddObserver(&display_observer);

  // Turn on mirror mode.
  SetSoftwareMirrorMode(true);
  EXPECT_TRUE(display_observer.changed_and_reset());
  EXPECT_EQ(1U, display_manager()->GetNumDisplays());
  EXPECT_EQ(gfx::Rect(0, 0, 300, 400),
            display::Screen::GetScreen()->GetPrimaryDisplay().bounds());

  std::vector<aura::WindowTreeHost*> host_list = test_api.GetHosts();
  ASSERT_EQ(2U, host_list.size());
  EXPECT_EQ(gfx::Size(400, 500), host_list[0]->GetBoundsInPixels().size());
  EXPECT_EQ(gfx::Size(300, 400), host_list[0]->window()->bounds().size());
  EXPECT_EQ(gfx::Size(500, 600), host_list[1]->GetBoundsInPixels().size());
  EXPECT_EQ(gfx::Size(300, 400), host_list[1]->window()->bounds().size());

  EXPECT_TRUE(display_manager()->IsInSoftwareMirrorMode());
  EXPECT_FALSE(display_manager()->IsInHardwareMirrorMode());

  // Turn off mirror mode.
  SetSoftwareMirrorMode(false);
  EXPECT_TRUE(display_observer.changed_and_reset());
  EXPECT_EQ(3U, display_manager()->GetNumDisplays());

  host_list = test_api.GetHosts();
  EXPECT_TRUE(host_list.empty());

  EXPECT_FALSE(display_manager()->IsInMirrorMode());

  // Make sure the mirror window has the pixel size of the
  // source display.
  SetSoftwareMirrorMode(true);
  EXPECT_TRUE(display_observer.changed_and_reset());

  UpdateDisplay("300x400@0.5,400x500,500x600");
  EXPECT_FALSE(display_observer.changed_and_reset());
  host_list = test_api.GetHosts();
  EXPECT_EQ(gfx::Size(300, 400), host_list[0]->window()->bounds().size());
  EXPECT_EQ(gfx::Size(300, 400), host_list[1]->window()->bounds().size());

  UpdateDisplay("310x410*2,400x500,500x600");
  EXPECT_FALSE(display_observer.changed_and_reset());
  host_list = test_api.GetHosts();
  EXPECT_EQ(gfx::Size(310, 410), host_list[0]->window()->bounds().size());
  EXPECT_EQ(gfx::Size(310, 410), host_list[1]->window()->bounds().size());

  UpdateDisplay("320x420/r,400x500,500x600");
  EXPECT_FALSE(display_observer.changed_and_reset());
  host_list = test_api.GetHosts();
  EXPECT_EQ(gfx::Size(320, 420), host_list[0]->window()->bounds().size());
  EXPECT_EQ(gfx::Size(320, 420), host_list[1]->window()->bounds().size());

  UpdateDisplay("330x440/r,400x500,500x600");
  EXPECT_FALSE(display_observer.changed_and_reset());
  host_list = test_api.GetHosts();
  EXPECT_EQ(gfx::Size(330, 440), host_list[0]->window()->bounds().size());
  EXPECT_EQ(gfx::Size(330, 440), host_list[1]->window()->bounds().size());

  // Overscan insets are ignored.
  UpdateDisplay("400x600/o,600x800/o,500x600/o");
  EXPECT_FALSE(display_observer.changed_and_reset());
  host_list = test_api.GetHosts();
  EXPECT_EQ(gfx::Size(400, 600), host_list[0]->window()->bounds().size());
  EXPECT_EQ(gfx::Size(400, 600), host_list[1]->window()->bounds().size());

  display::Screen::GetScreen()->RemoveObserver(&display_observer);
}

TEST_F(DisplayManagerTest, SwitchToAndFromSoftwareMirrorMode) {
  // Don't check root window destruction in unified mode.
  Shell::GetPrimaryRootWindow()->RemoveObserver(this);

  UpdateDisplay("300x400,400x500,500x600");

  // Switch from extended to mirroring.
  SetSoftwareMirrorMode(true);
  EXPECT_TRUE(display_manager()->IsInSoftwareMirrorMode());
  EXPECT_FALSE(display_manager()->IsInUnifiedMode());

  // Switch from mirroring to extended.
  SetSoftwareMirrorMode(false);
  EXPECT_FALSE(display_manager()->IsInMirrorMode());
  EXPECT_FALSE(display_manager()->IsInUnifiedMode());

  // Switch from mirroring to unified, but it fails.
  SetSoftwareMirrorMode(true);
  display_manager()->SetUnifiedDesktopEnabled(true);
  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(display_manager()->IsInSoftwareMirrorMode());
  EXPECT_FALSE(display_manager()->IsInUnifiedMode());

  // Turn off mirroring, it switches to unified.
  SetSoftwareMirrorMode(false);
  EXPECT_FALSE(display_manager()->IsInMirrorMode());
  EXPECT_TRUE(display_manager()->IsInUnifiedMode());

  // Switch from unified to mirroring.
  SetSoftwareMirrorMode(true);
  EXPECT_TRUE(display_manager()->IsInSoftwareMirrorMode());
  EXPECT_FALSE(display_manager()->IsInUnifiedMode());
}

TEST_F(DisplayManagerTest, SourceAndDestinationInSoftwareMirrorMode) {
  constexpr int64_t first_display_id = 10;
  constexpr int64_t second_display_id = 11;
  constexpr int64_t third_display_id = 12;
  std::vector<display::ManagedDisplayInfo> display_info_list;
  display_info_list.emplace_back(
      display::CreateDisplayInfo(first_display_id, gfx::Rect(0, 0, 100, 100)));
  display_info_list.emplace_back(
      display::CreateDisplayInfo(second_display_id, gfx::Rect(1, 1, 500, 500)));
  display_info_list.emplace_back(
      display::CreateDisplayInfo(third_display_id, gfx::Rect(2, 2, 500, 500)));

  // Connect all displays.
  display_manager()->OnNativeDisplaysChanged(display_info_list);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(display::kInvalidDisplayId,
            display_manager()->mirroring_source_id());
  EXPECT_TRUE(
      display_manager()->GetMirroringDestinationDisplayIdList().empty());

  // Activate software mirror mode.
  SetSoftwareMirrorMode(true);
  EXPECT_EQ(first_display_id, display_manager()->mirroring_source_id());
  display::DisplayIdList id_list =
      display_manager()->GetMirroringDestinationDisplayIdList();
  EXPECT_EQ(2U, id_list.size());
  EXPECT_EQ(second_display_id, id_list[0]);
  EXPECT_EQ(third_display_id, id_list[1]);

  // Set the second display as internal display.
  SetSoftwareMirrorMode(false);

  display::test::ScopedSetInternalDisplayId set_internal(display_manager(),
                                                         second_display_id);
  SetSoftwareMirrorMode(true);
  EXPECT_TRUE(display_manager()->IsInSoftwareMirrorMode());
  EXPECT_EQ(second_display_id, display_manager()->mirroring_source_id());
  id_list = display_manager()->GetMirroringDestinationDisplayIdList();
  EXPECT_EQ(2U, id_list.size());
  EXPECT_EQ(first_display_id, id_list[0]);
  EXPECT_EQ(third_display_id, id_list[1]);
}

TEST_F(DisplayManagerTest, CompositingCursorInMultiSoftwareMirroring) {
  const int64_t internal_display_id =
      display::test::DisplayManagerTestApi(display_manager())
          .SetFirstDisplayAsInternalDisplay();
  constexpr int64_t first_mirror_id = 11;
  constexpr int64_t second_mirror_id = 12;
  std::vector<display::ManagedDisplayInfo> display_info_list;
  display_info_list.push_back(display::CreateDisplayInfo(
      internal_display_id, gfx::Rect(0, 0, 100, 100)));
  display_info_list.push_back(
      display::CreateDisplayInfo(first_mirror_id, gfx::Rect(1, 1, 500, 500)));
  display_info_list.push_back(
      display::CreateDisplayInfo(second_mirror_id, gfx::Rect(2, 2, 500, 500)));

  // Connect all displays, cursor compositing is disabled by default.
  display_manager()->OnNativeDisplaysChanged(display_info_list);
  base::RunLoop().RunUntilIdle();
  CursorWindowController* cursor_window_controller =
      Shell::Get()->window_tree_host_manager()->cursor_window_controller();
  EXPECT_FALSE(cursor_window_controller->is_cursor_compositing_enabled());
  MirrorWindowTestApi test_api;
  EXPECT_EQ(nullptr, test_api.GetCursorWindow());

  // Turn on mirror mode, cursor compositing is enabled and cursor window is
  // composited in internal display's root window.
  SetSoftwareMirrorMode(true);
  EXPECT_TRUE(cursor_window_controller->is_cursor_compositing_enabled());
  EXPECT_TRUE(Shell::GetRootWindowForDisplayId(internal_display_id)
                  ->Contains(test_api.GetCursorWindow()));

  // Turn off mirror mode, cursor compositing is disabled and cursor window does
  // not exist.
  SetSoftwareMirrorMode(false);
  EXPECT_FALSE(cursor_window_controller->is_cursor_compositing_enabled());
  EXPECT_EQ(nullptr, test_api.GetCursorWindow());
}

TEST_F(DisplayManagerTest, MirrorModeRestore) {
  const int64_t internal_display_id =
      display::test::DisplayManagerTestApi(display_manager())
          .SetFirstDisplayAsInternalDisplay();
  constexpr int64_t first_display_id = 210000001;
  constexpr int64_t second_display_id = 220000002;
  const int64_t first_display_masked_id =
      display::GetDisplayIdWithoutOutputIndex(first_display_id);
  const int64_t second_display_masked_id =
      display::GetDisplayIdWithoutOutputIndex(second_display_id);
  display::ManagedDisplayInfo first_mirror_info =
      display::CreateDisplayInfo(first_display_id, gfx::Rect(1, 1, 500, 500));
  display::ManagedDisplayInfo second_mirror_info =
      display::CreateDisplayInfo(second_display_id, gfx::Rect(2, 2, 500, 500));
  std::vector<display::ManagedDisplayInfo> display_info_list;

  // There's no external display now.
  display_info_list.push_back(display::CreateDisplayInfo(
      internal_display_id, gfx::Rect(0, 0, 100, 100)));
  display_manager()->OnNativeDisplaysChanged(display_info_list);
  EXPECT_FALSE(display_manager()->IsInMirrorMode());
  EXPECT_TRUE(display_manager()->external_display_mirror_info().empty());

  // Connect the first external display.
  display_info_list.push_back(first_mirror_info);
  display_manager()->OnNativeDisplaysChanged(display_info_list);
  EXPECT_FALSE(display_manager()->IsInMirrorMode());
  EXPECT_TRUE(display_manager()->external_display_mirror_info().empty());

  // Turn on mirror mode.
  SetSoftwareMirrorMode(true);
  EXPECT_TRUE(display_manager()->IsInMirrorMode());
  EXPECT_EQ(1U, display_manager()->external_display_mirror_info().size());
  EXPECT_TRUE(display_manager()->external_display_mirror_info().count(
      first_display_masked_id));

  // Remove the first external display.
  display_info_list.erase(display_info_list.end() - 1);
  display_manager()->OnNativeDisplaysChanged(display_info_list);
  EXPECT_FALSE(display_manager()->IsInMirrorMode());
  EXPECT_EQ(1U, display_manager()->external_display_mirror_info().size());
  EXPECT_TRUE(display_manager()->external_display_mirror_info().count(
      first_display_masked_id));

  // Reconnect the first external display.
  display_info_list.push_back(first_mirror_info);
  display_manager()->OnNativeDisplaysChanged(display_info_list);
  EXPECT_TRUE(display_manager()->IsInMirrorMode());
  EXPECT_EQ(1U, display_manager()->external_display_mirror_info().size());
  EXPECT_TRUE(display_manager()->external_display_mirror_info().count(
      first_display_masked_id));

  // Remove the first external display.
  display_info_list.erase(display_info_list.end() - 1);
  display_manager()->OnNativeDisplaysChanged(display_info_list);
  EXPECT_FALSE(display_manager()->IsInMirrorMode());
  EXPECT_EQ(1U, display_manager()->external_display_mirror_info().size());
  EXPECT_TRUE(display_manager()->external_display_mirror_info().count(
      first_display_masked_id));

  // Connect the second external display.
  display_info_list.push_back(second_mirror_info);
  display_manager()->OnNativeDisplaysChanged(display_info_list);
  EXPECT_FALSE(display_manager()->IsInMirrorMode());
  EXPECT_EQ(1U, display_manager()->external_display_mirror_info().size());
  EXPECT_TRUE(display_manager()->external_display_mirror_info().count(
      first_display_masked_id));

  // Remove the second external display.
  display_info_list.erase(display_info_list.end() - 1);
  display_manager()->OnNativeDisplaysChanged(display_info_list);
  EXPECT_FALSE(display_manager()->IsInMirrorMode());
  EXPECT_EQ(1U, display_manager()->external_display_mirror_info().size());
  EXPECT_TRUE(display_manager()->external_display_mirror_info().count(
      first_display_masked_id));

  // Add the first and then add the second external display (not mirrored
  // before).
  display_info_list.push_back(first_mirror_info);
  display_manager()->OnNativeDisplaysChanged(display_info_list);
  display_info_list.push_back(second_mirror_info);
  display_manager()->OnNativeDisplaysChanged(display_info_list);
  EXPECT_TRUE(display_manager()->IsInMirrorMode());
  EXPECT_EQ(2U, display_manager()->external_display_mirror_info().size());
  EXPECT_TRUE(display_manager()->external_display_mirror_info().count(
      first_display_masked_id));
  EXPECT_TRUE(display_manager()->external_display_mirror_info().count(
      second_display_masked_id));

  // Remove the second display.
  display_info_list.erase(display_info_list.end() - 1);
  display_manager()->OnNativeDisplaysChanged(display_info_list);
  EXPECT_TRUE(display_manager()->IsInMirrorMode());
  EXPECT_EQ(2U, display_manager()->external_display_mirror_info().size());
  EXPECT_TRUE(display_manager()->external_display_mirror_info().count(
      first_display_masked_id));
  EXPECT_TRUE(display_manager()->external_display_mirror_info().count(
      second_display_masked_id));

  // Remove the first display and then add the second display.
  display_info_list.erase(display_info_list.end() - 1);
  display_manager()->OnNativeDisplaysChanged(display_info_list);
  display_info_list.push_back(second_mirror_info);
  display_manager()->OnNativeDisplaysChanged(display_info_list);
  EXPECT_TRUE(display_manager()->IsInMirrorMode());
  EXPECT_EQ(2U, display_manager()->external_display_mirror_info().size());
  EXPECT_TRUE(display_manager()->external_display_mirror_info().count(
      first_display_masked_id));
  EXPECT_TRUE(display_manager()->external_display_mirror_info().count(
      second_display_masked_id));

  // Turn off mirror mode.
  SetSoftwareMirrorMode(false);
  EXPECT_FALSE(display_manager()->IsInMirrorMode());
  EXPECT_EQ(1U, display_manager()->external_display_mirror_info().size());
  EXPECT_TRUE(display_manager()->external_display_mirror_info().count(
      first_display_masked_id));

  // Add the first display (mirrored before).
  display_info_list.push_back(first_mirror_info);
  display_manager()->OnNativeDisplaysChanged(display_info_list);
  EXPECT_FALSE(display_manager()->IsInMirrorMode());
  EXPECT_FALSE(display_manager()->IsInMirrorMode());
  EXPECT_TRUE(display_manager()->external_display_mirror_info().empty());
}

TEST_F(DisplayManagerTest, MixedMirrorModeBasics) {
  UpdateDisplay("300x400,400x500,500x600");
  display::DisplayIdList id_list = display_manager()->GetCurrentDisplayIdList();

  // Turn on mixed mirror mode. (Mirror from the first display to the second
  // display)
  display::DisplayIdList dst_ids;
  dst_ids.emplace_back(id_list[1]);
  base::Optional<display::MixedMirrorModeParams> mixed_params(
      base::in_place, id_list[0], dst_ids);
  display_manager()->SetMirrorMode(display::MirrorMode::kMixed, mixed_params);
  EXPECT_TRUE(display_manager()->IsInSoftwareMirrorMode());
  EXPECT_EQ(id_list[0], display_manager()->mirroring_source_id());
  display::DisplayIdList destination_ids =
      display_manager()->GetMirroringDestinationDisplayIdList();
  EXPECT_EQ(1U, destination_ids.size());
  EXPECT_EQ(id_list[1], destination_ids[0]);
  EXPECT_TRUE(display_manager()->mixed_mirror_mode_params());

  // Turn off mirror mode.
  display_manager()->SetMirrorMode(display::MirrorMode::kOff, base::nullopt);
  EXPECT_FALSE(display_manager()->IsInMirrorMode());
  EXPECT_FALSE(display_manager()->mixed_mirror_mode_params());
}

TEST_F(DisplayManagerTest, MixedMirrorModeToMirrorMode) {
  UpdateDisplay("300x400,400x500,500x600");
  display::DisplayIdList id_list = display_manager()->GetCurrentDisplayIdList();

  // Turn on mixed mirror mode. (Mirror from the first display to the second
  // display)
  display::DisplayIdList dst_ids;
  dst_ids.emplace_back(id_list[1]);
  base::Optional<display::MixedMirrorModeParams> mixed_params(
      base::in_place, id_list[0], dst_ids);
  display_manager()->SetMirrorMode(display::MirrorMode::kMixed, mixed_params);
  EXPECT_TRUE(display_manager()->IsInSoftwareMirrorMode());
  EXPECT_EQ(id_list[0], display_manager()->mirroring_source_id());
  display::DisplayIdList destination_ids =
      display_manager()->GetMirroringDestinationDisplayIdList();
  EXPECT_EQ(1U, destination_ids.size());
  EXPECT_EQ(id_list[1], destination_ids[0]);
  EXPECT_TRUE(display_manager()->mixed_mirror_mode_params());

  // Overwrite mixed mirror mode with default mirror mode (Mirror all
  // displays).
  display_manager()->SetMirrorMode(display::MirrorMode::kNormal, base::nullopt);
  EXPECT_TRUE(display_manager()->IsInMirrorMode());
  EXPECT_EQ(id_list[0], display_manager()->mirroring_source_id());
  destination_ids = display_manager()->GetMirroringDestinationDisplayIdList();
  EXPECT_EQ(2U, destination_ids.size());
  EXPECT_EQ(id_list[1], destination_ids[0]);
  EXPECT_EQ(id_list[2], destination_ids[1]);
  EXPECT_FALSE(display_manager()->mixed_mirror_mode_params());
}

TEST_F(DisplayManagerTest, MirrorModeToMixedMirrorMode) {
  UpdateDisplay("300x400,400x500,500x600");
  display::DisplayIdList id_list = display_manager()->GetCurrentDisplayIdList();

  // Turn on mirror mode.
  display_manager()->SetMirrorMode(display::MirrorMode::kNormal, base::nullopt);
  EXPECT_TRUE(display_manager()->IsInMirrorMode());
  EXPECT_EQ(id_list[0], display_manager()->mirroring_source_id());
  display::DisplayIdList destination_ids =
      display_manager()->GetMirroringDestinationDisplayIdList();
  EXPECT_EQ(2U, destination_ids.size());
  EXPECT_EQ(id_list[1], destination_ids[0]);
  EXPECT_EQ(id_list[2], destination_ids[1]);
  EXPECT_FALSE(display_manager()->mixed_mirror_mode_params());

  // Overwrite default mirror mode with mixed mirror mode. (Mirror from the
  // first display to the second display)
  display::DisplayIdList dst_ids;
  dst_ids.emplace_back(id_list[1]);
  base::Optional<display::MixedMirrorModeParams> mixed_params(
      base::in_place, id_list[0], dst_ids);
  display_manager()->SetMirrorMode(display::MirrorMode::kMixed, mixed_params);
  EXPECT_TRUE(display_manager()->IsInSoftwareMirrorMode());
  EXPECT_EQ(id_list[0], display_manager()->mirroring_source_id());
  destination_ids = display_manager()->GetMirroringDestinationDisplayIdList();
  EXPECT_EQ(1U, destination_ids.size());
  EXPECT_EQ(id_list[1], destination_ids[0]);
  EXPECT_TRUE(display_manager()->mixed_mirror_mode_params());
}

TEST_F(DisplayManagerTest, MixedMirrorModeRestore) {
  const int64_t internal_display_id =
      display::test::DisplayManagerTestApi(display_manager())
          .SetFirstDisplayAsInternalDisplay();
  constexpr int64_t first_display_id = 210000001;
  constexpr int64_t second_display_id = 220000002;
  display::ManagedDisplayInfo first_mirror_info =
      display::CreateDisplayInfo(first_display_id, gfx::Rect(1, 1, 500, 500));
  display::ManagedDisplayInfo second_mirror_info =
      display::CreateDisplayInfo(second_display_id, gfx::Rect(2, 2, 500, 500));
  std::vector<display::ManagedDisplayInfo> display_info_list;

  // Connect the first and second displays.
  display_info_list.push_back(display::CreateDisplayInfo(
      internal_display_id, gfx::Rect(0, 0, 100, 100)));
  display_info_list.push_back(first_mirror_info);
  display_info_list.push_back(second_mirror_info);
  display_manager()->OnNativeDisplaysChanged(display_info_list);

  // Turn on mixed mirror mode. (Mirror from the internal display to the
  // first display)
  display::DisplayIdList dst_ids;
  dst_ids.emplace_back(first_display_id);
  base::Optional<display::MixedMirrorModeParams> mixed_params(
      base::in_place, internal_display_id, dst_ids);
  display_manager()->SetMirrorMode(display::MirrorMode::kMixed, mixed_params);
  EXPECT_TRUE(display_manager()->IsInSoftwareMirrorMode());
  EXPECT_EQ(internal_display_id, display_manager()->mirroring_source_id());
  display::DisplayIdList destination_ids =
      display_manager()->GetMirroringDestinationDisplayIdList();
  EXPECT_EQ(1U, destination_ids.size());
  EXPECT_EQ(first_display_id, destination_ids[0]);

  // Remove the second display. Mirroring is not changed.
  display_info_list.erase(display_info_list.end() - 1);
  display_manager()->OnNativeDisplaysChanged(display_info_list);
  EXPECT_TRUE(display_manager()->IsInSoftwareMirrorMode());
  EXPECT_EQ(internal_display_id, display_manager()->mirroring_source_id());
  destination_ids = display_manager()->GetMirroringDestinationDisplayIdList();
  EXPECT_EQ(1U, destination_ids.size());
  EXPECT_EQ(first_display_id, destination_ids[0]);

  // Add the second display. Mirroring is not changed.
  display_info_list.push_back(second_mirror_info);
  display_manager()->OnNativeDisplaysChanged(display_info_list);
  EXPECT_TRUE(display_manager()->IsInSoftwareMirrorMode());
  EXPECT_EQ(internal_display_id, display_manager()->mirroring_source_id());
  destination_ids = display_manager()->GetMirroringDestinationDisplayIdList();
  EXPECT_EQ(1U, destination_ids.size());
  EXPECT_EQ(first_display_id, destination_ids[0]);

  // Remove the first display. Mirroring ends.
  display_info_list.erase(display_info_list.end() - 2);
  display_manager()->OnNativeDisplaysChanged(display_info_list);
  EXPECT_FALSE(display_manager()->IsInMirrorMode());

  // Add the first display. Mirroring is restored.
  display_info_list.push_back(first_mirror_info);
  display_manager()->OnNativeDisplaysChanged(display_info_list);
  EXPECT_TRUE(display_manager()->IsInSoftwareMirrorMode());
  EXPECT_EQ(internal_display_id, display_manager()->mirroring_source_id());
  destination_ids = display_manager()->GetMirroringDestinationDisplayIdList();
  EXPECT_EQ(1U, destination_ids.size());
  EXPECT_EQ(first_display_id, destination_ids[0]);
}

TEST_F(DisplayManagerTest, MirrorModeRestoreAfterResume) {
  const int64_t internal_display_id =
      display::test::DisplayManagerTestApi(display_manager())
          .SetFirstDisplayAsInternalDisplay();
  constexpr int64_t external_display_id = 210000001;
  std::vector<display::ManagedDisplayInfo> display_info_list;
  display_info_list.emplace_back(display::CreateDisplayInfo(
      internal_display_id, gfx::Rect(0, 0, 100, 100)));
  display_info_list.emplace_back(display::CreateDisplayInfo(
      external_display_id, gfx::Rect(1, 1, 500, 500)));

  // Turn on mirror mode.
  display_manager()->OnNativeDisplaysChanged(display_info_list);
  display_manager()->SetMirrorMode(display::MirrorMode::kNormal, base::nullopt);
  EXPECT_TRUE(display_manager()->IsInMirrorMode());

  // Suspend.
  display_manager()->SetMultiDisplayMode(display::DisplayManager::MIRRORING);
  display_manager()->OnNativeDisplaysChanged(
      std::vector<display::ManagedDisplayInfo>());
  EXPECT_TRUE(display_manager()->IsInMirrorMode());

  // Resume.
  display_manager()->SetMultiDisplayMode(display::DisplayManager::MIRRORING);
  display_manager()->OnNativeDisplaysChanged(display_info_list);
  EXPECT_TRUE(display_manager()->IsInMirrorMode());
}

TEST_F(DisplayManagerTest, SoftwareMirrorRotationForTablet) {
  UpdateDisplay("400x300,800x800");
  base::RunLoop().RunUntilIdle();

  // Set the first display as internal display so that the tablet mode can be
  // enabled.
  display::test::DisplayManagerTestApi(display_manager())
      .SetFirstDisplayAsInternalDisplay();

  // Simulate turning on mirror mode triggered by tablet mode on.
  Shell::Get()->tablet_mode_controller()->EnableTabletModeWindowManager(true);
  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(display_manager()->IsInSoftwareMirrorMode());
  EXPECT_EQ(gfx::Rect(0, 0, 400, 300),
            display::Screen::GetScreen()->GetPrimaryDisplay().bounds());
  MirrorWindowTestApi test_api;
  std::vector<aura::WindowTreeHost*> host_list = test_api.GetHosts();
  ASSERT_EQ(1U, host_list.size());
  EXPECT_EQ(gfx::Size(800, 800), host_list[0]->GetBoundsInPixels().size());
  EXPECT_EQ(gfx::Size(400, 300), host_list[0]->window()->bounds().size());

  // Test the target display's bounds after the transforms are applied.
  gfx::RectF transformed_rect1(
      display::Screen::GetScreen()->GetPrimaryDisplay().bounds());
  Shell::Get()->GetPrimaryRootWindow()->transform().TransformRect(
      &transformed_rect1);
  host_list[0]->window()->transform().TransformRect(&transformed_rect1);
  EXPECT_EQ(gfx::RectF(0.0f, 100.0f, 800.0f, 600.0f), transformed_rect1);

  // Rotate the source display by 90 degrees.
  UpdateDisplay("400x300/r,800x800");
  EXPECT_TRUE(display_manager()->IsInSoftwareMirrorMode());
  EXPECT_EQ(gfx::Rect(0, 0, 300, 400),
            display::Screen::GetScreen()->GetPrimaryDisplay().bounds());
  host_list = test_api.GetHosts();
  ASSERT_EQ(1U, host_list.size());
  EXPECT_EQ(gfx::Size(800, 800), host_list[0]->GetBoundsInPixels().size());
  EXPECT_EQ(gfx::Size(300, 400), host_list[0]->window()->bounds().size());

  // Test the target display's bounds after the transforms are applied.
  gfx::RectF transformed_rect2(
      display::Screen::GetScreen()->GetPrimaryDisplay().bounds());
  Shell::Get()->GetPrimaryRootWindow()->transform().TransformRect(
      &transformed_rect2);
  host_list[0]->window()->transform().TransformRect(&transformed_rect2);
  EXPECT_EQ(gfx::RectF(100.0f, 0.0f, 600.0f, 800.0f), transformed_rect2);

  // Change the bounds of the source display and rotate the source display by 90
  // degrees.
  UpdateDisplay("300x400/r,800x800");
  EXPECT_TRUE(display_manager()->IsInSoftwareMirrorMode());
  EXPECT_EQ(gfx::Rect(0, 0, 400, 300),
            display::Screen::GetScreen()->GetPrimaryDisplay().bounds());
  host_list = test_api.GetHosts();
  ASSERT_EQ(1U, host_list.size());
  EXPECT_EQ(gfx::Size(800, 800), host_list[0]->GetBoundsInPixels().size());
  EXPECT_EQ(gfx::Size(400, 300), host_list[0]->window()->bounds().size());

  // Test the target display's bounds after the transforms are applied.
  gfx::RectF transformed_rect3(
      display::Screen::GetScreen()->GetPrimaryDisplay().bounds());
  Shell::Get()->GetPrimaryRootWindow()->transform().TransformRect(
      &transformed_rect3);
  host_list[0]->window()->transform().TransformRect(&transformed_rect3);
  EXPECT_EQ(gfx::RectF(0.0f, 100.0f, 800.0f, 600.0f), transformed_rect3);
}

TEST_F(DisplayManagerTest, SoftwareMirrorRotationForNonTablet) {
  MirrorWindowTestApi test_api;
  UpdateDisplay("400x300,800x800");

  // Simulate turning on mirror mode not triggered by tablet mode.
  SetSoftwareMirrorMode(true);
  EXPECT_TRUE(display_manager()->IsInSoftwareMirrorMode());
  EXPECT_EQ(gfx::Rect(0, 0, 400, 300),
            display::Screen::GetScreen()->GetPrimaryDisplay().bounds());
  std::vector<aura::WindowTreeHost*> host_list = test_api.GetHosts();
  ASSERT_EQ(1U, host_list.size());
  EXPECT_EQ(gfx::Size(800, 800), host_list[0]->GetBoundsInPixels().size());
  EXPECT_EQ(gfx::Size(400, 300), host_list[0]->window()->bounds().size());

  // Test the target display's bounds after the transforms are applied.
  gfx::RectF transformed_rect1(
      display::Screen::GetScreen()->GetPrimaryDisplay().bounds());
  Shell::Get()->GetPrimaryRootWindow()->transform().TransformRect(
      &transformed_rect1);
  host_list[0]->window()->transform().TransformRect(&transformed_rect1);
  EXPECT_EQ(gfx::RectF(0.0f, 100.0f, 800.0f, 600.0f), transformed_rect1);

  // Rotate the source display by 90 degrees.
  UpdateDisplay("400x300/r,800x800");
  EXPECT_TRUE(display_manager()->IsInSoftwareMirrorMode());
  EXPECT_EQ(gfx::Rect(0, 0, 300, 400),
            display::Screen::GetScreen()->GetPrimaryDisplay().bounds());
  host_list = test_api.GetHosts();
  ASSERT_EQ(1U, host_list.size());
  EXPECT_EQ(gfx::Size(800, 800), host_list[0]->GetBoundsInPixels().size());
  EXPECT_EQ(gfx::Size(400, 300), host_list[0]->window()->bounds().size());

  // Test the target display's bounds after the transforms are applied.
  gfx::RectF transformed_rect2(
      display::Screen::GetScreen()->GetPrimaryDisplay().bounds());
  Shell::Get()->GetPrimaryRootWindow()->transform().TransformRect(
      &transformed_rect2);
  host_list[0]->window()->transform().TransformRect(&transformed_rect2);
  EXPECT_EQ(gfx::RectF(0.0f, 100.0f, 800.0f, 600.0f), transformed_rect2);

  // Change the bounds of the source display and rotate the source display by 90
  // degrees.
  UpdateDisplay("300x400/r,800x800");
  EXPECT_TRUE(display_manager()->IsInSoftwareMirrorMode());
  EXPECT_EQ(gfx::Rect(0, 0, 400, 300),
            display::Screen::GetScreen()->GetPrimaryDisplay().bounds());
  host_list = test_api.GetHosts();
  ASSERT_EQ(1U, host_list.size());
  EXPECT_EQ(gfx::Size(800, 800), host_list[0]->GetBoundsInPixels().size());
  EXPECT_EQ(gfx::Size(300, 400), host_list[0]->window()->bounds().size());

  // Test the target display's bounds after the transforms are applied.
  gfx::RectF transformed_rect3(
      display::Screen::GetScreen()->GetPrimaryDisplay().bounds());
  Shell::Get()->GetPrimaryRootWindow()->transform().TransformRect(
      &transformed_rect3);
  host_list[0]->window()->transform().TransformRect(&transformed_rect3);
  EXPECT_EQ(gfx::RectF(100.0f, 0.0f, 600.0f, 800.0f), transformed_rect3);
}

}  // namespace ash
