OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "services/ui/display/platform_screen_ozone.h" | 5 #include "services/ui/display/platform_screen_ozone.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
79 // pretend something display related has happened. | 79 // pretend something display related has happened. |
80 if (!base::SysInfo::IsRunningOnChromeOS()) { | 80 if (!base::SysInfo::IsRunningOnChromeOS()) { |
81 fake_display_controller_ = | 81 fake_display_controller_ = |
82 native_display_delegate->GetFakeDisplayController(); | 82 native_display_delegate->GetFakeDisplayController(); |
83 } | 83 } |
84 | 84 |
85 // We want display configuration to happen even off device to keep the control | 85 // We want display configuration to happen even off device to keep the control |
86 // flow similar. | 86 // flow similar. |
87 display_configurator_.set_configure_display(true); | 87 display_configurator_.set_configure_display(true); |
88 display_configurator_.AddObserver(this); | 88 display_configurator_.AddObserver(this); |
| 89 display_configurator_.set_state_controller(this); |
89 display_configurator_.Init(std::move(native_display_delegate), false); | 90 display_configurator_.Init(std::move(native_display_delegate), false); |
90 display_configurator_.ForceInitialConfigure(kChromeOsBootColor); | 91 display_configurator_.ForceInitialConfigure(kChromeOsBootColor); |
91 } | 92 } |
92 | 93 |
93 void PlatformScreenOzone::RequestCloseDisplay(int64_t display_id) { | 94 void PlatformScreenOzone::RequestCloseDisplay(int64_t display_id) { |
94 if (!fake_display_controller_ || wait_for_display_config_update_) | 95 if (!fake_display_controller_ || wait_for_display_config_update_) |
95 return; | 96 return; |
96 | 97 |
97 CachedDisplayIterator iter = GetCachedDisplayIterator(display_id); | 98 CachedDisplayIterator iter = GetCachedDisplayIterator(display_id); |
98 if (iter != cached_displays_.end()) { | 99 if (iter != cached_displays_.end()) { |
99 // Tell the NDD to remove the display. PlatformScreen will get an update | 100 // Tell the NDD to remove the display. PlatformScreen will get an update |
100 // that the display configuration has changed and the display will be gone. | 101 // that the display configuration has changed and the display will be gone. |
101 wait_for_display_config_update_ = | 102 wait_for_display_config_update_ = |
102 fake_display_controller_->RemoveDisplay(iter->id); | 103 fake_display_controller_->RemoveDisplay(iter->id); |
103 } | 104 } |
104 } | 105 } |
105 | 106 |
106 int64_t PlatformScreenOzone::GetPrimaryDisplayId() const { | 107 int64_t PlatformScreenOzone::GetPrimaryDisplayId() const { |
107 return primary_display_id_; | 108 return primary_display_id_; |
108 } | 109 } |
109 | 110 |
110 void PlatformScreenOzone::ToggleAddRemoveDisplay() { | 111 void PlatformScreenOzone::ToggleAddRemoveDisplay() { |
111 if (!fake_display_controller_ || wait_for_display_config_update_) | 112 if (!fake_display_controller_ || wait_for_display_config_update_) |
112 return; | 113 return; |
113 | 114 |
114 if (cached_displays_.size() == 1) { | 115 if (cached_displays_.size() == 1) { |
115 const gfx::Size& pixel_size = cached_displays_[0].pixel_size; | 116 const gfx::Size& pixel_size = cached_displays_[0].metrics.pixel_size; |
116 wait_for_display_config_update_ = | 117 wait_for_display_config_update_ = |
117 fake_display_controller_->AddDisplay(pixel_size) != | 118 fake_display_controller_->AddDisplay(pixel_size) != |
118 Display::kInvalidDisplayID; | 119 Display::kInvalidDisplayID; |
119 } else if (cached_displays_.size() > 1) { | 120 } else if (cached_displays_.size() > 1) { |
120 wait_for_display_config_update_ = | 121 wait_for_display_config_update_ = |
121 fake_display_controller_->RemoveDisplay(cached_displays_.back().id); | 122 fake_display_controller_->RemoveDisplay(cached_displays_.back().id); |
122 } else { | 123 } else { |
123 NOTREACHED(); | 124 NOTREACHED(); |
124 } | 125 } |
125 } | 126 } |
126 | 127 |
| 128 void PlatformScreenOzone::ToggleDisplayResolution() { |
| 129 DisplayInfo& display = cached_displays_[0]; |
| 130 |
| 131 // Toggle the display size to use. |
| 132 size_t num_sizes = display.supported_sizes.size(); |
| 133 for (size_t i = 0; i < num_sizes; i++) { |
| 134 if (display.supported_sizes[i] == display.requested_size) { |
| 135 if (i + 1 == num_sizes) |
| 136 display.requested_size = display.supported_sizes[0]; |
| 137 else |
| 138 display.requested_size = display.supported_sizes[i + 1]; |
| 139 break; |
| 140 } |
| 141 } |
| 142 |
| 143 display_configurator_.OnConfigurationChanged(); |
| 144 } |
| 145 |
127 void PlatformScreenOzone::SwapPrimaryDisplay() { | 146 void PlatformScreenOzone::SwapPrimaryDisplay() { |
128 const size_t num_displays = cached_displays_.size(); | 147 const size_t num_displays = cached_displays_.size(); |
129 if (num_displays <= 1) | 148 if (num_displays <= 1) |
130 return; | 149 return; |
131 | 150 |
132 // Find index of current primary display. | 151 // Find index of current primary display. |
133 size_t primary_display_index = 0; | 152 size_t primary_display_index = 0; |
134 for (size_t i = 0; i < num_displays; i++) { | 153 for (size_t i = 0; i < num_displays; i++) { |
135 if (cached_displays_[i].id == primary_display_id_) { | 154 if (cached_displays_[i].id == primary_display_id_) { |
136 primary_display_index = i; | 155 primary_display_index = i; |
(...skipping 14 matching lines...) Expand all Loading... |
151 void PlatformScreenOzone::SetDisplayWorkArea(int64_t display_id, | 170 void PlatformScreenOzone::SetDisplayWorkArea(int64_t display_id, |
152 const gfx::Size& size, | 171 const gfx::Size& size, |
153 const gfx::Insets& insets) { | 172 const gfx::Insets& insets) { |
154 CachedDisplayIterator iter = GetCachedDisplayIterator(display_id); | 173 CachedDisplayIterator iter = GetCachedDisplayIterator(display_id); |
155 if (iter == cached_displays_.end()) { | 174 if (iter == cached_displays_.end()) { |
156 NOTREACHED() << display_id; | 175 NOTREACHED() << display_id; |
157 return; | 176 return; |
158 } | 177 } |
159 | 178 |
160 DisplayInfo& display_info = *iter; | 179 DisplayInfo& display_info = *iter; |
161 if (display_info.bounds.size() == size) { | 180 if (display_info.metrics.bounds.size() == size) { |
162 // TODO(kylechar): Change workarea and update ws::DisplayManager. | 181 gfx::Rect new_work_area = display_info.metrics.bounds; |
| 182 new_work_area.Inset(insets); |
| 183 |
| 184 if (new_work_area != display_info.metrics.work_area) { |
| 185 display_info.last_work_area_insets = insets; |
| 186 display_info.metrics.work_area = new_work_area; |
| 187 display_info.modified = true; |
| 188 UpdateCachedDisplays(); |
| 189 } |
163 } | 190 } |
164 } | 191 } |
165 | 192 |
| 193 PlatformScreenOzone::DisplayInfo::DisplayInfo() = default; |
| 194 PlatformScreenOzone::DisplayInfo::DisplayInfo(const DisplayInfo& other) = |
| 195 default; |
| 196 PlatformScreenOzone::DisplayInfo::~DisplayInfo() = default; |
| 197 |
166 void PlatformScreenOzone::ProcessRemovedDisplays( | 198 void PlatformScreenOzone::ProcessRemovedDisplays( |
167 const ui::DisplayConfigurator::DisplayStateList& snapshots) { | 199 const ui::DisplayConfigurator::DisplayStateList& snapshots) { |
168 std::vector<int64_t> current_ids; | 200 std::vector<int64_t> current_ids; |
169 for (ui::DisplaySnapshot* snapshot : snapshots) | 201 for (ui::DisplaySnapshot* snapshot : snapshots) |
170 current_ids.push_back(snapshot->display_id()); | 202 current_ids.push_back(snapshot->display_id()); |
171 | 203 |
172 // Find cached displays with no matching snapshot and mark as removed. | 204 // Find cached displays with no matching snapshot and mark as removed. |
173 for (DisplayInfo& display : cached_displays_) { | 205 for (DisplayInfo& display : cached_displays_) { |
174 if (std::find(current_ids.begin(), current_ids.end(), display.id) == | 206 if (std::find(current_ids.begin(), current_ids.end(), display.id) == |
175 current_ids.end()) { | 207 current_ids.end()) { |
(...skipping 13 matching lines...) Expand all Loading... |
189 } | 221 } |
190 } | 222 } |
191 } | 223 } |
192 | 224 |
193 void PlatformScreenOzone::ProcessModifiedDisplays( | 225 void PlatformScreenOzone::ProcessModifiedDisplays( |
194 const ui::DisplayConfigurator::DisplayStateList& snapshots) { | 226 const ui::DisplayConfigurator::DisplayStateList& snapshots) { |
195 for (ui::DisplaySnapshot* snapshot : snapshots) { | 227 for (ui::DisplaySnapshot* snapshot : snapshots) { |
196 auto iter = GetCachedDisplayIterator(snapshot->display_id()); | 228 auto iter = GetCachedDisplayIterator(snapshot->display_id()); |
197 if (iter != cached_displays_.end()) { | 229 if (iter != cached_displays_.end()) { |
198 DisplayInfo& display_info = *iter; | 230 DisplayInfo& display_info = *iter; |
199 DisplayInfo new_info = DisplayInfoFromSnapshot(*snapshot); | 231 ViewportMetrics new_metrics = |
| 232 MetricsFromSnapshot(*snapshot, display_info.metrics.bounds.origin()); |
| 233 new_metrics.work_area.Inset(display_info.last_work_area_insets); |
200 | 234 |
201 if (new_info.bounds.size() != display_info.bounds.size() || | 235 if (new_metrics != display_info.metrics) { |
202 new_info.device_scale_factor != display_info.device_scale_factor) { | 236 display_info.metrics = new_metrics; |
203 display_info = new_info; | |
204 display_info.modified = true; | 237 display_info.modified = true; |
205 } | 238 } |
206 } | 239 } |
207 } | 240 } |
208 } | 241 } |
209 | 242 |
210 void PlatformScreenOzone::UpdateCachedDisplays() { | 243 void PlatformScreenOzone::UpdateCachedDisplays() { |
211 // Walk through cached displays after processing the snapshots to find any | 244 // Walk through cached displays after processing the snapshots to find any |
212 // removed or modified displays. This ensures that we only send one update per | 245 // removed or modified displays. This ensures that we only send one update per |
213 // display to the delegate. | 246 // display to the delegate. |
214 next_display_origin_.SetPoint(0, 0); | 247 next_display_origin_.SetPoint(0, 0); |
215 for (auto iter = cached_displays_.begin(); iter != cached_displays_.end();) { | 248 for (auto iter = cached_displays_.begin(); iter != cached_displays_.end();) { |
216 DisplayInfo& display_info = *iter; | 249 DisplayInfo& display_info = *iter; |
217 if (display_info.removed) { | 250 if (display_info.removed) { |
218 // Update delegate and remove from cache. | 251 // Update delegate and remove from cache. |
219 delegate_->OnDisplayRemoved(display_info.id); | 252 delegate_->OnDisplayRemoved(display_info.id); |
220 iter = cached_displays_.erase(iter); | 253 iter = cached_displays_.erase(iter); |
221 } else { | 254 } else { |
222 // Check if the display origin needs to be updated. | 255 // Check if the display origin needs to be updated. |
223 if (next_display_origin_ != display_info.bounds.origin()) { | 256 if (next_display_origin_ != display_info.metrics.bounds.origin()) { |
224 display_info.bounds.set_origin(next_display_origin_); | 257 display_info.metrics.bounds.set_origin(next_display_origin_); |
| 258 display_info.metrics.work_area.set_origin(next_display_origin_); |
225 display_info.modified = true; | 259 display_info.modified = true; |
226 } | 260 } |
227 next_display_origin_.Offset(display_info.bounds.width(), 0); | 261 next_display_origin_.Offset(display_info.metrics.bounds.width(), 0); |
228 | 262 |
229 // Check if the window bounds have changed and update delegate. | 263 // Check if the window bounds have changed and update delegate. |
230 if (display_info.modified) { | 264 if (display_info.modified) { |
231 display_info.modified = false; | 265 display_info.modified = false; |
232 delegate_->OnDisplayModified(display_info.id, display_info.bounds, | 266 delegate_->OnDisplayModified(display_info.id, display_info.metrics); |
233 display_info.pixel_size, | |
234 display_info.device_scale_factor); | |
235 } | 267 } |
236 ++iter; | 268 ++iter; |
237 } | 269 } |
238 } | 270 } |
239 } | 271 } |
240 | 272 |
241 void PlatformScreenOzone::AddNewDisplays( | 273 void PlatformScreenOzone::AddNewDisplays( |
242 const ui::DisplayConfigurator::DisplayStateList& snapshots) { | 274 const ui::DisplayConfigurator::DisplayStateList& snapshots) { |
243 for (ui::DisplaySnapshot* snapshot : snapshots) { | 275 for (ui::DisplaySnapshot* snapshot : snapshots) { |
244 const int64_t id = snapshot->display_id(); | 276 const int64_t id = snapshot->display_id(); |
245 | 277 |
246 // Check if display already exists and skip. | 278 // Check if display already exists and skip. |
247 if (GetCachedDisplayIterator(id) != cached_displays_.end()) | 279 if (GetCachedDisplayIterator(id) != cached_displays_.end()) |
248 continue; | 280 continue; |
249 | 281 |
250 // If we have no primary display then this one should be it. | 282 // If we have no primary display then this one should be it. |
251 if (primary_display_id_ == Display::kInvalidDisplayID) | 283 if (primary_display_id_ == Display::kInvalidDisplayID) |
252 primary_display_id_ = id; | 284 primary_display_id_ = id; |
253 | 285 |
254 DisplayInfo display_info = DisplayInfoFromSnapshot(*snapshot); | 286 DisplayInfo display_info; |
| 287 display_info.id = snapshot->display_id(); |
| 288 display_info.metrics = MetricsFromSnapshot(*snapshot, next_display_origin_); |
| 289 |
| 290 // Store the display mode sizes so we can toggle through them. |
| 291 for (auto& mode : snapshot->modes()) { |
| 292 display_info.supported_sizes.push_back(mode->size()); |
| 293 if (mode.get() == snapshot->current_mode()) |
| 294 display_info.requested_size = mode->size(); |
| 295 } |
255 | 296 |
256 // Move the origin so that next display is to the right of current display. | 297 // Move the origin so that next display is to the right of current display. |
257 next_display_origin_.Offset(display_info.bounds.width(), 0); | 298 next_display_origin_.Offset(display_info.metrics.bounds.width(), 0); |
258 | 299 |
259 cached_displays_.push_back(display_info); | 300 cached_displays_.push_back(display_info); |
260 delegate_->OnDisplayAdded(display_info.id, display_info.bounds, | 301 delegate_->OnDisplayAdded(display_info.id, display_info.metrics); |
261 display_info.pixel_size, | |
262 display_info.device_scale_factor); | |
263 } | 302 } |
264 } | 303 } |
265 | 304 |
266 PlatformScreenOzone::CachedDisplayIterator | 305 PlatformScreenOzone::CachedDisplayIterator |
267 PlatformScreenOzone::GetCachedDisplayIterator(int64_t display_id) { | 306 PlatformScreenOzone::GetCachedDisplayIterator(int64_t display_id) { |
268 return std::find_if(cached_displays_.begin(), cached_displays_.end(), | 307 return std::find_if(cached_displays_.begin(), cached_displays_.end(), |
269 [display_id](const DisplayInfo& display_info) { | 308 [display_id](const DisplayInfo& display_info) { |
270 return display_info.id == display_id; | 309 return display_info.id == display_id; |
271 }); | 310 }); |
272 } | 311 } |
273 | 312 |
274 PlatformScreenOzone::DisplayInfo PlatformScreenOzone::DisplayInfoFromSnapshot( | 313 ViewportMetrics PlatformScreenOzone::MetricsFromSnapshot( |
275 const ui::DisplaySnapshot& snapshot) { | 314 const ui::DisplaySnapshot& snapshot, |
| 315 const gfx::Point& origin) { |
276 const ui::DisplayMode* current_mode = snapshot.current_mode(); | 316 const ui::DisplayMode* current_mode = snapshot.current_mode(); |
277 DCHECK(current_mode); | 317 DCHECK(current_mode); |
278 | 318 |
279 DisplayInfo display_info; | 319 ViewportMetrics metrics; |
280 display_info.id = snapshot.display_id(); | 320 metrics.pixel_size = current_mode->size(); |
281 display_info.pixel_size = current_mode->size(); | 321 metrics.device_scale_factor = FindDeviceScaleFactor( |
282 display_info.device_scale_factor = FindDeviceScaleFactor( | |
283 ComputeDisplayDPI(current_mode->size(), snapshot.physical_size())); | 322 ComputeDisplayDPI(current_mode->size(), snapshot.physical_size())); |
284 // Get DIP size based on device scale factor. We are assuming the | 323 // Get DIP size based on device scale factor. We are assuming the |
285 // ui scale factor is always 1.0 here for now. | 324 // ui scale factor is always 1.0 here for now. |
286 gfx::Size scaled_size = gfx::ScaleToRoundedSize( | 325 gfx::Size scaled_size = gfx::ScaleToRoundedSize( |
287 current_mode->size(), 1.0f / display_info.device_scale_factor); | 326 current_mode->size(), 1.0f / metrics.device_scale_factor); |
288 display_info.bounds = gfx::Rect(next_display_origin_, scaled_size); | 327 metrics.bounds = gfx::Rect(origin, scaled_size); |
289 return display_info; | 328 metrics.work_area = metrics.bounds; |
| 329 return metrics; |
290 } | 330 } |
291 | 331 |
292 void PlatformScreenOzone::OnDisplayModeChanged( | 332 void PlatformScreenOzone::OnDisplayModeChanged( |
293 const ui::DisplayConfigurator::DisplayStateList& displays) { | 333 const ui::DisplayConfigurator::DisplayStateList& displays) { |
294 ProcessRemovedDisplays(displays); | 334 ProcessRemovedDisplays(displays); |
295 ProcessModifiedDisplays(displays); | 335 ProcessModifiedDisplays(displays); |
296 UpdateCachedDisplays(); | 336 UpdateCachedDisplays(); |
297 AddNewDisplays(displays); | 337 AddNewDisplays(displays); |
298 wait_for_display_config_update_ = false; | 338 wait_for_display_config_update_ = false; |
299 } | 339 } |
300 | 340 |
301 void PlatformScreenOzone::OnDisplayModeChangeFailed( | 341 void PlatformScreenOzone::OnDisplayModeChangeFailed( |
302 const ui::DisplayConfigurator::DisplayStateList& displays, | 342 const ui::DisplayConfigurator::DisplayStateList& displays, |
303 ui::MultipleDisplayState failed_new_state) { | 343 ui::MultipleDisplayState failed_new_state) { |
304 LOG(ERROR) << "OnDisplayModeChangeFailed from DisplayConfigurator"; | 344 LOG(ERROR) << "OnDisplayModeChangeFailed from DisplayConfigurator"; |
305 wait_for_display_config_update_ = false; | 345 wait_for_display_config_update_ = false; |
306 } | 346 } |
307 | 347 |
308 void PlatformScreenOzone::Create( | 348 void PlatformScreenOzone::Create( |
309 const service_manager::Identity& remote_identity, | 349 const service_manager::Identity& remote_identity, |
310 mojom::DisplayControllerRequest request) { | 350 mojom::DisplayControllerRequest request) { |
311 controller_bindings_.AddBinding(this, std::move(request)); | 351 controller_bindings_.AddBinding(this, std::move(request)); |
312 } | 352 } |
313 | 353 |
| 354 ui::MultipleDisplayState PlatformScreenOzone::GetStateForDisplayIds( |
| 355 const ui::DisplayConfigurator::DisplayStateList& display_states) const { |
| 356 return (display_states.size() == 1 |
| 357 ? ui::MULTIPLE_DISPLAY_STATE_SINGLE |
| 358 : ui::MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED); |
| 359 } |
| 360 |
| 361 bool PlatformScreenOzone::GetResolutionForDisplayId(int64_t display_id, |
| 362 gfx::Size* size) const { |
| 363 for (const DisplayInfo& display : cached_displays_) { |
| 364 if (display.id == display_id) { |
| 365 *size = display.requested_size; |
| 366 return true; |
| 367 } |
| 368 } |
| 369 |
| 370 return false; |
| 371 } |
| 372 |
314 void PlatformScreenOzone::Create( | 373 void PlatformScreenOzone::Create( |
315 const service_manager::Identity& remote_identity, | 374 const service_manager::Identity& remote_identity, |
316 mojom::TestDisplayControllerRequest request) { | 375 mojom::TestDisplayControllerRequest request) { |
317 test_bindings_.AddBinding(this, std::move(request)); | 376 test_bindings_.AddBinding(this, std::move(request)); |
318 } | 377 } |
319 | 378 |
320 } // namespace display | 379 } // namespace display |
OLD | NEW |