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