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