Chromium Code Reviews| 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 } | |
| 34 | |
| 35 UpdateDisplayConfigurationTask::~UpdateDisplayConfigurationTask() { | |
| 36 delegate_->UngrabServer(); | |
|
Daniel Erat
2014/12/11 23:34:07
you shouldn't do this unless Run() was called
| |
| 37 } | |
| 38 | |
| 39 void UpdateDisplayConfigurationTask::Run() { | |
| 40 delegate_->GrabServer(); | |
| 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 << DisplayStateToString(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 |