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/test/action_logger_util.h"
10 #include "ui/display/chromeos/test/test_display_snapshot.h"
11 #include "ui/display/chromeos/test/test_native_display_delegate.h"
12 #include "ui/display/chromeos/update_display_configuration_task.h"
19 class TestDisplayLayoutManager
20 : public DisplayConfigurator::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();
86 const DisplayMode
* FindMirrorMode(
87 const std::vector
<DisplaySnapshot
*>& displays
) const {
88 const DisplayMode
* mode
= displays
[0]->native_mode();
89 for (DisplaySnapshot
* display
: displays
) {
90 if (mode
->size().GetArea() > display
->native_mode()->size().GetArea())
91 mode
= display
->native_mode();
99 MultipleDisplayState display_state_
;
101 chromeos::DisplayPowerState power_state_
;
103 DISALLOW_COPY_AND_ASSIGN(TestDisplayLayoutManager
);
106 class UpdateDisplayConfigurationTaskTest
: public testing::Test
{
108 UpdateDisplayConfigurationTaskTest()
110 small_mode_(gfx::Size(1366, 768), false, 60.0f
),
111 big_mode_(gfx::Size(2560, 1600), false, 60.0f
),
113 configuration_status_(false),
114 display_state_(MULTIPLE_DISPLAY_STATE_INVALID
),
115 power_state_(chromeos::DISPLAY_POWER_ALL_ON
) {
116 std::vector
<const DisplayMode
*> modes
;
117 modes
.push_back(&small_mode_
);
118 displays_
[0].set_current_mode(&small_mode_
);
119 displays_
[0].set_native_mode(&small_mode_
);
120 displays_
[0].set_modes(modes
);
121 displays_
[0].set_display_id(123);
123 modes
.push_back(&big_mode_
);
124 displays_
[1].set_current_mode(&big_mode_
);
125 displays_
[1].set_native_mode(&big_mode_
);
126 displays_
[1].set_modes(modes
);
127 displays_
[1].set_display_id(456);
129 ~UpdateDisplayConfigurationTaskTest() override
{}
131 void UpdateDisplays(size_t count
) {
132 std::vector
<DisplaySnapshot
*> displays
;
133 for (size_t i
= 0; i
< count
; ++i
)
134 displays
.push_back(&displays_
[i
]);
136 delegate_
.set_outputs(displays
);
139 void ResponseCallback(bool success
,
140 const std::vector
<DisplaySnapshot
*>& displays
,
141 const gfx::Size
& framebuffer_size
,
142 MultipleDisplayState new_display_state
,
143 chromeos::DisplayPowerState new_power_state
) {
145 configuration_status_
= success
;
146 display_states_
= displays
;
147 display_state_
= new_display_state
;
148 power_state_
= new_power_state
;
151 layout_manager_
.set_display_state(display_state_
);
152 layout_manager_
.set_power_state(power_state_
);
158 TestNativeDisplayDelegate delegate_
;
159 TestDisplayLayoutManager layout_manager_
;
161 const DisplayMode small_mode_
;
162 const DisplayMode big_mode_
;
164 TestDisplaySnapshot displays_
[2];
167 bool configuration_status_
;
168 std::vector
<DisplaySnapshot
*> display_states_
;
169 MultipleDisplayState display_state_
;
170 chromeos::DisplayPowerState power_state_
;
173 DISALLOW_COPY_AND_ASSIGN(UpdateDisplayConfigurationTaskTest
);
178 TEST_F(UpdateDisplayConfigurationTaskTest
, HeadlessConfiguration
) {
180 UpdateDisplayConfigurationTask
task(
181 &delegate_
, &layout_manager_
, MULTIPLE_DISPLAY_STATE_HEADLESS
,
182 chromeos::DISPLAY_POWER_ALL_ON
, 0, 0, false,
183 base::Bind(&UpdateDisplayConfigurationTaskTest::ResponseCallback
,
184 base::Unretained(this)));
188 EXPECT_TRUE(configured_
);
189 EXPECT_TRUE(configuration_status_
);
190 EXPECT_EQ(MULTIPLE_DISPLAY_STATE_HEADLESS
, display_state_
);
191 EXPECT_EQ(chromeos::DISPLAY_POWER_ALL_ON
, power_state_
);
192 EXPECT_EQ(JoinActions(kGrab
, kUngrab
, NULL
), log_
.GetActionsAndClear());
195 TEST_F(UpdateDisplayConfigurationTaskTest
, SingleConfiguration
) {
199 UpdateDisplayConfigurationTask
task(
200 &delegate_
, &layout_manager_
, MULTIPLE_DISPLAY_STATE_SINGLE
,
201 chromeos::DISPLAY_POWER_ALL_ON
, 0, 0, false,
202 base::Bind(&UpdateDisplayConfigurationTaskTest::ResponseCallback
,
203 base::Unretained(this)));
207 EXPECT_TRUE(configured_
);
208 EXPECT_TRUE(configuration_status_
);
209 EXPECT_EQ(MULTIPLE_DISPLAY_STATE_SINGLE
, display_state_
);
210 EXPECT_EQ(chromeos::DISPLAY_POWER_ALL_ON
, power_state_
);
211 EXPECT_EQ(JoinActions(
212 kGrab
, GetFramebufferAction(small_mode_
.size(), &displays_
[0],
214 GetCrtcAction(displays_
[0], &small_mode_
, gfx::Point()).c_str(),
216 log_
.GetActionsAndClear());
219 TEST_F(UpdateDisplayConfigurationTaskTest
, ExtendedConfiguration
) {
223 UpdateDisplayConfigurationTask
task(
224 &delegate_
, &layout_manager_
, MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED
,
225 chromeos::DISPLAY_POWER_ALL_ON
, 0, 0, false,
226 base::Bind(&UpdateDisplayConfigurationTaskTest::ResponseCallback
,
227 base::Unretained(this)));
231 EXPECT_TRUE(configured_
);
232 EXPECT_TRUE(configuration_status_
);
233 EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED
, display_state_
);
234 EXPECT_EQ(chromeos::DISPLAY_POWER_ALL_ON
, power_state_
);
237 kGrab
, GetFramebufferAction(gfx::Size(big_mode_
.size().width(),
238 small_mode_
.size().height() +
239 big_mode_
.size().height()),
240 &displays_
[0], &displays_
[1]).c_str(),
241 GetCrtcAction(displays_
[0], &small_mode_
, gfx::Point()).c_str(),
242 GetCrtcAction(displays_
[1], &big_mode_
,
243 gfx::Point(0, small_mode_
.size().height())).c_str(),
245 log_
.GetActionsAndClear());
248 TEST_F(UpdateDisplayConfigurationTaskTest
, MirrorConfiguration
) {
252 UpdateDisplayConfigurationTask
task(
253 &delegate_
, &layout_manager_
, MULTIPLE_DISPLAY_STATE_DUAL_MIRROR
,
254 chromeos::DISPLAY_POWER_ALL_ON
, 0, 0, false,
255 base::Bind(&UpdateDisplayConfigurationTaskTest::ResponseCallback
,
256 base::Unretained(this)));
260 EXPECT_TRUE(configured_
);
261 EXPECT_TRUE(configuration_status_
);
262 EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR
, display_state_
);
263 EXPECT_EQ(chromeos::DISPLAY_POWER_ALL_ON
, power_state_
);
264 EXPECT_EQ(JoinActions(
265 kGrab
, GetFramebufferAction(small_mode_
.size(), &displays_
[0],
266 &displays_
[1]).c_str(),
267 GetCrtcAction(displays_
[0], &small_mode_
, gfx::Point()).c_str(),
268 GetCrtcAction(displays_
[1], &small_mode_
, gfx::Point()).c_str(),
270 log_
.GetActionsAndClear());
273 TEST_F(UpdateDisplayConfigurationTaskTest
, FailMirrorConfiguration
) {
274 layout_manager_
.set_should_mirror(false);
278 UpdateDisplayConfigurationTask
task(
279 &delegate_
, &layout_manager_
, MULTIPLE_DISPLAY_STATE_DUAL_MIRROR
,
280 chromeos::DISPLAY_POWER_ALL_ON
, 0, 0, false,
281 base::Bind(&UpdateDisplayConfigurationTaskTest::ResponseCallback
,
282 base::Unretained(this)));
286 EXPECT_TRUE(configured_
);
287 EXPECT_FALSE(configuration_status_
);
288 EXPECT_EQ(JoinActions(kGrab
, kUngrab
, NULL
), log_
.GetActionsAndClear());
291 TEST_F(UpdateDisplayConfigurationTaskTest
, FailExtendedConfiguration
) {
292 delegate_
.set_max_configurable_pixels(1);
296 UpdateDisplayConfigurationTask
task(
297 &delegate_
, &layout_manager_
, MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED
,
298 chromeos::DISPLAY_POWER_ALL_ON
, 0, 0, false,
299 base::Bind(&UpdateDisplayConfigurationTaskTest::ResponseCallback
,
300 base::Unretained(this)));
304 EXPECT_TRUE(configured_
);
305 EXPECT_FALSE(configuration_status_
);
308 kGrab
, GetFramebufferAction(gfx::Size(big_mode_
.size().width(),
309 small_mode_
.size().height() +
310 big_mode_
.size().height()),
311 &displays_
[0], &displays_
[1]).c_str(),
312 GetCrtcAction(displays_
[0], &small_mode_
, gfx::Point()).c_str(),
313 GetCrtcAction(displays_
[1], &big_mode_
,
314 gfx::Point(0, small_mode_
.size().height())).c_str(),
315 GetCrtcAction(displays_
[1], &small_mode_
,
316 gfx::Point(0, small_mode_
.size().height())).c_str(),
318 log_
.GetActionsAndClear());
321 TEST_F(UpdateDisplayConfigurationTaskTest
, SingleChangePowerConfiguration
) {
325 UpdateDisplayConfigurationTask
task(
326 &delegate_
, &layout_manager_
, MULTIPLE_DISPLAY_STATE_SINGLE
,
327 chromeos::DISPLAY_POWER_ALL_ON
, 0, 0, false,
328 base::Bind(&UpdateDisplayConfigurationTaskTest::ResponseCallback
,
329 base::Unretained(this)));
333 EXPECT_TRUE(configured_
);
334 EXPECT_TRUE(configuration_status_
);
335 EXPECT_EQ(MULTIPLE_DISPLAY_STATE_SINGLE
, display_state_
);
336 EXPECT_EQ(chromeos::DISPLAY_POWER_ALL_ON
, power_state_
);
337 EXPECT_EQ(JoinActions(
338 kGrab
, GetFramebufferAction(small_mode_
.size(), &displays_
[0],
340 GetCrtcAction(displays_
[0], &small_mode_
, gfx::Point()).c_str(),
342 log_
.GetActionsAndClear());
346 UpdateDisplayConfigurationTask
task(
347 &delegate_
, &layout_manager_
, MULTIPLE_DISPLAY_STATE_SINGLE
,
348 chromeos::DISPLAY_POWER_ALL_OFF
, 0, 0, false,
349 base::Bind(&UpdateDisplayConfigurationTaskTest::ResponseCallback
,
350 base::Unretained(this)));
354 EXPECT_TRUE(configuration_status_
);
355 EXPECT_EQ(MULTIPLE_DISPLAY_STATE_SINGLE
, display_state_
);
356 EXPECT_EQ(chromeos::DISPLAY_POWER_ALL_OFF
, power_state_
);
358 JoinActions(kGrab
, GetFramebufferAction(small_mode_
.size(), &displays_
[0],
360 GetCrtcAction(displays_
[0], nullptr, gfx::Point()).c_str(),
362 log_
.GetActionsAndClear());