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"
15 #include "base/compiler_specific.h"
16 #include "base/format_macros.h"
17 #include "base/memory/scoped_vector.h"
18 #include "base/message_loop/message_loop.h"
19 #include "base/strings/stringprintf.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21 #include "ui/display/chromeos/test/test_display_snapshot.h"
22 #include "ui/display/types/chromeos/display_mode.h"
23 #include "ui/display/types/chromeos/native_display_delegate.h"
29 // Strings returned by TestNativeDisplayDelegate::GetActionsAndClear() to
30 // describe various actions that were performed.
31 const char kInitXRandR
[] = "init";
32 const char kGrab
[] = "grab";
33 const char kUngrab
[] = "ungrab";
34 const char kSync
[] = "sync";
35 const char kForceDPMS
[] = "dpms";
37 // String returned by TestNativeDisplayDelegate::GetActionsAndClear() if no
38 // actions were requested.
39 const char kNoActions
[] = "";
41 std::string
DisplaySnapshotToString(const DisplaySnapshot
& output
) {
42 return base::StringPrintf("id=%" PRId64
, output
.display_id());
45 // Returns a string describing a TestNativeDisplayDelegate::SetBackgroundColor()
47 std::string
GetBackgroundAction(uint32_t color_argb
) {
48 return base::StringPrintf("background(0x%x)", color_argb
);
51 // Returns a string describing a TestNativeDisplayDelegate::AddOutputMode()
53 std::string
GetAddOutputModeAction(const DisplaySnapshot
& output
,
54 const DisplayMode
* mode
) {
55 return base::StringPrintf("add_mode(output=%" PRId64
",mode=%s)",
57 mode
->ToString().c_str());
60 // Returns a string describing a TestNativeDisplayDelegate::Configure()
62 std::string
GetCrtcAction(const DisplaySnapshot
& output
,
63 const DisplayMode
* mode
,
64 const gfx::Point
& origin
) {
65 return base::StringPrintf("crtc(display=[%s],x=%d,y=%d,mode=[%s])",
66 DisplaySnapshotToString(output
).c_str(),
69 mode
? mode
->ToString().c_str() : "NULL");
72 // Returns a string describing a TestNativeDisplayDelegate::CreateFramebuffer()
74 std::string
GetFramebufferAction(const gfx::Size
& size
,
75 const DisplaySnapshot
* out1
,
76 const DisplaySnapshot
* out2
) {
77 return base::StringPrintf(
78 "framebuffer(width=%d,height=%d,display1=%s,display2=%s)",
81 out1
? DisplaySnapshotToString(*out1
).c_str() : "NULL",
82 out2
? DisplaySnapshotToString(*out2
).c_str() : "NULL");
85 // Returns a string describing a TestNativeDisplayDelegate::SetHDCPState() call.
86 std::string
GetSetHDCPStateAction(const DisplaySnapshot
& output
,
88 return base::StringPrintf(
89 "set_hdcp(id=%" PRId64
",state=%d)", output
.display_id(), state
);
92 // Joins a sequence of strings describing actions (e.g. kScreenDim) such
93 // that they can be compared against a string returned by
94 // ActionLogger::GetActionsAndClear(). The list of actions must be
95 // terminated by a NULL pointer.
96 std::string
JoinActions(const char* action
, ...) {
100 va_start(arg_list
, action
);
102 if (!actions
.empty())
105 action
= va_arg(arg_list
, const char*);
115 void AppendAction(const std::string
& action
) {
116 if (!actions_
.empty())
121 // Returns a comma-separated string describing the actions that were
122 // requested since the previous call to GetActionsAndClear() (i.e.
123 // results are non-repeatable).
124 std::string
GetActionsAndClear() {
125 std::string actions
= actions_
;
131 std::string actions_
;
133 DISALLOW_COPY_AND_ASSIGN(ActionLogger
);
136 class TestTouchscreenDelegate
137 : public DisplayConfigurator::TouchscreenDelegate
{
139 // Ownership of |log| remains with the caller.
140 explicit TestTouchscreenDelegate(ActionLogger
* log
)
142 configure_touchscreens_(false) {}
143 virtual ~TestTouchscreenDelegate() {}
145 void set_configure_touchscreens(bool state
) {
146 configure_touchscreens_
= state
;
149 // DisplayConfigurator::TouchscreenDelegate implementation:
150 virtual void AssociateTouchscreens(
151 DisplayConfigurator::DisplayStateList
* outputs
) OVERRIDE
{
152 if (configure_touchscreens_
) {
153 for (size_t i
= 0; i
< outputs
->size(); ++i
)
154 (*outputs
)[i
].touch_device_id
= i
+ 1;
159 ActionLogger
* log_
; // Not owned.
161 bool configure_touchscreens_
;
163 DISALLOW_COPY_AND_ASSIGN(TestTouchscreenDelegate
);
166 class TestNativeDisplayDelegate
: public NativeDisplayDelegate
{
168 // Ownership of |log| remains with the caller.
169 explicit TestNativeDisplayDelegate(ActionLogger
* log
)
170 : max_configurable_pixels_(0),
171 hdcp_state_(HDCP_STATE_UNDESIRED
),
173 virtual ~TestNativeDisplayDelegate() {}
175 const std::vector
<DisplaySnapshot
*>& outputs() const { return outputs_
; }
176 void set_outputs(const std::vector
<DisplaySnapshot
*>& outputs
) {
180 void set_max_configurable_pixels(int pixels
) {
181 max_configurable_pixels_
= pixels
;
184 void set_hdcp_state(HDCPState state
) { hdcp_state_
= state
; }
186 // DisplayConfigurator::Delegate overrides:
187 virtual void Initialize() OVERRIDE
{ log_
->AppendAction(kInitXRandR
); }
188 virtual void GrabServer() OVERRIDE
{ log_
->AppendAction(kGrab
); }
189 virtual void UngrabServer() OVERRIDE
{ log_
->AppendAction(kUngrab
); }
190 virtual void SyncWithServer() OVERRIDE
{ log_
->AppendAction(kSync
); }
191 virtual void SetBackgroundColor(uint32_t color_argb
) OVERRIDE
{
192 log_
->AppendAction(GetBackgroundAction(color_argb
));
194 virtual void ForceDPMSOn() OVERRIDE
{ log_
->AppendAction(kForceDPMS
); }
195 virtual std::vector
<DisplaySnapshot
*> GetDisplays() OVERRIDE
{
198 virtual void AddMode(const DisplaySnapshot
& output
,
199 const DisplayMode
* mode
) OVERRIDE
{
200 log_
->AppendAction(GetAddOutputModeAction(output
, mode
));
202 virtual bool Configure(const DisplaySnapshot
& output
,
203 const DisplayMode
* mode
,
204 const gfx::Point
& origin
) OVERRIDE
{
205 log_
->AppendAction(GetCrtcAction(output
, mode
, origin
));
207 if (max_configurable_pixels_
== 0)
213 return mode
->size().GetArea() <= max_configurable_pixels_
;
215 virtual void CreateFrameBuffer(const gfx::Size
& size
) OVERRIDE
{
217 GetFramebufferAction(size
,
218 outputs_
.size() >= 1 ? outputs_
[0] : NULL
,
219 outputs_
.size() >= 2 ? outputs_
[1] : NULL
));
221 virtual bool GetHDCPState(const DisplaySnapshot
& output
,
222 HDCPState
* state
) OVERRIDE
{
223 *state
= hdcp_state_
;
227 virtual bool SetHDCPState(const DisplaySnapshot
& output
,
228 HDCPState state
) OVERRIDE
{
229 log_
->AppendAction(GetSetHDCPStateAction(output
, state
));
233 virtual std::vector
<ui::ColorCalibrationProfile
>
234 GetAvailableColorCalibrationProfiles(const DisplaySnapshot
& output
) OVERRIDE
{
235 return std::vector
<ui::ColorCalibrationProfile
>();
238 virtual bool SetColorCalibrationProfile(
239 const DisplaySnapshot
& output
,
240 ui::ColorCalibrationProfile new_profile
) OVERRIDE
{
244 virtual void AddObserver(NativeDisplayObserver
* observer
) OVERRIDE
{}
246 virtual void RemoveObserver(NativeDisplayObserver
* observer
) OVERRIDE
{}
249 // Outputs to be returned by GetDisplays().
250 std::vector
<DisplaySnapshot
*> outputs_
;
252 // |max_configurable_pixels_| represents the maximum number of pixels that
253 // Configure will support. Tests can use this to force Configure
254 // to fail if attempting to set a resolution that is higher than what
255 // a device might support under a given circumstance.
256 // A value of 0 means that no limit is enforced and Configure will
257 // return success regardless of the resolution.
258 int max_configurable_pixels_
;
260 // Result value of GetHDCPState().
261 HDCPState hdcp_state_
;
263 ActionLogger
* log_
; // Not owned.
265 DISALLOW_COPY_AND_ASSIGN(TestNativeDisplayDelegate
);
268 class TestObserver
: public DisplayConfigurator::Observer
{
270 explicit TestObserver(DisplayConfigurator
* configurator
)
271 : configurator_(configurator
) {
273 configurator_
->AddObserver(this);
275 virtual ~TestObserver() { configurator_
->RemoveObserver(this); }
277 int num_changes() const { return num_changes_
; }
278 int num_failures() const { return num_failures_
; }
279 const DisplayConfigurator::DisplayStateList
& latest_outputs() const {
280 return latest_outputs_
;
282 MultipleDisplayState
latest_failed_state() const {
283 return latest_failed_state_
;
289 latest_outputs_
.clear();
290 latest_failed_state_
= MULTIPLE_DISPLAY_STATE_INVALID
;
293 // DisplayConfigurator::Observer overrides:
294 virtual void OnDisplayModeChanged(
295 const DisplayConfigurator::DisplayStateList
& outputs
) OVERRIDE
{
297 latest_outputs_
= outputs
;
300 virtual void OnDisplayModeChangeFailed(MultipleDisplayState failed_new_state
)
303 latest_failed_state_
= failed_new_state
;
307 DisplayConfigurator
* configurator_
; // Not owned.
309 // Number of times that OnDisplayMode*() has been called.
313 // Parameters most recently passed to OnDisplayMode*().
314 DisplayConfigurator::DisplayStateList latest_outputs_
;
315 MultipleDisplayState latest_failed_state_
;
317 DISALLOW_COPY_AND_ASSIGN(TestObserver
);
320 class TestStateController
: public DisplayConfigurator::StateController
{
322 TestStateController() : state_(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED
) {}
323 virtual ~TestStateController() {}
325 void set_state(MultipleDisplayState state
) { state_
= state
; }
327 // DisplayConfigurator::StateController overrides:
328 virtual MultipleDisplayState
GetStateForDisplayIds(
329 const std::vector
<int64_t>& outputs
) const OVERRIDE
{
332 virtual bool GetResolutionForDisplayId(int64_t display_id
,
333 gfx::Size
* size
) const OVERRIDE
{
338 MultipleDisplayState state_
;
340 DISALLOW_COPY_AND_ASSIGN(TestStateController
);
343 class TestMirroringController
344 : public DisplayConfigurator::SoftwareMirroringController
{
346 TestMirroringController() : software_mirroring_enabled_(false) {}
347 virtual ~TestMirroringController() {}
349 virtual void SetSoftwareMirroring(bool enabled
) OVERRIDE
{
350 software_mirroring_enabled_
= enabled
;
353 virtual bool SoftwareMirroringEnabled() const OVERRIDE
{
354 return software_mirroring_enabled_
;
358 bool software_mirroring_enabled_
;
360 DISALLOW_COPY_AND_ASSIGN(TestMirroringController
);
363 class DisplayConfiguratorTest
: public testing::Test
{
365 DisplayConfiguratorTest()
366 : small_mode_(gfx::Size(1366, 768), false, 60.0f
),
367 big_mode_(gfx::Size(2560, 1600), false, 60.0f
),
368 observer_(&configurator_
),
369 test_api_(&configurator_
) {}
370 virtual ~DisplayConfiguratorTest() {}
372 virtual void SetUp() OVERRIDE
{
373 log_
.reset(new ActionLogger());
375 native_display_delegate_
= new TestNativeDisplayDelegate(log_
.get());
376 touchscreen_delegate_
= new TestTouchscreenDelegate(log_
.get());
377 configurator_
.SetDelegatesForTesting(
378 scoped_ptr
<NativeDisplayDelegate
>(native_display_delegate_
),
379 scoped_ptr
<DisplayConfigurator::TouchscreenDelegate
>(
380 touchscreen_delegate_
));
382 configurator_
.set_state_controller(&state_controller_
);
383 configurator_
.set_mirroring_controller(&mirroring_controller_
);
385 std::vector
<const DisplayMode
*> modes
;
386 modes
.push_back(&small_mode_
);
388 TestDisplaySnapshot
* o
= &outputs_
[0];
389 o
->set_current_mode(&small_mode_
);
390 o
->set_native_mode(&small_mode_
);
392 o
->set_type(DISPLAY_CONNECTION_TYPE_INTERNAL
);
393 o
->set_is_aspect_preserving_scaling(true);
394 o
->set_display_id(123);
395 o
->set_has_proper_display_id(true);
398 o
->set_current_mode(&big_mode_
);
399 o
->set_native_mode(&big_mode_
);
400 modes
.push_back(&big_mode_
);
402 o
->set_type(DISPLAY_CONNECTION_TYPE_HDMI
);
403 o
->set_is_aspect_preserving_scaling(true);
404 o
->set_display_id(456);
405 o
->set_has_proper_display_id(true);
407 UpdateOutputs(2, false);
410 // Predefined modes that can be used by outputs.
411 const DisplayMode small_mode_
;
412 const DisplayMode big_mode_
;
415 // Configures |native_display_delegate_| to return the first |num_outputs|
417 // |outputs_|. If |send_events| is true, also sends screen-change and
418 // output-change events to |configurator_| and triggers the configure
419 // timeout if one was scheduled.
420 void UpdateOutputs(size_t num_outputs
, bool send_events
) {
421 ASSERT_LE(num_outputs
, arraysize(outputs_
));
422 std::vector
<DisplaySnapshot
*> outputs
;
423 for (size_t i
= 0; i
< num_outputs
; ++i
)
424 outputs
.push_back(&outputs_
[i
]);
425 native_display_delegate_
->set_outputs(outputs
);
428 configurator_
.OnConfigurationChanged();
429 EXPECT_TRUE(test_api_
.TriggerConfigureTimeout());
433 // Initializes |configurator_| with a single internal display.
434 void InitWithSingleOutput() {
435 UpdateOutputs(1, false);
436 EXPECT_EQ(kNoActions
, log_
->GetActionsAndClear());
437 configurator_
.Init(false);
438 EXPECT_EQ(kNoActions
, log_
->GetActionsAndClear());
439 configurator_
.ForceInitialConfigure(0);
444 GetFramebufferAction(small_mode_
.size(), &outputs_
[0], NULL
)
446 GetCrtcAction(outputs_
[0], &small_mode_
, gfx::Point(0, 0)).c_str(),
450 log_
->GetActionsAndClear());
453 base::MessageLoop message_loop_
;
454 TestStateController state_controller_
;
455 TestMirroringController mirroring_controller_
;
456 DisplayConfigurator configurator_
;
457 TestObserver observer_
;
458 scoped_ptr
<ActionLogger
> log_
;
459 TestNativeDisplayDelegate
* native_display_delegate_
; // not owned
460 TestTouchscreenDelegate
* touchscreen_delegate_
; // not owned
461 DisplayConfigurator::TestApi test_api_
;
463 TestDisplaySnapshot outputs_
[2];
466 DISALLOW_COPY_AND_ASSIGN(DisplayConfiguratorTest
);
471 TEST_F(DisplayConfiguratorTest
, FindDisplayModeMatchingSize
) {
472 ScopedVector
<const DisplayMode
> modes
;
474 // Fields are width, height, interlaced, refresh rate.
475 modes
.push_back(new DisplayMode(gfx::Size(1920, 1200), false, 60.0));
477 modes
.push_back(new DisplayMode(gfx::Size(1920, 1080), false, 30.0));
478 modes
.push_back(new DisplayMode(gfx::Size(1920, 1080), false, 50.0));
479 modes
.push_back(new DisplayMode(gfx::Size(1920, 1080), false, 40.0));
480 modes
.push_back(new DisplayMode(gfx::Size(1920, 1080), false, 0.0));
481 // Interlaced vs non-interlaced.
482 modes
.push_back(new DisplayMode(gfx::Size(1280, 720), true, 60.0));
483 modes
.push_back(new DisplayMode(gfx::Size(1280, 720), false, 40.0));
485 modes
.push_back(new DisplayMode(gfx::Size(1024, 768), true, 0.0));
486 modes
.push_back(new DisplayMode(gfx::Size(1024, 768), true, 40.0));
487 modes
.push_back(new DisplayMode(gfx::Size(1024, 768), true, 60.0));
489 modes
.push_back(new DisplayMode(gfx::Size(1024, 600), true, 60.0));
490 modes
.push_back(new DisplayMode(gfx::Size(1024, 600), false, 40.0));
491 modes
.push_back(new DisplayMode(gfx::Size(1024, 600), false, 50.0));
492 // Just one interlaced mode.
493 modes
.push_back(new DisplayMode(gfx::Size(640, 480), true, 60.0));
494 // Refresh rate not available.
495 modes
.push_back(new DisplayMode(gfx::Size(320, 200), false, 0.0));
497 TestDisplaySnapshot output
;
498 output
.set_modes(modes
.get());
501 DisplayConfigurator::FindDisplayModeMatchingSize(
502 output
, gfx::Size(1920, 1200)));
504 // Should pick highest refresh rate.
506 DisplayConfigurator::FindDisplayModeMatchingSize(
507 output
, gfx::Size(1920, 1080)));
509 // Should pick non-interlaced mode.
511 DisplayConfigurator::FindDisplayModeMatchingSize(
512 output
, gfx::Size(1280, 720)));
514 // Interlaced only. Should pick one with the highest refresh rate in
517 DisplayConfigurator::FindDisplayModeMatchingSize(
518 output
, gfx::Size(1024, 768)));
520 // Mixed: Should pick one with the highest refresh rate in
523 DisplayConfigurator::FindDisplayModeMatchingSize(
524 output
, gfx::Size(1024, 600)));
526 // Just one interlaced mode.
528 DisplayConfigurator::FindDisplayModeMatchingSize(
529 output
, gfx::Size(640, 480)));
531 // Refresh rate not available.
533 DisplayConfigurator::FindDisplayModeMatchingSize(
534 output
, gfx::Size(320, 200)));
538 DisplayConfigurator::FindDisplayModeMatchingSize(
539 output
, gfx::Size(1440, 900)));
542 TEST_F(DisplayConfiguratorTest
, ConnectSecondOutput
) {
543 InitWithSingleOutput();
545 // Connect a second output and check that the configurator enters
548 state_controller_
.set_state(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED
);
549 UpdateOutputs(2, true);
550 const int kDualHeight
= small_mode_
.size().height() +
551 DisplayConfigurator::kVerticalGap
+
552 big_mode_
.size().height();
556 GetFramebufferAction(gfx::Size(big_mode_
.size().width(), kDualHeight
),
558 &outputs_
[1]).c_str(),
559 GetCrtcAction(outputs_
[0], &small_mode_
, gfx::Point(0, 0)).c_str(),
560 GetCrtcAction(outputs_
[1],
563 small_mode_
.size().height() +
564 DisplayConfigurator::kVerticalGap
))
568 log_
->GetActionsAndClear());
569 EXPECT_FALSE(mirroring_controller_
.SoftwareMirroringEnabled());
570 EXPECT_EQ(1, observer_
.num_changes());
573 EXPECT_TRUE(configurator_
.SetDisplayMode(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR
));
577 GetFramebufferAction(small_mode_
.size(), &outputs_
[0], &outputs_
[1])
579 GetCrtcAction(outputs_
[0], &small_mode_
, gfx::Point(0, 0)).c_str(),
580 GetCrtcAction(outputs_
[1], &small_mode_
, gfx::Point(0, 0)).c_str(),
583 log_
->GetActionsAndClear());
584 EXPECT_FALSE(mirroring_controller_
.SoftwareMirroringEnabled());
585 EXPECT_EQ(1, observer_
.num_changes());
587 // Disconnect the second output.
589 UpdateOutputs(1, true);
593 GetFramebufferAction(small_mode_
.size(), &outputs_
[0], NULL
).c_str(),
594 GetCrtcAction(outputs_
[0], &small_mode_
, gfx::Point(0, 0)).c_str(),
597 log_
->GetActionsAndClear());
598 EXPECT_FALSE(mirroring_controller_
.SoftwareMirroringEnabled());
599 EXPECT_EQ(1, observer_
.num_changes());
601 // Get rid of shared modes to force software mirroring.
602 outputs_
[1].set_modes(std::vector
<const DisplayMode
*>(1, &big_mode_
));
603 state_controller_
.set_state(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED
);
604 UpdateOutputs(2, true);
608 GetFramebufferAction(gfx::Size(big_mode_
.size().width(), kDualHeight
),
610 &outputs_
[1]).c_str(),
611 GetCrtcAction(outputs_
[0], &small_mode_
, gfx::Point(0, 0)).c_str(),
612 GetCrtcAction(outputs_
[1],
615 small_mode_
.size().height() +
616 DisplayConfigurator::kVerticalGap
))
620 log_
->GetActionsAndClear());
621 EXPECT_FALSE(mirroring_controller_
.SoftwareMirroringEnabled());
624 EXPECT_TRUE(configurator_
.SetDisplayMode(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR
));
625 EXPECT_EQ(JoinActions(kGrab
, kUngrab
, NULL
), log_
->GetActionsAndClear());
626 EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED
,
627 configurator_
.display_state());
628 EXPECT_TRUE(mirroring_controller_
.SoftwareMirroringEnabled());
629 EXPECT_EQ(1, observer_
.num_changes());
631 // Setting MULTIPLE_DISPLAY_STATE_DUAL_MIRROR should try to reconfigure.
634 configurator_
.SetDisplayMode(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED
));
635 EXPECT_EQ(JoinActions(NULL
), log_
->GetActionsAndClear());
636 EXPECT_FALSE(mirroring_controller_
.SoftwareMirroringEnabled());
637 EXPECT_EQ(1, observer_
.num_changes());
639 // Set back to software mirror mode.
641 EXPECT_TRUE(configurator_
.SetDisplayMode(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR
));
642 EXPECT_EQ(JoinActions(kGrab
, kUngrab
, NULL
), log_
->GetActionsAndClear());
643 EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED
,
644 configurator_
.display_state());
645 EXPECT_TRUE(mirroring_controller_
.SoftwareMirroringEnabled());
646 EXPECT_EQ(1, observer_
.num_changes());
648 // Disconnect the second output.
650 UpdateOutputs(1, true);
654 GetFramebufferAction(small_mode_
.size(), &outputs_
[0], NULL
).c_str(),
655 GetCrtcAction(outputs_
[0], &small_mode_
, gfx::Point(0, 0)).c_str(),
658 log_
->GetActionsAndClear());
659 EXPECT_FALSE(mirroring_controller_
.SoftwareMirroringEnabled());
660 EXPECT_EQ(1, observer_
.num_changes());
663 TEST_F(DisplayConfiguratorTest
, SetDisplayPower
) {
664 InitWithSingleOutput();
666 state_controller_
.set_state(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR
);
668 UpdateOutputs(2, true);
672 GetFramebufferAction(small_mode_
.size(), &outputs_
[0], &outputs_
[1])
674 GetCrtcAction(outputs_
[0], &small_mode_
, gfx::Point(0, 0)).c_str(),
675 GetCrtcAction(outputs_
[1], &small_mode_
, gfx::Point(0, 0)).c_str(),
678 log_
->GetActionsAndClear());
679 EXPECT_FALSE(mirroring_controller_
.SoftwareMirroringEnabled());
680 EXPECT_EQ(1, observer_
.num_changes());
682 // Turning off the internal display should switch the external display to
685 configurator_
.SetDisplayPower(
686 chromeos::DISPLAY_POWER_INTERNAL_OFF_EXTERNAL_ON
,
687 DisplayConfigurator::kSetDisplayPowerNoFlags
);
691 GetFramebufferAction(big_mode_
.size(), &outputs_
[0], &outputs_
[1])
693 GetCrtcAction(outputs_
[0], NULL
, gfx::Point(0, 0)).c_str(),
694 GetCrtcAction(outputs_
[1], &big_mode_
, gfx::Point(0, 0)).c_str(),
698 log_
->GetActionsAndClear());
699 EXPECT_EQ(MULTIPLE_DISPLAY_STATE_SINGLE
, configurator_
.display_state());
700 EXPECT_EQ(1, observer_
.num_changes());
702 // When all displays are turned off, the framebuffer should switch back
703 // to the mirrored size.
705 configurator_
.SetDisplayPower(chromeos::DISPLAY_POWER_ALL_OFF
,
706 DisplayConfigurator::kSetDisplayPowerNoFlags
);
709 GetFramebufferAction(
710 small_mode_
.size(), &outputs_
[0], &outputs_
[1]).c_str(),
711 GetCrtcAction(outputs_
[0], NULL
, gfx::Point(0, 0)).c_str(),
712 GetCrtcAction(outputs_
[1], NULL
, gfx::Point(0, 0)).c_str(),
715 log_
->GetActionsAndClear());
716 EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR
, configurator_
.display_state());
717 EXPECT_FALSE(mirroring_controller_
.SoftwareMirroringEnabled());
718 EXPECT_EQ(1, observer_
.num_changes());
720 // Turn all displays on and check that mirroring is still used.
722 configurator_
.SetDisplayPower(chromeos::DISPLAY_POWER_ALL_ON
,
723 DisplayConfigurator::kSetDisplayPowerNoFlags
);
727 GetFramebufferAction(small_mode_
.size(), &outputs_
[0], &outputs_
[1])
729 GetCrtcAction(outputs_
[0], &small_mode_
, gfx::Point(0, 0)).c_str(),
730 GetCrtcAction(outputs_
[1], &small_mode_
, gfx::Point(0, 0)).c_str(),
734 log_
->GetActionsAndClear());
735 EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR
, configurator_
.display_state());
736 EXPECT_FALSE(mirroring_controller_
.SoftwareMirroringEnabled());
737 EXPECT_EQ(1, observer_
.num_changes());
739 // Get rid of shared modes to force software mirroring.
740 outputs_
[1].set_modes(std::vector
<const DisplayMode
*>(1, &big_mode_
));
741 state_controller_
.set_state(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR
);
743 UpdateOutputs(2, true);
744 const int kDualHeight
= small_mode_
.size().height() +
745 DisplayConfigurator::kVerticalGap
+
746 big_mode_
.size().height();
750 GetFramebufferAction(gfx::Size(big_mode_
.size().width(), kDualHeight
),
752 &outputs_
[1]).c_str(),
753 GetCrtcAction(outputs_
[0], &small_mode_
, gfx::Point(0, 0)).c_str(),
754 GetCrtcAction(outputs_
[1],
757 small_mode_
.size().height() +
758 DisplayConfigurator::kVerticalGap
))
762 log_
->GetActionsAndClear());
763 EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED
,
764 configurator_
.display_state());
765 EXPECT_TRUE(mirroring_controller_
.SoftwareMirroringEnabled());
766 EXPECT_EQ(1, observer_
.num_changes());
768 // Turning off the internal display should switch the external display to
771 configurator_
.SetDisplayPower(
772 chromeos::DISPLAY_POWER_INTERNAL_OFF_EXTERNAL_ON
,
773 DisplayConfigurator::kSetDisplayPowerNoFlags
);
777 GetFramebufferAction(big_mode_
.size(), &outputs_
[0], &outputs_
[1])
779 GetCrtcAction(outputs_
[0], NULL
, gfx::Point(0, 0)).c_str(),
780 GetCrtcAction(outputs_
[1], &big_mode_
, gfx::Point(0, 0)).c_str(),
784 log_
->GetActionsAndClear());
785 EXPECT_EQ(MULTIPLE_DISPLAY_STATE_SINGLE
, configurator_
.display_state());
786 EXPECT_FALSE(mirroring_controller_
.SoftwareMirroringEnabled());
787 EXPECT_EQ(1, observer_
.num_changes());
789 // When all displays are turned off, the framebuffer should switch back
790 // to the extended + software mirroring.
792 configurator_
.SetDisplayPower(chromeos::DISPLAY_POWER_ALL_OFF
,
793 DisplayConfigurator::kSetDisplayPowerNoFlags
);
797 GetFramebufferAction(gfx::Size(big_mode_
.size().width(), kDualHeight
),
799 &outputs_
[1]).c_str(),
800 GetCrtcAction(outputs_
[0], NULL
, gfx::Point(0, 0)).c_str(),
801 GetCrtcAction(outputs_
[1],
804 small_mode_
.size().height() +
805 DisplayConfigurator::kVerticalGap
))
809 log_
->GetActionsAndClear());
810 EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED
,
811 configurator_
.display_state());
812 EXPECT_TRUE(mirroring_controller_
.SoftwareMirroringEnabled());
813 EXPECT_EQ(1, observer_
.num_changes());
815 // Turn all displays on and check that mirroring is still used.
817 configurator_
.SetDisplayPower(chromeos::DISPLAY_POWER_ALL_ON
,
818 DisplayConfigurator::kSetDisplayPowerNoFlags
);
822 GetFramebufferAction(gfx::Size(big_mode_
.size().width(), kDualHeight
),
824 &outputs_
[1]).c_str(),
825 GetCrtcAction(outputs_
[0], &small_mode_
, gfx::Point(0, 0)).c_str(),
826 GetCrtcAction(outputs_
[1],
829 small_mode_
.size().height() +
830 DisplayConfigurator::kVerticalGap
))
835 log_
->GetActionsAndClear());
836 EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED
,
837 configurator_
.display_state());
838 EXPECT_TRUE(mirroring_controller_
.SoftwareMirroringEnabled());
839 EXPECT_EQ(1, observer_
.num_changes());
842 TEST_F(DisplayConfiguratorTest
, SuspendAndResume
) {
843 InitWithSingleOutput();
845 // No preparation is needed before suspending when the display is already
846 // on. The configurator should still reprobe on resume in case a display
847 // was connected while suspended.
848 configurator_
.SuspendDisplays();
849 EXPECT_EQ(kNoActions
, log_
->GetActionsAndClear());
850 configurator_
.ResumeDisplays();
851 EXPECT_TRUE(test_api_
.TriggerConfigureTimeout());
855 GetFramebufferAction(small_mode_
.size(), &outputs_
[0], NULL
).c_str(),
856 GetCrtcAction(outputs_
[0], &small_mode_
, gfx::Point(0, 0)).c_str(),
860 log_
->GetActionsAndClear());
862 // Now turn the display off before suspending and check that the
863 // configurator turns it back on and syncs with the server.
864 configurator_
.SetDisplayPower(chromeos::DISPLAY_POWER_ALL_OFF
,
865 DisplayConfigurator::kSetDisplayPowerNoFlags
);
869 GetFramebufferAction(small_mode_
.size(), &outputs_
[0], NULL
).c_str(),
870 GetCrtcAction(outputs_
[0], NULL
, gfx::Point(0, 0)).c_str(),
873 log_
->GetActionsAndClear());
875 configurator_
.SuspendDisplays();
879 GetFramebufferAction(small_mode_
.size(), &outputs_
[0], NULL
).c_str(),
880 GetCrtcAction(outputs_
[0], &small_mode_
, gfx::Point(0, 0)).c_str(),
885 log_
->GetActionsAndClear());
887 configurator_
.ResumeDisplays();
888 EXPECT_TRUE(test_api_
.TriggerConfigureTimeout());
892 GetFramebufferAction(small_mode_
.size(), &outputs_
[0], NULL
).c_str(),
893 GetCrtcAction(outputs_
[0], &small_mode_
, gfx::Point(0, 0)).c_str(),
897 log_
->GetActionsAndClear());
899 // If a second, external display is connected, the displays shouldn't be
900 // powered back on before suspending.
901 state_controller_
.set_state(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR
);
902 UpdateOutputs(2, true);
906 GetFramebufferAction(small_mode_
.size(), &outputs_
[0], &outputs_
[1])
908 GetCrtcAction(outputs_
[0], &small_mode_
, gfx::Point(0, 0)).c_str(),
909 GetCrtcAction(outputs_
[1], &small_mode_
, gfx::Point(0, 0)).c_str(),
912 log_
->GetActionsAndClear());
914 configurator_
.SetDisplayPower(chromeos::DISPLAY_POWER_ALL_OFF
,
915 DisplayConfigurator::kSetDisplayPowerNoFlags
);
918 GetFramebufferAction(
919 small_mode_
.size(), &outputs_
[0], &outputs_
[1]).c_str(),
920 GetCrtcAction(outputs_
[0], NULL
, gfx::Point(0, 0)).c_str(),
921 GetCrtcAction(outputs_
[1], NULL
, gfx::Point(0, 0)).c_str(),
924 log_
->GetActionsAndClear());
926 configurator_
.SuspendDisplays();
927 EXPECT_EQ(JoinActions(kGrab
, kUngrab
, kSync
, NULL
),
928 log_
->GetActionsAndClear());
930 // If a display is disconnected while suspended, the configurator should
931 // pick up the change.
932 UpdateOutputs(1, false);
933 configurator_
.ResumeDisplays();
934 EXPECT_TRUE(test_api_
.TriggerConfigureTimeout());
938 GetFramebufferAction(small_mode_
.size(), &outputs_
[0], NULL
).c_str(),
939 GetCrtcAction(outputs_
[0], NULL
, gfx::Point(0, 0)).c_str(),
942 log_
->GetActionsAndClear());
945 TEST_F(DisplayConfiguratorTest
, Headless
) {
946 UpdateOutputs(0, false);
947 EXPECT_EQ(kNoActions
, log_
->GetActionsAndClear());
948 configurator_
.Init(false);
949 EXPECT_EQ(kNoActions
, log_
->GetActionsAndClear());
950 configurator_
.ForceInitialConfigure(0);
951 EXPECT_EQ(JoinActions(kGrab
, kInitXRandR
, kForceDPMS
, kUngrab
, NULL
),
952 log_
->GetActionsAndClear());
954 // Not much should happen when the display power state is changed while
955 // no displays are connected.
956 configurator_
.SetDisplayPower(chromeos::DISPLAY_POWER_ALL_OFF
,
957 DisplayConfigurator::kSetDisplayPowerNoFlags
);
958 EXPECT_EQ(JoinActions(kGrab
, kUngrab
, NULL
), log_
->GetActionsAndClear());
959 configurator_
.SetDisplayPower(chromeos::DISPLAY_POWER_ALL_ON
,
960 DisplayConfigurator::kSetDisplayPowerNoFlags
);
961 EXPECT_EQ(JoinActions(kGrab
, kForceDPMS
, kUngrab
, NULL
),
962 log_
->GetActionsAndClear());
964 // Connect an external display and check that it's configured correctly.
965 outputs_
[0].set_current_mode(outputs_
[1].current_mode());
966 outputs_
[0].set_native_mode(outputs_
[1].native_mode());
967 outputs_
[0].set_modes(outputs_
[1].modes());
968 outputs_
[0].set_type(outputs_
[1].type());
970 UpdateOutputs(1, true);
974 GetFramebufferAction(big_mode_
.size(), &outputs_
[0], NULL
).c_str(),
975 GetCrtcAction(outputs_
[0], &big_mode_
, gfx::Point(0, 0)).c_str(),
978 log_
->GetActionsAndClear());
981 TEST_F(DisplayConfiguratorTest
, StartWithTwoOutputs
) {
982 UpdateOutputs(2, false);
983 EXPECT_EQ(kNoActions
, log_
->GetActionsAndClear());
984 configurator_
.Init(false);
985 EXPECT_EQ(kNoActions
, log_
->GetActionsAndClear());
987 state_controller_
.set_state(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR
);
988 configurator_
.ForceInitialConfigure(0);
993 GetFramebufferAction(small_mode_
.size(), &outputs_
[0], &outputs_
[1])
995 GetCrtcAction(outputs_
[0], &small_mode_
, gfx::Point(0, 0)).c_str(),
996 GetCrtcAction(outputs_
[1], &small_mode_
, gfx::Point(0, 0)).c_str(),
1000 log_
->GetActionsAndClear());
1003 TEST_F(DisplayConfiguratorTest
, InvalidMultipleDisplayStates
) {
1004 UpdateOutputs(0, false);
1005 EXPECT_EQ(kNoActions
, log_
->GetActionsAndClear());
1006 configurator_
.Init(false);
1007 configurator_
.ForceInitialConfigure(0);
1009 EXPECT_TRUE(configurator_
.SetDisplayMode(MULTIPLE_DISPLAY_STATE_HEADLESS
));
1010 EXPECT_FALSE(configurator_
.SetDisplayMode(MULTIPLE_DISPLAY_STATE_SINGLE
));
1012 configurator_
.SetDisplayMode(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR
));
1014 configurator_
.SetDisplayMode(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED
));
1015 EXPECT_EQ(1, observer_
.num_changes());
1016 EXPECT_EQ(3, observer_
.num_failures());
1018 UpdateOutputs(1, true);
1020 EXPECT_FALSE(configurator_
.SetDisplayMode(MULTIPLE_DISPLAY_STATE_HEADLESS
));
1021 EXPECT_TRUE(configurator_
.SetDisplayMode(MULTIPLE_DISPLAY_STATE_SINGLE
));
1023 configurator_
.SetDisplayMode(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR
));
1025 configurator_
.SetDisplayMode(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED
));
1026 EXPECT_EQ(1, observer_
.num_changes());
1027 EXPECT_EQ(3, observer_
.num_failures());
1029 state_controller_
.set_state(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED
);
1030 UpdateOutputs(2, true);
1032 EXPECT_FALSE(configurator_
.SetDisplayMode(MULTIPLE_DISPLAY_STATE_HEADLESS
));
1033 EXPECT_FALSE(configurator_
.SetDisplayMode(MULTIPLE_DISPLAY_STATE_SINGLE
));
1034 EXPECT_TRUE(configurator_
.SetDisplayMode(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR
));
1036 configurator_
.SetDisplayMode(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED
));
1037 EXPECT_EQ(2, observer_
.num_changes());
1038 EXPECT_EQ(2, observer_
.num_failures());
1041 TEST_F(DisplayConfiguratorTest
, GetMultipleDisplayStateForDisplaysWithoutId
) {
1042 outputs_
[0].set_has_proper_display_id(false);
1043 UpdateOutputs(2, false);
1044 configurator_
.Init(false);
1045 state_controller_
.set_state(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR
);
1046 configurator_
.ForceInitialConfigure(0);
1047 EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED
,
1048 configurator_
.display_state());
1051 TEST_F(DisplayConfiguratorTest
, GetMultipleDisplayStateForDisplaysWithId
) {
1052 outputs_
[0].set_has_proper_display_id(true);
1053 UpdateOutputs(2, false);
1054 configurator_
.Init(false);
1055 state_controller_
.set_state(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR
);
1056 configurator_
.ForceInitialConfigure(0);
1057 EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR
, configurator_
.display_state());
1060 TEST_F(DisplayConfiguratorTest
, UpdateCachedOutputsEvenAfterFailure
) {
1061 InitWithSingleOutput();
1062 const DisplayConfigurator::DisplayStateList
* cached
=
1063 &configurator_
.cached_displays();
1064 ASSERT_EQ(static_cast<size_t>(1), cached
->size());
1065 EXPECT_EQ(outputs_
[0].current_mode(), (*cached
)[0].display
->current_mode());
1067 // After connecting a second output, check that it shows up in
1068 // |cached_displays_| even if an invalid state is requested.
1069 state_controller_
.set_state(MULTIPLE_DISPLAY_STATE_SINGLE
);
1070 UpdateOutputs(2, true);
1071 cached
= &configurator_
.cached_displays();
1072 ASSERT_EQ(static_cast<size_t>(2), cached
->size());
1073 EXPECT_EQ(outputs_
[0].current_mode(), (*cached
)[0].display
->current_mode());
1074 EXPECT_EQ(outputs_
[1].current_mode(), (*cached
)[1].display
->current_mode());
1077 TEST_F(DisplayConfiguratorTest
, PanelFitting
) {
1078 // Configure the internal display to support only the big mode and the
1079 // external display to support only the small mode.
1080 outputs_
[0].set_current_mode(&big_mode_
);
1081 outputs_
[0].set_native_mode(&big_mode_
);
1082 outputs_
[0].set_modes(std::vector
<const DisplayMode
*>(1, &big_mode_
));
1084 outputs_
[1].set_current_mode(&small_mode_
);
1085 outputs_
[1].set_native_mode(&small_mode_
);
1086 outputs_
[1].set_modes(std::vector
<const DisplayMode
*>(1, &small_mode_
));
1088 // The small mode should be added to the internal output when requesting
1090 UpdateOutputs(2, false);
1091 state_controller_
.set_state(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR
);
1092 configurator_
.Init(true /* is_panel_fitting_enabled */);
1093 configurator_
.ForceInitialConfigure(0);
1094 EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR
, configurator_
.display_state());
1099 GetAddOutputModeAction(outputs_
[0], &small_mode_
).c_str(),
1100 GetFramebufferAction(small_mode_
.size(), &outputs_
[0], &outputs_
[1])
1102 GetCrtcAction(outputs_
[0], &small_mode_
, gfx::Point(0, 0)).c_str(),
1103 GetCrtcAction(outputs_
[1], &small_mode_
, gfx::Point(0, 0)).c_str(),
1107 log_
->GetActionsAndClear());
1109 // Both outputs should be using the small mode.
1110 ASSERT_EQ(1, observer_
.num_changes());
1111 ASSERT_EQ(static_cast<size_t>(2), observer_
.latest_outputs().size());
1112 EXPECT_EQ(&small_mode_
, observer_
.latest_outputs()[0].mirror_mode
);
1113 EXPECT_EQ(&small_mode_
,
1114 observer_
.latest_outputs()[0].display
->current_mode());
1115 EXPECT_EQ(&small_mode_
, observer_
.latest_outputs()[1].mirror_mode
);
1116 EXPECT_EQ(&small_mode_
,
1117 observer_
.latest_outputs()[1].display
->current_mode());
1119 // Also check that the newly-added small mode is present in the internal
1120 // snapshot that was passed to the observer (http://crbug.com/289159).
1121 const DisplayConfigurator::DisplayState
& state
=
1122 observer_
.latest_outputs()[0];
1123 ASSERT_NE(state
.display
->modes().end(),
1124 std::find(state
.display
->modes().begin(),
1125 state
.display
->modes().end(),
1129 TEST_F(DisplayConfiguratorTest
, ContentProtection
) {
1130 configurator_
.Init(false);
1131 configurator_
.ForceInitialConfigure(0);
1132 EXPECT_NE(kNoActions
, log_
->GetActionsAndClear());
1134 DisplayConfigurator::ContentProtectionClientId id
=
1135 configurator_
.RegisterContentProtectionClient();
1139 UpdateOutputs(1, true);
1140 EXPECT_NE(kNoActions
, log_
->GetActionsAndClear());
1141 uint32_t link_mask
= 0;
1142 uint32_t protection_mask
= 0;
1143 EXPECT_TRUE(configurator_
.QueryContentProtectionStatus(
1144 id
, outputs_
[0].display_id(), &link_mask
, &protection_mask
));
1145 EXPECT_EQ(static_cast<uint32_t>(DISPLAY_CONNECTION_TYPE_INTERNAL
), link_mask
);
1146 EXPECT_EQ(static_cast<uint32_t>(CONTENT_PROTECTION_METHOD_NONE
),
1148 EXPECT_EQ(kNoActions
, log_
->GetActionsAndClear());
1151 UpdateOutputs(2, true);
1152 EXPECT_NE(kNoActions
, log_
->GetActionsAndClear());
1153 EXPECT_TRUE(configurator_
.QueryContentProtectionStatus(
1154 id
, outputs_
[1].display_id(), &link_mask
, &protection_mask
));
1155 EXPECT_EQ(static_cast<uint32_t>(DISPLAY_CONNECTION_TYPE_HDMI
), link_mask
);
1156 EXPECT_EQ(static_cast<uint32_t>(CONTENT_PROTECTION_METHOD_NONE
),
1158 EXPECT_EQ(kNoActions
, log_
->GetActionsAndClear());
1160 EXPECT_TRUE(configurator_
.EnableContentProtection(
1161 id
, outputs_
[1].display_id(), CONTENT_PROTECTION_METHOD_HDCP
));
1162 EXPECT_EQ(GetSetHDCPStateAction(outputs_
[1], HDCP_STATE_DESIRED
),
1163 log_
->GetActionsAndClear());
1165 // Enable protection.
1166 native_display_delegate_
->set_hdcp_state(HDCP_STATE_ENABLED
);
1167 EXPECT_TRUE(configurator_
.QueryContentProtectionStatus(
1168 id
, outputs_
[1].display_id(), &link_mask
, &protection_mask
));
1169 EXPECT_EQ(static_cast<uint32_t>(DISPLAY_CONNECTION_TYPE_HDMI
), link_mask
);
1170 EXPECT_EQ(static_cast<uint32_t>(CONTENT_PROTECTION_METHOD_HDCP
),
1172 EXPECT_EQ(kNoActions
, log_
->GetActionsAndClear());
1174 // Protections should be disabled after unregister.
1175 configurator_
.UnregisterContentProtectionClient(id
);
1176 EXPECT_EQ(GetSetHDCPStateAction(outputs_
[1], HDCP_STATE_UNDESIRED
),
1177 log_
->GetActionsAndClear());
1180 TEST_F(DisplayConfiguratorTest
, ContentProtectionTwoClients
) {
1181 DisplayConfigurator::ContentProtectionClientId client1
=
1182 configurator_
.RegisterContentProtectionClient();
1183 DisplayConfigurator::ContentProtectionClientId client2
=
1184 configurator_
.RegisterContentProtectionClient();
1185 EXPECT_NE(client1
, client2
);
1187 configurator_
.Init(false);
1188 configurator_
.ForceInitialConfigure(0);
1189 UpdateOutputs(2, true);
1190 EXPECT_NE(kNoActions
, log_
->GetActionsAndClear());
1192 // Clients never know state enableness for methods that they didn't request.
1193 EXPECT_TRUE(configurator_
.EnableContentProtection(
1194 client1
, outputs_
[1].display_id(), CONTENT_PROTECTION_METHOD_HDCP
));
1195 EXPECT_EQ(GetSetHDCPStateAction(outputs_
[1], HDCP_STATE_DESIRED
).c_str(),
1196 log_
->GetActionsAndClear());
1197 native_display_delegate_
->set_hdcp_state(HDCP_STATE_ENABLED
);
1199 uint32_t link_mask
= 0;
1200 uint32_t protection_mask
= 0;
1201 EXPECT_TRUE(configurator_
.QueryContentProtectionStatus(
1202 client1
, outputs_
[1].display_id(), &link_mask
, &protection_mask
));
1203 EXPECT_EQ(static_cast<uint32_t>(DISPLAY_CONNECTION_TYPE_HDMI
), link_mask
);
1204 EXPECT_EQ(CONTENT_PROTECTION_METHOD_HDCP
, protection_mask
);
1206 EXPECT_TRUE(configurator_
.QueryContentProtectionStatus(
1207 client2
, outputs_
[1].display_id(), &link_mask
, &protection_mask
));
1208 EXPECT_EQ(static_cast<uint32_t>(DISPLAY_CONNECTION_TYPE_HDMI
), link_mask
);
1209 EXPECT_EQ(CONTENT_PROTECTION_METHOD_NONE
, protection_mask
);
1211 // Protections will be disabled only if no more clients request them.
1212 EXPECT_TRUE(configurator_
.EnableContentProtection(
1213 client2
, outputs_
[1].display_id(), CONTENT_PROTECTION_METHOD_NONE
));
1214 EXPECT_EQ(GetSetHDCPStateAction(outputs_
[1], HDCP_STATE_DESIRED
).c_str(),
1215 log_
->GetActionsAndClear());
1216 EXPECT_TRUE(configurator_
.EnableContentProtection(
1217 client1
, outputs_
[1].display_id(), CONTENT_PROTECTION_METHOD_NONE
));
1218 EXPECT_EQ(GetSetHDCPStateAction(outputs_
[1], HDCP_STATE_UNDESIRED
).c_str(),
1219 log_
->GetActionsAndClear());
1222 TEST_F(DisplayConfiguratorTest
, HandleConfigureCrtcFailure
) {
1223 InitWithSingleOutput();
1225 ScopedVector
<const DisplayMode
> modes
;
1226 // The first mode is the mode we are requesting DisplayConfigurator to choose.
1227 // The test will be setup so that this mode will fail and it will have to
1228 // choose the next best option.
1229 modes
.push_back(new DisplayMode(gfx::Size(2560, 1600), false, 60.0));
1230 modes
.push_back(new DisplayMode(gfx::Size(1024, 768), false, 60.0));
1231 modes
.push_back(new DisplayMode(gfx::Size(1280, 720), false, 60.0));
1232 modes
.push_back(new DisplayMode(gfx::Size(1920, 1080), false, 60.0));
1233 modes
.push_back(new DisplayMode(gfx::Size(1920, 1080), false, 40.0));
1235 for (unsigned int i
= 0; i
< arraysize(outputs_
); i
++) {
1236 outputs_
[i
].set_modes(modes
.get());
1237 outputs_
[i
].set_current_mode(modes
[0]);
1238 outputs_
[i
].set_native_mode(modes
[0]);
1241 configurator_
.Init(false);
1243 // First test simply fails in MULTIPLE_DISPLAY_STATE_SINGLE mode. This is
1244 // probably unrealistic but we want to make sure any assumptions don't creep
1246 native_display_delegate_
->set_max_configurable_pixels(
1247 modes
[2]->size().GetArea());
1248 state_controller_
.set_state(MULTIPLE_DISPLAY_STATE_SINGLE
);
1249 UpdateOutputs(1, true);
1254 GetFramebufferAction(big_mode_
.size(), &outputs_
[0], NULL
).c_str(),
1255 GetCrtcAction(outputs_
[0], modes
[0], gfx::Point(0, 0)).c_str(),
1256 GetCrtcAction(outputs_
[0], modes
[3], gfx::Point(0, 0)).c_str(),
1257 GetCrtcAction(outputs_
[0], modes
[2], gfx::Point(0, 0)).c_str(),
1260 log_
->GetActionsAndClear());
1262 // This test should attempt to configure a mirror mode that will not succeed
1263 // and should end up in extended mode.
1264 native_display_delegate_
->set_max_configurable_pixels(
1265 modes
[3]->size().GetArea());
1266 state_controller_
.set_state(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR
);
1267 UpdateOutputs(2, true);
1272 GetFramebufferAction(modes
[0]->size(), &outputs_
[0], &outputs_
[1])
1274 GetCrtcAction(outputs_
[0], modes
[0], gfx::Point(0, 0)).c_str(),
1275 // First mode tried is expected to fail and it will
1276 // retry wil the 4th mode in the list.
1277 GetCrtcAction(outputs_
[0], modes
[3], gfx::Point(0, 0)).c_str(),
1278 // Then attempt to configure crtc1 with the first mode.
1279 GetCrtcAction(outputs_
[1], modes
[0], gfx::Point(0, 0)).c_str(),
1280 GetCrtcAction(outputs_
[1], modes
[3], gfx::Point(0, 0)).c_str(),
1281 // Since it was requested to go into mirror mode
1282 // and the configured modes were different, it
1283 // should now try and setup a valid configurable
1285 GetFramebufferAction(
1286 gfx::Size(modes
[0]->size().width(),
1287 modes
[0]->size().height() + modes
[0]->size().height() +
1288 DisplayConfigurator::kVerticalGap
),
1290 &outputs_
[1]).c_str(),
1291 GetCrtcAction(outputs_
[0], modes
[0], gfx::Point(0, 0)).c_str(),
1292 GetCrtcAction(outputs_
[0], modes
[3], gfx::Point(0, 0)).c_str(),
1293 GetCrtcAction(outputs_
[1],
1296 modes
[0]->size().height() +
1297 DisplayConfigurator::kVerticalGap
))
1299 GetCrtcAction(outputs_
[1],
1302 modes
[0]->size().height() +
1303 DisplayConfigurator::kVerticalGap
))
1307 log_
->GetActionsAndClear());