OLD | NEW |
(Empty) | |
| 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. |
| 4 |
| 5 #include "ui/display/chromeos/update_display_configuration_task.h" |
| 6 |
| 7 #include "ui/display/chromeos/configure_displays_task.h" |
| 8 #include "ui/display/chromeos/display_util.h" |
| 9 #include "ui/display/types/display_snapshot.h" |
| 10 #include "ui/display/types/native_display_delegate.h" |
| 11 |
| 12 namespace ui { |
| 13 |
| 14 UpdateDisplayConfigurationTask::UpdateDisplayConfigurationTask( |
| 15 NativeDisplayDelegate* delegate, |
| 16 DisplayConfigurator::DisplayLayoutManager* layout_manager, |
| 17 MultipleDisplayState new_display_state, |
| 18 chromeos::DisplayPowerState new_power_state, |
| 19 int power_flags, |
| 20 uint32_t background_color_argb, |
| 21 bool force_configure, |
| 22 const ResponseCallback& callback) |
| 23 : delegate_(delegate), |
| 24 layout_manager_(layout_manager), |
| 25 new_display_state_(new_display_state), |
| 26 new_power_state_(new_power_state), |
| 27 power_flags_(power_flags), |
| 28 background_color_argb_(background_color_argb), |
| 29 force_configure_(force_configure), |
| 30 callback_(callback), |
| 31 force_dpms_(false), |
| 32 weak_ptr_factory_(this) { |
| 33 delegate_->GrabServer(); |
| 34 } |
| 35 |
| 36 UpdateDisplayConfigurationTask::~UpdateDisplayConfigurationTask() { |
| 37 delegate_->UngrabServer(); |
| 38 } |
| 39 |
| 40 void UpdateDisplayConfigurationTask::Run() { |
| 41 delegate_->GetDisplays( |
| 42 base::Bind(&UpdateDisplayConfigurationTask::OnDisplaysUpdated, |
| 43 weak_ptr_factory_.GetWeakPtr())); |
| 44 } |
| 45 |
| 46 void UpdateDisplayConfigurationTask::OnDisplaysUpdated( |
| 47 const std::vector<DisplaySnapshot*>& displays) { |
| 48 cached_displays_ = layout_manager_->ParseDisplays(displays); |
| 49 |
| 50 if (cached_displays_.size() > 1 && background_color_argb_) |
| 51 delegate_->SetBackgroundColor(background_color_argb_); |
| 52 |
| 53 // If the user hasn't requested a display state, update it using the requested |
| 54 // power state. |
| 55 if (new_display_state_ == MULTIPLE_DISPLAY_STATE_INVALID) |
| 56 new_display_state_ = ChooseDisplayState(); |
| 57 |
| 58 VLOG(1) << "OnDisplaysUpdated: new_display_state=" |
| 59 << MultipleDisplayStateToString(new_display_state_) |
| 60 << " new_power_state=" << DisplayPowerStateToString(new_power_state_) |
| 61 << " flags=" << power_flags_ |
| 62 << " force_configure=" << force_configure_ |
| 63 << " display_count=" << cached_displays_.size(); |
| 64 // If there has been any change in the requested power state and the displays |
| 65 // aren't being turned off force a change in DPMS state. |
| 66 force_dpms_ = ShouldForceDpms() && ShouldConfigure(); |
| 67 |
| 68 if (ShouldConfigure()) { |
| 69 EnterState(base::Bind(&UpdateDisplayConfigurationTask::OnStateEntered, |
| 70 weak_ptr_factory_.GetWeakPtr())); |
| 71 } else { |
| 72 // If we don't have to configure then we're sticking with the old |
| 73 // configuration. Update it such that it reflects in the reported value. |
| 74 new_power_state_ = layout_manager_->GetPowerState(); |
| 75 FinishConfiguration(true); |
| 76 } |
| 77 } |
| 78 |
| 79 void UpdateDisplayConfigurationTask::EnterState( |
| 80 const ConfigureDisplaysTask::ResponseCallback& callback) { |
| 81 VLOG(2) << "EnterState"; |
| 82 std::vector<DisplayConfigureRequest> requests; |
| 83 if (!layout_manager_->GetDisplayLayout(cached_displays_, new_display_state_, |
| 84 new_power_state_, &requests, |
| 85 &framebuffer_size_)) { |
| 86 callback.Run(ConfigureDisplaysTask::ERROR); |
| 87 return; |
| 88 } |
| 89 |
| 90 if (!requests.empty()) { |
| 91 delegate_->CreateFrameBuffer(framebuffer_size_); |
| 92 configure_task_.reset( |
| 93 new ConfigureDisplaysTask(delegate_, requests, callback)); |
| 94 configure_task_->Run(); |
| 95 } else { |
| 96 VLOG(2) << "No displays"; |
| 97 callback.Run(ConfigureDisplaysTask::SUCCESS); |
| 98 } |
| 99 } |
| 100 |
| 101 void UpdateDisplayConfigurationTask::OnStateEntered( |
| 102 ConfigureDisplaysTask::Status status) { |
| 103 bool success = status != ConfigureDisplaysTask::ERROR; |
| 104 if (new_display_state_ == MULTIPLE_DISPLAY_STATE_DUAL_MIRROR && |
| 105 status == ConfigureDisplaysTask::PARTIAL_SUCCESS) |
| 106 success = false; |
| 107 |
| 108 if (layout_manager_->GetSoftwareMirroringController()) { |
| 109 bool enable_software_mirroring = false; |
| 110 if (!success && new_display_state_ == MULTIPLE_DISPLAY_STATE_DUAL_MIRROR) { |
| 111 if (layout_manager_->GetDisplayState() != |
| 112 MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED || |
| 113 layout_manager_->GetPowerState() != new_power_state_) { |
| 114 new_display_state_ = MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED; |
| 115 EnterState(base::Bind( |
| 116 &UpdateDisplayConfigurationTask::OnEnableSoftwareMirroring, |
| 117 weak_ptr_factory_.GetWeakPtr())); |
| 118 return; |
| 119 } |
| 120 |
| 121 success = layout_manager_->GetDisplayState() == |
| 122 MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED; |
| 123 enable_software_mirroring = success; |
| 124 if (success) |
| 125 new_display_state_ = MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED; |
| 126 } |
| 127 |
| 128 layout_manager_->GetSoftwareMirroringController()->SetSoftwareMirroring( |
| 129 enable_software_mirroring); |
| 130 } |
| 131 |
| 132 FinishConfiguration(success); |
| 133 } |
| 134 |
| 135 void UpdateDisplayConfigurationTask::OnEnableSoftwareMirroring( |
| 136 ConfigureDisplaysTask::Status status) { |
| 137 bool success = status != ConfigureDisplaysTask::ERROR; |
| 138 layout_manager_->GetSoftwareMirroringController()->SetSoftwareMirroring( |
| 139 success); |
| 140 FinishConfiguration(success); |
| 141 } |
| 142 |
| 143 void UpdateDisplayConfigurationTask::FinishConfiguration(bool success) { |
| 144 if (success && force_dpms_) |
| 145 delegate_->ForceDPMSOn(); |
| 146 |
| 147 callback_.Run(success, cached_displays_, framebuffer_size_, |
| 148 new_display_state_, new_power_state_); |
| 149 } |
| 150 |
| 151 bool UpdateDisplayConfigurationTask::ShouldForceDpms() const { |
| 152 return new_power_state_ != chromeos::DISPLAY_POWER_ALL_OFF && |
| 153 (layout_manager_->GetPowerState() != new_power_state_ || |
| 154 (power_flags_ & DisplayConfigurator::kSetDisplayPowerForceProbe)); |
| 155 } |
| 156 |
| 157 bool UpdateDisplayConfigurationTask::ShouldConfigure() const { |
| 158 if (force_configure_) |
| 159 return true; |
| 160 |
| 161 if (cached_displays_.size() == 1 && |
| 162 cached_displays_[0].display->type() == DISPLAY_CONNECTION_TYPE_INTERNAL) |
| 163 return true; |
| 164 |
| 165 if (!(power_flags_ & |
| 166 DisplayConfigurator::kSetDisplayPowerOnlyIfSingleInternalDisplay)) |
| 167 return true; |
| 168 |
| 169 if (new_display_state_ != layout_manager_->GetDisplayState()) |
| 170 return true; |
| 171 |
| 172 return false; |
| 173 } |
| 174 |
| 175 MultipleDisplayState UpdateDisplayConfigurationTask::ChooseDisplayState() |
| 176 const { |
| 177 int num_on_displays = |
| 178 GetDisplayPower(cached_displays_, new_power_state_, NULL); |
| 179 switch (cached_displays_.size()) { |
| 180 case 0: |
| 181 return MULTIPLE_DISPLAY_STATE_HEADLESS; |
| 182 case 1: |
| 183 return MULTIPLE_DISPLAY_STATE_SINGLE; |
| 184 default: { |
| 185 if (num_on_displays == 1) { |
| 186 // If only one display is currently turned on, return the "single" |
| 187 // state so that its native mode will be used. |
| 188 return MULTIPLE_DISPLAY_STATE_SINGLE; |
| 189 } |
| 190 if (num_on_displays >= 3) { |
| 191 return MULTIPLE_DISPLAY_STATE_MULTI_EXTENDED; |
| 192 } else if (cached_displays_.size() == 2) { |
| 193 if (!layout_manager_->GetStateController()) |
| 194 return MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED; |
| 195 // With either both displays on or both displays off, use one of the |
| 196 // dual modes. |
| 197 std::vector<int64_t> display_ids; |
| 198 for (size_t i = 0; i < cached_displays_.size(); ++i) |
| 199 display_ids.push_back(cached_displays_[i].display->display_id()); |
| 200 |
| 201 return layout_manager_->GetStateController()->GetStateForDisplayIds( |
| 202 display_ids); |
| 203 } |
| 204 NOTREACHED(); |
| 205 } |
| 206 } |
| 207 return MULTIPLE_DISPLAY_STATE_INVALID; |
| 208 } |
| 209 |
| 210 } // namespace ui |
OLD | NEW |