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.
5 #include "ui/display/chromeos/display_configurator.h"
7 #include "base/memory/scoped_vector.h"
8 #include "base/message_loop/message_loop.h"
9 #include "testing/gtest/include/gtest/gtest.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"
19 class TestObserver
: public DisplayConfigurator::Observer
{
21 explicit TestObserver(DisplayConfigurator
* configurator
)
22 : configurator_(configurator
) {
24 configurator_
->AddObserver(this);
26 ~TestObserver() override
{ configurator_
->RemoveObserver(this); }
28 int num_changes() const { return num_changes_
; }
29 int num_failures() const { return num_failures_
; }
30 const DisplayConfigurator::DisplayStateList
& latest_outputs() const {
31 return latest_outputs_
;
33 MultipleDisplayState
latest_failed_state() const {
34 return latest_failed_state_
;
40 latest_outputs_
.clear();
41 latest_failed_state_
= MULTIPLE_DISPLAY_STATE_INVALID
;
44 // DisplayConfigurator::Observer overrides:
45 void OnDisplayModeChanged(
46 const DisplayConfigurator::DisplayStateList
& outputs
) override
{
48 latest_outputs_
= outputs
;
51 void OnDisplayModeChangeFailed(
52 const DisplayConfigurator::DisplayStateList
& outputs
,
53 MultipleDisplayState failed_new_state
) override
{
55 latest_failed_state_
= failed_new_state
;
59 DisplayConfigurator
* configurator_
; // Not owned.
61 // Number of times that OnDisplayMode*() has been called.
65 // Parameters most recently passed to OnDisplayMode*().
66 DisplayConfigurator::DisplayStateList latest_outputs_
;
67 MultipleDisplayState latest_failed_state_
;
69 DISALLOW_COPY_AND_ASSIGN(TestObserver
);
72 class TestStateController
: public DisplayConfigurator::StateController
{
74 TestStateController() : state_(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED
) {}
75 ~TestStateController() override
{}
77 void set_state(MultipleDisplayState state
) { state_
= state
; }
79 // DisplayConfigurator::StateController overrides:
80 MultipleDisplayState
GetStateForDisplayIds(
81 const DisplayConfigurator::DisplayStateList
& outputs
) const override
{
84 bool GetResolutionForDisplayId(int64_t display_id
,
85 gfx::Size
* size
) const override
{
90 MultipleDisplayState state_
;
92 DISALLOW_COPY_AND_ASSIGN(TestStateController
);
95 class TestMirroringController
96 : public DisplayConfigurator::SoftwareMirroringController
{
98 TestMirroringController() : software_mirroring_enabled_(false) {}
99 ~TestMirroringController() override
{}
101 void SetSoftwareMirroring(bool enabled
) override
{
102 software_mirroring_enabled_
= enabled
;
105 bool SoftwareMirroringEnabled() const override
{
106 return software_mirroring_enabled_
;
110 bool software_mirroring_enabled_
;
112 DISALLOW_COPY_AND_ASSIGN(TestMirroringController
);
115 class DisplayConfiguratorTest
: public testing::Test
{
117 enum CallbackResult
{
123 DisplayConfiguratorTest()
124 : small_mode_(gfx::Size(1366, 768), false, 60.0f
),
125 big_mode_(gfx::Size(2560, 1600), false, 60.0f
),
126 observer_(&configurator_
),
127 test_api_(&configurator_
),
128 enable_content_protection_status_(0),
129 enable_content_protection_call_count_(0),
130 query_content_protection_call_count_(0),
131 callback_result_(CALLBACK_NOT_CALLED
),
132 display_control_result_(CALLBACK_NOT_CALLED
) {}
133 ~DisplayConfiguratorTest() override
{}
135 void SetUp() override
{
136 log_
.reset(new ActionLogger());
138 native_display_delegate_
= new TestNativeDisplayDelegate(log_
.get());
139 configurator_
.SetDelegateForTesting(
140 scoped_ptr
<NativeDisplayDelegate
>(native_display_delegate_
));
142 configurator_
.set_state_controller(&state_controller_
);
143 configurator_
.set_mirroring_controller(&mirroring_controller_
);
145 std::vector
<const DisplayMode
*> modes
;
146 modes
.push_back(&small_mode_
);
148 TestDisplaySnapshot
* o
= &outputs_
[0];
149 o
->set_current_mode(&small_mode_
);
150 o
->set_native_mode(&small_mode_
);
152 o
->set_type(DISPLAY_CONNECTION_TYPE_INTERNAL
);
153 o
->set_is_aspect_preserving_scaling(true);
154 o
->set_display_id(123);
157 o
->set_current_mode(&big_mode_
);
158 o
->set_native_mode(&big_mode_
);
159 modes
.push_back(&big_mode_
);
161 o
->set_type(DISPLAY_CONNECTION_TYPE_HDMI
);
162 o
->set_is_aspect_preserving_scaling(true);
163 o
->set_display_id(456);
165 UpdateOutputs(2, false);
168 void OnConfiguredCallback(bool status
) {
169 callback_result_
= (status
? CALLBACK_SUCCESS
: CALLBACK_FAILURE
);
172 void OnDisplayControlUpdated(bool status
) {
173 display_control_result_
= (status
? CALLBACK_SUCCESS
: CALLBACK_FAILURE
);
176 void EnableContentProtectionCallback(bool status
) {
177 enable_content_protection_status_
= status
;
178 enable_content_protection_call_count_
++;
181 void QueryContentProtectionCallback(
182 const DisplayConfigurator::QueryProtectionResponse
& response
) {
183 query_content_protection_response_
= response
;
184 query_content_protection_call_count_
++;
187 // Predefined modes that can be used by outputs.
188 const DisplayMode small_mode_
;
189 const DisplayMode big_mode_
;
192 // Configures |native_display_delegate_| to return the first |num_outputs|
194 // |outputs_|. If |send_events| is true, also sends screen-change and
195 // output-change events to |configurator_| and triggers the configure
196 // timeout if one was scheduled.
197 void UpdateOutputs(size_t num_outputs
, bool send_events
) {
198 ASSERT_LE(num_outputs
, arraysize(outputs_
));
199 std::vector
<DisplaySnapshot
*> outputs
;
200 for (size_t i
= 0; i
< num_outputs
; ++i
)
201 outputs
.push_back(&outputs_
[i
]);
202 native_display_delegate_
->set_outputs(outputs
);
205 configurator_
.OnConfigurationChanged();
206 EXPECT_TRUE(test_api_
.TriggerConfigureTimeout());
210 // Initializes |configurator_| with a single internal display.
211 void InitWithSingleOutput() {
212 UpdateOutputs(1, false);
213 EXPECT_EQ(kNoActions
, log_
->GetActionsAndClear());
214 configurator_
.Init(false);
215 EXPECT_EQ(kNoActions
, log_
->GetActionsAndClear());
216 configurator_
.ForceInitialConfigure(0);
217 EXPECT_EQ(JoinActions(kInitXRandR
, kGrab
,
218 GetFramebufferAction(small_mode_
.size(), &outputs_
[0],
220 GetCrtcAction(outputs_
[0], &small_mode_
,
221 gfx::Point(0, 0)).c_str(),
222 kForceDPMS
, kUngrab
, NULL
),
223 log_
->GetActionsAndClear());
226 CallbackResult
PopCallbackResult() {
227 CallbackResult result
= callback_result_
;
228 callback_result_
= CALLBACK_NOT_CALLED
;
232 CallbackResult
PopDisplayControlResult() {
233 CallbackResult result
= display_control_result_
;
234 display_control_result_
= CALLBACK_NOT_CALLED
;
238 base::MessageLoop message_loop_
;
239 TestStateController state_controller_
;
240 TestMirroringController mirroring_controller_
;
241 DisplayConfigurator configurator_
;
242 TestObserver observer_
;
243 scoped_ptr
<ActionLogger
> log_
;
244 TestNativeDisplayDelegate
* native_display_delegate_
; // not owned
245 DisplayConfigurator::TestApi test_api_
;
247 bool enable_content_protection_status_
;
248 int enable_content_protection_call_count_
;
249 DisplayConfigurator::QueryProtectionResponse
250 query_content_protection_response_
;
251 int query_content_protection_call_count_
;
253 TestDisplaySnapshot outputs_
[2];
255 CallbackResult callback_result_
;
256 CallbackResult display_control_result_
;
259 DISALLOW_COPY_AND_ASSIGN(DisplayConfiguratorTest
);
264 TEST_F(DisplayConfiguratorTest
, FindDisplayModeMatchingSize
) {
265 ScopedVector
<const DisplayMode
> modes
;
267 // Fields are width, height, interlaced, refresh rate.
268 modes
.push_back(new DisplayMode(gfx::Size(1920, 1200), false, 60.0));
269 DisplayMode
* native_mode
=
270 new DisplayMode(gfx::Size(1920, 1200), false, 50.0);
271 modes
.push_back(native_mode
);
273 modes
.push_back(new DisplayMode(gfx::Size(1920, 1080), false, 30.0));
274 modes
.push_back(new DisplayMode(gfx::Size(1920, 1080), false, 50.0));
275 modes
.push_back(new DisplayMode(gfx::Size(1920, 1080), false, 40.0));
276 modes
.push_back(new DisplayMode(gfx::Size(1920, 1080), false, 0.0));
277 // Interlaced vs non-interlaced.
278 modes
.push_back(new DisplayMode(gfx::Size(1280, 720), true, 60.0));
279 modes
.push_back(new DisplayMode(gfx::Size(1280, 720), false, 40.0));
281 modes
.push_back(new DisplayMode(gfx::Size(1024, 768), true, 0.0));
282 modes
.push_back(new DisplayMode(gfx::Size(1024, 768), true, 40.0));
283 modes
.push_back(new DisplayMode(gfx::Size(1024, 768), true, 60.0));
285 modes
.push_back(new DisplayMode(gfx::Size(1024, 600), true, 60.0));
286 modes
.push_back(new DisplayMode(gfx::Size(1024, 600), false, 40.0));
287 modes
.push_back(new DisplayMode(gfx::Size(1024, 600), false, 50.0));
288 // Just one interlaced mode.
289 modes
.push_back(new DisplayMode(gfx::Size(640, 480), true, 60.0));
290 // Refresh rate not available.
291 modes
.push_back(new DisplayMode(gfx::Size(320, 200), false, 0.0));
293 TestDisplaySnapshot output
;
294 output
.set_modes(modes
.get());
295 output
.set_native_mode(native_mode
);
297 // Should pick native over highest refresh rate.
299 DisplayConfigurator::FindDisplayModeMatchingSize(
300 output
, gfx::Size(1920, 1200)));
302 // Should pick highest refresh rate.
304 DisplayConfigurator::FindDisplayModeMatchingSize(
305 output
, gfx::Size(1920, 1080)));
307 // Should pick non-interlaced mode.
309 DisplayConfigurator::FindDisplayModeMatchingSize(
310 output
, gfx::Size(1280, 720)));
312 // Interlaced only. Should pick one with the highest refresh rate in
315 DisplayConfigurator::FindDisplayModeMatchingSize(
316 output
, gfx::Size(1024, 768)));
318 // Mixed: Should pick one with the highest refresh rate in
321 DisplayConfigurator::FindDisplayModeMatchingSize(
322 output
, gfx::Size(1024, 600)));
324 // Just one interlaced mode.
326 DisplayConfigurator::FindDisplayModeMatchingSize(
327 output
, gfx::Size(640, 480)));
329 // Refresh rate not available.
331 DisplayConfigurator::FindDisplayModeMatchingSize(
332 output
, gfx::Size(320, 200)));
336 DisplayConfigurator::FindDisplayModeMatchingSize(
337 output
, gfx::Size(1440, 900)));
340 TEST_F(DisplayConfiguratorTest
, ConnectSecondOutput
) {
341 InitWithSingleOutput();
343 // Connect a second output and check that the configurator enters
346 state_controller_
.set_state(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED
);
347 UpdateOutputs(2, true);
348 const int kDualHeight
= small_mode_
.size().height() +
349 DisplayConfigurator::kVerticalGap
+
350 big_mode_
.size().height();
354 GetFramebufferAction(gfx::Size(big_mode_
.size().width(), kDualHeight
),
356 &outputs_
[1]).c_str(),
357 GetCrtcAction(outputs_
[0], &small_mode_
, gfx::Point(0, 0)).c_str(),
358 GetCrtcAction(outputs_
[1],
361 small_mode_
.size().height() +
362 DisplayConfigurator::kVerticalGap
))
366 log_
->GetActionsAndClear());
367 EXPECT_FALSE(mirroring_controller_
.SoftwareMirroringEnabled());
368 EXPECT_EQ(1, observer_
.num_changes());
371 configurator_
.SetDisplayMode(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR
);
375 GetFramebufferAction(small_mode_
.size(), &outputs_
[0], &outputs_
[1])
377 GetCrtcAction(outputs_
[0], &small_mode_
, gfx::Point(0, 0)).c_str(),
378 GetCrtcAction(outputs_
[1], &small_mode_
, gfx::Point(0, 0)).c_str(),
381 log_
->GetActionsAndClear());
382 EXPECT_FALSE(mirroring_controller_
.SoftwareMirroringEnabled());
383 EXPECT_EQ(1, observer_
.num_changes());
385 // Disconnect the second output.
387 UpdateOutputs(1, true);
391 GetFramebufferAction(small_mode_
.size(), &outputs_
[0], NULL
).c_str(),
392 GetCrtcAction(outputs_
[0], &small_mode_
, gfx::Point(0, 0)).c_str(),
395 log_
->GetActionsAndClear());
396 EXPECT_FALSE(mirroring_controller_
.SoftwareMirroringEnabled());
397 EXPECT_EQ(1, observer_
.num_changes());
399 // Get rid of shared modes to force software mirroring.
400 outputs_
[1].set_modes(std::vector
<const DisplayMode
*>(1, &big_mode_
));
401 state_controller_
.set_state(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED
);
402 UpdateOutputs(2, true);
406 GetFramebufferAction(gfx::Size(big_mode_
.size().width(), kDualHeight
),
408 &outputs_
[1]).c_str(),
409 GetCrtcAction(outputs_
[0], &small_mode_
, gfx::Point(0, 0)).c_str(),
410 GetCrtcAction(outputs_
[1],
413 small_mode_
.size().height() +
414 DisplayConfigurator::kVerticalGap
))
418 log_
->GetActionsAndClear());
419 EXPECT_FALSE(mirroring_controller_
.SoftwareMirroringEnabled());
420 const gfx::Size framebuffer_size
= configurator_
.framebuffer_size();
421 DCHECK(!framebuffer_size
.IsEmpty());
424 configurator_
.SetDisplayMode(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR
);
425 EXPECT_EQ(JoinActions(kGrab
, kUngrab
, NULL
), log_
->GetActionsAndClear());
426 EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED
,
427 configurator_
.display_state());
428 EXPECT_TRUE(mirroring_controller_
.SoftwareMirroringEnabled());
429 EXPECT_EQ(framebuffer_size
.ToString(),
430 configurator_
.framebuffer_size().ToString());
432 EXPECT_EQ(1, observer_
.num_changes());
434 // Setting MULTIPLE_DISPLAY_STATE_DUAL_MIRROR should try to reconfigure.
436 configurator_
.SetDisplayMode(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED
);
437 EXPECT_EQ(JoinActions(NULL
), log_
->GetActionsAndClear());
438 EXPECT_FALSE(mirroring_controller_
.SoftwareMirroringEnabled());
439 EXPECT_EQ(1, observer_
.num_changes());
441 // Set back to software mirror mode.
443 configurator_
.SetDisplayMode(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR
);
444 EXPECT_EQ(JoinActions(kGrab
, kUngrab
, NULL
), log_
->GetActionsAndClear());
445 EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED
,
446 configurator_
.display_state());
447 EXPECT_TRUE(mirroring_controller_
.SoftwareMirroringEnabled());
448 EXPECT_EQ(1, observer_
.num_changes());
450 // Disconnect the second output.
452 UpdateOutputs(1, true);
456 GetFramebufferAction(small_mode_
.size(), &outputs_
[0], NULL
).c_str(),
457 GetCrtcAction(outputs_
[0], &small_mode_
, gfx::Point(0, 0)).c_str(),
460 log_
->GetActionsAndClear());
461 EXPECT_FALSE(mirroring_controller_
.SoftwareMirroringEnabled());
462 EXPECT_EQ(1, observer_
.num_changes());
465 TEST_F(DisplayConfiguratorTest
, SetDisplayPower
) {
466 InitWithSingleOutput();
468 state_controller_
.set_state(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR
);
470 UpdateOutputs(2, true);
474 GetFramebufferAction(small_mode_
.size(), &outputs_
[0], &outputs_
[1])
476 GetCrtcAction(outputs_
[0], &small_mode_
, gfx::Point(0, 0)).c_str(),
477 GetCrtcAction(outputs_
[1], &small_mode_
, gfx::Point(0, 0)).c_str(),
480 log_
->GetActionsAndClear());
481 EXPECT_FALSE(mirroring_controller_
.SoftwareMirroringEnabled());
482 EXPECT_EQ(1, observer_
.num_changes());
484 // Turning off the internal display should switch the external display to
487 configurator_
.SetDisplayPower(
488 chromeos::DISPLAY_POWER_INTERNAL_OFF_EXTERNAL_ON
,
489 DisplayConfigurator::kSetDisplayPowerNoFlags
,
490 base::Bind(&DisplayConfiguratorTest::OnConfiguredCallback
,
491 base::Unretained(this)));
492 EXPECT_EQ(CALLBACK_SUCCESS
, PopCallbackResult());
496 GetFramebufferAction(big_mode_
.size(), &outputs_
[0], &outputs_
[1])
498 GetCrtcAction(outputs_
[0], NULL
, gfx::Point(0, 0)).c_str(),
499 GetCrtcAction(outputs_
[1], &big_mode_
, gfx::Point(0, 0)).c_str(),
503 log_
->GetActionsAndClear());
504 EXPECT_EQ(MULTIPLE_DISPLAY_STATE_SINGLE
, configurator_
.display_state());
505 EXPECT_EQ(1, observer_
.num_changes());
507 // When all displays are turned off, the framebuffer should switch back
508 // to the mirrored size.
510 configurator_
.SetDisplayPower(
511 chromeos::DISPLAY_POWER_ALL_OFF
,
512 DisplayConfigurator::kSetDisplayPowerNoFlags
,
513 base::Bind(&DisplayConfiguratorTest::OnConfiguredCallback
,
514 base::Unretained(this)));
515 EXPECT_EQ(CALLBACK_SUCCESS
, PopCallbackResult());
518 GetFramebufferAction(
519 small_mode_
.size(), &outputs_
[0], &outputs_
[1]).c_str(),
520 GetCrtcAction(outputs_
[0], NULL
, gfx::Point(0, 0)).c_str(),
521 GetCrtcAction(outputs_
[1], NULL
, gfx::Point(0, 0)).c_str(),
524 log_
->GetActionsAndClear());
525 EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR
, configurator_
.display_state());
526 EXPECT_FALSE(mirroring_controller_
.SoftwareMirroringEnabled());
527 EXPECT_EQ(1, observer_
.num_changes());
529 // Turn all displays on and check that mirroring is still used.
531 configurator_
.SetDisplayPower(
532 chromeos::DISPLAY_POWER_ALL_ON
,
533 DisplayConfigurator::kSetDisplayPowerNoFlags
,
534 base::Bind(&DisplayConfiguratorTest::OnConfiguredCallback
,
535 base::Unretained(this)));
536 EXPECT_EQ(CALLBACK_SUCCESS
, PopCallbackResult());
540 GetFramebufferAction(small_mode_
.size(), &outputs_
[0], &outputs_
[1])
542 GetCrtcAction(outputs_
[0], &small_mode_
, gfx::Point(0, 0)).c_str(),
543 GetCrtcAction(outputs_
[1], &small_mode_
, gfx::Point(0, 0)).c_str(),
547 log_
->GetActionsAndClear());
548 EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR
, configurator_
.display_state());
549 EXPECT_FALSE(mirroring_controller_
.SoftwareMirroringEnabled());
550 EXPECT_EQ(1, observer_
.num_changes());
552 // Get rid of shared modes to force software mirroring.
553 outputs_
[1].set_modes(std::vector
<const DisplayMode
*>(1, &big_mode_
));
554 state_controller_
.set_state(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR
);
556 UpdateOutputs(2, true);
557 const int kDualHeight
= small_mode_
.size().height() +
558 DisplayConfigurator::kVerticalGap
+
559 big_mode_
.size().height();
563 GetFramebufferAction(gfx::Size(big_mode_
.size().width(), kDualHeight
),
565 &outputs_
[1]).c_str(),
566 GetCrtcAction(outputs_
[0], &small_mode_
, gfx::Point(0, 0)).c_str(),
567 GetCrtcAction(outputs_
[1],
570 small_mode_
.size().height() +
571 DisplayConfigurator::kVerticalGap
))
575 log_
->GetActionsAndClear());
576 EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED
,
577 configurator_
.display_state());
578 EXPECT_TRUE(mirroring_controller_
.SoftwareMirroringEnabled());
579 EXPECT_EQ(1, observer_
.num_changes());
581 // Turning off the internal display should switch the external display to
584 configurator_
.SetDisplayPower(
585 chromeos::DISPLAY_POWER_INTERNAL_OFF_EXTERNAL_ON
,
586 DisplayConfigurator::kSetDisplayPowerNoFlags
,
587 base::Bind(&DisplayConfiguratorTest::OnConfiguredCallback
,
588 base::Unretained(this)));
589 EXPECT_EQ(CALLBACK_SUCCESS
, PopCallbackResult());
593 GetFramebufferAction(big_mode_
.size(), &outputs_
[0], &outputs_
[1])
595 GetCrtcAction(outputs_
[0], NULL
, gfx::Point(0, 0)).c_str(),
596 GetCrtcAction(outputs_
[1], &big_mode_
, gfx::Point(0, 0)).c_str(),
600 log_
->GetActionsAndClear());
601 EXPECT_EQ(MULTIPLE_DISPLAY_STATE_SINGLE
, configurator_
.display_state());
602 EXPECT_FALSE(mirroring_controller_
.SoftwareMirroringEnabled());
603 EXPECT_EQ(1, observer_
.num_changes());
605 // When all displays are turned off, the framebuffer should switch back
606 // to the extended + software mirroring.
608 configurator_
.SetDisplayPower(
609 chromeos::DISPLAY_POWER_ALL_OFF
,
610 DisplayConfigurator::kSetDisplayPowerNoFlags
,
611 base::Bind(&DisplayConfiguratorTest::OnConfiguredCallback
,
612 base::Unretained(this)));
613 EXPECT_EQ(CALLBACK_SUCCESS
, PopCallbackResult());
617 GetFramebufferAction(gfx::Size(big_mode_
.size().width(), kDualHeight
),
619 &outputs_
[1]).c_str(),
620 GetCrtcAction(outputs_
[0], NULL
, gfx::Point(0, 0)).c_str(),
621 GetCrtcAction(outputs_
[1],
624 small_mode_
.size().height() +
625 DisplayConfigurator::kVerticalGap
))
629 log_
->GetActionsAndClear());
630 EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED
,
631 configurator_
.display_state());
632 EXPECT_TRUE(mirroring_controller_
.SoftwareMirroringEnabled());
633 EXPECT_EQ(1, observer_
.num_changes());
635 // Turn all displays on and check that mirroring is still used.
637 configurator_
.SetDisplayPower(
638 chromeos::DISPLAY_POWER_ALL_ON
,
639 DisplayConfigurator::kSetDisplayPowerNoFlags
,
640 base::Bind(&DisplayConfiguratorTest::OnConfiguredCallback
,
641 base::Unretained(this)));
642 EXPECT_EQ(CALLBACK_SUCCESS
, PopCallbackResult());
646 GetFramebufferAction(gfx::Size(big_mode_
.size().width(), kDualHeight
),
648 &outputs_
[1]).c_str(),
649 GetCrtcAction(outputs_
[0], &small_mode_
, gfx::Point(0, 0)).c_str(),
650 GetCrtcAction(outputs_
[1],
653 small_mode_
.size().height() +
654 DisplayConfigurator::kVerticalGap
))
659 log_
->GetActionsAndClear());
660 EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED
,
661 configurator_
.display_state());
662 EXPECT_TRUE(mirroring_controller_
.SoftwareMirroringEnabled());
663 EXPECT_EQ(1, observer_
.num_changes());
666 TEST_F(DisplayConfiguratorTest
, SuspendAndResume
) {
667 InitWithSingleOutput();
669 // No preparation is needed before suspending when the display is already
670 // on. The configurator should still reprobe on resume in case a display
671 // was connected while suspended.
672 const gfx::Size framebuffer_size
= configurator_
.framebuffer_size();
673 DCHECK(!framebuffer_size
.IsEmpty());
674 configurator_
.SuspendDisplays(base::Bind(
675 &DisplayConfiguratorTest::OnConfiguredCallback
, base::Unretained(this)));
676 EXPECT_EQ(CALLBACK_SUCCESS
, PopCallbackResult());
677 EXPECT_EQ(framebuffer_size
.ToString(),
678 configurator_
.framebuffer_size().ToString());
679 EXPECT_EQ(kNoActions
, log_
->GetActionsAndClear());
680 configurator_
.ResumeDisplays();
681 EXPECT_TRUE(test_api_
.TriggerConfigureTimeout());
685 GetFramebufferAction(small_mode_
.size(), &outputs_
[0], NULL
).c_str(),
686 GetCrtcAction(outputs_
[0], &small_mode_
, gfx::Point(0, 0)).c_str(),
690 log_
->GetActionsAndClear());
692 // Now turn the display off before suspending and check that the
693 // configurator turns it back on and syncs with the server.
694 configurator_
.SetDisplayPower(
695 chromeos::DISPLAY_POWER_ALL_OFF
,
696 DisplayConfigurator::kSetDisplayPowerNoFlags
,
697 base::Bind(&DisplayConfiguratorTest::OnConfiguredCallback
,
698 base::Unretained(this)));
699 EXPECT_EQ(CALLBACK_SUCCESS
, PopCallbackResult());
703 GetFramebufferAction(small_mode_
.size(), &outputs_
[0], NULL
).c_str(),
704 GetCrtcAction(outputs_
[0], NULL
, gfx::Point(0, 0)).c_str(),
707 log_
->GetActionsAndClear());
709 configurator_
.SuspendDisplays(base::Bind(
710 &DisplayConfiguratorTest::OnConfiguredCallback
, base::Unretained(this)));
711 EXPECT_EQ(CALLBACK_SUCCESS
, PopCallbackResult());
715 GetFramebufferAction(small_mode_
.size(), &outputs_
[0], NULL
).c_str(),
716 GetCrtcAction(outputs_
[0], &small_mode_
, gfx::Point(0, 0)).c_str(),
721 log_
->GetActionsAndClear());
723 configurator_
.ResumeDisplays();
724 EXPECT_TRUE(test_api_
.TriggerConfigureTimeout());
728 GetFramebufferAction(small_mode_
.size(), &outputs_
[0], NULL
).c_str(),
729 GetCrtcAction(outputs_
[0], &small_mode_
, gfx::Point(0, 0)).c_str(),
733 log_
->GetActionsAndClear());
735 // If a second, external display is connected, the displays shouldn't be
736 // powered back on before suspending.
737 state_controller_
.set_state(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR
);
738 UpdateOutputs(2, true);
742 GetFramebufferAction(small_mode_
.size(), &outputs_
[0], &outputs_
[1])
744 GetCrtcAction(outputs_
[0], &small_mode_
, gfx::Point(0, 0)).c_str(),
745 GetCrtcAction(outputs_
[1], &small_mode_
, gfx::Point(0, 0)).c_str(),
748 log_
->GetActionsAndClear());
750 configurator_
.SetDisplayPower(
751 chromeos::DISPLAY_POWER_ALL_OFF
,
752 DisplayConfigurator::kSetDisplayPowerNoFlags
,
753 base::Bind(&DisplayConfiguratorTest::OnConfiguredCallback
,
754 base::Unretained(this)));
755 EXPECT_EQ(CALLBACK_SUCCESS
, PopCallbackResult());
758 GetFramebufferAction(
759 small_mode_
.size(), &outputs_
[0], &outputs_
[1]).c_str(),
760 GetCrtcAction(outputs_
[0], NULL
, gfx::Point(0, 0)).c_str(),
761 GetCrtcAction(outputs_
[1], NULL
, gfx::Point(0, 0)).c_str(),
764 log_
->GetActionsAndClear());
766 configurator_
.SuspendDisplays(base::Bind(
767 &DisplayConfiguratorTest::OnConfiguredCallback
, base::Unretained(this)));
768 EXPECT_EQ(CALLBACK_SUCCESS
, PopCallbackResult());
769 EXPECT_EQ(JoinActions(kGrab
, kUngrab
, kSync
, NULL
),
770 log_
->GetActionsAndClear());
772 // If a display is disconnected while suspended, the configurator should
773 // pick up the change.
774 UpdateOutputs(1, false);
775 configurator_
.ResumeDisplays();
776 EXPECT_TRUE(test_api_
.TriggerConfigureTimeout());
780 GetFramebufferAction(small_mode_
.size(), &outputs_
[0], NULL
).c_str(),
781 GetCrtcAction(outputs_
[0], NULL
, gfx::Point(0, 0)).c_str(),
784 log_
->GetActionsAndClear());
787 TEST_F(DisplayConfiguratorTest
, Headless
) {
788 UpdateOutputs(0, false);
789 EXPECT_EQ(kNoActions
, log_
->GetActionsAndClear());
790 configurator_
.Init(false);
791 EXPECT_EQ(kNoActions
, log_
->GetActionsAndClear());
792 configurator_
.ForceInitialConfigure(0);
793 EXPECT_EQ(JoinActions(kInitXRandR
, kGrab
, kForceDPMS
, kUngrab
, NULL
),
794 log_
->GetActionsAndClear());
796 // Not much should happen when the display power state is changed while
797 // no displays are connected.
798 configurator_
.SetDisplayPower(
799 chromeos::DISPLAY_POWER_ALL_OFF
,
800 DisplayConfigurator::kSetDisplayPowerNoFlags
,
801 base::Bind(&DisplayConfiguratorTest::OnConfiguredCallback
,
802 base::Unretained(this)));
803 EXPECT_EQ(CALLBACK_SUCCESS
, PopCallbackResult());
804 EXPECT_EQ(JoinActions(kGrab
, kUngrab
, NULL
), log_
->GetActionsAndClear());
805 configurator_
.SetDisplayPower(
806 chromeos::DISPLAY_POWER_ALL_ON
,
807 DisplayConfigurator::kSetDisplayPowerNoFlags
,
808 base::Bind(&DisplayConfiguratorTest::OnConfiguredCallback
,
809 base::Unretained(this)));
810 EXPECT_EQ(CALLBACK_SUCCESS
, PopCallbackResult());
811 EXPECT_EQ(JoinActions(kGrab
, kForceDPMS
, kUngrab
, NULL
),
812 log_
->GetActionsAndClear());
814 // Connect an external display and check that it's configured correctly.
815 outputs_
[0].set_current_mode(outputs_
[1].current_mode());
816 outputs_
[0].set_native_mode(outputs_
[1].native_mode());
817 outputs_
[0].set_modes(outputs_
[1].modes());
818 outputs_
[0].set_type(outputs_
[1].type());
820 UpdateOutputs(1, true);
824 GetFramebufferAction(big_mode_
.size(), &outputs_
[0], NULL
).c_str(),
825 GetCrtcAction(outputs_
[0], &big_mode_
, gfx::Point(0, 0)).c_str(),
828 log_
->GetActionsAndClear());
829 const gfx::Size framebuffer_size
= configurator_
.framebuffer_size();
830 DCHECK(!framebuffer_size
.IsEmpty());
832 UpdateOutputs(0, true);
833 EXPECT_EQ(JoinActions(kGrab
, kUngrab
, NULL
), log_
->GetActionsAndClear());
834 EXPECT_EQ(framebuffer_size
.ToString(),
835 configurator_
.framebuffer_size().ToString());
838 TEST_F(DisplayConfiguratorTest
, StartWithTwoOutputs
) {
839 UpdateOutputs(2, false);
840 EXPECT_EQ(kNoActions
, log_
->GetActionsAndClear());
841 configurator_
.Init(false);
842 EXPECT_EQ(kNoActions
, log_
->GetActionsAndClear());
844 state_controller_
.set_state(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR
);
845 configurator_
.ForceInitialConfigure(0);
849 GetFramebufferAction(small_mode_
.size(), &outputs_
[0], &outputs_
[1])
851 GetCrtcAction(outputs_
[0], &small_mode_
, gfx::Point(0, 0)).c_str(),
852 GetCrtcAction(outputs_
[1], &small_mode_
, gfx::Point(0, 0)).c_str(),
853 kForceDPMS
, kUngrab
, NULL
),
854 log_
->GetActionsAndClear());
857 TEST_F(DisplayConfiguratorTest
, InvalidMultipleDisplayStates
) {
858 UpdateOutputs(0, false);
859 EXPECT_EQ(kNoActions
, log_
->GetActionsAndClear());
860 configurator_
.Init(false);
861 configurator_
.ForceInitialConfigure(0);
863 configurator_
.SetDisplayMode(MULTIPLE_DISPLAY_STATE_HEADLESS
);
864 EXPECT_EQ(1, observer_
.num_changes());
865 EXPECT_EQ(0, observer_
.num_failures());
866 configurator_
.SetDisplayMode(MULTIPLE_DISPLAY_STATE_SINGLE
);
867 configurator_
.SetDisplayMode(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR
);
868 configurator_
.SetDisplayMode(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED
);
869 EXPECT_EQ(1, observer_
.num_changes());
870 EXPECT_EQ(3, observer_
.num_failures());
872 UpdateOutputs(1, true);
874 configurator_
.SetDisplayMode(MULTIPLE_DISPLAY_STATE_HEADLESS
);
875 EXPECT_EQ(0, observer_
.num_changes());
876 EXPECT_EQ(1, observer_
.num_failures());
877 configurator_
.SetDisplayMode(MULTIPLE_DISPLAY_STATE_SINGLE
);
878 EXPECT_EQ(1, observer_
.num_changes());
879 EXPECT_EQ(1, observer_
.num_failures());
880 configurator_
.SetDisplayMode(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR
);
881 configurator_
.SetDisplayMode(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED
);
882 EXPECT_EQ(1, observer_
.num_changes());
883 EXPECT_EQ(3, observer_
.num_failures());
885 state_controller_
.set_state(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED
);
886 UpdateOutputs(2, true);
888 configurator_
.SetDisplayMode(MULTIPLE_DISPLAY_STATE_HEADLESS
);
889 configurator_
.SetDisplayMode(MULTIPLE_DISPLAY_STATE_SINGLE
);
890 EXPECT_EQ(0, observer_
.num_changes());
891 EXPECT_EQ(2, observer_
.num_failures());
892 configurator_
.SetDisplayMode(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR
);
893 configurator_
.SetDisplayMode(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED
);
894 EXPECT_EQ(2, observer_
.num_changes());
895 EXPECT_EQ(2, observer_
.num_failures());
898 TEST_F(DisplayConfiguratorTest
, GetMultipleDisplayStateForMirroredDisplays
) {
899 UpdateOutputs(2, false);
900 configurator_
.Init(false);
901 state_controller_
.set_state(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR
);
902 configurator_
.ForceInitialConfigure(0);
903 EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR
, configurator_
.display_state());
906 TEST_F(DisplayConfiguratorTest
, UpdateCachedOutputsEvenAfterFailure
) {
907 InitWithSingleOutput();
908 const DisplayConfigurator::DisplayStateList
* cached
=
909 &configurator_
.cached_displays();
910 ASSERT_EQ(static_cast<size_t>(1), cached
->size());
911 EXPECT_EQ(outputs_
[0].current_mode(), (*cached
)[0]->current_mode());
913 // After connecting a second output, check that it shows up in
914 // |cached_displays_| even if an invalid state is requested.
915 state_controller_
.set_state(MULTIPLE_DISPLAY_STATE_SINGLE
);
916 UpdateOutputs(2, true);
917 cached
= &configurator_
.cached_displays();
918 ASSERT_EQ(static_cast<size_t>(2), cached
->size());
919 EXPECT_EQ(outputs_
[0].current_mode(), (*cached
)[0]->current_mode());
920 EXPECT_EQ(outputs_
[1].current_mode(), (*cached
)[1]->current_mode());
923 TEST_F(DisplayConfiguratorTest
, PanelFitting
) {
924 // Configure the internal display to support only the big mode and the
925 // external display to support only the small mode.
926 outputs_
[0].set_current_mode(&big_mode_
);
927 outputs_
[0].set_native_mode(&big_mode_
);
928 outputs_
[0].set_modes(std::vector
<const DisplayMode
*>(1, &big_mode_
));
930 outputs_
[1].set_current_mode(&small_mode_
);
931 outputs_
[1].set_native_mode(&small_mode_
);
932 outputs_
[1].set_modes(std::vector
<const DisplayMode
*>(1, &small_mode_
));
934 // The small mode should be added to the internal output when requesting
936 UpdateOutputs(2, false);
937 state_controller_
.set_state(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR
);
938 configurator_
.Init(true /* is_panel_fitting_enabled */);
939 configurator_
.ForceInitialConfigure(0);
940 EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR
, configurator_
.display_state());
944 GetAddOutputModeAction(outputs_
[0], &small_mode_
).c_str(),
945 GetFramebufferAction(small_mode_
.size(), &outputs_
[0], &outputs_
[1])
947 GetCrtcAction(outputs_
[0], &small_mode_
, gfx::Point(0, 0)).c_str(),
948 GetCrtcAction(outputs_
[1], &small_mode_
, gfx::Point(0, 0)).c_str(),
949 kForceDPMS
, kUngrab
, NULL
),
950 log_
->GetActionsAndClear());
952 // Both outputs should be using the small mode.
953 ASSERT_EQ(1, observer_
.num_changes());
954 ASSERT_EQ(static_cast<size_t>(2), observer_
.latest_outputs().size());
955 EXPECT_EQ(&small_mode_
, observer_
.latest_outputs()[0]->current_mode());
956 EXPECT_EQ(&small_mode_
, observer_
.latest_outputs()[1]->current_mode());
958 // Also check that the newly-added small mode is present in the internal
959 // snapshot that was passed to the observer (http://crbug.com/289159).
960 DisplaySnapshot
* state
= observer_
.latest_outputs()[0];
962 state
->modes().end(),
963 std::find(state
->modes().begin(), state
->modes().end(), &small_mode_
));
966 TEST_F(DisplayConfiguratorTest
, ContentProtection
) {
967 configurator_
.Init(false);
968 configurator_
.ForceInitialConfigure(0);
969 EXPECT_NE(kNoActions
, log_
->GetActionsAndClear());
971 DisplayConfigurator::ContentProtectionClientId id
=
972 configurator_
.RegisterContentProtectionClient();
976 UpdateOutputs(1, true);
977 EXPECT_NE(kNoActions
, log_
->GetActionsAndClear());
978 configurator_
.QueryContentProtectionStatus(
979 id
, outputs_
[0].display_id(),
980 base::Bind(&DisplayConfiguratorTest::QueryContentProtectionCallback
,
981 base::Unretained(this)));
982 EXPECT_EQ(1, query_content_protection_call_count_
);
983 EXPECT_TRUE(query_content_protection_response_
.success
);
984 EXPECT_EQ(static_cast<uint32_t>(DISPLAY_CONNECTION_TYPE_INTERNAL
),
985 query_content_protection_response_
.link_mask
);
986 EXPECT_EQ(static_cast<uint32_t>(CONTENT_PROTECTION_METHOD_NONE
),
987 query_content_protection_response_
.protection_mask
);
988 EXPECT_EQ(kNoActions
, log_
->GetActionsAndClear());
991 UpdateOutputs(2, true);
992 EXPECT_NE(kNoActions
, log_
->GetActionsAndClear());
993 configurator_
.QueryContentProtectionStatus(
994 id
, outputs_
[1].display_id(),
995 base::Bind(&DisplayConfiguratorTest::QueryContentProtectionCallback
,
996 base::Unretained(this)));
997 EXPECT_EQ(2, query_content_protection_call_count_
);
998 EXPECT_TRUE(query_content_protection_response_
.success
);
999 EXPECT_EQ(static_cast<uint32_t>(DISPLAY_CONNECTION_TYPE_HDMI
),
1000 query_content_protection_response_
.link_mask
);
1001 EXPECT_EQ(static_cast<uint32_t>(CONTENT_PROTECTION_METHOD_NONE
),
1002 query_content_protection_response_
.protection_mask
);
1003 EXPECT_EQ(kNoActions
, log_
->GetActionsAndClear());
1005 configurator_
.EnableContentProtection(
1006 id
, outputs_
[1].display_id(), CONTENT_PROTECTION_METHOD_HDCP
,
1007 base::Bind(&DisplayConfiguratorTest::EnableContentProtectionCallback
,
1008 base::Unretained(this)));
1009 EXPECT_EQ(1, enable_content_protection_call_count_
);
1010 EXPECT_TRUE(enable_content_protection_status_
);
1011 EXPECT_EQ(GetSetHDCPStateAction(outputs_
[1], HDCP_STATE_DESIRED
),
1012 log_
->GetActionsAndClear());
1014 // Enable protection.
1015 native_display_delegate_
->set_hdcp_state(HDCP_STATE_ENABLED
);
1016 configurator_
.QueryContentProtectionStatus(
1017 id
, outputs_
[1].display_id(),
1018 base::Bind(&DisplayConfiguratorTest::QueryContentProtectionCallback
,
1019 base::Unretained(this)));
1020 EXPECT_EQ(3, query_content_protection_call_count_
);
1021 EXPECT_TRUE(query_content_protection_response_
.success
);
1022 EXPECT_EQ(static_cast<uint32_t>(DISPLAY_CONNECTION_TYPE_HDMI
),
1023 query_content_protection_response_
.link_mask
);
1024 EXPECT_EQ(static_cast<uint32_t>(CONTENT_PROTECTION_METHOD_HDCP
),
1025 query_content_protection_response_
.protection_mask
);
1026 EXPECT_EQ(kNoActions
, log_
->GetActionsAndClear());
1028 // Protections should be disabled after unregister.
1029 configurator_
.UnregisterContentProtectionClient(id
);
1030 EXPECT_EQ(GetSetHDCPStateAction(outputs_
[1], HDCP_STATE_UNDESIRED
),
1031 log_
->GetActionsAndClear());
1034 TEST_F(DisplayConfiguratorTest
, DoNotConfigureWithSuspendedDisplays
) {
1035 InitWithSingleOutput();
1037 // The DisplayConfigurator may occasionally receive OnConfigurationChanged()
1038 // after the displays have been suspended. This event should be ignored since
1039 // the DisplayConfigurator will force a probe and reconfiguration of displays
1041 configurator_
.SuspendDisplays(base::Bind(
1042 &DisplayConfiguratorTest::OnConfiguredCallback
, base::Unretained(this)));
1043 EXPECT_EQ(CALLBACK_SUCCESS
, PopCallbackResult());
1044 EXPECT_EQ(kNoActions
, log_
->GetActionsAndClear());
1046 // The configuration timer should not be started when the displays
1048 configurator_
.OnConfigurationChanged();
1049 EXPECT_FALSE(test_api_
.TriggerConfigureTimeout());
1050 EXPECT_EQ(kNoActions
, log_
->GetActionsAndClear());
1052 // Calls to SetDisplayPower and SetDisplayMode should be successful.
1053 configurator_
.SetDisplayPower(
1054 chromeos::DISPLAY_POWER_ALL_OFF
,
1055 DisplayConfigurator::kSetDisplayPowerNoFlags
,
1056 base::Bind(&DisplayConfiguratorTest::OnConfiguredCallback
,
1057 base::Unretained(this)));
1058 EXPECT_EQ(CALLBACK_SUCCESS
, PopCallbackResult());
1062 GetFramebufferAction(small_mode_
.size(), &outputs_
[0], NULL
).c_str(),
1063 GetCrtcAction(outputs_
[0], NULL
, gfx::Point(0, 0)).c_str(),
1066 log_
->GetActionsAndClear());
1067 configurator_
.SetDisplayPower(
1068 chromeos::DISPLAY_POWER_ALL_ON
,
1069 DisplayConfigurator::kSetDisplayPowerNoFlags
,
1070 base::Bind(&DisplayConfiguratorTest::OnConfiguredCallback
,
1071 base::Unretained(this)));
1072 EXPECT_EQ(CALLBACK_SUCCESS
, PopCallbackResult());
1076 GetFramebufferAction(small_mode_
.size(), &outputs_
[0], NULL
).c_str(),
1077 GetCrtcAction(outputs_
[0], &small_mode_
, gfx::Point(0, 0)).c_str(),
1081 log_
->GetActionsAndClear());
1083 UpdateOutputs(2, false);
1084 configurator_
.SetDisplayMode(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR
);
1088 GetFramebufferAction(small_mode_
.size(), &outputs_
[0], &outputs_
[1])
1090 GetCrtcAction(outputs_
[0], &small_mode_
, gfx::Point(0, 0)).c_str(),
1091 GetCrtcAction(outputs_
[1], &small_mode_
, gfx::Point(0, 0)).c_str(),
1094 log_
->GetActionsAndClear());
1096 // The DisplayConfigurator should force a probe and reconfiguration at resume
1098 UpdateOutputs(1, false);
1099 configurator_
.ResumeDisplays();
1100 EXPECT_TRUE(test_api_
.TriggerConfigureTimeout());
1104 GetFramebufferAction(small_mode_
.size(), &outputs_
[0], NULL
).c_str(),
1105 GetCrtcAction(outputs_
[0], &small_mode_
, gfx::Point(0, 0)).c_str(),
1109 log_
->GetActionsAndClear());
1111 // If a configuration task is pending when the displays are suspended, that
1112 // task should not run either and the timer should be stopped.
1113 configurator_
.OnConfigurationChanged();
1114 configurator_
.SuspendDisplays(base::Bind(
1115 &DisplayConfiguratorTest::OnConfiguredCallback
, base::Unretained(this)));
1116 EXPECT_EQ(CALLBACK_SUCCESS
, PopCallbackResult());
1117 EXPECT_EQ(kNoActions
, log_
->GetActionsAndClear());
1119 EXPECT_FALSE(test_api_
.TriggerConfigureTimeout());
1120 EXPECT_EQ(kNoActions
, log_
->GetActionsAndClear());
1122 configurator_
.ResumeDisplays();
1123 EXPECT_TRUE(test_api_
.TriggerConfigureTimeout());
1127 GetFramebufferAction(small_mode_
.size(), &outputs_
[0], NULL
).c_str(),
1128 GetCrtcAction(outputs_
[0], &small_mode_
, gfx::Point(0, 0)).c_str(),
1132 log_
->GetActionsAndClear());
1135 TEST_F(DisplayConfiguratorTest
, ContentProtectionTwoClients
) {
1136 DisplayConfigurator::ContentProtectionClientId client1
=
1137 configurator_
.RegisterContentProtectionClient();
1138 DisplayConfigurator::ContentProtectionClientId client2
=
1139 configurator_
.RegisterContentProtectionClient();
1140 EXPECT_NE(client1
, client2
);
1142 configurator_
.Init(false);
1143 configurator_
.ForceInitialConfigure(0);
1144 UpdateOutputs(2, true);
1145 EXPECT_NE(kNoActions
, log_
->GetActionsAndClear());
1147 // Clients never know state enableness for methods that they didn't request.
1148 configurator_
.EnableContentProtection(
1149 client1
, outputs_
[1].display_id(), CONTENT_PROTECTION_METHOD_HDCP
,
1150 base::Bind(&DisplayConfiguratorTest::EnableContentProtectionCallback
,
1151 base::Unretained(this)));
1152 EXPECT_EQ(1, enable_content_protection_call_count_
);
1153 EXPECT_TRUE(enable_content_protection_status_
);
1154 EXPECT_EQ(GetSetHDCPStateAction(outputs_
[1], HDCP_STATE_DESIRED
).c_str(),
1155 log_
->GetActionsAndClear());
1156 native_display_delegate_
->set_hdcp_state(HDCP_STATE_ENABLED
);
1158 configurator_
.QueryContentProtectionStatus(
1159 client1
, outputs_
[1].display_id(),
1160 base::Bind(&DisplayConfiguratorTest::QueryContentProtectionCallback
,
1161 base::Unretained(this)));
1162 EXPECT_EQ(1, query_content_protection_call_count_
);
1163 EXPECT_TRUE(query_content_protection_response_
.success
);
1164 EXPECT_EQ(static_cast<uint32_t>(DISPLAY_CONNECTION_TYPE_HDMI
),
1165 query_content_protection_response_
.link_mask
);
1166 EXPECT_EQ(CONTENT_PROTECTION_METHOD_HDCP
,
1167 query_content_protection_response_
.protection_mask
);
1169 configurator_
.QueryContentProtectionStatus(
1170 client2
, outputs_
[1].display_id(),
1171 base::Bind(&DisplayConfiguratorTest::QueryContentProtectionCallback
,
1172 base::Unretained(this)));
1173 EXPECT_EQ(2, query_content_protection_call_count_
);
1174 EXPECT_TRUE(query_content_protection_response_
.success
);
1175 EXPECT_EQ(static_cast<uint32_t>(DISPLAY_CONNECTION_TYPE_HDMI
),
1176 query_content_protection_response_
.link_mask
);
1177 EXPECT_EQ(CONTENT_PROTECTION_METHOD_NONE
,
1178 query_content_protection_response_
.protection_mask
);
1180 // Protections will be disabled only if no more clients request them.
1181 configurator_
.EnableContentProtection(
1182 client2
, outputs_
[1].display_id(), CONTENT_PROTECTION_METHOD_NONE
,
1183 base::Bind(&DisplayConfiguratorTest::EnableContentProtectionCallback
,
1184 base::Unretained(this)));
1185 EXPECT_EQ(2, enable_content_protection_call_count_
);
1186 EXPECT_TRUE(enable_content_protection_status_
);
1187 EXPECT_EQ(kNoActions
, log_
->GetActionsAndClear());
1189 configurator_
.EnableContentProtection(
1190 client1
, outputs_
[1].display_id(), CONTENT_PROTECTION_METHOD_NONE
,
1191 base::Bind(&DisplayConfiguratorTest::EnableContentProtectionCallback
,
1192 base::Unretained(this)));
1193 EXPECT_EQ(3, enable_content_protection_call_count_
);
1194 EXPECT_TRUE(enable_content_protection_status_
);
1195 EXPECT_EQ(GetSetHDCPStateAction(outputs_
[1], HDCP_STATE_UNDESIRED
).c_str(),
1196 log_
->GetActionsAndClear());
1199 TEST_F(DisplayConfiguratorTest
, ContentProtectionTwoClientsEnable
) {
1200 DisplayConfigurator::ContentProtectionClientId client1
=
1201 configurator_
.RegisterContentProtectionClient();
1202 DisplayConfigurator::ContentProtectionClientId client2
=
1203 configurator_
.RegisterContentProtectionClient();
1204 EXPECT_NE(client1
, client2
);
1206 configurator_
.Init(false);
1207 configurator_
.ForceInitialConfigure(0);
1208 UpdateOutputs(2, true);
1209 log_
->GetActionsAndClear();
1211 // Only enable once if HDCP is enabling.
1212 configurator_
.EnableContentProtection(
1213 client1
, outputs_
[1].display_id(), CONTENT_PROTECTION_METHOD_HDCP
,
1214 base::Bind(&DisplayConfiguratorTest::EnableContentProtectionCallback
,
1215 base::Unretained(this)));
1216 EXPECT_EQ(1, enable_content_protection_call_count_
);
1217 EXPECT_TRUE(enable_content_protection_status_
);
1218 native_display_delegate_
->set_hdcp_state(HDCP_STATE_DESIRED
);
1219 configurator_
.EnableContentProtection(
1220 client2
, outputs_
[1].display_id(), CONTENT_PROTECTION_METHOD_HDCP
,
1221 base::Bind(&DisplayConfiguratorTest::EnableContentProtectionCallback
,
1222 base::Unretained(this)));
1223 EXPECT_EQ(2, enable_content_protection_call_count_
);
1224 EXPECT_TRUE(enable_content_protection_status_
);
1225 EXPECT_EQ(GetSetHDCPStateAction(outputs_
[1], HDCP_STATE_DESIRED
).c_str(),
1226 log_
->GetActionsAndClear());
1227 native_display_delegate_
->set_hdcp_state(HDCP_STATE_ENABLED
);
1229 // Don't enable again if HDCP is already active.
1230 configurator_
.EnableContentProtection(
1231 client1
, outputs_
[1].display_id(), CONTENT_PROTECTION_METHOD_HDCP
,
1232 base::Bind(&DisplayConfiguratorTest::EnableContentProtectionCallback
,
1233 base::Unretained(this)));
1234 EXPECT_EQ(3, enable_content_protection_call_count_
);
1235 EXPECT_TRUE(enable_content_protection_status_
);
1236 configurator_
.EnableContentProtection(
1237 client2
, outputs_
[1].display_id(), CONTENT_PROTECTION_METHOD_HDCP
,
1238 base::Bind(&DisplayConfiguratorTest::EnableContentProtectionCallback
,
1239 base::Unretained(this)));
1240 EXPECT_EQ(4, enable_content_protection_call_count_
);
1241 EXPECT_TRUE(enable_content_protection_status_
);
1242 EXPECT_EQ(kNoActions
, log_
->GetActionsAndClear());
1245 TEST_F(DisplayConfiguratorTest
, HandleConfigureCrtcFailure
) {
1246 InitWithSingleOutput();
1248 ScopedVector
<const DisplayMode
> modes
;
1249 // The first mode is the mode we are requesting DisplayConfigurator to choose.
1250 // The test will be setup so that this mode will fail and it will have to
1251 // choose the next best option.
1252 modes
.push_back(new DisplayMode(gfx::Size(2560, 1600), false, 60.0));
1253 modes
.push_back(new DisplayMode(gfx::Size(1024, 768), false, 60.0));
1254 modes
.push_back(new DisplayMode(gfx::Size(1280, 720), false, 60.0));
1255 modes
.push_back(new DisplayMode(gfx::Size(1920, 1080), false, 60.0));
1256 modes
.push_back(new DisplayMode(gfx::Size(1920, 1080), false, 40.0));
1258 for (unsigned int i
= 0; i
< arraysize(outputs_
); i
++) {
1259 outputs_
[i
].set_modes(modes
.get());
1260 outputs_
[i
].set_current_mode(modes
[0]);
1261 outputs_
[i
].set_native_mode(modes
[0]);
1264 // First test simply fails in MULTIPLE_DISPLAY_STATE_SINGLE mode. This is
1265 // probably unrealistic but we want to make sure any assumptions don't creep
1267 native_display_delegate_
->set_max_configurable_pixels(
1268 modes
[2]->size().GetArea());
1269 state_controller_
.set_state(MULTIPLE_DISPLAY_STATE_SINGLE
);
1270 UpdateOutputs(1, true);
1275 GetFramebufferAction(big_mode_
.size(), &outputs_
[0], NULL
).c_str(),
1276 GetCrtcAction(outputs_
[0], modes
[0], gfx::Point(0, 0)).c_str(),
1277 GetCrtcAction(outputs_
[0], modes
[3], gfx::Point(0, 0)).c_str(),
1278 GetCrtcAction(outputs_
[0], modes
[2], gfx::Point(0, 0)).c_str(),
1281 log_
->GetActionsAndClear());
1283 // This test should attempt to configure a mirror mode that will not succeed
1284 // and should end up in extended mode.
1285 native_display_delegate_
->set_max_configurable_pixels(
1286 modes
[3]->size().GetArea());
1287 state_controller_
.set_state(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR
);
1288 UpdateOutputs(2, true);
1292 kGrab
, GetFramebufferAction(modes
[0]->size(), &outputs_
[0],
1293 &outputs_
[1]).c_str(),
1294 GetCrtcAction(outputs_
[0], modes
[0], gfx::Point(0, 0)).c_str(),
1295 // Then attempt to configure crtc1 with the first mode.
1296 GetCrtcAction(outputs_
[1], modes
[0], gfx::Point(0, 0)).c_str(),
1297 // First mode tried is expected to fail and it will
1298 // retry wil the 4th mode in the list.
1299 GetCrtcAction(outputs_
[0], modes
[3], gfx::Point(0, 0)).c_str(),
1300 GetCrtcAction(outputs_
[1], modes
[3], gfx::Point(0, 0)).c_str(),
1301 // Since it was requested to go into mirror mode
1302 // and the configured modes were different, it
1303 // should now try and setup a valid configurable
1305 GetFramebufferAction(
1306 gfx::Size(modes
[0]->size().width(),
1307 modes
[0]->size().height() + modes
[0]->size().height() +
1308 DisplayConfigurator::kVerticalGap
),
1309 &outputs_
[0], &outputs_
[1]).c_str(),
1310 GetCrtcAction(outputs_
[0], modes
[0], gfx::Point(0, 0)).c_str(),
1311 GetCrtcAction(outputs_
[1], modes
[0],
1312 gfx::Point(0, modes
[0]->size().height() +
1313 DisplayConfigurator::kVerticalGap
))
1315 GetCrtcAction(outputs_
[0], modes
[3], gfx::Point(0, 0)).c_str(),
1316 GetCrtcAction(outputs_
[1], modes
[3],
1317 gfx::Point(0, modes
[0]->size().height() +
1318 DisplayConfigurator::kVerticalGap
))
1321 log_
->GetActionsAndClear());
1324 // Tests that power state requests are saved after failed configuration attempts
1325 // so they can be reused later: http://crosbug.com/p/31571
1326 TEST_F(DisplayConfiguratorTest
, SaveDisplayPowerStateOnConfigFailure
) {
1327 // Start out with two displays in extended mode.
1328 state_controller_
.set_state(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED
);
1329 configurator_
.Init(false);
1330 configurator_
.ForceInitialConfigure(0);
1331 log_
->GetActionsAndClear();
1334 // Turn off the internal display, simulating docked mode.
1335 configurator_
.SetDisplayPower(
1336 chromeos::DISPLAY_POWER_INTERNAL_OFF_EXTERNAL_ON
,
1337 DisplayConfigurator::kSetDisplayPowerNoFlags
,
1338 base::Bind(&DisplayConfiguratorTest::OnConfiguredCallback
,
1339 base::Unretained(this)));
1340 EXPECT_EQ(CALLBACK_SUCCESS
, PopCallbackResult());
1341 EXPECT_EQ(1, observer_
.num_changes());
1342 EXPECT_EQ(0, observer_
.num_failures());
1343 log_
->GetActionsAndClear();
1345 // Make all subsequent configuration requests fail and try to turn the
1346 // internal display back on.
1347 native_display_delegate_
->set_max_configurable_pixels(1);
1348 configurator_
.SetDisplayPower(
1349 chromeos::DISPLAY_POWER_ALL_ON
,
1350 DisplayConfigurator::kSetDisplayPowerNoFlags
,
1351 base::Bind(&DisplayConfiguratorTest::OnConfiguredCallback
,
1352 base::Unretained(this)));
1353 EXPECT_EQ(CALLBACK_FAILURE
, PopCallbackResult());
1354 EXPECT_EQ(1, observer_
.num_changes());
1355 EXPECT_EQ(1, observer_
.num_failures());
1356 log_
->GetActionsAndClear();
1358 // Simulate the external display getting disconnected and check that the
1359 // internal display is turned on (i.e. DISPLAY_POWER_ALL_ON is used) rather
1360 // than the earlier DISPLAY_POWER_INTERNAL_OFF_EXTERNAL_ON state.
1361 native_display_delegate_
->set_max_configurable_pixels(0);
1362 UpdateOutputs(1, true);
1363 EXPECT_EQ(JoinActions(kGrab
, GetFramebufferAction(small_mode_
.size(),
1364 &outputs_
[0], NULL
).c_str(),
1365 GetCrtcAction(outputs_
[0], &small_mode_
,
1366 gfx::Point(0, 0)).c_str(),
1367 kForceDPMS
, kUngrab
, NULL
),
1368 log_
->GetActionsAndClear());
1371 // Tests that the SetDisplayPowerState() task posted by HandleResume() doesn't
1372 // use a stale state if a new state is requested before it runs:
1373 // http://crosbug.com/p/32393
1374 TEST_F(DisplayConfiguratorTest
, DontRestoreStalePowerStateAfterResume
) {
1375 // Start out with two displays in mirrored mode.
1376 state_controller_
.set_state(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR
);
1377 configurator_
.Init(false);
1378 configurator_
.ForceInitialConfigure(0);
1379 log_
->GetActionsAndClear();
1382 // Turn off the internal display, simulating docked mode.
1383 configurator_
.SetDisplayPower(
1384 chromeos::DISPLAY_POWER_INTERNAL_OFF_EXTERNAL_ON
,
1385 DisplayConfigurator::kSetDisplayPowerNoFlags
,
1386 base::Bind(&DisplayConfiguratorTest::OnConfiguredCallback
,
1387 base::Unretained(this)));
1388 EXPECT_EQ(CALLBACK_SUCCESS
, PopCallbackResult());
1389 EXPECT_EQ(1, observer_
.num_changes());
1390 EXPECT_EQ(0, observer_
.num_failures());
1394 GetFramebufferAction(big_mode_
.size(), &outputs_
[0], &outputs_
[1])
1396 GetCrtcAction(outputs_
[0], NULL
, gfx::Point(0, 0)).c_str(),
1397 GetCrtcAction(outputs_
[1], &big_mode_
, gfx::Point(0, 0)).c_str(),
1401 log_
->GetActionsAndClear());
1403 // Suspend and resume the system. Resuming should post a task to restore the
1404 // previous power state, additionally forcing a probe.
1405 configurator_
.SuspendDisplays(base::Bind(
1406 &DisplayConfiguratorTest::OnConfiguredCallback
, base::Unretained(this)));
1407 EXPECT_EQ(CALLBACK_SUCCESS
, PopCallbackResult());
1408 configurator_
.ResumeDisplays();
1410 // Before the task runs, exit docked mode.
1411 configurator_
.SetDisplayPower(
1412 chromeos::DISPLAY_POWER_ALL_ON
,
1413 DisplayConfigurator::kSetDisplayPowerNoFlags
,
1414 base::Bind(&DisplayConfiguratorTest::OnConfiguredCallback
,
1415 base::Unretained(this)));
1416 EXPECT_EQ(CALLBACK_SUCCESS
, PopCallbackResult());
1417 EXPECT_EQ(2, observer_
.num_changes());
1418 EXPECT_EQ(0, observer_
.num_failures());
1422 GetFramebufferAction(small_mode_
.size(), &outputs_
[0], &outputs_
[1])
1424 GetCrtcAction(outputs_
[0], &small_mode_
, gfx::Point(0, 0)).c_str(),
1425 GetCrtcAction(outputs_
[1], &small_mode_
, gfx::Point(0, 0)).c_str(),
1429 log_
->GetActionsAndClear());
1431 // Check that the task doesn't restore the old internal-off-external-on power
1433 EXPECT_TRUE(test_api_
.TriggerConfigureTimeout());
1437 GetFramebufferAction(small_mode_
.size(), &outputs_
[0], &outputs_
[1])
1439 GetCrtcAction(outputs_
[0], &small_mode_
, gfx::Point(0, 0)).c_str(),
1440 GetCrtcAction(outputs_
[1], &small_mode_
, gfx::Point(0, 0)).c_str(),
1444 log_
->GetActionsAndClear());
1447 TEST_F(DisplayConfiguratorTest
, ExternalControl
) {
1448 InitWithSingleOutput();
1449 state_controller_
.set_state(MULTIPLE_DISPLAY_STATE_SINGLE
);
1450 configurator_
.RelinquishControl(
1451 base::Bind(&DisplayConfiguratorTest::OnDisplayControlUpdated
,
1452 base::Unretained(this)));
1453 EXPECT_EQ(CALLBACK_SUCCESS
, PopDisplayControlResult());
1456 kRelinquishDisplayControl
,
1458 log_
->GetActionsAndClear());
1459 configurator_
.TakeControl(
1460 base::Bind(&DisplayConfiguratorTest::OnDisplayControlUpdated
,
1461 base::Unretained(this)));
1462 EXPECT_EQ(CALLBACK_SUCCESS
, PopDisplayControlResult());
1463 EXPECT_EQ(JoinActions(kTakeDisplayControl
, kGrab
,
1464 GetFramebufferAction(small_mode_
.size(), &outputs_
[0],
1466 GetCrtcAction(outputs_
[0], &small_mode_
,
1467 gfx::Point(0, 0)).c_str(),
1469 log_
->GetActionsAndClear());