[go: nahoru, domu]

blob: 71ca9c15c597580c7afd9211a7afe66fce887e6c [file] [log] [blame]
Zoraiz Naeem6a49a562023-03-06 20:33:131// Copyright 2023 The Chromium Authors
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "ash/rounded_display/rounded_display_provider.h"
6
7#include <algorithm>
8#include <memory>
9#include <string>
10#include <vector>
11
12#include "ash/rounded_display/rounded_display_gutter.h"
13#include "ash/rounded_display/rounded_display_provider_test_api.h"
14#include "ash/shell.h"
15#include "ash/test/ash_test_base.h"
16#include "base/test/gtest_util.h"
17#include "testing/gmock/include/gmock/gmock.h"
18#include "testing/gtest/include/gtest/gtest.h"
19#include "ui/display/display.h"
20#include "ui/display/manager/display_manager.h"
21#include "ui/gfx/geometry/rounded_corners_f.h"
22
23namespace ash {
24namespace {
25
26using Gutters = std::vector<RoundedDisplayGutter*>;
27using RoundedCorner = RoundedDisplayGutter::RoundedCorner;
28using RoundedCornerPosition = RoundedDisplayGutter::RoundedCorner::Position;
29using ProviderStrategy = RoundedDisplayProvider::Strategy;
30
31constexpr ProviderStrategy kDefaultTestStrategy = ProviderStrategy::kScanout;
32
33gfx::RoundedCornersF CreateHorizontallyUniformRadii(int radius_a,
34 int radius_b) {
35 return gfx::RoundedCornersF(radius_a, radius_a, radius_b, radius_b);
36}
37
38// The matcher matches a RoundedDisplayGutter that has the rounded corners of
39// `positions`.
40template <typename... Matchers>
41auto GutterWithMatchingCorners(Matchers&&... positions) {
42 return testing::ResultOf(
43 "positions",
44 [](const RoundedDisplayGutter* gutter) {
45 std::vector<RoundedCornerPosition> positions;
46 const std::vector<RoundedCorner>& corners = gutter->GetGutterCorners();
47 base::ranges::transform(
48 corners.begin(), corners.end(), std::back_inserter(positions),
49 [](const RoundedCorner& corner) { return corner.position(); });
50 return positions;
51 },
52 testing::UnorderedElementsAre(positions...));
53}
54
55class RoundedDisplayProviderTest : public AshTestBase {
56 public:
57 RoundedDisplayProviderTest() = default;
58
59 RoundedDisplayProviderTest(const RoundedDisplayProviderTest&) = delete;
60 RoundedDisplayProviderTest& operator=(const RoundedDisplayProviderTest&) =
61 delete;
62
63 ~RoundedDisplayProviderTest() override = default;
64
65 void SetUp() override {
66 AshTestBase::SetUp();
67 // Create the rounded display provider for the primary display.
68 provider_ = RoundedDisplayProvider::Create(GetPrimaryDisplay().id());
69 }
70
71 void TearDown() override {
72 provider_.reset();
73 AshTestBase::TearDown();
74 }
75
76 protected:
77 const display::Display& GetDisplay(int64_t display_id) {
78 return display_manager()->GetDisplayForId(display_id);
79 }
80
81 std::unique_ptr<RoundedDisplayProvider> provider_;
82};
83
84TEST_F(RoundedDisplayProviderTest, InitializeWithNonUniformRadii) {
85 RoundedDisplayProviderTestApi test_api(provider_.get());
86
87 const gfx::RoundedCornersF not_valid_radii(10, 11, 12, 12);
88
89 EXPECT_DCHECK_DEATH(
90 { provider_->Init(not_valid_radii, kDefaultTestStrategy); });
91}
92
93TEST_F(RoundedDisplayProviderTest, CorrectNumberOfGuttersAreProvided) {
94 RoundedDisplayProviderTestApi test_api(provider_.get());
95 const gfx::RoundedCornersF radii = CreateHorizontallyUniformRadii(10, 12);
96
Zoraiz Naeem3fff1f262023-04-21 13:21:5197 // We expect 2 overlay gutters to be created.
Zoraiz Naeem6a49a562023-03-06 20:33:1398 provider_->Init(radii, kDefaultTestStrategy);
Zoraiz Naeem3fff1f262023-04-21 13:21:5199 EXPECT_EQ(test_api.GetGutters().size(), 2u);
Zoraiz Naeem6a49a562023-03-06 20:33:13100}
101
102TEST_F(RoundedDisplayProviderTest,
103 CorrectGutterCreatedForStrategy_ScanoutDirection) {
104 RoundedDisplayProviderTestApi test_api(provider_.get());
105 const gfx::RoundedCornersF radii = CreateHorizontallyUniformRadii(10, 12);
106
107 provider_->Init(radii, ProviderStrategy::kScanout);
108
109 const auto& gutters = test_api.GetGutters();
110
Zoraiz Naeem3fff1f262023-04-21 13:21:51111 EXPECT_EQ(gutters.size(), 2u);
Zoraiz Naeem6a49a562023-03-06 20:33:13112
113 // Check that we have two overlay gutters that in the scanout direction.
114 EXPECT_THAT(gutters, testing::Contains(GutterWithMatchingCorners(
115 RoundedCornerPosition::kUpperLeft,
116 RoundedCornerPosition::kUpperRight)));
117 EXPECT_THAT(gutters, testing::Contains(GutterWithMatchingCorners(
118 RoundedCornerPosition::kLowerLeft,
119 RoundedCornerPosition::kLowerRight)));
120}
121
122TEST_F(RoundedDisplayProviderTest,
123 CorrectGutterCreatedForStrategy_OtherDirection) {
124 RoundedDisplayProviderTestApi test_api(provider_.get());
125 const gfx::RoundedCornersF radii = CreateHorizontallyUniformRadii(10, 12);
126
127 provider_->Init(radii, ProviderStrategy::kOther);
128
129 const auto& gutters = test_api.GetGutters();
130
Zoraiz Naeem3fff1f262023-04-21 13:21:51131 EXPECT_EQ(gutters.size(), 2u);
Zoraiz Naeem6a49a562023-03-06 20:33:13132
133 // Check that we have two overlay gutters that in the scanout direction.
134 EXPECT_THAT(gutters, testing::Contains(GutterWithMatchingCorners(
135 RoundedCornerPosition::kUpperLeft,
136 RoundedCornerPosition::kLowerLeft)));
137 // Right overlay gutter.
138 EXPECT_THAT(gutters, testing::Contains(GutterWithMatchingCorners(
139 RoundedCornerPosition::kUpperRight,
140 RoundedCornerPosition::kLowerRight)));
141}
142
143class RoundedDisplayProviderSurfaceUpdateTest
144 : public RoundedDisplayProviderTest,
145 public ::testing::WithParamInterface<
146 std::tuple<std::string, std::string, bool>> {
147 public:
148 RoundedDisplayProviderSurfaceUpdateTest()
149 : initial_display_spec_(std::get<0>(GetParam())),
150 updated_display_spec_(std::get<1>(GetParam())),
151 expect_update_(std::get<2>(GetParam())) {}
152
153 RoundedDisplayProviderSurfaceUpdateTest(
154 const RoundedDisplayProviderSurfaceUpdateTest&) = delete;
155 RoundedDisplayProviderSurfaceUpdateTest& operator=(
156 const RoundedDisplayProviderSurfaceUpdateTest&) = delete;
157
158 ~RoundedDisplayProviderSurfaceUpdateTest() override = default;
159
160 protected:
161 std::string initial_display_spec_;
162 std::string updated_display_spec_;
163 bool expect_update_;
164};
165
166TEST_P(RoundedDisplayProviderSurfaceUpdateTest,
167 UpdatesSurfaceOnlyWhenNecessary) {
168 RoundedDisplayProviderTestApi test_api(provider_.get());
169
170 display::Display primary_display =
171 display::Screen::GetScreen()->GetPrimaryDisplay();
172
173 auto display_id = primary_display.id();
174
175 UpdateDisplay(initial_display_spec_);
176
177 gfx::RoundedCornersF radii =
Zoraiz Naeem72bf4162023-04-26 21:43:55178 display_manager()->GetDisplayInfo(display_id).panel_corners_radii();
Zoraiz Naeem6a49a562023-03-06 20:33:13179
180 provider_->Init(radii, kDefaultTestStrategy);
181
182 ASSERT_TRUE(provider_->UpdateRoundedDisplaySurface());
183
184 UpdateDisplay(updated_display_spec_);
185
186 Gutters before_update_gutters = test_api.GetGutters();
187 ASSERT_EQ(provider_->UpdateRoundedDisplaySurface(), expect_update_);
188 Gutters after_update_gutters = test_api.GetGutters();
189
190 // Confirm that we did not change gutters.
191 EXPECT_EQ(before_update_gutters, after_update_gutters);
192}
193
194const std::string kInitialDisplaySpec = "500x400~15";
195const std::string kInitialDisplaySpecWithRotation = "500x400/r~15";
196
197INSTANTIATE_TEST_SUITE_P(
198 /* no prefix */,
199 RoundedDisplayProviderSurfaceUpdateTest,
200 testing::Values(
201 // If nothing changes, we should skip surface update.
202 std::make_tuple(kInitialDisplaySpec,
203 "500x400~15",
204 /*expect_update=*/false),
205 // Change in device scale factor, should only cause a surface update.
206 std::make_tuple(kInitialDisplaySpec,
207 "500x400*2~15",
208 /*expect_update=*/true),
209 // Further display rotation, should only cause a surface update.
210 std::make_tuple(kInitialDisplaySpecWithRotation,
211 "500x400/u~15",
212 /*expect_update=*/true),
213 // Multiple spec changes, should appropriately cause a surface update.
214 std::make_tuple(kInitialDisplaySpec,
215 "500x400*2~15",
216 /*expect_update=*/true)));
217
218} // namespace
219} // namespace ash