blob: f2839ac2aa55c8eed55aae152a650cfabe0683e4 [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"
11#include "testing/gtest/include/gtest/gtest.h"
12#include "ui/display/display.h"
13#include "ui/display/display_observer.h"
14
msw5e048a72016-09-07 18:55:3015namespace display {
sky7afbf7c2016-05-17 23:07:4216namespace {
17
kylechar7a067ec2017-01-07 01:16:2818class DisplayObserverImpl : public DisplayObserver {
sky7afbf7c2016-05-17 23:07:4219 public:
20 DisplayObserverImpl() {}
21 ~DisplayObserverImpl() override {}
22
23 std::string GetAndClearChanges() {
24 std::string changes;
25 std::swap(changes, changes_);
26 return changes;
27 }
28
29 private:
30 static void AddPartChange(uint32_t changed,
31 uint32_t part,
32 const std::string& description,
33 std::string* changed_string) {
34 if ((changed & part) != part)
35 return;
36
37 *changed_string += " ";
38 *changed_string += description;
39 }
40
41 void AddChange(const std::string& change) {
42 if (!changes_.empty())
43 changes_ += "\n";
44 changes_ += change;
45 }
46
47 void OnDisplayAdded(const Display& new_display) override {
48 AddChange("Added id=" + base::Int64ToString(new_display.id()));
49 }
50 void OnDisplayRemoved(const Display& old_display) override {
51 AddChange("Removed id=" + base::Int64ToString(old_display.id()));
52 }
53 void OnDisplayMetricsChanged(const Display& display,
54 uint32_t changed_metrics) override {
55 std::string parts;
56 AddPartChange(changed_metrics, DISPLAY_METRIC_BOUNDS, "bounds", &parts);
57 AddPartChange(changed_metrics, DISPLAY_METRIC_WORK_AREA, "work_area",
58 &parts);
59 AddPartChange(changed_metrics, DISPLAY_METRIC_DEVICE_SCALE_FACTOR,
60 "scale_factor", &parts);
61 AddPartChange(changed_metrics, DISPLAY_METRIC_ROTATION, "rotation", &parts);
62 AddPartChange(changed_metrics, DISPLAY_METRIC_PRIMARY, "primary", &parts);
63
64 AddChange("Changed id=" + base::Int64ToString(display.id()) + parts);
65 }
66
67 std::string changes_;
68
69 DISALLOW_COPY_AND_ASSIGN(DisplayObserverImpl);
70};
71
sky56172f6d2016-05-19 16:42:5172TEST(DisplayListTest, AddUpdateRemove) {
sky7afbf7c2016-05-17 23:07:4273 DisplayList display_list;
74 DisplayObserverImpl observer;
75 display_list.AddObserver(&observer);
kylechar7a067ec2017-01-07 01:16:2876 display_list.AddDisplay(Display(2, gfx::Rect(0, 0, 801, 802)),
sky7afbf7c2016-05-17 23:07:4277 DisplayList::Type::PRIMARY);
78 EXPECT_EQ("Added id=2", observer.GetAndClearChanges());
79
80 // Update the bounds.
81 {
kylechar7a067ec2017-01-07 01:16:2882 Display updated_display = *(display_list.displays().begin());
sky7afbf7c2016-05-17 23:07:4283 updated_display.set_bounds(gfx::Rect(0, 0, 803, 802));
84 display_list.UpdateDisplay(updated_display, DisplayList::Type::PRIMARY);
85 EXPECT_EQ("Changed id=2 bounds", observer.GetAndClearChanges());
86 }
87
88 // Add another.
kylechar7a067ec2017-01-07 01:16:2889 display_list.AddDisplay(Display(3, gfx::Rect(0, 0, 809, 802)),
sky7afbf7c2016-05-17 23:07:4290 DisplayList::Type::NOT_PRIMARY);
91 EXPECT_EQ("Added id=3", observer.GetAndClearChanges());
92 ASSERT_EQ(2u, display_list.displays().size());
93 EXPECT_EQ(2, display_list.displays()[0].id());
94 EXPECT_EQ(3, display_list.displays()[1].id());
95 EXPECT_EQ(2, display_list.GetPrimaryDisplayIterator()->id());
96
97 // Make the second the primary.
98 display_list.UpdateDisplay(display_list.displays()[1],
99 DisplayList::Type::PRIMARY);
100 EXPECT_EQ("Changed id=3 primary", observer.GetAndClearChanges());
101 EXPECT_EQ(3, display_list.GetPrimaryDisplayIterator()->id());
102
103 // Delete the first.
104 display_list.RemoveDisplay(2);
105 ASSERT_EQ(1u, display_list.displays().size());
106 EXPECT_EQ("Removed id=2", observer.GetAndClearChanges());
107 EXPECT_EQ(3, display_list.GetPrimaryDisplayIterator()->id());
108}
109
sky3e56abe2016-09-29 19:38:21110TEST(DisplayListTest, SuspendUpdates) {
111 DisplayList display_list;
kylechar7a067ec2017-01-07 01:16:28112 display_list.AddDisplay(Display(2, gfx::Rect(0, 0, 801, 802)),
sky3e56abe2016-09-29 19:38:21113 DisplayList::Type::PRIMARY);
114 DisplayObserverImpl observer;
115 display_list.AddObserver(&observer);
116 {
117 // Suspend updates and add a new display.
118 std::unique_ptr<DisplayListObserverLock> lock =
119 display_list.SuspendObserverUpdates();
kylechar7a067ec2017-01-07 01:16:28120 display_list.AddDisplay(Display(3, gfx::Rect(0, 0, 809, 802)),
sky3e56abe2016-09-29 19:38:21121 DisplayList::Type::NOT_PRIMARY);
122 EXPECT_EQ(2u, display_list.displays().size());
123 // No update should have been generated.
124 EXPECT_TRUE(observer.GetAndClearChanges().empty());
125 }
126 // The lock has been destroyed, but no updates should be sent yet.
127 EXPECT_TRUE(observer.GetAndClearChanges().empty());
128
129 // Update a display and verify observer called.
kylechar7a067ec2017-01-07 01:16:28130 Display updated_display = display_list.displays()[0];
sky3e56abe2016-09-29 19:38:21131 updated_display.set_bounds(gfx::Rect(0, 0, 803, 802));
132 display_list.UpdateDisplay(updated_display, DisplayList::Type::PRIMARY);
133 EXPECT_EQ("Changed id=2 bounds", observer.GetAndClearChanges());
134}
135
sky7afbf7c2016-05-17 23:07:42136} // namespace
msw5e048a72016-09-07 18:55:30137} // namespace display