Chromium Code Reviews| Index: ui/display/chromeos/display_configurator_unittest.cc |
| diff --git a/ui/display/chromeos/display_configurator_unittest.cc b/ui/display/chromeos/display_configurator_unittest.cc |
| index 394533d7c2e26af543a467df62a6e98ffa8f952b..8264025c6cf64641b3ebea17c43224bc927bacba 100644 |
| --- a/ui/display/chromeos/display_configurator_unittest.cc |
| +++ b/ui/display/chromeos/display_configurator_unittest.cc |
| @@ -33,6 +33,20 @@ std::unique_ptr<ui::DisplayMode> MakeDisplayMode(int width, |
| is_interlaced, refresh_rate); |
| } |
| +enum CallbackResult { |
| + CALLBACK_FAILURE, |
| + CALLBACK_SUCCESS, |
| + CALLBACK_NOT_CALLED, |
| +}; |
| + |
| +// Expected immediate configurations should be done without any delays. |
| +constexpr base::TimeDelta kNoDelay = base::TimeDelta::FromMilliseconds(0); |
| + |
| +// The expected configuration delay when resuming from suspend while in 2+ |
| +// display mode. |
| +constexpr base::TimeDelta kLongDelayMs = base::TimeDelta::FromMilliseconds( |
|
Daniel Erat
2016/10/31 18:25:46
nit: rename to 'kLongDelay' (sorry, i gave a bad s
afakhry
2016/10/31 21:20:14
Done.
|
| + DisplayConfigurator::kResumeConfigureMultiDisplayDelayMs); |
| + |
| class TestObserver : public DisplayConfigurator::Observer { |
| public: |
| explicit TestObserver(DisplayConfigurator* configurator) |
| @@ -129,23 +143,74 @@ class TestMirroringController |
| DISALLOW_COPY_AND_ASSIGN(TestMirroringController); |
| }; |
| -class DisplayConfiguratorTest : public testing::Test { |
| +// Abstracts waiting for the display configuration to be completed and getting |
| +// the time it took to complete. |
| +class ConfigurationWaiter { |
| public: |
| - enum CallbackResult { |
| - CALLBACK_FAILURE, |
| - CALLBACK_SUCCESS, |
| - CALLBACK_NOT_CALLED, |
| - }; |
| + ConfigurationWaiter(DisplayConfigurator::TestApi* test_api) |
| + : on_configured_callback_(base::Bind(&ConfigurationWaiter::OnConfigured, |
| + base::Unretained(this))), |
| + test_api_(test_api), |
| + callback_result_(CALLBACK_NOT_CALLED) {} |
| + |
| + ~ConfigurationWaiter() = default; |
| + |
| + const DisplayConfigurator::ConfigurationCallback& on_configuration_callback() |
| + const { |
| + return on_configured_callback_; |
| + } |
| + |
| + CallbackResult callback_result() const { return callback_result_; } |
| + |
| + void Reset() { |
| + callback_result_ = CALLBACK_NOT_CALLED; |
| + } |
| + |
| + // Simulates waiting for the next configuration. If an async task is pending, |
| + // runs it and returns base::TimeDelta(). Otherwise, triggers the |
| + // configuration timer and returns its delay. If the timer wasn't running, |
| + // returns base::TimeDelta::Max(). |
| + base::TimeDelta Wait() WARN_UNUSED_RESULT { |
| + base::RunLoop().RunUntilIdle(); |
| + if (callback_result_ != CALLBACK_NOT_CALLED) |
| + return base::TimeDelta(); |
| + const base::TimeDelta delay = test_api_->GetConfigureDelay(); |
| + if (!test_api_->TriggerConfigureTimeout()) |
| + return base::TimeDelta::Max(); |
| + |
| + return delay; |
| + } |
| + |
| + private: |
| + void OnConfigured(bool status) { |
|
Daniel Erat
2016/10/31 18:25:46
is it possible to CHECK_EQ(callback_result_, CALLB
afakhry
2016/10/31 21:20:14
Done.
|
| + callback_result_ = status ? CALLBACK_SUCCESS : CALLBACK_FAILURE; |
| + } |
| + |
| + // The callback that should be used with the DisplayConfigurator calls to be |
| + // invoked with the display configuration is done. It will always execute this |
| + // waiter's OnConfigured(). |
|
Daniel Erat
2016/10/31 18:25:46
nit: maybe simplify to "Passed with configuration
afakhry
2016/10/31 21:20:14
Done.
|
| + const DisplayConfigurator::ConfigurationCallback on_configured_callback_; |
| + |
| + DisplayConfigurator::TestApi* test_api_; // Not owned. |
| + |
| + // The status of the display configuration. |
| + CallbackResult callback_result_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(ConfigurationWaiter); |
| +}; |
| + |
| +class DisplayConfiguratorTest : public testing::Test { |
| + public: |
| DisplayConfiguratorTest() |
| : small_mode_(gfx::Size(1366, 768), false, 60.0f), |
| big_mode_(gfx::Size(2560, 1600), false, 60.0f), |
| observer_(&configurator_), |
| test_api_(&configurator_), |
| + config_waiter_(&test_api_), |
| enable_content_protection_status_(0), |
| enable_content_protection_call_count_(0), |
| query_content_protection_call_count_(0), |
| - callback_result_(CALLBACK_NOT_CALLED), |
| display_control_result_(CALLBACK_NOT_CALLED) {} |
| ~DisplayConfiguratorTest() override {} |
| @@ -187,10 +252,6 @@ class DisplayConfiguratorTest : public testing::Test { |
| UpdateOutputs(2, false); |
| } |
| - void OnConfiguredCallback(bool status) { |
| - callback_result_ = (status ? CALLBACK_SUCCESS : CALLBACK_FAILURE); |
| - } |
| - |
| void OnDisplayControlUpdated(bool status) { |
| display_control_result_ = (status ? CALLBACK_SUCCESS : CALLBACK_FAILURE); |
| } |
| @@ -251,12 +312,6 @@ class DisplayConfiguratorTest : public testing::Test { |
| log_->GetActionsAndClear()); |
| } |
| - CallbackResult PopCallbackResult() { |
| - CallbackResult result = callback_result_; |
| - callback_result_ = CALLBACK_NOT_CALLED; |
| - return result; |
| - } |
| - |
| CallbackResult PopDisplayControlResult() { |
| CallbackResult result = display_control_result_; |
| display_control_result_ = CALLBACK_NOT_CALLED; |
| @@ -271,7 +326,7 @@ class DisplayConfiguratorTest : public testing::Test { |
| std::unique_ptr<ActionLogger> log_; |
| TestNativeDisplayDelegate* native_display_delegate_; // not owned |
| DisplayConfigurator::TestApi test_api_; |
| - |
| + ConfigurationWaiter config_waiter_; |
| bool enable_content_protection_status_; |
| int enable_content_protection_call_count_; |
| DisplayConfigurator::QueryProtectionResponse |
| @@ -280,7 +335,6 @@ class DisplayConfiguratorTest : public testing::Test { |
| std::unique_ptr<DisplaySnapshot> outputs_[3]; |
| - CallbackResult callback_result_; |
| CallbackResult display_control_result_; |
| private: |
| @@ -657,12 +711,13 @@ TEST_F(DisplayConfiguratorTest, SetDisplayPower) { |
| // Turning off the internal display should switch the external display to |
| // its native mode. |
| observer_.Reset(); |
| + config_waiter_.Reset(); |
| configurator_.SetDisplayPower( |
| chromeos::DISPLAY_POWER_INTERNAL_OFF_EXTERNAL_ON, |
| DisplayConfigurator::kSetDisplayPowerNoFlags, |
| - base::Bind(&DisplayConfiguratorTest::OnConfiguredCallback, |
| - base::Unretained(this))); |
| - EXPECT_EQ(CALLBACK_SUCCESS, PopCallbackResult()); |
| + config_waiter_.on_configuration_callback()); |
|
Daniel Erat
2016/10/31 18:25:46
i'm not sure if it applies to this particular test
afakhry
2016/10/31 21:20:14
We have a similar check in line 1780 of this file:
|
| + EXPECT_EQ(kNoDelay, config_waiter_.Wait()); |
| + EXPECT_EQ(CALLBACK_SUCCESS, config_waiter_.callback_result()); |
| EXPECT_EQ( |
| JoinActions( |
| kGrab, GetFramebufferAction(big_mode_.size(), outputs_[0].get(), |
| @@ -678,12 +733,12 @@ TEST_F(DisplayConfiguratorTest, SetDisplayPower) { |
| // When all displays are turned off, the framebuffer should switch back |
| // to the mirrored size. |
| observer_.Reset(); |
| - configurator_.SetDisplayPower( |
| - chromeos::DISPLAY_POWER_ALL_OFF, |
| - DisplayConfigurator::kSetDisplayPowerNoFlags, |
| - base::Bind(&DisplayConfiguratorTest::OnConfiguredCallback, |
| - base::Unretained(this))); |
| - EXPECT_EQ(CALLBACK_SUCCESS, PopCallbackResult()); |
| + config_waiter_.Reset(); |
| + configurator_.SetDisplayPower(chromeos::DISPLAY_POWER_ALL_OFF, |
| + DisplayConfigurator::kSetDisplayPowerNoFlags, |
| + config_waiter_.on_configuration_callback()); |
| + EXPECT_EQ(kNoDelay, config_waiter_.Wait()); |
| + EXPECT_EQ(CALLBACK_SUCCESS, config_waiter_.callback_result()); |
| EXPECT_EQ( |
| JoinActions( |
| kGrab, GetFramebufferAction(small_mode_.size(), outputs_[0].get(), |
| @@ -699,12 +754,12 @@ TEST_F(DisplayConfiguratorTest, SetDisplayPower) { |
| // Turn all displays on and check that mirroring is still used. |
| observer_.Reset(); |
| - configurator_.SetDisplayPower( |
| - chromeos::DISPLAY_POWER_ALL_ON, |
| - DisplayConfigurator::kSetDisplayPowerNoFlags, |
| - base::Bind(&DisplayConfiguratorTest::OnConfiguredCallback, |
| - base::Unretained(this))); |
| - EXPECT_EQ(CALLBACK_SUCCESS, PopCallbackResult()); |
| + config_waiter_.Reset(); |
| + configurator_.SetDisplayPower(chromeos::DISPLAY_POWER_ALL_ON, |
| + DisplayConfigurator::kSetDisplayPowerNoFlags, |
| + config_waiter_.on_configuration_callback()); |
| + EXPECT_EQ(kNoDelay, config_waiter_.Wait()); |
| + EXPECT_EQ(CALLBACK_SUCCESS, config_waiter_.callback_result()); |
| EXPECT_EQ( |
| JoinActions( |
| kGrab, GetFramebufferAction(small_mode_.size(), outputs_[0].get(), |
| @@ -754,12 +809,13 @@ TEST_F(DisplayConfiguratorTest, SetDisplayPower) { |
| // Turning off the internal display should switch the external display to |
| // its native mode. |
| observer_.Reset(); |
| + config_waiter_.Reset(); |
| configurator_.SetDisplayPower( |
| chromeos::DISPLAY_POWER_INTERNAL_OFF_EXTERNAL_ON, |
| DisplayConfigurator::kSetDisplayPowerNoFlags, |
| - base::Bind(&DisplayConfiguratorTest::OnConfiguredCallback, |
| - base::Unretained(this))); |
| - EXPECT_EQ(CALLBACK_SUCCESS, PopCallbackResult()); |
| + config_waiter_.on_configuration_callback()); |
| + EXPECT_EQ(kNoDelay, config_waiter_.Wait()); |
| + EXPECT_EQ(CALLBACK_SUCCESS, config_waiter_.callback_result()); |
| EXPECT_EQ( |
| JoinActions( |
| kGrab, GetFramebufferAction(big_mode_.size(), outputs_[0].get(), |
| @@ -776,12 +832,12 @@ TEST_F(DisplayConfiguratorTest, SetDisplayPower) { |
| // When all displays are turned off, the framebuffer should switch back |
| // to the extended + software mirroring. |
| observer_.Reset(); |
| - configurator_.SetDisplayPower( |
| - chromeos::DISPLAY_POWER_ALL_OFF, |
| - DisplayConfigurator::kSetDisplayPowerNoFlags, |
| - base::Bind(&DisplayConfiguratorTest::OnConfiguredCallback, |
| - base::Unretained(this))); |
| - EXPECT_EQ(CALLBACK_SUCCESS, PopCallbackResult()); |
| + config_waiter_.Reset(); |
| + configurator_.SetDisplayPower(chromeos::DISPLAY_POWER_ALL_OFF, |
| + DisplayConfigurator::kSetDisplayPowerNoFlags, |
| + config_waiter_.on_configuration_callback()); |
| + EXPECT_EQ(kNoDelay, config_waiter_.Wait()); |
| + EXPECT_EQ(CALLBACK_SUCCESS, config_waiter_.callback_result()); |
| EXPECT_EQ( |
| JoinActions( |
| kGrab, |
| @@ -802,12 +858,12 @@ TEST_F(DisplayConfiguratorTest, SetDisplayPower) { |
| // Turn all displays on and check that mirroring is still used. |
| observer_.Reset(); |
| - configurator_.SetDisplayPower( |
| - chromeos::DISPLAY_POWER_ALL_ON, |
| - DisplayConfigurator::kSetDisplayPowerNoFlags, |
| - base::Bind(&DisplayConfiguratorTest::OnConfiguredCallback, |
| - base::Unretained(this))); |
| - EXPECT_EQ(CALLBACK_SUCCESS, PopCallbackResult()); |
| + config_waiter_.Reset(); |
| + configurator_.SetDisplayPower(chromeos::DISPLAY_POWER_ALL_ON, |
| + DisplayConfigurator::kSetDisplayPowerNoFlags, |
| + config_waiter_.on_configuration_callback()); |
| + EXPECT_EQ(kNoDelay, config_waiter_.Wait()); |
| + EXPECT_EQ(CALLBACK_SUCCESS, config_waiter_.callback_result()); |
| EXPECT_EQ( |
| JoinActions( |
| kGrab, |
| @@ -835,9 +891,10 @@ TEST_F(DisplayConfiguratorTest, SuspendAndResume) { |
| // was connected while suspended. |
| const gfx::Size framebuffer_size = configurator_.framebuffer_size(); |
| DCHECK(!framebuffer_size.IsEmpty()); |
| - configurator_.SuspendDisplays(base::Bind( |
| - &DisplayConfiguratorTest::OnConfiguredCallback, base::Unretained(this))); |
| - EXPECT_EQ(CALLBACK_SUCCESS, PopCallbackResult()); |
| + config_waiter_.Reset(); |
| + configurator_.SuspendDisplays(config_waiter_.on_configuration_callback()); |
| + EXPECT_EQ(kNoDelay, config_waiter_.Wait()); |
| + EXPECT_EQ(CALLBACK_SUCCESS, config_waiter_.callback_result()); |
| EXPECT_EQ(framebuffer_size.ToString(), |
| configurator_.framebuffer_size().ToString()); |
| EXPECT_EQ(JoinActions( |
| @@ -847,7 +904,12 @@ TEST_F(DisplayConfiguratorTest, SuspendAndResume) { |
| GetCrtcAction(*outputs_[0], nullptr, gfx::Point(0, 0)).c_str(), |
| kUngrab, kSync, nullptr), |
| log_->GetActionsAndClear()); |
| + |
| + // No resume delay in single display mode. |
| + config_waiter_.Reset(); |
| configurator_.ResumeDisplays(); |
| + // The timer should not be running. |
| + EXPECT_EQ(base::TimeDelta::Max(), config_waiter_.Wait()); |
| EXPECT_EQ( |
| JoinActions( |
| kGrab, |
| @@ -859,12 +921,12 @@ TEST_F(DisplayConfiguratorTest, SuspendAndResume) { |
| // Now turn the display off before suspending and check that the |
| // configurator turns it back on and syncs with the server. |
| - configurator_.SetDisplayPower( |
| - chromeos::DISPLAY_POWER_ALL_OFF, |
| - DisplayConfigurator::kSetDisplayPowerNoFlags, |
| - base::Bind(&DisplayConfiguratorTest::OnConfiguredCallback, |
| - base::Unretained(this))); |
| - EXPECT_EQ(CALLBACK_SUCCESS, PopCallbackResult()); |
| + config_waiter_.Reset(); |
| + configurator_.SetDisplayPower(chromeos::DISPLAY_POWER_ALL_OFF, |
| + DisplayConfigurator::kSetDisplayPowerNoFlags, |
| + config_waiter_.on_configuration_callback()); |
| + EXPECT_EQ(kNoDelay, config_waiter_.Wait()); |
| + EXPECT_EQ(CALLBACK_SUCCESS, config_waiter_.callback_result()); |
| EXPECT_EQ(JoinActions( |
| kGrab, GetFramebufferAction(small_mode_.size(), |
| outputs_[0].get(), nullptr) |
| @@ -873,19 +935,24 @@ TEST_F(DisplayConfiguratorTest, SuspendAndResume) { |
| kUngrab, nullptr), |
| log_->GetActionsAndClear()); |
| - configurator_.SuspendDisplays(base::Bind( |
| - &DisplayConfiguratorTest::OnConfiguredCallback, base::Unretained(this))); |
| - EXPECT_EQ(CALLBACK_SUCCESS, PopCallbackResult()); |
| + config_waiter_.Reset(); |
| + configurator_.SuspendDisplays(config_waiter_.on_configuration_callback()); |
| + EXPECT_EQ(kNoDelay, config_waiter_.Wait()); |
| + EXPECT_EQ(CALLBACK_SUCCESS, config_waiter_.callback_result()); |
| EXPECT_EQ(kSync, log_->GetActionsAndClear()); |
| + config_waiter_.Reset(); |
| configurator_.ResumeDisplays(); |
| + // The timer should not be running. |
| + EXPECT_EQ(base::TimeDelta::Max(), config_waiter_.Wait()); |
| EXPECT_EQ(kNoActions, log_->GetActionsAndClear()); |
| - configurator_.SetDisplayPower( |
| - chromeos::DISPLAY_POWER_ALL_ON, |
| - DisplayConfigurator::kSetDisplayPowerNoFlags, |
| - base::Bind(&DisplayConfiguratorTest::OnConfiguredCallback, |
| - base::Unretained(this))); |
| + config_waiter_.Reset(); |
| + configurator_.SetDisplayPower(chromeos::DISPLAY_POWER_ALL_ON, |
| + DisplayConfigurator::kSetDisplayPowerNoFlags, |
| + config_waiter_.on_configuration_callback()); |
| + EXPECT_EQ(kNoDelay, config_waiter_.Wait()); |
| + EXPECT_EQ(CALLBACK_SUCCESS, config_waiter_.callback_result()); |
| EXPECT_EQ( |
| JoinActions( |
| kGrab, |
| @@ -907,12 +974,13 @@ TEST_F(DisplayConfiguratorTest, SuspendAndResume) { |
| kUngrab, nullptr), |
| log_->GetActionsAndClear()); |
| - configurator_.SetDisplayPower( |
| - chromeos::DISPLAY_POWER_ALL_OFF, |
| - DisplayConfigurator::kSetDisplayPowerNoFlags, |
| - base::Bind(&DisplayConfiguratorTest::OnConfiguredCallback, |
| - base::Unretained(this))); |
| - EXPECT_EQ(CALLBACK_SUCCESS, PopCallbackResult()); |
| + config_waiter_.Reset(); |
| + configurator_.SetDisplayPower(chromeos::DISPLAY_POWER_ALL_OFF, |
| + DisplayConfigurator::kSetDisplayPowerNoFlags, |
| + config_waiter_.on_configuration_callback()); |
| + EXPECT_EQ(kNoDelay, config_waiter_.Wait()); |
| + EXPECT_EQ(CALLBACK_SUCCESS, config_waiter_.callback_result()); |
| + EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR, configurator_.display_state()); |
| EXPECT_EQ( |
| JoinActions( |
| kGrab, GetFramebufferAction(small_mode_.size(), outputs_[0].get(), |
| @@ -923,22 +991,33 @@ TEST_F(DisplayConfiguratorTest, SuspendAndResume) { |
| kUngrab, nullptr), |
| log_->GetActionsAndClear()); |
| - configurator_.SuspendDisplays(base::Bind( |
| - &DisplayConfiguratorTest::OnConfiguredCallback, base::Unretained(this))); |
| - EXPECT_EQ(CALLBACK_SUCCESS, PopCallbackResult()); |
| + // No delay in suspend. |
| + config_waiter_.Reset(); |
| + configurator_.SuspendDisplays(config_waiter_.on_configuration_callback()); |
| + EXPECT_EQ(kNoDelay, config_waiter_.Wait()); |
| + EXPECT_EQ(CALLBACK_SUCCESS, config_waiter_.callback_result()); |
| + EXPECT_EQ(chromeos::DISPLAY_POWER_ALL_OFF, |
| + configurator_.current_power_state()); |
| + EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_MIRROR, configurator_.display_state()); |
| EXPECT_EQ(kSync, log_->GetActionsAndClear()); |
| // If a display is disconnected while suspended, the configurator should |
| - // pick up the change and only turn on the internal display. |
| + // pick up the change and only turn on the internal display. The should be |
| + // a longer configuration delay when we set the displays back to on. |
| UpdateOutputs(1, false); |
| + config_waiter_.Reset(); |
| configurator_.ResumeDisplays(); |
| + // Since we were in dual display mirror mode before suspend, the timer should |
| + // be running with kMinLongDelayMs. |
| + EXPECT_EQ(kLongDelayMs, test_api_.GetConfigureDelay()); |
| EXPECT_EQ(kNoActions, log_->GetActionsAndClear()); |
| - configurator_.SetDisplayPower( |
| - chromeos::DISPLAY_POWER_ALL_ON, |
| - DisplayConfigurator::kSetDisplayPowerNoFlags, |
| - base::Bind(&DisplayConfiguratorTest::OnConfiguredCallback, |
| - base::Unretained(this))); |
| + config_waiter_.Reset(); |
| + configurator_.SetDisplayPower(chromeos::DISPLAY_POWER_ALL_ON, |
| + DisplayConfigurator::kSetDisplayPowerNoFlags, |
| + config_waiter_.on_configuration_callback()); |
| + EXPECT_EQ(kLongDelayMs, config_waiter_.Wait()); |
| + EXPECT_EQ(CALLBACK_SUCCESS, config_waiter_.callback_result()); |
| EXPECT_EQ( |
| JoinActions( |
| kGrab, |
| @@ -960,19 +1039,19 @@ TEST_F(DisplayConfiguratorTest, Headless) { |
| // Not much should happen when the display power state is changed while |
| // no displays are connected. |
| - configurator_.SetDisplayPower( |
| - chromeos::DISPLAY_POWER_ALL_OFF, |
| - DisplayConfigurator::kSetDisplayPowerNoFlags, |
| - base::Bind(&DisplayConfiguratorTest::OnConfiguredCallback, |
| - base::Unretained(this))); |
| - EXPECT_EQ(CALLBACK_SUCCESS, PopCallbackResult()); |
| + config_waiter_.Reset(); |
| + configurator_.SetDisplayPower(chromeos::DISPLAY_POWER_ALL_OFF, |
| + DisplayConfigurator::kSetDisplayPowerNoFlags, |
| + config_waiter_.on_configuration_callback()); |
| + EXPECT_EQ(kNoDelay, config_waiter_.Wait()); |
| + EXPECT_EQ(CALLBACK_SUCCESS, config_waiter_.callback_result()); |
| EXPECT_EQ(JoinActions(kGrab, kUngrab, nullptr), log_->GetActionsAndClear()); |
| - configurator_.SetDisplayPower( |
| - chromeos::DISPLAY_POWER_ALL_ON, |
| - DisplayConfigurator::kSetDisplayPowerNoFlags, |
| - base::Bind(&DisplayConfiguratorTest::OnConfiguredCallback, |
| - base::Unretained(this))); |
| - EXPECT_EQ(CALLBACK_SUCCESS, PopCallbackResult()); |
| + config_waiter_.Reset(); |
| + configurator_.SetDisplayPower(chromeos::DISPLAY_POWER_ALL_ON, |
| + DisplayConfigurator::kSetDisplayPowerNoFlags, |
| + config_waiter_.on_configuration_callback()); |
| + EXPECT_EQ(kNoDelay, config_waiter_.Wait()); |
| + EXPECT_EQ(CALLBACK_SUCCESS, config_waiter_.callback_result()); |
| EXPECT_EQ(JoinActions(kGrab, kForceDPMS, kUngrab, nullptr), |
| log_->GetActionsAndClear()); |
| @@ -1216,9 +1295,10 @@ TEST_F(DisplayConfiguratorTest, DoNotConfigureWithSuspendedDisplays) { |
| // after the displays have been suspended. This event should be ignored since |
| // the DisplayConfigurator will force a probe and reconfiguration of displays |
| // at resume time. |
| - configurator_.SuspendDisplays(base::Bind( |
| - &DisplayConfiguratorTest::OnConfiguredCallback, base::Unretained(this))); |
| - EXPECT_EQ(CALLBACK_SUCCESS, PopCallbackResult()); |
| + config_waiter_.Reset(); |
| + configurator_.SuspendDisplays(config_waiter_.on_configuration_callback()); |
| + EXPECT_EQ(kNoDelay, config_waiter_.Wait()); |
| + EXPECT_EQ(CALLBACK_SUCCESS, config_waiter_.callback_result()); |
| EXPECT_EQ(JoinActions( |
| kGrab, GetFramebufferAction(small_mode_.size(), |
| outputs_[0].get(), nullptr) |
| @@ -1235,19 +1315,19 @@ TEST_F(DisplayConfiguratorTest, DoNotConfigureWithSuspendedDisplays) { |
| // Calls to SetDisplayPower should do nothing if the power state doesn't |
| // change. |
| - configurator_.SetDisplayPower( |
| - chromeos::DISPLAY_POWER_ALL_OFF, |
| - DisplayConfigurator::kSetDisplayPowerNoFlags, |
| - base::Bind(&DisplayConfiguratorTest::OnConfiguredCallback, |
| - base::Unretained(this))); |
| - EXPECT_EQ(CALLBACK_SUCCESS, PopCallbackResult()); |
| + config_waiter_.Reset(); |
| + configurator_.SetDisplayPower(chromeos::DISPLAY_POWER_ALL_OFF, |
| + DisplayConfigurator::kSetDisplayPowerNoFlags, |
| + config_waiter_.on_configuration_callback()); |
| + EXPECT_EQ(kNoDelay, config_waiter_.Wait()); |
| + EXPECT_EQ(CALLBACK_SUCCESS, config_waiter_.callback_result()); |
| EXPECT_EQ(kNoActions, log_->GetActionsAndClear()); |
| - configurator_.SetDisplayPower( |
| - chromeos::DISPLAY_POWER_ALL_ON, |
| - DisplayConfigurator::kSetDisplayPowerNoFlags, |
| - base::Bind(&DisplayConfiguratorTest::OnConfiguredCallback, |
| - base::Unretained(this))); |
| - EXPECT_EQ(CALLBACK_SUCCESS, PopCallbackResult()); |
| + config_waiter_.Reset(); |
| + configurator_.SetDisplayPower(chromeos::DISPLAY_POWER_ALL_ON, |
| + DisplayConfigurator::kSetDisplayPowerNoFlags, |
| + config_waiter_.on_configuration_callback()); |
| + EXPECT_EQ(kNoDelay, config_waiter_.Wait()); |
| + EXPECT_EQ(CALLBACK_SUCCESS, config_waiter_.callback_result()); |
| EXPECT_EQ( |
| JoinActions( |
| kGrab, |
| @@ -1271,6 +1351,7 @@ TEST_F(DisplayConfiguratorTest, DoNotConfigureWithSuspendedDisplays) { |
| // The DisplayConfigurator should do nothing at resume time if there is no |
| // state change. |
| + config_waiter_.Reset(); |
| UpdateOutputs(1, false); |
| configurator_.ResumeDisplays(); |
| EXPECT_EQ(kNoActions, log_->GetActionsAndClear()); |
| @@ -1279,9 +1360,10 @@ TEST_F(DisplayConfiguratorTest, DoNotConfigureWithSuspendedDisplays) { |
| // task should not run either and the timer should be stopped. The displays |
| // should be turned off by suspend. |
| configurator_.OnConfigurationChanged(); |
| - configurator_.SuspendDisplays(base::Bind( |
| - &DisplayConfiguratorTest::OnConfiguredCallback, base::Unretained(this))); |
| - EXPECT_EQ(CALLBACK_SUCCESS, PopCallbackResult()); |
| + config_waiter_.Reset(); |
| + configurator_.SuspendDisplays(config_waiter_.on_configuration_callback()); |
| + EXPECT_EQ(kNoDelay, config_waiter_.Wait()); |
| + EXPECT_EQ(CALLBACK_SUCCESS, config_waiter_.callback_result()); |
| EXPECT_EQ(JoinActions( |
| kGrab, GetFramebufferAction(small_mode_.size(), |
| outputs_[0].get(), nullptr) |
| @@ -1289,11 +1371,13 @@ TEST_F(DisplayConfiguratorTest, DoNotConfigureWithSuspendedDisplays) { |
| GetCrtcAction(*outputs_[0], nullptr, gfx::Point(0, 0)).c_str(), |
| kUngrab, kSync, nullptr), |
| log_->GetActionsAndClear()); |
| - |
| EXPECT_FALSE(test_api_.TriggerConfigureTimeout()); |
| EXPECT_EQ(kNoActions, log_->GetActionsAndClear()); |
| + config_waiter_.Reset(); |
| configurator_.ResumeDisplays(); |
| + // The timer should not be running. |
| + EXPECT_EQ(base::TimeDelta::Max(), config_waiter_.Wait()); |
| EXPECT_EQ( |
| JoinActions( |
| kGrab, |
| @@ -1527,9 +1611,9 @@ TEST_F(DisplayConfiguratorTest, SaveDisplayPowerStateOnConfigFailure) { |
| configurator_.SetDisplayPower( |
| chromeos::DISPLAY_POWER_INTERNAL_OFF_EXTERNAL_ON, |
| DisplayConfigurator::kSetDisplayPowerNoFlags, |
| - base::Bind(&DisplayConfiguratorTest::OnConfiguredCallback, |
| - base::Unretained(this))); |
| - EXPECT_EQ(CALLBACK_SUCCESS, PopCallbackResult()); |
| + config_waiter_.on_configuration_callback()); |
| + EXPECT_EQ(kNoDelay, config_waiter_.Wait()); |
| + EXPECT_EQ(CALLBACK_SUCCESS, config_waiter_.callback_result()); |
| EXPECT_EQ(1, observer_.num_changes()); |
| EXPECT_EQ(0, observer_.num_failures()); |
| log_->GetActionsAndClear(); |
| @@ -1537,12 +1621,11 @@ TEST_F(DisplayConfiguratorTest, SaveDisplayPowerStateOnConfigFailure) { |
| // Make all subsequent configuration requests fail and try to turn the |
| // internal display back on. |
| native_display_delegate_->set_max_configurable_pixels(1); |
| - configurator_.SetDisplayPower( |
| - chromeos::DISPLAY_POWER_ALL_ON, |
| - DisplayConfigurator::kSetDisplayPowerNoFlags, |
| - base::Bind(&DisplayConfiguratorTest::OnConfiguredCallback, |
| - base::Unretained(this))); |
| - EXPECT_EQ(CALLBACK_FAILURE, PopCallbackResult()); |
| + configurator_.SetDisplayPower(chromeos::DISPLAY_POWER_ALL_ON, |
| + DisplayConfigurator::kSetDisplayPowerNoFlags, |
| + config_waiter_.on_configuration_callback()); |
| + EXPECT_EQ(kNoDelay, config_waiter_.Wait()); |
| + EXPECT_EQ(CALLBACK_FAILURE, config_waiter_.callback_result()); |
| EXPECT_EQ(1, observer_.num_changes()); |
| EXPECT_EQ(1, observer_.num_failures()); |
| log_->GetActionsAndClear(); |
| @@ -1577,9 +1660,9 @@ TEST_F(DisplayConfiguratorTest, DontRestoreStalePowerStateAfterResume) { |
| configurator_.SetDisplayPower( |
| chromeos::DISPLAY_POWER_INTERNAL_OFF_EXTERNAL_ON, |
| DisplayConfigurator::kSetDisplayPowerNoFlags, |
| - base::Bind(&DisplayConfiguratorTest::OnConfiguredCallback, |
| - base::Unretained(this))); |
| - EXPECT_EQ(CALLBACK_SUCCESS, PopCallbackResult()); |
| + config_waiter_.on_configuration_callback()); |
| + EXPECT_EQ(kNoDelay, config_waiter_.Wait()); |
| + EXPECT_EQ(CALLBACK_SUCCESS, config_waiter_.callback_result()); |
| EXPECT_EQ(1, observer_.num_changes()); |
| EXPECT_EQ(0, observer_.num_failures()); |
| EXPECT_EQ( |
| @@ -1595,9 +1678,10 @@ TEST_F(DisplayConfiguratorTest, DontRestoreStalePowerStateAfterResume) { |
| // Suspend and resume the system. Resuming should restore the previous power |
| // state and force a probe. Suspend should turn off the displays since an |
| // external monitor is connected. |
| - configurator_.SuspendDisplays(base::Bind( |
| - &DisplayConfiguratorTest::OnConfiguredCallback, base::Unretained(this))); |
| - EXPECT_EQ(CALLBACK_SUCCESS, PopCallbackResult()); |
| + config_waiter_.Reset(); |
| + configurator_.SuspendDisplays(config_waiter_.on_configuration_callback()); |
| + EXPECT_EQ(kNoDelay, config_waiter_.Wait()); |
| + EXPECT_EQ(CALLBACK_SUCCESS, config_waiter_.callback_result()); |
| EXPECT_EQ(2, observer_.num_changes()); |
| EXPECT_EQ( |
| JoinActions( |
| @@ -1610,12 +1694,12 @@ TEST_F(DisplayConfiguratorTest, DontRestoreStalePowerStateAfterResume) { |
| log_->GetActionsAndClear()); |
| // Before the task runs, exit docked mode. |
| - configurator_.SetDisplayPower( |
| - chromeos::DISPLAY_POWER_ALL_ON, |
| - DisplayConfigurator::kSetDisplayPowerNoFlags, |
| - base::Bind(&DisplayConfiguratorTest::OnConfiguredCallback, |
| - base::Unretained(this))); |
| - EXPECT_EQ(CALLBACK_SUCCESS, PopCallbackResult()); |
| + config_waiter_.Reset(); |
| + configurator_.SetDisplayPower(chromeos::DISPLAY_POWER_ALL_ON, |
| + DisplayConfigurator::kSetDisplayPowerNoFlags, |
| + config_waiter_.on_configuration_callback()); |
| + EXPECT_EQ(kNoDelay, config_waiter_.Wait()); |
| + EXPECT_EQ(CALLBACK_SUCCESS, config_waiter_.callback_result()); |
| EXPECT_EQ(3, observer_.num_changes()); |
| EXPECT_EQ(0, observer_.num_failures()); |
| EXPECT_EQ( |
| @@ -1629,8 +1713,25 @@ TEST_F(DisplayConfiguratorTest, DontRestoreStalePowerStateAfterResume) { |
| log_->GetActionsAndClear()); |
| // Check that the display states are not changed after resuming. |
| + config_waiter_.Reset(); |
| + // Since we are in dual display mode, a configuration task is scheduled after |
| + // kMinLongDelayMs delay. |
| configurator_.ResumeDisplays(); |
| + EXPECT_EQ(kLongDelayMs, test_api_.GetConfigureDelay()); |
| + EXPECT_EQ(chromeos::DISPLAY_POWER_ALL_ON, |
| + configurator_.current_power_state()); |
| EXPECT_EQ(kNoActions, log_->GetActionsAndClear()); |
| + // Now trigger that delayed configuration. |
| + EXPECT_EQ(kLongDelayMs, config_waiter_.Wait()); |
| + EXPECT_EQ( |
| + JoinActions( |
| + kGrab, GetFramebufferAction(small_mode_.size(), outputs_[0].get(), |
| + outputs_[1].get()) |
| + .c_str(), |
| + GetCrtcAction(*outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(), |
| + GetCrtcAction(*outputs_[1], &small_mode_, gfx::Point(0, 0)).c_str(), |
| + kUngrab, nullptr), |
| + log_->GetActionsAndClear()); |
| } |
| TEST_F(DisplayConfiguratorTest, ExternalControl) { |
| @@ -1667,21 +1768,18 @@ TEST_F(DisplayConfiguratorTest, |
| native_display_delegate_->set_run_async(true); |
| - configurator_.SetDisplayPower( |
| - chromeos::DISPLAY_POWER_ALL_OFF, |
| - DisplayConfigurator::kSetDisplayPowerNoFlags, |
| - base::Bind(&DisplayConfiguratorTest::OnConfiguredCallback, |
| - base::Unretained(this))); |
| + config_waiter_.Reset(); |
| + configurator_.SetDisplayPower(chromeos::DISPLAY_POWER_ALL_OFF, |
| + DisplayConfigurator::kSetDisplayPowerNoFlags, |
| + config_waiter_.on_configuration_callback()); |
| - configurator_.SetDisplayPower( |
| - chromeos::DISPLAY_POWER_ALL_ON, |
| - DisplayConfigurator::kSetDisplayPowerNoFlags, |
| - base::Bind(&DisplayConfiguratorTest::OnConfiguredCallback, |
| - base::Unretained(this))); |
| + configurator_.SetDisplayPower(chromeos::DISPLAY_POWER_ALL_ON, |
| + DisplayConfigurator::kSetDisplayPowerNoFlags, |
| + config_waiter_.on_configuration_callback()); |
| - EXPECT_EQ(CALLBACK_NOT_CALLED, PopCallbackResult()); |
| - base::RunLoop().RunUntilIdle(); |
| - EXPECT_EQ(CALLBACK_SUCCESS, PopCallbackResult()); |
| + EXPECT_EQ(CALLBACK_NOT_CALLED, config_waiter_.callback_result()); |
| + EXPECT_EQ(kNoDelay, config_waiter_.Wait()); |
| + EXPECT_EQ(CALLBACK_SUCCESS, config_waiter_.callback_result()); |
| EXPECT_EQ(1, observer_.num_changes()); |
| EXPECT_EQ(0, observer_.num_failures()); |
| @@ -1702,9 +1800,10 @@ TEST_F(DisplayConfiguratorTest, |
| kUngrab, nullptr), |
| log_->GetActionsAndClear()); |
| + config_waiter_.Reset(); |
| EXPECT_TRUE(test_api_.TriggerConfigureTimeout()); |
| - base::RunLoop().RunUntilIdle(); |
| - EXPECT_EQ(CALLBACK_SUCCESS, PopCallbackResult()); |
| + EXPECT_EQ(kNoDelay, config_waiter_.Wait()); |
| + EXPECT_EQ(CALLBACK_SUCCESS, config_waiter_.callback_result()); |
| EXPECT_EQ(2, observer_.num_changes()); |
| EXPECT_EQ(0, observer_.num_failures()); |
| @@ -1735,13 +1834,12 @@ TEST_F(DisplayConfiguratorTest, |
| // Fail display configuration. |
| native_display_delegate_->set_max_configurable_pixels(-1); |
| - configurator_.SetDisplayPower( |
| - chromeos::DISPLAY_POWER_ALL_OFF, |
| - DisplayConfigurator::kSetDisplayPowerNoFlags, |
| - base::Bind(&DisplayConfiguratorTest::OnConfiguredCallback, |
| - base::Unretained(this))); |
| - |
| - EXPECT_EQ(CALLBACK_FAILURE, PopCallbackResult()); |
| + config_waiter_.Reset(); |
| + configurator_.SetDisplayPower(chromeos::DISPLAY_POWER_ALL_OFF, |
| + DisplayConfigurator::kSetDisplayPowerNoFlags, |
| + config_waiter_.on_configuration_callback()); |
| + EXPECT_EQ(kNoDelay, config_waiter_.Wait()); |
| + EXPECT_EQ(CALLBACK_FAILURE, config_waiter_.callback_result()); |
| EXPECT_EQ(0, observer_.num_changes()); |
| EXPECT_EQ(1, observer_.num_failures()); |
| @@ -1765,11 +1863,11 @@ TEST_F(DisplayConfiguratorTest, |
| // This configuration should trigger a display configuration since the |
| // previous configuration failed. |
| - configurator_.SetDisplayPower( |
| - chromeos::DISPLAY_POWER_ALL_ON, |
| - DisplayConfigurator::kSetDisplayPowerNoFlags, |
| - base::Bind(&DisplayConfiguratorTest::OnConfiguredCallback, |
| - base::Unretained(this))); |
| + config_waiter_.Reset(); |
| + configurator_.SetDisplayPower(chromeos::DISPLAY_POWER_ALL_ON, |
| + DisplayConfigurator::kSetDisplayPowerNoFlags, |
| + config_waiter_.on_configuration_callback()); |
| + EXPECT_EQ(kNoDelay, config_waiter_.Wait()); |
| EXPECT_EQ(0, observer_.num_changes()); |
| EXPECT_EQ(2, observer_.num_failures()); |
| @@ -1855,13 +1953,12 @@ TEST_F(DisplayConfiguratorTest, TestWithThreeDisplays) { |
| log_->GetActionsAndClear()); |
| // Verify that turning the power off works. |
| - configurator_.SetDisplayPower( |
| - chromeos::DISPLAY_POWER_ALL_OFF, |
| - DisplayConfigurator::kSetDisplayPowerNoFlags, |
| - base::Bind(&DisplayConfiguratorTest::OnConfiguredCallback, |
| - base::Unretained(this))); |
| - |
| - EXPECT_EQ(CALLBACK_SUCCESS, PopCallbackResult()); |
| + config_waiter_.Reset(); |
| + configurator_.SetDisplayPower(chromeos::DISPLAY_POWER_ALL_OFF, |
| + DisplayConfigurator::kSetDisplayPowerNoFlags, |
| + config_waiter_.on_configuration_callback()); |
| + EXPECT_EQ(kNoDelay, config_waiter_.Wait()); |
| + EXPECT_EQ(CALLBACK_SUCCESS, config_waiter_.callback_result()); |
| EXPECT_EQ( |
| JoinActions( |
| kGrab, GetFramebufferAction( |
| @@ -1882,13 +1979,12 @@ TEST_F(DisplayConfiguratorTest, TestWithThreeDisplays) { |
| kUngrab, nullptr), |
| log_->GetActionsAndClear()); |
| - configurator_.SetDisplayPower( |
| - chromeos::DISPLAY_POWER_ALL_ON, |
| - DisplayConfigurator::kSetDisplayPowerNoFlags, |
| - base::Bind(&DisplayConfiguratorTest::OnConfiguredCallback, |
| - base::Unretained(this))); |
| - |
| - EXPECT_EQ(CALLBACK_SUCCESS, PopCallbackResult()); |
| + config_waiter_.Reset(); |
| + configurator_.SetDisplayPower(chromeos::DISPLAY_POWER_ALL_ON, |
| + DisplayConfigurator::kSetDisplayPowerNoFlags, |
| + config_waiter_.on_configuration_callback()); |
| + EXPECT_EQ(kNoDelay, config_waiter_.Wait()); |
| + EXPECT_EQ(CALLBACK_SUCCESS, config_waiter_.callback_result()); |
| EXPECT_EQ( |
| JoinActions( |
| kGrab, GetFramebufferAction( |
| @@ -1928,5 +2024,150 @@ TEST_F(DisplayConfiguratorTest, TestWithThreeDisplays) { |
| log_->GetActionsAndClear()); |
| } |
| +// Tests the suspend and resume behavior when in dual or multi display modes. |
| +TEST_F(DisplayConfiguratorTest, SuspendResumeWithMultipleDisplays) { |
| + InitWithSingleOutput(); |
| + state_controller_.set_state(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED); |
| + observer_.Reset(); |
| + UpdateOutputs(2, true); |
| + EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED, |
| + configurator_.display_state()); |
| + EXPECT_FALSE(mirroring_controller_.SoftwareMirroringEnabled()); |
| + EXPECT_EQ(1, observer_.num_changes()); |
| + EXPECT_EQ(chromeos::DISPLAY_POWER_ALL_ON, |
| + configurator_.current_power_state()); |
| + const int kDualHeight = small_mode_.size().height() + |
| + DisplayConfigurator::kVerticalGap + |
| + big_mode_.size().height(); |
| + EXPECT_EQ( |
| + JoinActions( |
| + kGrab, |
| + GetFramebufferAction(gfx::Size(big_mode_.size().width(), kDualHeight), |
| + outputs_[0].get(), outputs_[1].get()) |
| + .c_str(), |
| + GetCrtcAction(*outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(), |
| + GetCrtcAction(*outputs_[1], &big_mode_, |
| + gfx::Point(0, small_mode_.size().height() + |
| + DisplayConfigurator::kVerticalGap)) |
| + .c_str(), |
| + kUngrab, nullptr), |
| + log_->GetActionsAndClear()); |
| + |
| + // Suspending displays should result in an immediate configuration without |
| + // delays, even in dual display mode. |
| + config_waiter_.Reset(); |
| + configurator_.SuspendDisplays(config_waiter_.on_configuration_callback()); |
| + EXPECT_EQ(kNoDelay, config_waiter_.Wait()); |
| + EXPECT_EQ(CALLBACK_SUCCESS, config_waiter_.callback_result()); |
| + EXPECT_EQ(chromeos::DISPLAY_POWER_ALL_OFF, |
| + configurator_.current_power_state()); |
| + EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED, |
| + configurator_.display_state()); |
| + EXPECT_EQ( |
| + JoinActions( |
| + kGrab, |
| + GetFramebufferAction(gfx::Size(big_mode_.size().width(), kDualHeight), |
| + outputs_[0].get(), outputs_[1].get()) |
| + .c_str(), |
| + GetCrtcAction(*outputs_[0], nullptr, gfx::Point(0, 0)).c_str(), |
| + GetCrtcAction(*outputs_[1], nullptr, |
| + gfx::Point(0, small_mode_.size().height() + |
| + DisplayConfigurator::kVerticalGap)) |
| + .c_str(), |
| + kUngrab, kSync, nullptr), |
| + log_->GetActionsAndClear()); |
| + |
| + // Resuming from suspend with dual displays. Configuration should be done |
| + // after a long delay. Afterwards, we should still expect to be in a dual |
| + // display mode. |
| + config_waiter_.Reset(); |
| + configurator_.ResumeDisplays(); |
| + EXPECT_EQ(kLongDelayMs, config_waiter_.Wait()); |
| + EXPECT_EQ(chromeos::DISPLAY_POWER_ALL_ON, |
| + configurator_.current_power_state()); |
| + EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED, |
| + configurator_.display_state()); |
| + EXPECT_EQ( |
| + JoinActions( |
| + kGrab, |
| + GetFramebufferAction(gfx::Size(big_mode_.size().width(), kDualHeight), |
| + outputs_[0].get(), outputs_[1].get()) |
| + .c_str(), |
| + GetCrtcAction(*outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(), |
| + GetCrtcAction(*outputs_[1], &big_mode_, |
| + gfx::Point(0, small_mode_.size().height() + |
| + DisplayConfigurator::kVerticalGap)) |
| + .c_str(), |
| + kForceDPMS, kUngrab, nullptr), |
| + log_->GetActionsAndClear()); |
| + |
| + // Suspend displays and disconnect one of them while in suspend. |
| + config_waiter_.Reset(); |
| + configurator_.SuspendDisplays(config_waiter_.on_configuration_callback()); |
| + EXPECT_EQ(kNoDelay, config_waiter_.Wait()); |
| + EXPECT_EQ(CALLBACK_SUCCESS, config_waiter_.callback_result()); |
| + EXPECT_EQ(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED, |
| + configurator_.display_state()); |
| + EXPECT_EQ(chromeos::DISPLAY_POWER_ALL_OFF, |
| + configurator_.current_power_state()); |
| + EXPECT_EQ( |
| + JoinActions( |
| + kGrab, |
| + GetFramebufferAction(gfx::Size(big_mode_.size().width(), kDualHeight), |
| + outputs_[0].get(), outputs_[1].get()) |
| + .c_str(), |
| + GetCrtcAction(*outputs_[0], nullptr, gfx::Point(0, 0)).c_str(), |
| + GetCrtcAction(*outputs_[1], nullptr, |
| + gfx::Point(0, small_mode_.size().height() + |
| + DisplayConfigurator::kVerticalGap)) |
| + .c_str(), |
| + kUngrab, kSync, nullptr), |
| + log_->GetActionsAndClear()); |
| + UpdateOutputs(1, false); |
| + EXPECT_EQ(kNoActions, log_->GetActionsAndClear()); |
| + |
| + // Now resume, and expect that we'll still have a long delay since we were in |
| + // dual mode before suspend. The configurator should pick up the change and |
| + // detect that we are in single display mode now. |
| + config_waiter_.Reset(); |
| + configurator_.ResumeDisplays(); |
| + EXPECT_EQ(kLongDelayMs, config_waiter_.Wait()); |
| + EXPECT_EQ(chromeos::DISPLAY_POWER_ALL_ON, |
| + configurator_.current_power_state()); |
| + EXPECT_EQ(MULTIPLE_DISPLAY_STATE_SINGLE, configurator_.display_state()); |
| + EXPECT_EQ( |
| + JoinActions( |
| + kGrab, |
| + GetFramebufferAction(small_mode_.size(), outputs_[0].get(), nullptr) |
| + .c_str(), |
| + GetCrtcAction(*outputs_[0], &small_mode_, gfx::Point(0, 0)).c_str(), |
| + kForceDPMS, kUngrab, nullptr), |
| + log_->GetActionsAndClear()); |
| + |
| + // Verify that the above is the exact same behavior for 3+ displays. |
| + UpdateOutputs(3, true); |
| + EXPECT_EQ(MULTIPLE_DISPLAY_STATE_MULTI_EXTENDED, |
| + configurator_.display_state()); |
| + |
| + // Suspend. |
| + config_waiter_.Reset(); |
| + configurator_.SuspendDisplays(config_waiter_.on_configuration_callback()); |
| + EXPECT_EQ(kNoDelay, config_waiter_.Wait()); |
| + EXPECT_EQ(CALLBACK_SUCCESS, config_waiter_.callback_result()); |
| + EXPECT_EQ(MULTIPLE_DISPLAY_STATE_MULTI_EXTENDED, |
| + configurator_.display_state()); |
| + EXPECT_EQ(chromeos::DISPLAY_POWER_ALL_OFF, |
| + configurator_.current_power_state()); |
| + |
| + // Resume and expect the correct delay. |
| + config_waiter_.Reset(); |
| + configurator_.ResumeDisplays(); |
| + EXPECT_EQ(kLongDelayMs, config_waiter_.Wait()); |
| + EXPECT_EQ(chromeos::DISPLAY_POWER_ALL_ON, |
| + configurator_.current_power_state()); |
| + EXPECT_EQ(MULTIPLE_DISPLAY_STATE_MULTI_EXTENDED, |
| + configurator_.display_state()); |
| +} |
| + |
| } // namespace test |
| } // namespace ui |