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 |