diff --git a/ui/display/chromeos/update_display_configuration_task.cc b/ui/display/chromeos/update_display_configuration_task.cc index 7b254fc1e7c4f..33ac1feb526e0 100644 --- a/ui/display/chromeos/update_display_configuration_task.cc +++ b/ui/display/chromeos/update_display_configuration_task.cc @@ -111,7 +111,8 @@ void UpdateDisplayConfigurationTask::OnStateEntered( if (!success && new_display_state_ == MULTIPLE_DISPLAY_STATE_DUAL_MIRROR) { if (layout_manager_->GetDisplayState() != MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED || - layout_manager_->GetPowerState() != new_power_state_) { + layout_manager_->GetPowerState() != new_power_state_ || + force_configure_) { new_display_state_ = MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED; EnterState(base::Bind( &UpdateDisplayConfigurationTask::OnEnableSoftwareMirroring, diff --git a/ui/display/chromeos/update_display_configuration_task_unittest.cc b/ui/display/chromeos/update_display_configuration_task_unittest.cc index b2904c730f614..0abb9f12620b0 100644 --- a/ui/display/chromeos/update_display_configuration_task_unittest.cc +++ b/ui/display/chromeos/update_display_configuration_task_unittest.cc @@ -17,6 +17,22 @@ namespace test { namespace { +class TestSoftwareMirroringController + : public DisplayConfigurator::SoftwareMirroringController { + public: + TestSoftwareMirroringController() : is_enabled_(false) {} + ~TestSoftwareMirroringController() override {} + + // DisplayConfigurator::SoftwareMirroringController: + void SetSoftwareMirroring(bool enabled) override { is_enabled_ = enabled; } + bool SoftwareMirroringEnabled() const override { return is_enabled_; } + + private: + bool is_enabled_; + + DISALLOW_COPY_AND_ASSIGN(TestSoftwareMirroringController); +}; + class TestDisplayLayoutManager : public DisplayLayoutManager { public: TestDisplayLayoutManager() @@ -33,10 +49,16 @@ class TestDisplayLayoutManager : public DisplayLayoutManager { power_state_ = state; } + void set_software_mirroring_controller( + scoped_ptr + software_mirroring_controller) { + software_mirroring_controller_ = software_mirroring_controller.Pass(); + } + // DisplayConfigurator::DisplayLayoutManager: DisplayConfigurator::SoftwareMirroringController* GetSoftwareMirroringController() const override { - return nullptr; + return software_mirroring_controller_.get(); } DisplayConfigurator::StateController* GetStateController() const override { @@ -109,6 +131,9 @@ class TestDisplayLayoutManager : public DisplayLayoutManager { chromeos::DisplayPowerState power_state_; + scoped_ptr + software_mirroring_controller_; + DISALLOW_COPY_AND_ASSIGN(TestDisplayLayoutManager); }; @@ -371,5 +396,82 @@ TEST_F(UpdateDisplayConfigurationTaskTest, SingleChangePowerConfiguration) { log_.GetActionsAndClear()); } +TEST_F(UpdateDisplayConfigurationTaskTest, NoopSoftwareMirrorConfiguration) { + layout_manager_.set_should_mirror(false); + layout_manager_.set_software_mirroring_controller( + make_scoped_ptr(new TestSoftwareMirroringController())); + UpdateDisplays(2); + + { + UpdateDisplayConfigurationTask task( + &delegate_, &layout_manager_, MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED, + chromeos::DISPLAY_POWER_ALL_ON, 0, 0, false, + base::Bind(&UpdateDisplayConfigurationTaskTest::ResponseCallback, + base::Unretained(this))); + task.Run(); + } + + log_.GetActionsAndClear(); + + { + UpdateDisplayConfigurationTask task( + &delegate_, &layout_manager_, MULTIPLE_DISPLAY_STATE_DUAL_MIRROR, + chromeos::DISPLAY_POWER_ALL_ON, 0, 0, false, + base::Bind(&UpdateDisplayConfigurationTaskTest::ResponseCallback, + base::Unretained(this))); + task.Run(); + } + + EXPECT_TRUE(configuration_status_); + EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED, display_state_); + EXPECT_TRUE(layout_manager_.GetSoftwareMirroringController() + ->SoftwareMirroringEnabled()); + EXPECT_EQ(JoinActions(kGrab, kUngrab, NULL), log_.GetActionsAndClear()); +} + +TEST_F(UpdateDisplayConfigurationTaskTest, + ForceConfigurationWhileGoingToSoftwareMirror) { + layout_manager_.set_should_mirror(false); + layout_manager_.set_software_mirroring_controller( + make_scoped_ptr(new TestSoftwareMirroringController())); + UpdateDisplays(2); + + { + UpdateDisplayConfigurationTask task( + &delegate_, &layout_manager_, MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED, + chromeos::DISPLAY_POWER_ALL_ON, 0, 0, false, + base::Bind(&UpdateDisplayConfigurationTaskTest::ResponseCallback, + base::Unretained(this))); + task.Run(); + } + + log_.GetActionsAndClear(); + + { + UpdateDisplayConfigurationTask task( + &delegate_, &layout_manager_, MULTIPLE_DISPLAY_STATE_DUAL_MIRROR, + chromeos::DISPLAY_POWER_ALL_ON, 0, 0, true /* force_configure */, + base::Bind(&UpdateDisplayConfigurationTaskTest::ResponseCallback, + base::Unretained(this))); + task.Run(); + } + + EXPECT_TRUE(configuration_status_); + EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED, display_state_); + EXPECT_TRUE(layout_manager_.GetSoftwareMirroringController() + ->SoftwareMirroringEnabled()); + EXPECT_EQ( + JoinActions( + kGrab, GetFramebufferAction(gfx::Size(big_mode_.size().width(), + small_mode_.size().height() + + big_mode_.size().height()), + &displays_[0], &displays_[1]).c_str(), + GetCrtcAction(displays_[0], &small_mode_, gfx::Point()).c_str(), + GetCrtcAction(displays_[1], &big_mode_, + gfx::Point(0, small_mode_.size().height())).c_str(), + kUngrab, NULL), + log_.GetActionsAndClear()); +} + } // namespace test } // namespace ui