blob: 82f917b29662fc1cfab0863478affd08d0931e98 [file] [log] [blame]
sky7afbf7c2016-05-17 23:07:421// Copyright 2016 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
msw5e048a72016-09-07 18:55:305#include "ui/display/display_list.h"
sky7afbf7c2016-05-17 23:07:426
7#include <string>
8#include <vector>
9
10#include "base/strings/string_number_conversions.h"
Mike Wasserman11554ff92021-05-16 00:46:2611#include "base/test/gtest_util.h"
sky7afbf7c2016-05-17 23:07:4212#include "testing/gtest/include/gtest/gtest.h"
13#include "ui/display/display.h"
14#include "ui/display/display_observer.h"
15
msw5e048a72016-09-07 18:55:3016namespace display {
sky7afbf7c2016-05-17 23:07:4217namespace {
18
kylechar7a067ec2017-01-07 01:16:2819class DisplayObserverImpl : public DisplayObserver {
sky7afbf7c2016-05-17 23:07:4220 public:
21 DisplayObserverImpl() {}
22 ~DisplayObserverImpl() override {}
23
24 std::string GetAndClearChanges() {
25 std::string changes;
26 std::swap(changes, changes_);
27 return changes;
28 }
29
30 private:
31 static void AddPartChange(uint32_t changed,
32 uint32_t part,
33 const std::string& description,
34 std::string* changed_string) {
35 if ((changed & part) != part)
36 return;
37
38 *changed_string += " ";
39 *changed_string += description;
40 }
41
42 void AddChange(const std::string& change) {
43 if (!changes_.empty())
44 changes_ += "\n";
45 changes_ += change;
46 }
47
48 void OnDisplayAdded(const Display& new_display) override {
Raul Tambreffa3ec12019-03-26 19:32:4549 AddChange("Added id=" + base::NumberToString(new_display.id()));
sky7afbf7c2016-05-17 23:07:4250 }
51 void OnDisplayRemoved(const Display& old_display) override {
Raul Tambreffa3ec12019-03-26 19:32:4552 AddChange("Removed id=" + base::NumberToString(old_display.id()));
sky7afbf7c2016-05-17 23:07:4253 }
54 void OnDisplayMetricsChanged(const Display& display,
55 uint32_t changed_metrics) override {
56 std::string parts;
57 AddPartChange(changed_metrics, DISPLAY_METRIC_BOUNDS, "bounds", &parts);
58 AddPartChange(changed_metrics, DISPLAY_METRIC_WORK_AREA, "work_area",
59 &parts);
60 AddPartChange(changed_metrics, DISPLAY_METRIC_DEVICE_SCALE_FACTOR,
61 "scale_factor", &parts);
62 AddPartChange(changed_metrics, DISPLAY_METRIC_ROTATION, "rotation", &parts);
63 AddPartChange(changed_metrics, DISPLAY_METRIC_PRIMARY, "primary", &parts);
64
Raul Tambreffa3ec12019-03-26 19:32:4565 AddChange("Changed id=" + base::NumberToString(display.id()) + parts);
sky7afbf7c2016-05-17 23:07:4266 }
67
68 std::string changes_;
69
70 DISALLOW_COPY_AND_ASSIGN(DisplayObserverImpl);
71};
72
sky56172f6d2016-05-19 16:42:5173TEST(DisplayListTest, AddUpdateRemove) {
sky7afbf7c2016-05-17 23:07:4274 DisplayList display_list;
75 DisplayObserverImpl observer;
76 display_list.AddObserver(&observer);
kylechar7a067ec2017-01-07 01:16:2877 display_list.AddDisplay(Display(2, gfx::Rect(0, 0, 801, 802)),
sky7afbf7c2016-05-17 23:07:4278 DisplayList::Type::PRIMARY);
79 EXPECT_EQ("Added id=2", observer.GetAndClearChanges());
80
81 // Update the bounds.
82 {
kylechar7a067ec2017-01-07 01:16:2883 Display updated_display = *(display_list.displays().begin());
sky7afbf7c2016-05-17 23:07:4284 updated_display.set_bounds(gfx::Rect(0, 0, 803, 802));
85 display_list.UpdateDisplay(updated_display, DisplayList::Type::PRIMARY);
86 EXPECT_EQ("Changed id=2 bounds", observer.GetAndClearChanges());
87 }
88
89 // Add another.
kylechar7a067ec2017-01-07 01:16:2890 display_list.AddDisplay(Display(3, gfx::Rect(0, 0, 809, 802)),
sky7afbf7c2016-05-17 23:07:4291 DisplayList::Type::NOT_PRIMARY);
92 EXPECT_EQ("Added id=3", observer.GetAndClearChanges());
93 ASSERT_EQ(2u, display_list.displays().size());
94 EXPECT_EQ(2, display_list.displays()[0].id());
95 EXPECT_EQ(3, display_list.displays()[1].id());
Mike Wasserman1e8ee6c2021-05-20 18:34:5296 EXPECT_EQ(2, display_list.GetPrimaryDisplay().id());
sky7afbf7c2016-05-17 23:07:4297
98 // Make the second the primary.
99 display_list.UpdateDisplay(display_list.displays()[1],
100 DisplayList::Type::PRIMARY);
101 EXPECT_EQ("Changed id=3 primary", observer.GetAndClearChanges());
Mike Wasserman1e8ee6c2021-05-20 18:34:52102 EXPECT_EQ(3, display_list.GetPrimaryDisplay().id());
sky7afbf7c2016-05-17 23:07:42103
104 // Delete the first.
105 display_list.RemoveDisplay(2);
106 ASSERT_EQ(1u, display_list.displays().size());
107 EXPECT_EQ("Removed id=2", observer.GetAndClearChanges());
Mike Wasserman1e8ee6c2021-05-20 18:34:52108 EXPECT_EQ(3, display_list.GetPrimaryDisplay().id());
sky7afbf7c2016-05-17 23:07:42109}
110
Mike Wasserman11554ff92021-05-16 00:46:26111TEST(DisplayListTest, EmptyIsValid) {
112 DisplayList display_list;
Jayson Adams1ba49822021-06-24 00:20:29113 EXPECT_TRUE(display_list.IsValidOrEmpty());
Mike Wasserman11554ff92021-05-16 00:46:26114}
115
116TEST(DisplayListTest, FirstDisplayAddedIsForcedToBePrimary) {
117 DisplayList display_list;
118 display_list.AddDisplay(Display(1), DisplayList::Type::NOT_PRIMARY);
119 EXPECT_EQ(1, display_list.primary_id());
120}
121
122TEST(DisplayListTest, SinglePrimaryDisplayNoCurrentIdIsValid) {
123 DisplayList display_list({Display(1)}, /*primary_id=*/1,
124 /*current_id=*/kInvalidDisplayId);
Jayson Adams1ba49822021-06-24 00:20:29125 EXPECT_TRUE(display_list.IsValidOrEmpty());
Mike Wasserman11554ff92021-05-16 00:46:26126}
127
128TEST(DisplayListTest, SinglePrimaryDisplayWithCurrentIdIsValid) {
129 DisplayList display_list({Display(1)}, /*primary_id=*/1, /*current_id=*/1);
Jayson Adams1ba49822021-06-24 00:20:29130 EXPECT_TRUE(display_list.IsValidOrEmpty());
Mike Wasserman11554ff92021-05-16 00:46:26131}
132
133TEST(DisplayListTest, PrimaryMustBeInvalidWhenEmpty) {
134 // `primary_id` must be kInvalidDisplayId if `displays` is empty.
135 EXPECT_DCHECK_DEATH(EXPECT_FALSE(
136 DisplayList({}, /*primary_id=*/1, /*current_id=*/kInvalidDisplayId)
Jayson Adams1ba49822021-06-24 00:20:29137 .IsValidOrEmpty()));
Mike Wasserman11554ff92021-05-16 00:46:26138}
139
140TEST(DisplayListTest, CurrentMustBeInvalidWhenEmpty) {
141 // `primary_id` must be kInvalidDisplayId if `displays` is empty.
142 EXPECT_DCHECK_DEATH(
143 EXPECT_FALSE(DisplayList({}, /*primary_id=*/kInvalidDisplayId,
144 /*current_id=*/1)
Jayson Adams1ba49822021-06-24 00:20:29145 .IsValidOrEmpty()));
Mike Wasserman11554ff92021-05-16 00:46:26146}
147
148TEST(DisplayListTest, PrimaryIdMustBePresent) {
149 // `primary_id` must match an element of `displays`.
150 EXPECT_DCHECK_DEATH(EXPECT_FALSE(DisplayList({Display(1)}, /*primary_id=*/2,
151 /*current_id=*/1)
Jayson Adams1ba49822021-06-24 00:20:29152 .IsValidOrEmpty()));
Mike Wasserman11554ff92021-05-16 00:46:26153}
154
155TEST(DisplayListTest, CurrentIdMustBePresent) {
156 // `current_id` must match an element of `displays`.
157 EXPECT_DCHECK_DEATH(EXPECT_FALSE(DisplayList({Display(1)}, /*primary_id=*/1,
158 /*current_id=*/2)
Jayson Adams1ba49822021-06-24 00:20:29159 .IsValidOrEmpty()));
Mike Wasserman11554ff92021-05-16 00:46:26160}
161
162TEST(DisplayListTest, DisplaysIdsMustBeUnique) {
Jayson Adams1ba49822021-06-24 00:20:29163 // Make sure the duplicate-checking code correctly handles the single display
164 // case.
165 EXPECT_TRUE(DisplayList({Display(1)},
166 /*primary_id=*/1,
167 /*current_id=*/1)
168 .IsValidOrEmpty());
169
170 // Test with a handful of display ids.
171 EXPECT_DCHECK_DEATH(
172 EXPECT_FALSE(DisplayList({Display(9), Display(1), Display(5), Display(2),
173 Display(11), Display(5), Display(7)},
174 /*primary_id=*/1,
175 /*current_id=*/1)
176 .IsValidOrEmpty()));
Mike Wasserman11554ff92021-05-16 00:46:26177}
178
Mike Wasserman1e8ee6c2021-05-20 18:34:52179TEST(DisplayListTest, IsValidAndHasPrimaryAndCurrentDisplaysEmpty) {
180 EXPECT_FALSE(DisplayList().IsValidAndHasPrimaryAndCurrentDisplays());
181}
182
183TEST(DisplayListTest, IsValidAndHasPrimaryAndCurrentDisplaysNoCurrent) {
184 EXPECT_FALSE(DisplayList({Display(1)}, /*primary_id=*/1,
185 /*current_id=*/kInvalidDisplayId)
186 .IsValidAndHasPrimaryAndCurrentDisplays());
187}
188
189TEST(DisplayListTest, IsValidAndHasPrimaryAndCurrentDisplaysOk) {
190 EXPECT_TRUE(DisplayList({Display(1)}, /*primary_id=*/1, /*current_id=*/1)
191 .IsValidAndHasPrimaryAndCurrentDisplays());
192}
193
194TEST(DisplayListTest, GetPrimaryDisplayEmpty) {
195 DisplayList display_list;
196 EXPECT_EQ(display_list.displays().end(),
197 display_list.FindDisplayById(display_list.primary_id()));
198 EXPECT_DEATH_IF_SUPPORTED(EXPECT_NE(1, display_list.GetPrimaryDisplay().id()),
199 "");
200}
201
202TEST(DisplayListTest, GetPrimaryDisplayOk) {
203 DisplayList display_list({Display(1)}, /*primary_id=*/1, /*current_id=*/1);
204 EXPECT_NE(display_list.displays().end(),
205 display_list.FindDisplayById(display_list.primary_id()));
206 EXPECT_EQ(1, display_list.GetPrimaryDisplay().id());
207}
208
209TEST(DisplayListTest, GetCurrentDisplayEmpty) {
210 DisplayList display_list;
211 EXPECT_EQ(display_list.displays().end(),
212 display_list.FindDisplayById(display_list.current_id()));
213 EXPECT_DEATH_IF_SUPPORTED(EXPECT_NE(1, display_list.GetCurrentDisplay().id()),
214 "");
215}
216
217TEST(DisplayListTest, GetCurrentDisplayUnset) {
218 DisplayList display_list({Display(1)}, /*primary_id=*/1,
219 /*current_id=*/kInvalidDisplayId);
220 EXPECT_EQ(display_list.displays().end(),
221 display_list.FindDisplayById(display_list.current_id()));
222 EXPECT_DEATH_IF_SUPPORTED(EXPECT_NE(1, display_list.GetCurrentDisplay().id()),
223 "");
224}
225
226TEST(DisplayListTest, GetCurrentDisplayOk) {
227 DisplayList display_list({Display(1)}, /*primary_id=*/1, /*current_id=*/1);
228 EXPECT_NE(display_list.displays().end(),
229 display_list.FindDisplayById(display_list.current_id()));
230 EXPECT_EQ(1, display_list.GetCurrentDisplay().id());
231}
232
sky7afbf7c2016-05-17 23:07:42233} // namespace
msw5e048a72016-09-07 18:55:30234} // namespace display