Use the correct typedef for the return value of BlinkPlatformImpl::getTraceSamplingState
[chromium-blink-merge.git] / ui / display / chromeos / display_configurator_unittest.cc
blob9000af6ccc13d5c5aad4ba9837917048497b322e
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"
14 namespace ui {
15 namespace test {
17 namespace {
19 class TestObserver : public DisplayConfigurator::Observer {
20 public:
21 explicit TestObserver(DisplayConfigurator* configurator)
22 : configurator_(configurator) {
23 Reset();
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_;
37 void Reset() {
38 num_changes_ = 0;
39 num_failures_ = 0;
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 {
47 num_changes_++;
48 latest_outputs_ = outputs;
51 void OnDisplayModeChangeFailed(
52 const DisplayConfigurator::DisplayStateList& outputs,
53 MultipleDisplayState failed_new_state) override {
54 num_failures_++;
55 latest_failed_state_ = failed_new_state;
58 private:
59 DisplayConfigurator* configurator_; // Not owned.
61 // Number of times that OnDisplayMode*() has been called.
62 int num_changes_;
63 int num_failures_;
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 {
73 public:
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 std::vector<int64_t>& outputs) const override {
82 return state_;
84 bool GetResolutionForDisplayId(int64_t display_id,
85 gfx::Size* size) const override {
86 return false;
89 private:
90 MultipleDisplayState state_;
92 DISALLOW_COPY_AND_ASSIGN(TestStateController);
95 class TestMirroringController
96 : public DisplayConfigurator::SoftwareMirroringController {
97 public:
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_;
109 private:
110 bool software_mirroring_enabled_;
112 DISALLOW_COPY_AND_ASSIGN(TestMirroringController);
115 class DisplayConfiguratorTest : public testing::Test {
116 public:
117 enum CallbackResult {
118 CALLBACK_FAILURE,
119 CALLBACK_SUCCESS,
120 CALLBACK_NOT_CALLED,
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 ~DisplayConfiguratorTest() override {}
134 void SetUp() override {
135 log_.reset(new ActionLogger());
137 native_display_delegate_ = new TestNativeDisplayDelegate(log_.get());
138 configurator_.SetDelegateForTesting(
139 scoped_ptr<NativeDisplayDelegate>(native_display_delegate_));
141 configurator_.set_state_controller(&state_controller_);
142 configurator_.set_mirroring_controller(&mirroring_controller_);
144 std::vector<const DisplayMode*> modes;
145 modes.push_back(&small_mode_);
147 TestDisplaySnapshot* o = &outputs_[0];
148 o->set_current_mode(&small_mode_);
149 o->set_native_mode(&small_mode_);
150 o->set_modes(modes);
151 o->set_type(DISPLAY_CONNECTION_TYPE_INTERNAL);
152 o->set_is_aspect_preserving_scaling(true);
153 o->set_display_id(123);
155 o = &outputs_[1];
156 o->set_current_mode(&big_mode_);
157 o->set_native_mode(&big_mode_);
158 modes.push_back(&big_mode_);
159 o->set_modes(modes);
160 o->set_type(DISPLAY_CONNECTION_TYPE_HDMI);
161 o->set_is_aspect_preserving_scaling(true);
162 o->set_display_id(456);
164 UpdateOutputs(2, false);
167 void OnConfiguredCallback(bool status) {
168 callback_result_ = (status ? CALLBACK_SUCCESS : CALLBACK_FAILURE);
171 void EnableContentProtectionCallback(bool status) {
172 enable_content_protection_status_ = status;
173 enable_content_protection_call_count_++;
176 void QueryContentProtectionCallback(
177 const DisplayConfigurator::QueryProtectionResponse& response) {
178 query_content_protection_response_ = response;
179 query_content_protection_call_count_++;
182 // Predefined modes that can be used by outputs.
183 const DisplayMode small_mode_;
184 const DisplayMode big_mode_;
186 protected:
187 // Configures |native_display_delegate_| to return the first |num_outputs|
188 // entries from
189 // |outputs_|. If |send_events| is true, also sends screen-change and
190 // output-change events to |configurator_| and triggers the configure
191 // timeout if one was scheduled.
192 void UpdateOutputs(size_t num_outputs, bool send_events) {
193 ASSERT_LE(num_outputs, arraysize(outputs_));
194 std::vector<DisplaySnapshot*> outputs;
195 for (size_t i = 0; i < num_outputs; ++i)
196 outputs.push_back(&outputs_[i]);
197 native_display_delegate_->set_outputs(outputs);
199 if (send_events) {
200 configurator_.OnConfigurationChanged();
201 EXPECT_TRUE(test_api_.TriggerConfigureTimeout());
205 // Initializes |configurator_| with a single internal display.
206 void InitWithSingleOutput() {
207 UpdateOutputs(1, false);
208 EXPECT_EQ(kNoActions, log_->GetActionsAndClear());
209 configurator_.Init(false);
210 EXPECT_EQ(kNoActions, log_->GetActionsAndClear());
211 configurator_.ForceInitialConfigure(0);
212 EXPECT_EQ(JoinActions(kInitXRandR, kGrab,
213 GetFramebufferAction(small_mode_.size(), &outputs_[0],
214 NULL).c_str(),
215 GetCrtcAction(outputs_[0], &small_mode_,
216 gfx::Point(0, 0)).c_str(),
217 kForceDPMS, kUngrab, NULL),
218 log_->GetActionsAndClear());
221 CallbackResult PopCallbackResult() {
222 CallbackResult result = callback_result_;
223 callback_result_ = CALLBACK_NOT_CALLED;
224 return result;
227 base::MessageLoop message_loop_;
228 TestStateController state_controller_;
229 TestMirroringController mirroring_controller_;
230 DisplayConfigurator configurator_;
231 TestObserver observer_;
232 scoped_ptr<ActionLogger> log_;
233 TestNativeDisplayDelegate* native_display_delegate_; // not owned
234 DisplayConfigurator::TestApi test_api_;
236 bool enable_content_protection_status_;
237 int enable_content_protection_call_count_;
238 DisplayConfigurator::QueryProtectionResponse
239 query_content_protection_response_;
240 int query_content_protection_call_count_;
242 TestDisplaySnapshot outputs_[2];
244 CallbackResult callback_result_;
246 private:
247 DISALLOW_COPY_AND_ASSIGN(DisplayConfiguratorTest);
250 } // namespace
252 TEST_F(DisplayConfiguratorTest, FindDisplayModeMatchingSize) {
253 ScopedVector<const DisplayMode> modes;
255 // Fields are width, height, interlaced, refresh rate.
256 modes.push_back(new DisplayMode(gfx::Size(1920, 1200), false, 60.0));
257 DisplayMode* native_mode =
258 new DisplayMode(gfx::Size(1920, 1200), false, 50.0);
259 modes.push_back(native_mode);
260 // Different rates.
261 modes.push_back(new DisplayMode(gfx::Size(1920, 1080), false, 30.0));
262 modes.push_back(new DisplayMode(gfx::Size(1920, 1080), false, 50.0));
263 modes.push_back(new DisplayMode(gfx::Size(1920, 1080), false, 40.0));
264 modes.push_back(new DisplayMode(gfx::Size(1920, 1080), false, 0.0));
265 // Interlaced vs non-interlaced.
266 modes.push_back(new DisplayMode(gfx::Size(1280, 720), true, 60.0));
267 modes.push_back(new DisplayMode(gfx::Size(1280, 720), false, 40.0));
268 // Interlaced only.
269 modes.push_back(new DisplayMode(gfx::Size(1024, 768), true, 0.0));
270 modes.push_back(new DisplayMode(gfx::Size(1024, 768), true, 40.0));
271 modes.push_back(new DisplayMode(gfx::Size(1024, 768), true, 60.0));
272 // Mixed.
273 modes.push_back(new DisplayMode(gfx::Size(1024, 600), true, 60.0));
274 modes.push_back(new DisplayMode(gfx::Size(1024, 600), false, 40.0));
275 modes.push_back(new DisplayMode(gfx::Size(1024, 600), false, 50.0));
276 // Just one interlaced mode.
277 modes.push_back(new DisplayMode(gfx::Size(640, 480), true, 60.0));
278 // Refresh rate not available.
279 modes.push_back(new DisplayMode(gfx::Size(320, 200), false, 0.0));
281 TestDisplaySnapshot output;
282 output.set_modes(modes.get());
283 output.set_native_mode(native_mode);
285 // Should pick native over highest refresh rate.
286 EXPECT_EQ(modes[1],
287 DisplayConfigurator::FindDisplayModeMatchingSize(
288 output, gfx::Size(1920, 1200)));
290 // Should pick highest refresh rate.
291 EXPECT_EQ(modes[3],
292 DisplayConfigurator::FindDisplayModeMatchingSize(
293 output, gfx::Size(1920, 1080)));
295 // Should pick non-interlaced mode.
296 EXPECT_EQ(modes[7],
297 DisplayConfigurator::FindDisplayModeMatchingSize(
298 output, gfx::Size(1280, 720)));
300 // Interlaced only. Should pick one with the highest refresh rate in
301 // interlaced mode.
302 EXPECT_EQ(modes[10],
303 DisplayConfigurator::FindDisplayModeMatchingSize(
304 output, gfx::Size(1024, 768)));
306 // Mixed: Should pick one with the highest refresh rate in
307 // interlaced mode.
308 EXPECT_EQ(modes[13],
309 DisplayConfigurator::FindDisplayModeMatchingSize(
310 output, gfx::Size(1024, 600)));
312 // Just one interlaced mode.
313 EXPECT_EQ(modes[14],
314 DisplayConfigurator::FindDisplayModeMatchingSize(
315 output, gfx::Size(640, 480)));
317 // Refresh rate not available.
318 EXPECT_EQ(modes[15],
319 DisplayConfigurator::FindDisplayModeMatchingSize(
320 output, gfx::Size(320, 200)));
322 // No mode found.
323 EXPECT_EQ(NULL,
324 DisplayConfigurator::FindDisplayModeMatchingSize(
325 output, gfx::Size(1440, 900)));
328 TEST_F(DisplayConfiguratorTest, ConnectSecondOutput) {
329 InitWithSingleOutput();
331 // Connect a second output and check that the configurator enters
332 // extended mode.
333 observer_.Reset();
334 state_controller_.set_state(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED);
335 UpdateOutputs(2, true);
336 const int kDualHeight = small_mode_.size().height() +
337 DisplayConfigurator::kVerticalGap +
338 big_mode_.size().height();
339 EXPECT_EQ(
340 JoinActions(
341 kGrab,
342 GetFramebufferAction(gfx::Size(big_mode_.size().width(), kDualHeight),
343 &outputs_[0],
344 &outputs_[1]).c_str(),
345 GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
346 GetCrtcAction(outputs_[1],
347 &big_mode_,
348 gfx::Point(0,
349 small_mode_.size().height() +
350 DisplayConfigurator::kVerticalGap))
351 .c_str(),
352 kUngrab,
353 NULL),
354 log_->GetActionsAndClear());
355 EXPECT_FALSE(mirroring_controller_.SoftwareMirroringEnabled());
356 EXPECT_EQ(1, observer_.num_changes());
358 observer_.Reset();
359 configurator_.SetDisplayMode(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR);
360 EXPECT_EQ(
361 JoinActions(
362 kGrab,
363 GetFramebufferAction(small_mode_.size(), &outputs_[0], &outputs_[1])
364 .c_str(),
365 GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
366 GetCrtcAction(outputs_[1], &small_mode_, gfx::Point(0, 0)).c_str(),
367 kUngrab,
368 NULL),
369 log_->GetActionsAndClear());
370 EXPECT_FALSE(mirroring_controller_.SoftwareMirroringEnabled());
371 EXPECT_EQ(1, observer_.num_changes());
373 // Disconnect the second output.
374 observer_.Reset();
375 UpdateOutputs(1, true);
376 EXPECT_EQ(
377 JoinActions(
378 kGrab,
379 GetFramebufferAction(small_mode_.size(), &outputs_[0], NULL).c_str(),
380 GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
381 kUngrab,
382 NULL),
383 log_->GetActionsAndClear());
384 EXPECT_FALSE(mirroring_controller_.SoftwareMirroringEnabled());
385 EXPECT_EQ(1, observer_.num_changes());
387 // Get rid of shared modes to force software mirroring.
388 outputs_[1].set_modes(std::vector<const DisplayMode*>(1, &big_mode_));
389 state_controller_.set_state(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED);
390 UpdateOutputs(2, true);
391 EXPECT_EQ(
392 JoinActions(
393 kGrab,
394 GetFramebufferAction(gfx::Size(big_mode_.size().width(), kDualHeight),
395 &outputs_[0],
396 &outputs_[1]).c_str(),
397 GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
398 GetCrtcAction(outputs_[1],
399 &big_mode_,
400 gfx::Point(0,
401 small_mode_.size().height() +
402 DisplayConfigurator::kVerticalGap))
403 .c_str(),
404 kUngrab,
405 NULL),
406 log_->GetActionsAndClear());
407 EXPECT_FALSE(mirroring_controller_.SoftwareMirroringEnabled());
408 const gfx::Size framebuffer_size = configurator_.framebuffer_size();
409 DCHECK(!framebuffer_size.IsEmpty());
411 observer_.Reset();
412 configurator_.SetDisplayMode(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR);
413 EXPECT_EQ(JoinActions(kGrab, kUngrab, NULL), log_->GetActionsAndClear());
414 EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED,
415 configurator_.display_state());
416 EXPECT_TRUE(mirroring_controller_.SoftwareMirroringEnabled());
417 EXPECT_EQ(framebuffer_size.ToString(),
418 configurator_.framebuffer_size().ToString());
420 EXPECT_EQ(1, observer_.num_changes());
422 // Setting MULTIPLE_DISPLAY_STATE_DUAL_MIRROR should try to reconfigure.
423 observer_.Reset();
424 configurator_.SetDisplayMode(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED);
425 EXPECT_EQ(JoinActions(NULL), log_->GetActionsAndClear());
426 EXPECT_FALSE(mirroring_controller_.SoftwareMirroringEnabled());
427 EXPECT_EQ(1, observer_.num_changes());
429 // Set back to software mirror mode.
430 observer_.Reset();
431 configurator_.SetDisplayMode(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR);
432 EXPECT_EQ(JoinActions(kGrab, kUngrab, NULL), log_->GetActionsAndClear());
433 EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED,
434 configurator_.display_state());
435 EXPECT_TRUE(mirroring_controller_.SoftwareMirroringEnabled());
436 EXPECT_EQ(1, observer_.num_changes());
438 // Disconnect the second output.
439 observer_.Reset();
440 UpdateOutputs(1, true);
441 EXPECT_EQ(
442 JoinActions(
443 kGrab,
444 GetFramebufferAction(small_mode_.size(), &outputs_[0], NULL).c_str(),
445 GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
446 kUngrab,
447 NULL),
448 log_->GetActionsAndClear());
449 EXPECT_FALSE(mirroring_controller_.SoftwareMirroringEnabled());
450 EXPECT_EQ(1, observer_.num_changes());
453 TEST_F(DisplayConfiguratorTest, SetDisplayPower) {
454 InitWithSingleOutput();
456 state_controller_.set_state(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR);
457 observer_.Reset();
458 UpdateOutputs(2, true);
459 EXPECT_EQ(
460 JoinActions(
461 kGrab,
462 GetFramebufferAction(small_mode_.size(), &outputs_[0], &outputs_[1])
463 .c_str(),
464 GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
465 GetCrtcAction(outputs_[1], &small_mode_, gfx::Point(0, 0)).c_str(),
466 kUngrab,
467 NULL),
468 log_->GetActionsAndClear());
469 EXPECT_FALSE(mirroring_controller_.SoftwareMirroringEnabled());
470 EXPECT_EQ(1, observer_.num_changes());
472 // Turning off the internal display should switch the external display to
473 // its native mode.
474 observer_.Reset();
475 configurator_.SetDisplayPower(
476 chromeos::DISPLAY_POWER_INTERNAL_OFF_EXTERNAL_ON,
477 DisplayConfigurator::kSetDisplayPowerNoFlags,
478 base::Bind(&DisplayConfiguratorTest::OnConfiguredCallback,
479 base::Unretained(this)));
480 EXPECT_EQ(CALLBACK_SUCCESS, PopCallbackResult());
481 EXPECT_EQ(
482 JoinActions(
483 kGrab,
484 GetFramebufferAction(big_mode_.size(), &outputs_[0], &outputs_[1])
485 .c_str(),
486 GetCrtcAction(outputs_[0], NULL, gfx::Point(0, 0)).c_str(),
487 GetCrtcAction(outputs_[1], &big_mode_, gfx::Point(0, 0)).c_str(),
488 kForceDPMS,
489 kUngrab,
490 NULL),
491 log_->GetActionsAndClear());
492 EXPECT_EQ(MULTIPLE_DISPLAY_STATE_SINGLE, configurator_.display_state());
493 EXPECT_EQ(1, observer_.num_changes());
495 // When all displays are turned off, the framebuffer should switch back
496 // to the mirrored size.
497 observer_.Reset();
498 configurator_.SetDisplayPower(
499 chromeos::DISPLAY_POWER_ALL_OFF,
500 DisplayConfigurator::kSetDisplayPowerNoFlags,
501 base::Bind(&DisplayConfiguratorTest::OnConfiguredCallback,
502 base::Unretained(this)));
503 EXPECT_EQ(CALLBACK_SUCCESS, PopCallbackResult());
504 EXPECT_EQ(
505 JoinActions(kGrab,
506 GetFramebufferAction(
507 small_mode_.size(), &outputs_[0], &outputs_[1]).c_str(),
508 GetCrtcAction(outputs_[0], NULL, gfx::Point(0, 0)).c_str(),
509 GetCrtcAction(outputs_[1], NULL, gfx::Point(0, 0)).c_str(),
510 kUngrab,
511 NULL),
512 log_->GetActionsAndClear());
513 EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR, configurator_.display_state());
514 EXPECT_FALSE(mirroring_controller_.SoftwareMirroringEnabled());
515 EXPECT_EQ(1, observer_.num_changes());
517 // Turn all displays on and check that mirroring is still used.
518 observer_.Reset();
519 configurator_.SetDisplayPower(
520 chromeos::DISPLAY_POWER_ALL_ON,
521 DisplayConfigurator::kSetDisplayPowerNoFlags,
522 base::Bind(&DisplayConfiguratorTest::OnConfiguredCallback,
523 base::Unretained(this)));
524 EXPECT_EQ(CALLBACK_SUCCESS, PopCallbackResult());
525 EXPECT_EQ(
526 JoinActions(
527 kGrab,
528 GetFramebufferAction(small_mode_.size(), &outputs_[0], &outputs_[1])
529 .c_str(),
530 GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
531 GetCrtcAction(outputs_[1], &small_mode_, gfx::Point(0, 0)).c_str(),
532 kForceDPMS,
533 kUngrab,
534 NULL),
535 log_->GetActionsAndClear());
536 EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR, configurator_.display_state());
537 EXPECT_FALSE(mirroring_controller_.SoftwareMirroringEnabled());
538 EXPECT_EQ(1, observer_.num_changes());
540 // Get rid of shared modes to force software mirroring.
541 outputs_[1].set_modes(std::vector<const DisplayMode*>(1, &big_mode_));
542 state_controller_.set_state(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR);
543 observer_.Reset();
544 UpdateOutputs(2, true);
545 const int kDualHeight = small_mode_.size().height() +
546 DisplayConfigurator::kVerticalGap +
547 big_mode_.size().height();
548 EXPECT_EQ(
549 JoinActions(
550 kGrab,
551 GetFramebufferAction(gfx::Size(big_mode_.size().width(), kDualHeight),
552 &outputs_[0],
553 &outputs_[1]).c_str(),
554 GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
555 GetCrtcAction(outputs_[1],
556 &big_mode_,
557 gfx::Point(0,
558 small_mode_.size().height() +
559 DisplayConfigurator::kVerticalGap))
560 .c_str(),
561 kUngrab,
562 NULL),
563 log_->GetActionsAndClear());
564 EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED,
565 configurator_.display_state());
566 EXPECT_TRUE(mirroring_controller_.SoftwareMirroringEnabled());
567 EXPECT_EQ(1, observer_.num_changes());
569 // Turning off the internal display should switch the external display to
570 // its native mode.
571 observer_.Reset();
572 configurator_.SetDisplayPower(
573 chromeos::DISPLAY_POWER_INTERNAL_OFF_EXTERNAL_ON,
574 DisplayConfigurator::kSetDisplayPowerNoFlags,
575 base::Bind(&DisplayConfiguratorTest::OnConfiguredCallback,
576 base::Unretained(this)));
577 EXPECT_EQ(CALLBACK_SUCCESS, PopCallbackResult());
578 EXPECT_EQ(
579 JoinActions(
580 kGrab,
581 GetFramebufferAction(big_mode_.size(), &outputs_[0], &outputs_[1])
582 .c_str(),
583 GetCrtcAction(outputs_[0], NULL, gfx::Point(0, 0)).c_str(),
584 GetCrtcAction(outputs_[1], &big_mode_, gfx::Point(0, 0)).c_str(),
585 kForceDPMS,
586 kUngrab,
587 NULL),
588 log_->GetActionsAndClear());
589 EXPECT_EQ(MULTIPLE_DISPLAY_STATE_SINGLE, configurator_.display_state());
590 EXPECT_FALSE(mirroring_controller_.SoftwareMirroringEnabled());
591 EXPECT_EQ(1, observer_.num_changes());
593 // When all displays are turned off, the framebuffer should switch back
594 // to the extended + software mirroring.
595 observer_.Reset();
596 configurator_.SetDisplayPower(
597 chromeos::DISPLAY_POWER_ALL_OFF,
598 DisplayConfigurator::kSetDisplayPowerNoFlags,
599 base::Bind(&DisplayConfiguratorTest::OnConfiguredCallback,
600 base::Unretained(this)));
601 EXPECT_EQ(CALLBACK_SUCCESS, PopCallbackResult());
602 EXPECT_EQ(
603 JoinActions(
604 kGrab,
605 GetFramebufferAction(gfx::Size(big_mode_.size().width(), kDualHeight),
606 &outputs_[0],
607 &outputs_[1]).c_str(),
608 GetCrtcAction(outputs_[0], NULL, gfx::Point(0, 0)).c_str(),
609 GetCrtcAction(outputs_[1],
610 NULL,
611 gfx::Point(0,
612 small_mode_.size().height() +
613 DisplayConfigurator::kVerticalGap))
614 .c_str(),
615 kUngrab,
616 NULL),
617 log_->GetActionsAndClear());
618 EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED,
619 configurator_.display_state());
620 EXPECT_TRUE(mirroring_controller_.SoftwareMirroringEnabled());
621 EXPECT_EQ(1, observer_.num_changes());
623 // Turn all displays on and check that mirroring is still used.
624 observer_.Reset();
625 configurator_.SetDisplayPower(
626 chromeos::DISPLAY_POWER_ALL_ON,
627 DisplayConfigurator::kSetDisplayPowerNoFlags,
628 base::Bind(&DisplayConfiguratorTest::OnConfiguredCallback,
629 base::Unretained(this)));
630 EXPECT_EQ(CALLBACK_SUCCESS, PopCallbackResult());
631 EXPECT_EQ(
632 JoinActions(
633 kGrab,
634 GetFramebufferAction(gfx::Size(big_mode_.size().width(), kDualHeight),
635 &outputs_[0],
636 &outputs_[1]).c_str(),
637 GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
638 GetCrtcAction(outputs_[1],
639 &big_mode_,
640 gfx::Point(0,
641 small_mode_.size().height() +
642 DisplayConfigurator::kVerticalGap))
643 .c_str(),
644 kForceDPMS,
645 kUngrab,
646 NULL),
647 log_->GetActionsAndClear());
648 EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED,
649 configurator_.display_state());
650 EXPECT_TRUE(mirroring_controller_.SoftwareMirroringEnabled());
651 EXPECT_EQ(1, observer_.num_changes());
654 TEST_F(DisplayConfiguratorTest, SuspendAndResume) {
655 InitWithSingleOutput();
657 // No preparation is needed before suspending when the display is already
658 // on. The configurator should still reprobe on resume in case a display
659 // was connected while suspended.
660 const gfx::Size framebuffer_size = configurator_.framebuffer_size();
661 DCHECK(!framebuffer_size.IsEmpty());
662 configurator_.SuspendDisplays();
663 EXPECT_EQ(framebuffer_size.ToString(),
664 configurator_.framebuffer_size().ToString());
665 EXPECT_EQ(kNoActions, log_->GetActionsAndClear());
666 configurator_.ResumeDisplays();
667 EXPECT_TRUE(test_api_.TriggerConfigureTimeout());
668 EXPECT_EQ(
669 JoinActions(
670 kGrab,
671 GetFramebufferAction(small_mode_.size(), &outputs_[0], NULL).c_str(),
672 GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
673 kForceDPMS,
674 kUngrab,
675 NULL),
676 log_->GetActionsAndClear());
678 // Now turn the display off before suspending and check that the
679 // configurator turns it back on and syncs with the server.
680 configurator_.SetDisplayPower(
681 chromeos::DISPLAY_POWER_ALL_OFF,
682 DisplayConfigurator::kSetDisplayPowerNoFlags,
683 base::Bind(&DisplayConfiguratorTest::OnConfiguredCallback,
684 base::Unretained(this)));
685 EXPECT_EQ(CALLBACK_SUCCESS, PopCallbackResult());
686 EXPECT_EQ(
687 JoinActions(
688 kGrab,
689 GetFramebufferAction(small_mode_.size(), &outputs_[0], NULL).c_str(),
690 GetCrtcAction(outputs_[0], NULL, gfx::Point(0, 0)).c_str(),
691 kUngrab,
692 NULL),
693 log_->GetActionsAndClear());
695 configurator_.SuspendDisplays();
696 EXPECT_EQ(
697 JoinActions(
698 kGrab,
699 GetFramebufferAction(small_mode_.size(), &outputs_[0], NULL).c_str(),
700 GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
701 kForceDPMS,
702 kUngrab,
703 kSync,
704 NULL),
705 log_->GetActionsAndClear());
707 configurator_.ResumeDisplays();
708 EXPECT_TRUE(test_api_.TriggerConfigureTimeout());
709 EXPECT_EQ(
710 JoinActions(
711 kGrab,
712 GetFramebufferAction(small_mode_.size(), &outputs_[0], NULL).c_str(),
713 GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
714 kForceDPMS,
715 kUngrab,
716 NULL),
717 log_->GetActionsAndClear());
719 // If a second, external display is connected, the displays shouldn't be
720 // powered back on before suspending.
721 state_controller_.set_state(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR);
722 UpdateOutputs(2, true);
723 EXPECT_EQ(
724 JoinActions(
725 kGrab,
726 GetFramebufferAction(small_mode_.size(), &outputs_[0], &outputs_[1])
727 .c_str(),
728 GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
729 GetCrtcAction(outputs_[1], &small_mode_, gfx::Point(0, 0)).c_str(),
730 kUngrab,
731 NULL),
732 log_->GetActionsAndClear());
734 configurator_.SetDisplayPower(
735 chromeos::DISPLAY_POWER_ALL_OFF,
736 DisplayConfigurator::kSetDisplayPowerNoFlags,
737 base::Bind(&DisplayConfiguratorTest::OnConfiguredCallback,
738 base::Unretained(this)));
739 EXPECT_EQ(CALLBACK_SUCCESS, PopCallbackResult());
740 EXPECT_EQ(
741 JoinActions(kGrab,
742 GetFramebufferAction(
743 small_mode_.size(), &outputs_[0], &outputs_[1]).c_str(),
744 GetCrtcAction(outputs_[0], NULL, gfx::Point(0, 0)).c_str(),
745 GetCrtcAction(outputs_[1], NULL, gfx::Point(0, 0)).c_str(),
746 kUngrab,
747 NULL),
748 log_->GetActionsAndClear());
750 configurator_.SuspendDisplays();
751 EXPECT_EQ(JoinActions(kGrab, kUngrab, kSync, NULL),
752 log_->GetActionsAndClear());
754 // If a display is disconnected while suspended, the configurator should
755 // pick up the change.
756 UpdateOutputs(1, false);
757 configurator_.ResumeDisplays();
758 EXPECT_TRUE(test_api_.TriggerConfigureTimeout());
759 EXPECT_EQ(
760 JoinActions(
761 kGrab,
762 GetFramebufferAction(small_mode_.size(), &outputs_[0], NULL).c_str(),
763 GetCrtcAction(outputs_[0], NULL, gfx::Point(0, 0)).c_str(),
764 kUngrab,
765 NULL),
766 log_->GetActionsAndClear());
769 TEST_F(DisplayConfiguratorTest, Headless) {
770 UpdateOutputs(0, false);
771 EXPECT_EQ(kNoActions, log_->GetActionsAndClear());
772 configurator_.Init(false);
773 EXPECT_EQ(kNoActions, log_->GetActionsAndClear());
774 configurator_.ForceInitialConfigure(0);
775 EXPECT_EQ(JoinActions(kInitXRandR, kGrab, kForceDPMS, kUngrab, NULL),
776 log_->GetActionsAndClear());
778 // Not much should happen when the display power state is changed while
779 // no displays are connected.
780 configurator_.SetDisplayPower(
781 chromeos::DISPLAY_POWER_ALL_OFF,
782 DisplayConfigurator::kSetDisplayPowerNoFlags,
783 base::Bind(&DisplayConfiguratorTest::OnConfiguredCallback,
784 base::Unretained(this)));
785 EXPECT_EQ(CALLBACK_SUCCESS, PopCallbackResult());
786 EXPECT_EQ(JoinActions(kGrab, kUngrab, NULL), log_->GetActionsAndClear());
787 configurator_.SetDisplayPower(
788 chromeos::DISPLAY_POWER_ALL_ON,
789 DisplayConfigurator::kSetDisplayPowerNoFlags,
790 base::Bind(&DisplayConfiguratorTest::OnConfiguredCallback,
791 base::Unretained(this)));
792 EXPECT_EQ(CALLBACK_SUCCESS, PopCallbackResult());
793 EXPECT_EQ(JoinActions(kGrab, kForceDPMS, kUngrab, NULL),
794 log_->GetActionsAndClear());
796 // Connect an external display and check that it's configured correctly.
797 outputs_[0].set_current_mode(outputs_[1].current_mode());
798 outputs_[0].set_native_mode(outputs_[1].native_mode());
799 outputs_[0].set_modes(outputs_[1].modes());
800 outputs_[0].set_type(outputs_[1].type());
802 UpdateOutputs(1, true);
803 EXPECT_EQ(
804 JoinActions(
805 kGrab,
806 GetFramebufferAction(big_mode_.size(), &outputs_[0], NULL).c_str(),
807 GetCrtcAction(outputs_[0], &big_mode_, gfx::Point(0, 0)).c_str(),
808 kUngrab,
809 NULL),
810 log_->GetActionsAndClear());
811 const gfx::Size framebuffer_size = configurator_.framebuffer_size();
812 DCHECK(!framebuffer_size.IsEmpty());
814 UpdateOutputs(0, true);
815 EXPECT_EQ(JoinActions(kGrab, kUngrab, NULL), log_->GetActionsAndClear());
816 EXPECT_EQ(framebuffer_size.ToString(),
817 configurator_.framebuffer_size().ToString());
820 TEST_F(DisplayConfiguratorTest, StartWithTwoOutputs) {
821 UpdateOutputs(2, false);
822 EXPECT_EQ(kNoActions, log_->GetActionsAndClear());
823 configurator_.Init(false);
824 EXPECT_EQ(kNoActions, log_->GetActionsAndClear());
826 state_controller_.set_state(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR);
827 configurator_.ForceInitialConfigure(0);
828 EXPECT_EQ(
829 JoinActions(
830 kInitXRandR, kGrab,
831 GetFramebufferAction(small_mode_.size(), &outputs_[0], &outputs_[1])
832 .c_str(),
833 GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
834 GetCrtcAction(outputs_[1], &small_mode_, gfx::Point(0, 0)).c_str(),
835 kForceDPMS, kUngrab, NULL),
836 log_->GetActionsAndClear());
839 TEST_F(DisplayConfiguratorTest, InvalidMultipleDisplayStates) {
840 UpdateOutputs(0, false);
841 EXPECT_EQ(kNoActions, log_->GetActionsAndClear());
842 configurator_.Init(false);
843 configurator_.ForceInitialConfigure(0);
844 observer_.Reset();
845 configurator_.SetDisplayMode(MULTIPLE_DISPLAY_STATE_HEADLESS);
846 EXPECT_EQ(1, observer_.num_changes());
847 EXPECT_EQ(0, observer_.num_failures());
848 configurator_.SetDisplayMode(MULTIPLE_DISPLAY_STATE_SINGLE);
849 configurator_.SetDisplayMode(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR);
850 configurator_.SetDisplayMode(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED);
851 EXPECT_EQ(1, observer_.num_changes());
852 EXPECT_EQ(3, observer_.num_failures());
854 UpdateOutputs(1, true);
855 observer_.Reset();
856 configurator_.SetDisplayMode(MULTIPLE_DISPLAY_STATE_HEADLESS);
857 EXPECT_EQ(0, observer_.num_changes());
858 EXPECT_EQ(1, observer_.num_failures());
859 configurator_.SetDisplayMode(MULTIPLE_DISPLAY_STATE_SINGLE);
860 EXPECT_EQ(1, observer_.num_changes());
861 EXPECT_EQ(1, observer_.num_failures());
862 configurator_.SetDisplayMode(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR);
863 configurator_.SetDisplayMode(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED);
864 EXPECT_EQ(1, observer_.num_changes());
865 EXPECT_EQ(3, observer_.num_failures());
867 state_controller_.set_state(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED);
868 UpdateOutputs(2, true);
869 observer_.Reset();
870 configurator_.SetDisplayMode(MULTIPLE_DISPLAY_STATE_HEADLESS);
871 configurator_.SetDisplayMode(MULTIPLE_DISPLAY_STATE_SINGLE);
872 EXPECT_EQ(0, observer_.num_changes());
873 EXPECT_EQ(2, observer_.num_failures());
874 configurator_.SetDisplayMode(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR);
875 configurator_.SetDisplayMode(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED);
876 EXPECT_EQ(2, observer_.num_changes());
877 EXPECT_EQ(2, observer_.num_failures());
880 TEST_F(DisplayConfiguratorTest, GetMultipleDisplayStateForMirroredDisplays) {
881 UpdateOutputs(2, false);
882 configurator_.Init(false);
883 state_controller_.set_state(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR);
884 configurator_.ForceInitialConfigure(0);
885 EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR, configurator_.display_state());
888 TEST_F(DisplayConfiguratorTest, UpdateCachedOutputsEvenAfterFailure) {
889 InitWithSingleOutput();
890 const DisplayConfigurator::DisplayStateList* cached =
891 &configurator_.cached_displays();
892 ASSERT_EQ(static_cast<size_t>(1), cached->size());
893 EXPECT_EQ(outputs_[0].current_mode(), (*cached)[0]->current_mode());
895 // After connecting a second output, check that it shows up in
896 // |cached_displays_| even if an invalid state is requested.
897 state_controller_.set_state(MULTIPLE_DISPLAY_STATE_SINGLE);
898 UpdateOutputs(2, true);
899 cached = &configurator_.cached_displays();
900 ASSERT_EQ(static_cast<size_t>(2), cached->size());
901 EXPECT_EQ(outputs_[0].current_mode(), (*cached)[0]->current_mode());
902 EXPECT_EQ(outputs_[1].current_mode(), (*cached)[1]->current_mode());
905 TEST_F(DisplayConfiguratorTest, PanelFitting) {
906 // Configure the internal display to support only the big mode and the
907 // external display to support only the small mode.
908 outputs_[0].set_current_mode(&big_mode_);
909 outputs_[0].set_native_mode(&big_mode_);
910 outputs_[0].set_modes(std::vector<const DisplayMode*>(1, &big_mode_));
912 outputs_[1].set_current_mode(&small_mode_);
913 outputs_[1].set_native_mode(&small_mode_);
914 outputs_[1].set_modes(std::vector<const DisplayMode*>(1, &small_mode_));
916 // The small mode should be added to the internal output when requesting
917 // mirrored mode.
918 UpdateOutputs(2, false);
919 state_controller_.set_state(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR);
920 configurator_.Init(true /* is_panel_fitting_enabled */);
921 configurator_.ForceInitialConfigure(0);
922 EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR, configurator_.display_state());
923 EXPECT_EQ(
924 JoinActions(
925 kInitXRandR, kGrab,
926 GetAddOutputModeAction(outputs_[0], &small_mode_).c_str(),
927 GetFramebufferAction(small_mode_.size(), &outputs_[0], &outputs_[1])
928 .c_str(),
929 GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
930 GetCrtcAction(outputs_[1], &small_mode_, gfx::Point(0, 0)).c_str(),
931 kForceDPMS, kUngrab, NULL),
932 log_->GetActionsAndClear());
934 // Both outputs should be using the small mode.
935 ASSERT_EQ(1, observer_.num_changes());
936 ASSERT_EQ(static_cast<size_t>(2), observer_.latest_outputs().size());
937 EXPECT_EQ(&small_mode_, observer_.latest_outputs()[0]->current_mode());
938 EXPECT_EQ(&small_mode_, observer_.latest_outputs()[1]->current_mode());
940 // Also check that the newly-added small mode is present in the internal
941 // snapshot that was passed to the observer (http://crbug.com/289159).
942 DisplaySnapshot* state = observer_.latest_outputs()[0];
943 ASSERT_NE(
944 state->modes().end(),
945 std::find(state->modes().begin(), state->modes().end(), &small_mode_));
948 TEST_F(DisplayConfiguratorTest, ContentProtection) {
949 configurator_.Init(false);
950 configurator_.ForceInitialConfigure(0);
951 EXPECT_NE(kNoActions, log_->GetActionsAndClear());
953 DisplayConfigurator::ContentProtectionClientId id =
954 configurator_.RegisterContentProtectionClient();
955 EXPECT_NE(0u, id);
957 // One output.
958 UpdateOutputs(1, true);
959 EXPECT_NE(kNoActions, log_->GetActionsAndClear());
960 configurator_.QueryContentProtectionStatus(
961 id, outputs_[0].display_id(),
962 base::Bind(&DisplayConfiguratorTest::QueryContentProtectionCallback,
963 base::Unretained(this)));
964 EXPECT_EQ(1, query_content_protection_call_count_);
965 EXPECT_TRUE(query_content_protection_response_.success);
966 EXPECT_EQ(static_cast<uint32_t>(DISPLAY_CONNECTION_TYPE_INTERNAL),
967 query_content_protection_response_.link_mask);
968 EXPECT_EQ(static_cast<uint32_t>(CONTENT_PROTECTION_METHOD_NONE),
969 query_content_protection_response_.protection_mask);
970 EXPECT_EQ(kNoActions, log_->GetActionsAndClear());
972 // Two outputs.
973 UpdateOutputs(2, true);
974 EXPECT_NE(kNoActions, log_->GetActionsAndClear());
975 configurator_.QueryContentProtectionStatus(
976 id, outputs_[1].display_id(),
977 base::Bind(&DisplayConfiguratorTest::QueryContentProtectionCallback,
978 base::Unretained(this)));
979 EXPECT_EQ(2, query_content_protection_call_count_);
980 EXPECT_TRUE(query_content_protection_response_.success);
981 EXPECT_EQ(static_cast<uint32_t>(DISPLAY_CONNECTION_TYPE_HDMI),
982 query_content_protection_response_.link_mask);
983 EXPECT_EQ(static_cast<uint32_t>(CONTENT_PROTECTION_METHOD_NONE),
984 query_content_protection_response_.protection_mask);
985 EXPECT_EQ(kNoActions, log_->GetActionsAndClear());
987 configurator_.EnableContentProtection(
988 id, outputs_[1].display_id(), CONTENT_PROTECTION_METHOD_HDCP,
989 base::Bind(&DisplayConfiguratorTest::EnableContentProtectionCallback,
990 base::Unretained(this)));
991 EXPECT_EQ(1, enable_content_protection_call_count_);
992 EXPECT_TRUE(enable_content_protection_status_);
993 EXPECT_EQ(GetSetHDCPStateAction(outputs_[1], HDCP_STATE_DESIRED),
994 log_->GetActionsAndClear());
996 // Enable protection.
997 native_display_delegate_->set_hdcp_state(HDCP_STATE_ENABLED);
998 configurator_.QueryContentProtectionStatus(
999 id, outputs_[1].display_id(),
1000 base::Bind(&DisplayConfiguratorTest::QueryContentProtectionCallback,
1001 base::Unretained(this)));
1002 EXPECT_EQ(3, query_content_protection_call_count_);
1003 EXPECT_TRUE(query_content_protection_response_.success);
1004 EXPECT_EQ(static_cast<uint32_t>(DISPLAY_CONNECTION_TYPE_HDMI),
1005 query_content_protection_response_.link_mask);
1006 EXPECT_EQ(static_cast<uint32_t>(CONTENT_PROTECTION_METHOD_HDCP),
1007 query_content_protection_response_.protection_mask);
1008 EXPECT_EQ(kNoActions, log_->GetActionsAndClear());
1010 // Protections should be disabled after unregister.
1011 configurator_.UnregisterContentProtectionClient(id);
1012 EXPECT_EQ(GetSetHDCPStateAction(outputs_[1], HDCP_STATE_UNDESIRED),
1013 log_->GetActionsAndClear());
1016 TEST_F(DisplayConfiguratorTest, DoNotConfigureWithSuspendedDisplays) {
1017 InitWithSingleOutput();
1019 // The DisplayConfigurator may occasionally receive OnConfigurationChanged()
1020 // after the displays have been suspended. This event should be ignored since
1021 // the DisplayConfigurator will force a probe and reconfiguration of displays
1022 // at resume time.
1023 configurator_.SuspendDisplays();
1024 EXPECT_EQ(kNoActions, log_->GetActionsAndClear());
1026 // The configuration timer should not be started when the displays
1027 // are suspended.
1028 configurator_.OnConfigurationChanged();
1029 EXPECT_FALSE(test_api_.TriggerConfigureTimeout());
1030 EXPECT_EQ(kNoActions, log_->GetActionsAndClear());
1032 // Calls to SetDisplayPower and SetDisplayMode should be successful.
1033 configurator_.SetDisplayPower(
1034 chromeos::DISPLAY_POWER_ALL_OFF,
1035 DisplayConfigurator::kSetDisplayPowerNoFlags,
1036 base::Bind(&DisplayConfiguratorTest::OnConfiguredCallback,
1037 base::Unretained(this)));
1038 EXPECT_EQ(CALLBACK_SUCCESS, PopCallbackResult());
1039 EXPECT_EQ(
1040 JoinActions(
1041 kGrab,
1042 GetFramebufferAction(small_mode_.size(), &outputs_[0], NULL).c_str(),
1043 GetCrtcAction(outputs_[0], NULL, gfx::Point(0, 0)).c_str(),
1044 kUngrab,
1045 NULL),
1046 log_->GetActionsAndClear());
1047 configurator_.SetDisplayPower(
1048 chromeos::DISPLAY_POWER_ALL_ON,
1049 DisplayConfigurator::kSetDisplayPowerNoFlags,
1050 base::Bind(&DisplayConfiguratorTest::OnConfiguredCallback,
1051 base::Unretained(this)));
1052 EXPECT_EQ(CALLBACK_SUCCESS, PopCallbackResult());
1053 EXPECT_EQ(
1054 JoinActions(
1055 kGrab,
1056 GetFramebufferAction(small_mode_.size(), &outputs_[0], NULL).c_str(),
1057 GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
1058 kForceDPMS,
1059 kUngrab,
1060 NULL),
1061 log_->GetActionsAndClear());
1063 UpdateOutputs(2, false);
1064 configurator_.SetDisplayMode(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR);
1065 EXPECT_EQ(
1066 JoinActions(
1067 kGrab,
1068 GetFramebufferAction(small_mode_.size(), &outputs_[0], &outputs_[1])
1069 .c_str(),
1070 GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
1071 GetCrtcAction(outputs_[1], &small_mode_, gfx::Point(0, 0)).c_str(),
1072 kUngrab,
1073 NULL),
1074 log_->GetActionsAndClear());
1076 // The DisplayConfigurator should force a probe and reconfiguration at resume
1077 // time.
1078 UpdateOutputs(1, false);
1079 configurator_.ResumeDisplays();
1080 EXPECT_TRUE(test_api_.TriggerConfigureTimeout());
1081 EXPECT_EQ(
1082 JoinActions(
1083 kGrab,
1084 GetFramebufferAction(small_mode_.size(), &outputs_[0], NULL).c_str(),
1085 GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
1086 kForceDPMS,
1087 kUngrab,
1088 NULL),
1089 log_->GetActionsAndClear());
1091 // If a configuration task is pending when the displays are suspended, that
1092 // task should not run either and the timer should be stopped.
1093 configurator_.OnConfigurationChanged();
1094 configurator_.SuspendDisplays();
1095 EXPECT_EQ(kNoActions, log_->GetActionsAndClear());
1097 EXPECT_FALSE(test_api_.TriggerConfigureTimeout());
1098 EXPECT_EQ(kNoActions, log_->GetActionsAndClear());
1100 configurator_.ResumeDisplays();
1101 EXPECT_TRUE(test_api_.TriggerConfigureTimeout());
1102 EXPECT_EQ(
1103 JoinActions(
1104 kGrab,
1105 GetFramebufferAction(small_mode_.size(), &outputs_[0], NULL).c_str(),
1106 GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
1107 kForceDPMS,
1108 kUngrab,
1109 NULL),
1110 log_->GetActionsAndClear());
1113 TEST_F(DisplayConfiguratorTest, ContentProtectionTwoClients) {
1114 DisplayConfigurator::ContentProtectionClientId client1 =
1115 configurator_.RegisterContentProtectionClient();
1116 DisplayConfigurator::ContentProtectionClientId client2 =
1117 configurator_.RegisterContentProtectionClient();
1118 EXPECT_NE(client1, client2);
1120 configurator_.Init(false);
1121 configurator_.ForceInitialConfigure(0);
1122 UpdateOutputs(2, true);
1123 EXPECT_NE(kNoActions, log_->GetActionsAndClear());
1125 // Clients never know state enableness for methods that they didn't request.
1126 configurator_.EnableContentProtection(
1127 client1, outputs_[1].display_id(), CONTENT_PROTECTION_METHOD_HDCP,
1128 base::Bind(&DisplayConfiguratorTest::EnableContentProtectionCallback,
1129 base::Unretained(this)));
1130 EXPECT_EQ(1, enable_content_protection_call_count_);
1131 EXPECT_TRUE(enable_content_protection_status_);
1132 EXPECT_EQ(GetSetHDCPStateAction(outputs_[1], HDCP_STATE_DESIRED).c_str(),
1133 log_->GetActionsAndClear());
1134 native_display_delegate_->set_hdcp_state(HDCP_STATE_ENABLED);
1136 configurator_.QueryContentProtectionStatus(
1137 client1, outputs_[1].display_id(),
1138 base::Bind(&DisplayConfiguratorTest::QueryContentProtectionCallback,
1139 base::Unretained(this)));
1140 EXPECT_EQ(1, query_content_protection_call_count_);
1141 EXPECT_TRUE(query_content_protection_response_.success);
1142 EXPECT_EQ(static_cast<uint32_t>(DISPLAY_CONNECTION_TYPE_HDMI),
1143 query_content_protection_response_.link_mask);
1144 EXPECT_EQ(CONTENT_PROTECTION_METHOD_HDCP,
1145 query_content_protection_response_.protection_mask);
1147 configurator_.QueryContentProtectionStatus(
1148 client2, outputs_[1].display_id(),
1149 base::Bind(&DisplayConfiguratorTest::QueryContentProtectionCallback,
1150 base::Unretained(this)));
1151 EXPECT_EQ(2, query_content_protection_call_count_);
1152 EXPECT_TRUE(query_content_protection_response_.success);
1153 EXPECT_EQ(static_cast<uint32_t>(DISPLAY_CONNECTION_TYPE_HDMI),
1154 query_content_protection_response_.link_mask);
1155 EXPECT_EQ(CONTENT_PROTECTION_METHOD_NONE,
1156 query_content_protection_response_.protection_mask);
1158 // Protections will be disabled only if no more clients request them.
1159 configurator_.EnableContentProtection(
1160 client2, outputs_[1].display_id(), CONTENT_PROTECTION_METHOD_NONE,
1161 base::Bind(&DisplayConfiguratorTest::EnableContentProtectionCallback,
1162 base::Unretained(this)));
1163 EXPECT_EQ(2, enable_content_protection_call_count_);
1164 EXPECT_TRUE(enable_content_protection_status_);
1165 EXPECT_EQ(kNoActions, log_->GetActionsAndClear());
1167 configurator_.EnableContentProtection(
1168 client1, outputs_[1].display_id(), CONTENT_PROTECTION_METHOD_NONE,
1169 base::Bind(&DisplayConfiguratorTest::EnableContentProtectionCallback,
1170 base::Unretained(this)));
1171 EXPECT_EQ(3, enable_content_protection_call_count_);
1172 EXPECT_TRUE(enable_content_protection_status_);
1173 EXPECT_EQ(GetSetHDCPStateAction(outputs_[1], HDCP_STATE_UNDESIRED).c_str(),
1174 log_->GetActionsAndClear());
1177 TEST_F(DisplayConfiguratorTest, ContentProtectionTwoClientsEnable) {
1178 DisplayConfigurator::ContentProtectionClientId client1 =
1179 configurator_.RegisterContentProtectionClient();
1180 DisplayConfigurator::ContentProtectionClientId client2 =
1181 configurator_.RegisterContentProtectionClient();
1182 EXPECT_NE(client1, client2);
1184 configurator_.Init(false);
1185 configurator_.ForceInitialConfigure(0);
1186 UpdateOutputs(2, true);
1187 log_->GetActionsAndClear();
1189 // Only enable once if HDCP is enabling.
1190 configurator_.EnableContentProtection(
1191 client1, outputs_[1].display_id(), CONTENT_PROTECTION_METHOD_HDCP,
1192 base::Bind(&DisplayConfiguratorTest::EnableContentProtectionCallback,
1193 base::Unretained(this)));
1194 EXPECT_EQ(1, enable_content_protection_call_count_);
1195 EXPECT_TRUE(enable_content_protection_status_);
1196 native_display_delegate_->set_hdcp_state(HDCP_STATE_DESIRED);
1197 configurator_.EnableContentProtection(
1198 client2, outputs_[1].display_id(), CONTENT_PROTECTION_METHOD_HDCP,
1199 base::Bind(&DisplayConfiguratorTest::EnableContentProtectionCallback,
1200 base::Unretained(this)));
1201 EXPECT_EQ(2, enable_content_protection_call_count_);
1202 EXPECT_TRUE(enable_content_protection_status_);
1203 EXPECT_EQ(GetSetHDCPStateAction(outputs_[1], HDCP_STATE_DESIRED).c_str(),
1204 log_->GetActionsAndClear());
1205 native_display_delegate_->set_hdcp_state(HDCP_STATE_ENABLED);
1207 // Don't enable again if HDCP is already active.
1208 configurator_.EnableContentProtection(
1209 client1, outputs_[1].display_id(), CONTENT_PROTECTION_METHOD_HDCP,
1210 base::Bind(&DisplayConfiguratorTest::EnableContentProtectionCallback,
1211 base::Unretained(this)));
1212 EXPECT_EQ(3, enable_content_protection_call_count_);
1213 EXPECT_TRUE(enable_content_protection_status_);
1214 configurator_.EnableContentProtection(
1215 client2, outputs_[1].display_id(), CONTENT_PROTECTION_METHOD_HDCP,
1216 base::Bind(&DisplayConfiguratorTest::EnableContentProtectionCallback,
1217 base::Unretained(this)));
1218 EXPECT_EQ(4, enable_content_protection_call_count_);
1219 EXPECT_TRUE(enable_content_protection_status_);
1220 EXPECT_EQ(kNoActions, log_->GetActionsAndClear());
1223 TEST_F(DisplayConfiguratorTest, HandleConfigureCrtcFailure) {
1224 InitWithSingleOutput();
1226 ScopedVector<const DisplayMode> modes;
1227 // The first mode is the mode we are requesting DisplayConfigurator to choose.
1228 // The test will be setup so that this mode will fail and it will have to
1229 // choose the next best option.
1230 modes.push_back(new DisplayMode(gfx::Size(2560, 1600), false, 60.0));
1231 modes.push_back(new DisplayMode(gfx::Size(1024, 768), false, 60.0));
1232 modes.push_back(new DisplayMode(gfx::Size(1280, 720), false, 60.0));
1233 modes.push_back(new DisplayMode(gfx::Size(1920, 1080), false, 60.0));
1234 modes.push_back(new DisplayMode(gfx::Size(1920, 1080), false, 40.0));
1236 for (unsigned int i = 0; i < arraysize(outputs_); i++) {
1237 outputs_[i].set_modes(modes.get());
1238 outputs_[i].set_current_mode(modes[0]);
1239 outputs_[i].set_native_mode(modes[0]);
1242 // First test simply fails in MULTIPLE_DISPLAY_STATE_SINGLE mode. This is
1243 // probably unrealistic but we want to make sure any assumptions don't creep
1244 // in.
1245 native_display_delegate_->set_max_configurable_pixels(
1246 modes[2]->size().GetArea());
1247 state_controller_.set_state(MULTIPLE_DISPLAY_STATE_SINGLE);
1248 UpdateOutputs(1, true);
1250 EXPECT_EQ(
1251 JoinActions(
1252 kGrab,
1253 GetFramebufferAction(big_mode_.size(), &outputs_[0], NULL).c_str(),
1254 GetCrtcAction(outputs_[0], modes[0], gfx::Point(0, 0)).c_str(),
1255 GetCrtcAction(outputs_[0], modes[3], gfx::Point(0, 0)).c_str(),
1256 GetCrtcAction(outputs_[0], modes[2], gfx::Point(0, 0)).c_str(),
1257 kUngrab,
1258 NULL),
1259 log_->GetActionsAndClear());
1261 // This test should attempt to configure a mirror mode that will not succeed
1262 // and should end up in extended mode.
1263 native_display_delegate_->set_max_configurable_pixels(
1264 modes[3]->size().GetArea());
1265 state_controller_.set_state(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR);
1266 UpdateOutputs(2, true);
1268 EXPECT_EQ(
1269 JoinActions(
1270 kGrab, GetFramebufferAction(modes[0]->size(), &outputs_[0],
1271 &outputs_[1]).c_str(),
1272 GetCrtcAction(outputs_[0], modes[0], gfx::Point(0, 0)).c_str(),
1273 // Then attempt to configure crtc1 with the first mode.
1274 GetCrtcAction(outputs_[1], 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 GetCrtcAction(outputs_[1], modes[3], gfx::Point(0, 0)).c_str(),
1279 // Since it was requested to go into mirror mode
1280 // and the configured modes were different, it
1281 // should now try and setup a valid configurable
1282 // extended mode.
1283 GetFramebufferAction(
1284 gfx::Size(modes[0]->size().width(),
1285 modes[0]->size().height() + modes[0]->size().height() +
1286 DisplayConfigurator::kVerticalGap),
1287 &outputs_[0], &outputs_[1]).c_str(),
1288 GetCrtcAction(outputs_[0], modes[0], gfx::Point(0, 0)).c_str(),
1289 GetCrtcAction(outputs_[1], modes[0],
1290 gfx::Point(0, modes[0]->size().height() +
1291 DisplayConfigurator::kVerticalGap))
1292 .c_str(),
1293 GetCrtcAction(outputs_[0], modes[3], gfx::Point(0, 0)).c_str(),
1294 GetCrtcAction(outputs_[1], modes[3],
1295 gfx::Point(0, modes[0]->size().height() +
1296 DisplayConfigurator::kVerticalGap))
1297 .c_str(),
1298 kUngrab, NULL),
1299 log_->GetActionsAndClear());
1302 // Tests that power state requests are saved after failed configuration attempts
1303 // so they can be reused later: http://crosbug.com/p/31571
1304 TEST_F(DisplayConfiguratorTest, SaveDisplayPowerStateOnConfigFailure) {
1305 // Start out with two displays in extended mode.
1306 state_controller_.set_state(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED);
1307 configurator_.Init(false);
1308 configurator_.ForceInitialConfigure(0);
1309 log_->GetActionsAndClear();
1310 observer_.Reset();
1312 // Turn off the internal display, simulating docked mode.
1313 configurator_.SetDisplayPower(
1314 chromeos::DISPLAY_POWER_INTERNAL_OFF_EXTERNAL_ON,
1315 DisplayConfigurator::kSetDisplayPowerNoFlags,
1316 base::Bind(&DisplayConfiguratorTest::OnConfiguredCallback,
1317 base::Unretained(this)));
1318 EXPECT_EQ(CALLBACK_SUCCESS, PopCallbackResult());
1319 EXPECT_EQ(1, observer_.num_changes());
1320 EXPECT_EQ(0, observer_.num_failures());
1321 log_->GetActionsAndClear();
1323 // Make all subsequent configuration requests fail and try to turn the
1324 // internal display back on.
1325 native_display_delegate_->set_max_configurable_pixels(1);
1326 configurator_.SetDisplayPower(
1327 chromeos::DISPLAY_POWER_ALL_ON,
1328 DisplayConfigurator::kSetDisplayPowerNoFlags,
1329 base::Bind(&DisplayConfiguratorTest::OnConfiguredCallback,
1330 base::Unretained(this)));
1331 EXPECT_EQ(CALLBACK_FAILURE, PopCallbackResult());
1332 EXPECT_EQ(1, observer_.num_changes());
1333 EXPECT_EQ(1, observer_.num_failures());
1334 log_->GetActionsAndClear();
1336 // Simulate the external display getting disconnected and check that the
1337 // internal display is turned on (i.e. DISPLAY_POWER_ALL_ON is used) rather
1338 // than the earlier DISPLAY_POWER_INTERNAL_OFF_EXTERNAL_ON state.
1339 native_display_delegate_->set_max_configurable_pixels(0);
1340 UpdateOutputs(1, true);
1341 EXPECT_EQ(JoinActions(kGrab, GetFramebufferAction(small_mode_.size(),
1342 &outputs_[0], NULL).c_str(),
1343 GetCrtcAction(outputs_[0], &small_mode_,
1344 gfx::Point(0, 0)).c_str(),
1345 kForceDPMS, kUngrab, NULL),
1346 log_->GetActionsAndClear());
1349 // Tests that the SetDisplayPowerState() task posted by HandleResume() doesn't
1350 // use a stale state if a new state is requested before it runs:
1351 // http://crosbug.com/p/32393
1352 TEST_F(DisplayConfiguratorTest, DontRestoreStalePowerStateAfterResume) {
1353 // Start out with two displays in mirrored mode.
1354 state_controller_.set_state(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR);
1355 configurator_.Init(false);
1356 configurator_.ForceInitialConfigure(0);
1357 log_->GetActionsAndClear();
1358 observer_.Reset();
1360 // Turn off the internal display, simulating docked mode.
1361 configurator_.SetDisplayPower(
1362 chromeos::DISPLAY_POWER_INTERNAL_OFF_EXTERNAL_ON,
1363 DisplayConfigurator::kSetDisplayPowerNoFlags,
1364 base::Bind(&DisplayConfiguratorTest::OnConfiguredCallback,
1365 base::Unretained(this)));
1366 EXPECT_EQ(CALLBACK_SUCCESS, PopCallbackResult());
1367 EXPECT_EQ(1, observer_.num_changes());
1368 EXPECT_EQ(0, observer_.num_failures());
1369 EXPECT_EQ(
1370 JoinActions(
1371 kGrab,
1372 GetFramebufferAction(big_mode_.size(), &outputs_[0], &outputs_[1])
1373 .c_str(),
1374 GetCrtcAction(outputs_[0], NULL, gfx::Point(0, 0)).c_str(),
1375 GetCrtcAction(outputs_[1], &big_mode_, gfx::Point(0, 0)).c_str(),
1376 kForceDPMS,
1377 kUngrab,
1378 NULL),
1379 log_->GetActionsAndClear());
1381 // Suspend and resume the system. Resuming should post a task to restore the
1382 // previous power state, additionally forcing a probe.
1383 configurator_.SuspendDisplays();
1384 configurator_.ResumeDisplays();
1386 // Before the task runs, exit docked mode.
1387 configurator_.SetDisplayPower(
1388 chromeos::DISPLAY_POWER_ALL_ON,
1389 DisplayConfigurator::kSetDisplayPowerNoFlags,
1390 base::Bind(&DisplayConfiguratorTest::OnConfiguredCallback,
1391 base::Unretained(this)));
1392 EXPECT_EQ(CALLBACK_SUCCESS, PopCallbackResult());
1393 EXPECT_EQ(2, observer_.num_changes());
1394 EXPECT_EQ(0, observer_.num_failures());
1395 EXPECT_EQ(
1396 JoinActions(
1397 kGrab,
1398 GetFramebufferAction(small_mode_.size(), &outputs_[0], &outputs_[1])
1399 .c_str(),
1400 GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
1401 GetCrtcAction(outputs_[1], &small_mode_, gfx::Point(0, 0)).c_str(),
1402 kForceDPMS,
1403 kUngrab,
1404 NULL),
1405 log_->GetActionsAndClear());
1407 // Check that the task doesn't restore the old internal-off-external-on power
1408 // state.
1409 EXPECT_TRUE(test_api_.TriggerConfigureTimeout());
1410 EXPECT_EQ(
1411 JoinActions(
1412 kGrab,
1413 GetFramebufferAction(small_mode_.size(), &outputs_[0], &outputs_[1])
1414 .c_str(),
1415 GetCrtcAction(outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(),
1416 GetCrtcAction(outputs_[1], &small_mode_, gfx::Point(0, 0)).c_str(),
1417 kForceDPMS,
1418 kUngrab,
1419 NULL),
1420 log_->GetActionsAndClear());
1423 TEST_F(DisplayConfiguratorTest, ExternalControl) {
1424 InitWithSingleOutput();
1425 state_controller_.set_state(MULTIPLE_DISPLAY_STATE_SINGLE);
1426 configurator_.RelinquishControl();
1427 EXPECT_EQ(
1428 JoinActions(
1429 kRelinquishDisplayControl,
1430 NULL),
1431 log_->GetActionsAndClear());
1432 configurator_.TakeControl();
1433 EXPECT_EQ(JoinActions(kTakeDisplayControl, kGrab,
1434 GetFramebufferAction(small_mode_.size(), &outputs_[0],
1435 nullptr).c_str(),
1436 GetCrtcAction(outputs_[0], &small_mode_,
1437 gfx::Point(0, 0)).c_str(),
1438 kUngrab, NULL),
1439 log_->GetActionsAndClear());
1442 } // namespace test
1443 } // namespace ui