1 // Copyright 2014 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.
6 #include "base/message_loop/message_loop.h"
7 #include "base/run_loop.h"
8 #include "testing/gtest/include/gtest/gtest.h"
9 #include "ui/display/chromeos/display_layout_manager.h"
10 #include "ui/display/chromeos/test/action_logger_util.h"
11 #include "ui/display/chromeos/test/test_display_snapshot.h"
12 #include "ui/display/chromeos/test/test_native_display_delegate.h"
13 #include "ui/display/chromeos/update_display_configuration_task.h"
20 class TestDisplayLayoutManager
: public DisplayLayoutManager
{
22 TestDisplayLayoutManager()
23 : should_mirror_(true),
24 display_state_(MULTIPLE_DISPLAY_STATE_INVALID
),
25 power_state_(chromeos::DISPLAY_POWER_ALL_ON
) {}
26 ~TestDisplayLayoutManager() override
{}
28 void set_should_mirror(bool should_mirror
) { should_mirror_
= should_mirror
; }
30 void set_display_state(MultipleDisplayState state
) { display_state_
= state
; }
32 void set_power_state(chromeos::DisplayPowerState state
) {
36 // DisplayConfigurator::DisplayLayoutManager:
37 DisplayConfigurator::SoftwareMirroringController
*
38 GetSoftwareMirroringController() const override
{
42 DisplayConfigurator::StateController
* GetStateController() const override
{
46 MultipleDisplayState
GetDisplayState() const override
{
47 return display_state_
;
50 chromeos::DisplayPowerState
GetPowerState() const override
{
54 bool GetDisplayLayout(const std::vector
<DisplaySnapshot
*>& displays
,
55 MultipleDisplayState new_display_state
,
56 chromeos::DisplayPowerState new_power_state
,
57 std::vector
<DisplayConfigureRequest
>* requests
,
58 gfx::Size
* framebuffer_size
) const override
{
60 for (DisplaySnapshot
* display
: displays
) {
61 const DisplayMode
* mode
= display
->native_mode();
62 if (new_display_state
== MULTIPLE_DISPLAY_STATE_DUAL_MIRROR
)
63 mode
= should_mirror_
? FindMirrorMode(displays
) : nullptr;
68 if (new_power_state
== chromeos::DISPLAY_POWER_ALL_ON
) {
69 requests
->push_back(DisplayConfigureRequest(display
, mode
, origin
));
71 requests
->push_back(DisplayConfigureRequest(display
, nullptr, origin
));
74 if (new_display_state
!= MULTIPLE_DISPLAY_STATE_DUAL_MIRROR
) {
75 origin
.Offset(0, mode
->size().height());
76 framebuffer_size
->SetToMax(gfx::Size(mode
->size().width(), origin
.y()));
78 *framebuffer_size
= mode
->size();
85 DisplayConfigurator::DisplayStateList
GetDisplayStates() const override
{
87 return DisplayConfigurator::DisplayStateList();
90 bool IsMirroring() const override
{
91 return display_state_
== MULTIPLE_DISPLAY_STATE_DUAL_MIRROR
;
95 const DisplayMode
* FindMirrorMode(
96 const std::vector
<DisplaySnapshot
*>& displays
) const {
97 const DisplayMode
* mode
= displays
[0]->native_mode();
98 for (DisplaySnapshot
* display
: displays
) {
99 if (mode
->size().GetArea() > display
->native_mode()->size().GetArea())
100 mode
= display
->native_mode();
108 MultipleDisplayState display_state_
;
110 chromeos::DisplayPowerState power_state_
;
112 DISALLOW_COPY_AND_ASSIGN(TestDisplayLayoutManager
);
115 class UpdateDisplayConfigurationTaskTest
: public testing::Test
{
117 UpdateDisplayConfigurationTaskTest()
119 small_mode_(gfx::Size(1366, 768), false, 60.0f
),
120 big_mode_(gfx::Size(2560, 1600), false, 60.0f
),
122 configuration_status_(false),
123 display_state_(MULTIPLE_DISPLAY_STATE_INVALID
),
124 power_state_(chromeos::DISPLAY_POWER_ALL_ON
) {
125 std::vector
<const DisplayMode
*> modes
;
126 modes
.push_back(&small_mode_
);
127 displays_
[0].set_current_mode(&small_mode_
);
128 displays_
[0].set_native_mode(&small_mode_
);
129 displays_
[0].set_modes(modes
);
130 displays_
[0].set_display_id(123);
132 modes
.push_back(&big_mode_
);
133 displays_
[1].set_current_mode(&big_mode_
);
134 displays_
[1].set_native_mode(&big_mode_
);
135 displays_
[1].set_modes(modes
);
136 displays_
[1].set_display_id(456);
138 ~UpdateDisplayConfigurationTaskTest() override
{}
140 void UpdateDisplays(size_t count
) {
141 std::vector
<DisplaySnapshot
*> displays
;
142 for (size_t i
= 0; i
< count
; ++i
)
143 displays
.push_back(&displays_
[i
]);
145 delegate_
.set_outputs(displays
);
148 void ResponseCallback(bool success
,
149 const std::vector
<DisplaySnapshot
*>& displays
,
150 const gfx::Size
& framebuffer_size
,
151 MultipleDisplayState new_display_state
,
152 chromeos::DisplayPowerState new_power_state
) {
154 configuration_status_
= success
;
155 display_states_
= displays
;
156 display_state_
= new_display_state
;
157 power_state_
= new_power_state
;
160 layout_manager_
.set_display_state(display_state_
);
161 layout_manager_
.set_power_state(power_state_
);
167 TestNativeDisplayDelegate delegate_
;
168 TestDisplayLayoutManager layout_manager_
;
170 const DisplayMode small_mode_
;
171 const DisplayMode big_mode_
;
173 TestDisplaySnapshot displays_
[2];
176 bool configuration_status_
;
177 std::vector
<DisplaySnapshot
*> display_states_
;
178 MultipleDisplayState display_state_
;
179 chromeos::DisplayPowerState power_state_
;
182 DISALLOW_COPY_AND_ASSIGN(UpdateDisplayConfigurationTaskTest
);
187 TEST_F(UpdateDisplayConfigurationTaskTest
, HeadlessConfiguration
) {
189 UpdateDisplayConfigurationTask
task(
190 &delegate_
, &layout_manager_
, MULTIPLE_DISPLAY_STATE_HEADLESS
,
191 chromeos::DISPLAY_POWER_ALL_ON
, 0, 0, false,
192 base::Bind(&UpdateDisplayConfigurationTaskTest::ResponseCallback
,
193 base::Unretained(this)));
197 EXPECT_TRUE(configured_
);
198 EXPECT_TRUE(configuration_status_
);
199 EXPECT_EQ(MULTIPLE_DISPLAY_STATE_HEADLESS
, display_state_
);
200 EXPECT_EQ(chromeos::DISPLAY_POWER_ALL_ON
, power_state_
);
201 EXPECT_EQ(JoinActions(kGrab
, kUngrab
, NULL
), log_
.GetActionsAndClear());
204 TEST_F(UpdateDisplayConfigurationTaskTest
, SingleConfiguration
) {
208 UpdateDisplayConfigurationTask
task(
209 &delegate_
, &layout_manager_
, MULTIPLE_DISPLAY_STATE_SINGLE
,
210 chromeos::DISPLAY_POWER_ALL_ON
, 0, 0, false,
211 base::Bind(&UpdateDisplayConfigurationTaskTest::ResponseCallback
,
212 base::Unretained(this)));
216 EXPECT_TRUE(configured_
);
217 EXPECT_TRUE(configuration_status_
);
218 EXPECT_EQ(MULTIPLE_DISPLAY_STATE_SINGLE
, display_state_
);
219 EXPECT_EQ(chromeos::DISPLAY_POWER_ALL_ON
, power_state_
);
220 EXPECT_EQ(JoinActions(
221 kGrab
, GetFramebufferAction(small_mode_
.size(), &displays_
[0],
223 GetCrtcAction(displays_
[0], &small_mode_
, gfx::Point()).c_str(),
225 log_
.GetActionsAndClear());
228 TEST_F(UpdateDisplayConfigurationTaskTest
, ExtendedConfiguration
) {
232 UpdateDisplayConfigurationTask
task(
233 &delegate_
, &layout_manager_
, MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED
,
234 chromeos::DISPLAY_POWER_ALL_ON
, 0, 0, false,
235 base::Bind(&UpdateDisplayConfigurationTaskTest::ResponseCallback
,
236 base::Unretained(this)));
240 EXPECT_TRUE(configured_
);
241 EXPECT_TRUE(configuration_status_
);
242 EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED
, display_state_
);
243 EXPECT_EQ(chromeos::DISPLAY_POWER_ALL_ON
, power_state_
);
246 kGrab
, GetFramebufferAction(gfx::Size(big_mode_
.size().width(),
247 small_mode_
.size().height() +
248 big_mode_
.size().height()),
249 &displays_
[0], &displays_
[1]).c_str(),
250 GetCrtcAction(displays_
[0], &small_mode_
, gfx::Point()).c_str(),
251 GetCrtcAction(displays_
[1], &big_mode_
,
252 gfx::Point(0, small_mode_
.size().height())).c_str(),
254 log_
.GetActionsAndClear());
257 TEST_F(UpdateDisplayConfigurationTaskTest
, MirrorConfiguration
) {
261 UpdateDisplayConfigurationTask
task(
262 &delegate_
, &layout_manager_
, MULTIPLE_DISPLAY_STATE_DUAL_MIRROR
,
263 chromeos::DISPLAY_POWER_ALL_ON
, 0, 0, false,
264 base::Bind(&UpdateDisplayConfigurationTaskTest::ResponseCallback
,
265 base::Unretained(this)));
269 EXPECT_TRUE(configured_
);
270 EXPECT_TRUE(configuration_status_
);
271 EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR
, display_state_
);
272 EXPECT_EQ(chromeos::DISPLAY_POWER_ALL_ON
, power_state_
);
273 EXPECT_EQ(JoinActions(
274 kGrab
, GetFramebufferAction(small_mode_
.size(), &displays_
[0],
275 &displays_
[1]).c_str(),
276 GetCrtcAction(displays_
[0], &small_mode_
, gfx::Point()).c_str(),
277 GetCrtcAction(displays_
[1], &small_mode_
, gfx::Point()).c_str(),
279 log_
.GetActionsAndClear());
282 TEST_F(UpdateDisplayConfigurationTaskTest
, FailMirrorConfiguration
) {
283 layout_manager_
.set_should_mirror(false);
287 UpdateDisplayConfigurationTask
task(
288 &delegate_
, &layout_manager_
, MULTIPLE_DISPLAY_STATE_DUAL_MIRROR
,
289 chromeos::DISPLAY_POWER_ALL_ON
, 0, 0, false,
290 base::Bind(&UpdateDisplayConfigurationTaskTest::ResponseCallback
,
291 base::Unretained(this)));
295 EXPECT_TRUE(configured_
);
296 EXPECT_FALSE(configuration_status_
);
297 EXPECT_EQ(JoinActions(kGrab
, kUngrab
, NULL
), log_
.GetActionsAndClear());
300 TEST_F(UpdateDisplayConfigurationTaskTest
, FailExtendedConfiguration
) {
301 delegate_
.set_max_configurable_pixels(1);
305 UpdateDisplayConfigurationTask
task(
306 &delegate_
, &layout_manager_
, MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED
,
307 chromeos::DISPLAY_POWER_ALL_ON
, 0, 0, false,
308 base::Bind(&UpdateDisplayConfigurationTaskTest::ResponseCallback
,
309 base::Unretained(this)));
313 EXPECT_TRUE(configured_
);
314 EXPECT_FALSE(configuration_status_
);
317 kGrab
, GetFramebufferAction(gfx::Size(big_mode_
.size().width(),
318 small_mode_
.size().height() +
319 big_mode_
.size().height()),
320 &displays_
[0], &displays_
[1]).c_str(),
321 GetCrtcAction(displays_
[0], &small_mode_
, gfx::Point()).c_str(),
322 GetCrtcAction(displays_
[1], &big_mode_
,
323 gfx::Point(0, small_mode_
.size().height())).c_str(),
324 GetCrtcAction(displays_
[1], &small_mode_
,
325 gfx::Point(0, small_mode_
.size().height())).c_str(),
327 log_
.GetActionsAndClear());
330 TEST_F(UpdateDisplayConfigurationTaskTest
, SingleChangePowerConfiguration
) {
334 UpdateDisplayConfigurationTask
task(
335 &delegate_
, &layout_manager_
, MULTIPLE_DISPLAY_STATE_SINGLE
,
336 chromeos::DISPLAY_POWER_ALL_ON
, 0, 0, false,
337 base::Bind(&UpdateDisplayConfigurationTaskTest::ResponseCallback
,
338 base::Unretained(this)));
342 EXPECT_TRUE(configured_
);
343 EXPECT_TRUE(configuration_status_
);
344 EXPECT_EQ(MULTIPLE_DISPLAY_STATE_SINGLE
, display_state_
);
345 EXPECT_EQ(chromeos::DISPLAY_POWER_ALL_ON
, power_state_
);
346 EXPECT_EQ(JoinActions(
347 kGrab
, GetFramebufferAction(small_mode_
.size(), &displays_
[0],
349 GetCrtcAction(displays_
[0], &small_mode_
, gfx::Point()).c_str(),
351 log_
.GetActionsAndClear());
355 UpdateDisplayConfigurationTask
task(
356 &delegate_
, &layout_manager_
, MULTIPLE_DISPLAY_STATE_SINGLE
,
357 chromeos::DISPLAY_POWER_ALL_OFF
, 0, 0, false,
358 base::Bind(&UpdateDisplayConfigurationTaskTest::ResponseCallback
,
359 base::Unretained(this)));
363 EXPECT_TRUE(configuration_status_
);
364 EXPECT_EQ(MULTIPLE_DISPLAY_STATE_SINGLE
, display_state_
);
365 EXPECT_EQ(chromeos::DISPLAY_POWER_ALL_OFF
, power_state_
);
367 JoinActions(kGrab
, GetFramebufferAction(small_mode_
.size(), &displays_
[0],
369 GetCrtcAction(displays_
[0], nullptr, gfx::Point()).c_str(),
371 log_
.GetActionsAndClear());