| 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/screen_manager_ozone.h" | 5 #include "services/ui/display/screen_manager_ozone.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <string> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
| 11 #include "base/memory/ptr_util.h" | 11 #include "base/memory/ptr_util.h" |
| 12 #include "base/sys_info.h" | 12 #include "base/sys_info.h" |
| 13 #include "base/threading/thread_task_runner_handle.h" | 13 #include "base/threading/thread_task_runner_handle.h" |
| 14 #include "services/service_manager/public/cpp/interface_registry.h" | 14 #include "services/service_manager/public/cpp/interface_registry.h" |
| 15 #include "third_party/skia/include/core/SkColor.h" | 15 #include "third_party/skia/include/core/SkColor.h" |
| 16 #include "ui/display/manager/chromeos/display_change_observer.h" |
| 17 #include "ui/display/manager/display_layout_store.h" |
| 18 #include "ui/display/manager/display_manager_utilities.h" |
| 19 #include "ui/display/screen.h" |
| 20 #include "ui/display/screen_base.h" |
| 16 #include "ui/display/types/display_snapshot.h" | 21 #include "ui/display/types/display_snapshot.h" |
| 22 #include "ui/display/types/fake_display_controller.h" |
| 17 #include "ui/display/types/native_display_delegate.h" | 23 #include "ui/display/types/native_display_delegate.h" |
| 18 #include "ui/gfx/geometry/rect.h" | 24 #include "ui/gfx/geometry/rect.h" |
| 19 #include "ui/ozone/public/ozone_platform.h" | 25 #include "ui/ozone/public/ozone_platform.h" |
| 20 | 26 |
| 21 namespace display { | 27 namespace display { |
| 22 namespace { | 28 namespace { |
| 23 | 29 |
| 24 // Needed for DisplayConfigurator::ForceInitialConfigure. | 30 // Needed for DisplayConfigurator::ForceInitialConfigure. |
| 25 const SkColor kChromeOsBootColor = SkColorSetRGB(0xfe, 0xfe, 0xfe); | 31 const SkColor kChromeOsBootColor = SkColorSetRGB(0xfe, 0xfe, 0xfe); |
| 26 | 32 |
| 27 const float kInchInMm = 25.4f; | 33 // Recursively swaps the displays in a DisplayLayout to change the primary |
| 34 // display but keep the same relative display layout. |
| 35 // TODO(kylechar): This is copied from WindowTreeHostManager. The concept of |
| 36 // getting the same relative display layout with a different primary display id |
| 37 // should become a function on DisplayLayout itself to avoid reimplementing it |
| 38 // here. |
| 39 void SwapRecursive(const std::map<int64_t, DisplayPlacement*>& id_to_placement, |
| 40 int64_t current_primary_id, |
| 41 int64_t display_id) { |
| 42 if (display_id == current_primary_id) |
| 43 return; |
| 28 | 44 |
| 29 float ComputeDisplayDPI(const gfx::Size& pixel_size, | 45 DCHECK(id_to_placement.count(display_id)); |
| 30 const gfx::Size& physical_size) { | 46 DisplayPlacement* placement = id_to_placement.at(display_id); |
| 31 // The physical_size is broken for some devices, return standard DPI. See | 47 DCHECK(placement); |
| 32 // crbug.com/669554. | 48 SwapRecursive(id_to_placement, current_primary_id, |
| 33 if (physical_size.IsEmpty()) { | 49 placement->parent_display_id); |
| 34 LOG(ERROR) << "Display has empty phsical_size"; | 50 placement->Swap(); |
| 35 return 96.0f; | |
| 36 } | |
| 37 | |
| 38 return (pixel_size.width() / static_cast<float>(physical_size.width())) * | |
| 39 kInchInMm; | |
| 40 } | |
| 41 | |
| 42 // Finds the device scale factor based on the display DPI. Will use forced | |
| 43 // device scale factor if provided via command line. | |
| 44 float FindDeviceScaleFactor(float dpi) { | |
| 45 if (Display::HasForceDeviceScaleFactor()) | |
| 46 return Display::GetForcedDeviceScaleFactor(); | |
| 47 | |
| 48 // TODO(kylechar): If dpi > 150 then ash uses 1.25 now. Ignoring that for now. | |
| 49 if (dpi > 200.0) | |
| 50 return 2.0f; | |
| 51 else | |
| 52 return 1.0f; | |
| 53 } | 51 } |
| 54 | 52 |
| 55 } // namespace | 53 } // namespace |
| 56 | 54 |
| 57 // static | 55 // static |
| 58 std::unique_ptr<ScreenManager> ScreenManager::Create() { | 56 std::unique_ptr<ScreenManager> ScreenManager::Create() { |
| 59 return base::MakeUnique<ScreenManagerOzone>(); | 57 return base::MakeUnique<ScreenManagerOzone>(); |
| 60 } | 58 } |
| 61 | 59 |
| 62 ScreenManagerOzone::ScreenManagerOzone() {} | 60 ScreenManagerOzone::ScreenManagerOzone() {} |
| 63 | 61 |
| 64 ScreenManagerOzone::~ScreenManagerOzone() { | 62 ScreenManagerOzone::~ScreenManagerOzone() { |
| 65 // We are shutting down and don't want to make anymore display changes. | 63 // We are shutting down and don't want to make anymore display changes. |
| 66 fake_display_controller_ = nullptr; | 64 fake_display_controller_ = nullptr; |
| 67 display_configurator_.RemoveObserver(this); | 65 |
| 66 if (display_manager_) |
| 67 display_manager_->RemoveObserver(this); |
| 68 |
| 69 if (display_change_observer_) { |
| 70 display_configurator_.RemoveObserver(display_change_observer_.get()); |
| 71 display_change_observer_.reset(); |
| 72 } |
| 73 |
| 74 if (display_manager_) |
| 75 display_manager_.reset(); |
| 76 } |
| 77 |
| 78 void ScreenManagerOzone::SetPrimaryDisplayId(int64_t display_id) { |
| 79 DCHECK_NE(kInvalidDisplayId, display_id); |
| 80 if (primary_display_id_ == display_id) |
| 81 return; |
| 82 |
| 83 const Display& new_primary_display = |
| 84 display_manager_->GetDisplayForId(display_id); |
| 85 if (!new_primary_display.is_valid()) { |
| 86 LOG(ERROR) << "Invalid or non-existent display is requested:" |
| 87 << new_primary_display.ToString(); |
| 88 return; |
| 89 } |
| 90 |
| 91 int64_t old_primary_display_id = primary_display_id_; |
| 92 |
| 93 const DisplayLayout& layout = display_manager_->GetCurrentDisplayLayout(); |
| 94 // The requested primary id can be same as one in the stored layout |
| 95 // when the primary id is set after new displays are connected. |
| 96 // Only update the layout if it is requested to swap primary display. |
| 97 if (layout.primary_id != new_primary_display.id()) { |
| 98 std::unique_ptr<DisplayLayout> swapped_layout(layout.Copy()); |
| 99 |
| 100 std::map<int64_t, DisplayPlacement*> id_to_placement; |
| 101 for (auto& placement : swapped_layout->placement_list) |
| 102 id_to_placement[placement.display_id] = &placement; |
| 103 SwapRecursive(id_to_placement, primary_display_id_, |
| 104 new_primary_display.id()); |
| 105 |
| 106 std::sort(swapped_layout->placement_list.begin(), |
| 107 swapped_layout->placement_list.end(), |
| 108 [](const DisplayPlacement& d1, const DisplayPlacement& d2) { |
| 109 return d1.display_id < d2.display_id; |
| 110 }); |
| 111 |
| 112 swapped_layout->primary_id = new_primary_display.id(); |
| 113 DisplayIdList list = display_manager_->GetCurrentDisplayIdList(); |
| 114 display_manager_->layout_store()->RegisterLayoutForDisplayIdList( |
| 115 list, std::move(swapped_layout)); |
| 116 } |
| 117 |
| 118 primary_display_id_ = new_primary_display.id(); |
| 119 screen_->display_list().UpdateDisplay(new_primary_display, |
| 120 DisplayList::Type::PRIMARY); |
| 121 |
| 122 // Force updating display bounds for new primary display. |
| 123 display_manager_->set_force_bounds_changed(true); |
| 124 display_manager_->UpdateDisplays(); |
| 125 display_manager_->set_force_bounds_changed(false); |
| 126 |
| 127 DVLOG(1) << "Primary display changed from " << old_primary_display_id |
| 128 << " to " << primary_display_id_; |
| 129 delegate_->OnPrimaryDisplayChanged(primary_display_id_); |
| 68 } | 130 } |
| 69 | 131 |
| 70 void ScreenManagerOzone::AddInterfaces( | 132 void ScreenManagerOzone::AddInterfaces( |
| 71 service_manager::InterfaceRegistry* registry) { | 133 service_manager::InterfaceRegistry* registry) { |
| 72 registry->AddInterface<mojom::DisplayController>(this); | 134 registry->AddInterface<mojom::DisplayController>(this); |
| 73 registry->AddInterface<mojom::TestDisplayController>(this); | 135 registry->AddInterface<mojom::TestDisplayController>(this); |
| 74 } | 136 } |
| 75 | 137 |
| 76 void ScreenManagerOzone::Init(ScreenManagerDelegate* delegate) { | 138 void ScreenManagerOzone::Init(ScreenManagerDelegate* delegate) { |
| 77 DCHECK(delegate); | 139 DCHECK(delegate); |
| 78 delegate_ = delegate; | 140 delegate_ = delegate; |
| 79 | 141 |
| 80 std::unique_ptr<ui::NativeDisplayDelegate> native_display_delegate = | 142 // Tests may inject a NativeDisplayDelegate, otherwise get it from |
| 81 ui::OzonePlatform::GetInstance()->CreateNativeDisplayDelegate(); | 143 // OzonePlatform. |
| 144 if (!native_display_delegate_) { |
| 145 native_display_delegate_ = |
| 146 ui::OzonePlatform::GetInstance()->CreateNativeDisplayDelegate(); |
| 147 } |
| 82 | 148 |
| 83 // The FakeDisplayController gives us a way to make the NativeDisplayDelegate | 149 // The FakeDisplayController gives us a way to make the NativeDisplayDelegate |
| 84 // pretend something display related has happened. | 150 // pretend something display related has happened. |
| 85 if (!base::SysInfo::IsRunningOnChromeOS()) { | 151 if (!base::SysInfo::IsRunningOnChromeOS()) { |
| 86 fake_display_controller_ = | 152 fake_display_controller_ = |
| 87 native_display_delegate->GetFakeDisplayController(); | 153 native_display_delegate_->GetFakeDisplayController(); |
| 88 } | 154 } |
| 89 | 155 |
| 156 // Create a new Screen instance. |
| 157 std::unique_ptr<ScreenBase> screen = base::MakeUnique<ScreenBase>(); |
| 158 Screen::SetScreenInstance(screen.get()); |
| 159 screen_ = screen.get(); |
| 160 |
| 161 // Configure display manager. ScreenManager acts as an observer to find out |
| 162 // display changes and as a delegate to find out when changes start/stop. |
| 163 display_manager_ = base::MakeUnique<DisplayManager>(std::move(screen)); |
| 164 display_manager_->set_configure_displays(true); |
| 165 display_manager_->AddObserver(this); |
| 166 display_manager_->set_delegate(this); |
| 167 |
| 168 // DisplayChangeObserver observes DisplayConfigurator and sends updates to |
| 169 // DisplayManager. |
| 170 display_change_observer_ = base::MakeUnique<DisplayChangeObserver>( |
| 171 &display_configurator_, display_manager_.get()); |
| 172 |
| 90 // We want display configuration to happen even off device to keep the control | 173 // We want display configuration to happen even off device to keep the control |
| 91 // flow similar. | 174 // flow similar. |
| 92 display_configurator_.set_configure_display(true); | 175 display_configurator_.set_configure_display(true); |
| 93 display_configurator_.AddObserver(this); | 176 display_configurator_.AddObserver(display_change_observer_.get()); |
| 94 display_configurator_.set_state_controller(this); | 177 display_configurator_.set_state_controller(display_change_observer_.get()); |
| 95 display_configurator_.Init(std::move(native_display_delegate), false); | 178 display_configurator_.set_mirroring_controller(display_manager_.get()); |
| 179 |
| 180 // Perform initial configuration. |
| 181 display_configurator_.Init(std::move(native_display_delegate_), false); |
| 96 display_configurator_.ForceInitialConfigure(kChromeOsBootColor); | 182 display_configurator_.ForceInitialConfigure(kChromeOsBootColor); |
| 97 } | 183 } |
| 98 | 184 |
| 99 void ScreenManagerOzone::RequestCloseDisplay(int64_t display_id) { | 185 void ScreenManagerOzone::RequestCloseDisplay(int64_t display_id) { |
| 100 if (!fake_display_controller_ || wait_for_display_config_update_) | 186 if (!fake_display_controller_) |
| 101 return; | 187 return; |
| 102 | 188 |
| 103 CachedDisplayIterator iter = GetCachedDisplayIterator(display_id); | 189 // Tell the NDD to remove the display. ScreenManager will get an update |
| 104 if (iter != cached_displays_.end()) { | 190 // that the display configuration has changed and the display will be gone. |
| 105 // Tell the NDD to remove the display. ScreenManager will get an update | 191 fake_display_controller_->RemoveDisplay(display_id); |
| 106 // that the display configuration has changed and the display will be gone. | |
| 107 wait_for_display_config_update_ = | |
| 108 fake_display_controller_->RemoveDisplay(iter->id); | |
| 109 } | |
| 110 } | 192 } |
| 111 | 193 |
| 112 int64_t ScreenManagerOzone::GetPrimaryDisplayId() const { | 194 int64_t ScreenManagerOzone::GetPrimaryDisplayId() const { |
| 113 return primary_display_id_; | 195 return primary_display_id_; |
| 114 } | 196 } |
| 115 | 197 |
| 116 void ScreenManagerOzone::ToggleAddRemoveDisplay() { | 198 void ScreenManagerOzone::ToggleAddRemoveDisplay() { |
| 117 if (!fake_display_controller_ || wait_for_display_config_update_) | 199 if (!fake_display_controller_) |
| 118 return; | 200 return; |
| 201 DVLOG(1) << "ToggleAddRemoveDisplay"; |
| 119 | 202 |
| 120 if (cached_displays_.size() == 1) { | 203 int num_displays = display_manager_->GetNumDisplays(); |
| 121 const gfx::Size& pixel_size = cached_displays_[0].metrics.pixel_size; | 204 if (num_displays == 1) { |
| 122 wait_for_display_config_update_ = | 205 const gfx::Size& pixel_size = |
| 123 fake_display_controller_->AddDisplay(pixel_size) != kInvalidDisplayId; | 206 display_manager_->GetDisplayInfo(display_manager_->GetDisplayAt(0).id()) |
| 124 } else if (cached_displays_.size() > 1) { | 207 .bounds_in_native() |
| 125 wait_for_display_config_update_ = | 208 .size(); |
| 126 fake_display_controller_->RemoveDisplay(cached_displays_.back().id); | 209 fake_display_controller_->AddDisplay(pixel_size); |
| 127 } else { | 210 } else if (num_displays > 1) { |
| 128 NOTREACHED(); | 211 DisplayIdList displays = display_manager_->GetCurrentDisplayIdList(); |
| 212 fake_display_controller_->RemoveDisplay(displays.back()); |
| 129 } | 213 } |
| 130 } | 214 } |
| 131 | 215 |
| 132 void ScreenManagerOzone::ToggleDisplayResolution() { | 216 void ScreenManagerOzone::ToggleDisplayResolution() { |
| 133 DisplayInfo& display = cached_displays_[0]; | 217 if (primary_display_id_ == kInvalidDisplayId) |
| 218 return; |
| 134 | 219 |
| 135 // Toggle the display size to use. | 220 // Internal displays don't have alternate resolutions. |
| 136 size_t num_sizes = display.supported_sizes.size(); | 221 if (Display::HasInternalDisplay() && |
| 137 for (size_t i = 0; i < num_sizes; i++) { | 222 primary_display_id_ == Display::InternalDisplayId()) |
| 138 if (display.supported_sizes[i] == display.requested_size) { | 223 return; |
| 139 if (i + 1 == num_sizes) | |
| 140 display.requested_size = display.supported_sizes[0]; | |
| 141 else | |
| 142 display.requested_size = display.supported_sizes[i + 1]; | |
| 143 break; | |
| 144 } | |
| 145 } | |
| 146 | 224 |
| 147 display_configurator_.OnConfigurationChanged(); | 225 DVLOG(1) << "ToggleDisplayResolution"; |
| 226 |
| 227 const ManagedDisplayInfo& info = |
| 228 display_manager_->GetDisplayInfo(primary_display_id_); |
| 229 scoped_refptr<ManagedDisplayMode> mode = |
| 230 GetDisplayModeForNextResolution(info, true); |
| 231 |
| 232 // Loop back to first mode from last. |
| 233 if (mode->size() == info.bounds_in_native().size()) |
| 234 mode = info.display_modes()[0]; |
| 235 |
| 236 // Set mode only if it's different from current. |
| 237 if (mode->size() != info.bounds_in_native().size()) |
| 238 display_manager_->SetDisplayMode(primary_display_id_, mode); |
| 148 } | 239 } |
| 149 | 240 |
| 150 void ScreenManagerOzone::IncreaseInternalDisplayZoom() { | 241 void ScreenManagerOzone::IncreaseInternalDisplayZoom() { |
| 151 NOTIMPLEMENTED(); | 242 if (Display::HasInternalDisplay()) |
| 243 display_manager_->ZoomInternalDisplay(false); |
| 152 } | 244 } |
| 153 | 245 |
| 154 void ScreenManagerOzone::DecreaseInternalDisplayZoom() { | 246 void ScreenManagerOzone::DecreaseInternalDisplayZoom() { |
| 155 NOTIMPLEMENTED(); | 247 if (Display::HasInternalDisplay()) |
| 248 display_manager_->ZoomInternalDisplay(true); |
| 156 } | 249 } |
| 157 | 250 |
| 158 void ScreenManagerOzone::ResetInternalDisplayZoom() { | 251 void ScreenManagerOzone::ResetInternalDisplayZoom() { |
| 159 NOTIMPLEMENTED(); | 252 if (Display::HasInternalDisplay()) |
| 253 display_manager_->ResetInternalDisplayZoom(); |
| 160 } | 254 } |
| 161 | 255 |
| 162 void ScreenManagerOzone::RotateCurrentDisplayCW() { | 256 void ScreenManagerOzone::RotateCurrentDisplayCW() { |
| 163 NOTIMPLEMENTED(); | 257 NOTIMPLEMENTED(); |
| 164 } | 258 } |
| 165 | 259 |
| 166 void ScreenManagerOzone::SwapPrimaryDisplay() { | 260 void ScreenManagerOzone::SwapPrimaryDisplay() { |
| 167 const size_t num_displays = cached_displays_.size(); | 261 // Can't swap if there is only 1 display and swapping isn't supported for 3 or |
| 168 if (num_displays <= 1) | 262 // more displays. |
| 263 if (display_manager_->GetNumDisplays() != 2) |
| 169 return; | 264 return; |
| 170 | 265 |
| 171 // Find index of current primary display. | 266 DVLOG(1) << "SwapPrimaryDisplay()"; |
| 172 size_t primary_display_index = 0; | |
| 173 for (size_t i = 0; i < num_displays; i++) { | |
| 174 if (cached_displays_[i].id == primary_display_id_) { | |
| 175 primary_display_index = i; | |
| 176 break; | |
| 177 } | |
| 178 } | |
| 179 | 267 |
| 180 // Set next display index as primary, or loop back to first display if last. | 268 DisplayIdList display_ids = display_manager_->GetCurrentDisplayIdList(); |
| 181 if (primary_display_index + 1 == num_displays) { | |
| 182 primary_display_id_ = cached_displays_[0].id; | |
| 183 } else { | |
| 184 primary_display_id_ = cached_displays_[primary_display_index + 1].id; | |
| 185 } | |
| 186 | 269 |
| 187 delegate_->OnPrimaryDisplayChanged(primary_display_id_); | 270 // Find the next primary display. |
| 271 if (primary_display_id_ == display_ids[0]) |
| 272 SetPrimaryDisplayId(display_ids[1]); |
| 273 else |
| 274 SetPrimaryDisplayId(display_ids[0]); |
| 188 } | 275 } |
| 189 | 276 |
| 190 void ScreenManagerOzone::ToggleMirrorMode() { | 277 void ScreenManagerOzone::ToggleMirrorMode() { |
| 191 NOTIMPLEMENTED(); | 278 NOTIMPLEMENTED(); |
| 192 } | 279 } |
| 193 | 280 |
| 194 void ScreenManagerOzone::SetDisplayWorkArea(int64_t display_id, | 281 void ScreenManagerOzone::SetDisplayWorkArea(int64_t display_id, |
| 195 const gfx::Size& size, | 282 const gfx::Size& size, |
| 196 const gfx::Insets& insets) { | 283 const gfx::Insets& insets) { |
| 197 CachedDisplayIterator iter = GetCachedDisplayIterator(display_id); | 284 // TODO(kylechar): Check the size of the display matches the current size. |
| 198 if (iter == cached_displays_.end()) { | 285 display_manager_->UpdateWorkAreaOfDisplay(display_id, insets); |
| 199 NOTREACHED() << display_id; | |
| 200 return; | |
| 201 } | |
| 202 | |
| 203 DisplayInfo& display_info = *iter; | |
| 204 if (display_info.metrics.bounds.size() == size) { | |
| 205 gfx::Rect new_work_area = display_info.metrics.bounds; | |
| 206 new_work_area.Inset(insets); | |
| 207 | |
| 208 if (new_work_area != display_info.metrics.work_area) { | |
| 209 display_info.last_work_area_insets = insets; | |
| 210 display_info.metrics.work_area = new_work_area; | |
| 211 display_info.modified = true; | |
| 212 UpdateCachedDisplays(); | |
| 213 } | |
| 214 } | |
| 215 } | 286 } |
| 216 | 287 |
| 217 ScreenManagerOzone::DisplayInfo::DisplayInfo() = default; | 288 void ScreenManagerOzone::OnDisplayAdded(const Display& display) { |
| 218 ScreenManagerOzone::DisplayInfo::DisplayInfo(const DisplayInfo& other) = | 289 ViewportMetrics metrics = GetViewportMetricsForDisplay(display); |
| 219 default; | 290 DVLOG(1) << "OnDisplayAdded: " << display.ToString() << "\n " |
| 220 ScreenManagerOzone::DisplayInfo::~DisplayInfo() = default; | 291 << metrics.ToString(); |
| 221 | 292 screen_->display_list().AddDisplay(display, DisplayList::Type::NOT_PRIMARY); |
| 222 void ScreenManagerOzone::ProcessRemovedDisplays( | 293 delegate_->OnDisplayAdded(display.id(), metrics); |
| 223 const ui::DisplayConfigurator::DisplayStateList& snapshots) { | |
| 224 std::vector<int64_t> current_ids; | |
| 225 for (ui::DisplaySnapshot* snapshot : snapshots) | |
| 226 current_ids.push_back(snapshot->display_id()); | |
| 227 | |
| 228 // Find cached displays with no matching snapshot and mark as removed. | |
| 229 for (DisplayInfo& display : cached_displays_) { | |
| 230 if (std::find(current_ids.begin(), current_ids.end(), display.id) == | |
| 231 current_ids.end()) { | |
| 232 display.removed = true; | |
| 233 if (primary_display_id_ == display.id) | |
| 234 primary_display_id_ = kInvalidDisplayId; | |
| 235 } | |
| 236 } | |
| 237 } | 294 } |
| 238 | 295 |
| 239 void ScreenManagerOzone::ProcessModifiedDisplays( | 296 void ScreenManagerOzone::OnDisplayRemoved(const Display& display) { |
| 240 const ui::DisplayConfigurator::DisplayStateList& snapshots) { | 297 // TODO(kylechar): If we're removing the primary display we need to first set |
| 241 for (ui::DisplaySnapshot* snapshot : snapshots) { | 298 // a new primary display. This will crash until then. |
| 242 auto iter = GetCachedDisplayIterator(snapshot->display_id()); | |
| 243 if (iter != cached_displays_.end()) { | |
| 244 DisplayInfo& display_info = *iter; | |
| 245 ViewportMetrics new_metrics = | |
| 246 MetricsFromSnapshot(*snapshot, display_info.metrics.bounds.origin()); | |
| 247 new_metrics.work_area.Inset(display_info.last_work_area_insets); | |
| 248 | 299 |
| 249 if (new_metrics != display_info.metrics) { | 300 DVLOG(1) << "OnDisplayRemoved: " << display.ToString(); |
| 250 display_info.metrics = new_metrics; | 301 screen_->display_list().RemoveDisplay(display.id()); |
| 251 display_info.modified = true; | 302 delegate_->OnDisplayRemoved(display.id()); |
| 252 } | |
| 253 } | |
| 254 } | |
| 255 } | 303 } |
| 256 | 304 |
| 257 void ScreenManagerOzone::UpdateCachedDisplays() { | 305 void ScreenManagerOzone::OnDisplayMetricsChanged(const Display& display, |
| 258 // Walk through cached displays after processing the snapshots to find any | 306 uint32_t changed_metrics) { |
| 259 // removed or modified displays. This ensures that we only send one update per | 307 ViewportMetrics metrics = GetViewportMetricsForDisplay(display); |
| 260 // display to the delegate. | 308 DVLOG(1) << "OnDisplayModified: " << display.ToString() << "\n " |
| 261 next_display_origin_.SetPoint(0, 0); | 309 << metrics.ToString(); |
| 262 for (auto iter = cached_displays_.begin(); iter != cached_displays_.end();) { | 310 screen_->display_list().UpdateDisplay(display); |
| 263 DisplayInfo& display_info = *iter; | 311 delegate_->OnDisplayModified(display.id(), metrics); |
| 264 if (display_info.removed) { | |
| 265 // Update delegate and remove from cache. | |
| 266 delegate_->OnDisplayRemoved(display_info.id); | |
| 267 iter = cached_displays_.erase(iter); | |
| 268 } else { | |
| 269 // Check if the display origin needs to be updated. | |
| 270 if (next_display_origin_ != display_info.metrics.bounds.origin()) { | |
| 271 display_info.metrics.bounds.set_origin(next_display_origin_); | |
| 272 display_info.metrics.work_area.set_origin(next_display_origin_); | |
| 273 display_info.modified = true; | |
| 274 } | |
| 275 next_display_origin_.Offset(display_info.metrics.bounds.width(), 0); | |
| 276 | |
| 277 // Check if the window bounds have changed and update delegate. | |
| 278 if (display_info.modified) { | |
| 279 display_info.modified = false; | |
| 280 delegate_->OnDisplayModified(display_info.id, display_info.metrics); | |
| 281 } | |
| 282 ++iter; | |
| 283 } | |
| 284 } | |
| 285 } | 312 } |
| 286 | 313 |
| 287 void ScreenManagerOzone::AddNewDisplays( | 314 ViewportMetrics ScreenManagerOzone::GetViewportMetricsForDisplay( |
| 288 const ui::DisplayConfigurator::DisplayStateList& snapshots) { | 315 const Display& display) { |
| 289 for (ui::DisplaySnapshot* snapshot : snapshots) { | 316 const ManagedDisplayInfo& managed_info = |
| 290 const int64_t id = snapshot->display_id(); | 317 display_manager_->GetDisplayInfo(display.id()); |
| 291 | 318 |
| 292 // Check if display already exists and skip. | 319 ViewportMetrics metrics; |
| 293 if (GetCachedDisplayIterator(id) != cached_displays_.end()) | 320 metrics.bounds = display.bounds(); |
| 294 continue; | 321 metrics.work_area = display.work_area(); |
| 322 metrics.pixel_size = managed_info.bounds_in_native().size(); |
| 323 metrics.rotation = display.rotation(); |
| 324 metrics.touch_support = display.touch_support(); |
| 325 metrics.device_scale_factor = display.device_scale_factor(); |
| 326 metrics.ui_scale_factor = managed_info.configured_ui_scale(); |
| 295 | 327 |
| 296 DisplayInfo display_info; | 328 return metrics; |
| 297 display_info.id = snapshot->display_id(); | 329 } |
| 298 display_info.metrics = MetricsFromSnapshot(*snapshot, next_display_origin_); | |
| 299 | 330 |
| 300 // Store the display mode sizes so we can toggle through them. | 331 void ScreenManagerOzone::CreateOrUpdateMirroringDisplay( |
| 301 for (auto& mode : snapshot->modes()) { | 332 const DisplayInfoList& display_info_list) { |
| 302 display_info.supported_sizes.push_back(mode->size()); | 333 NOTIMPLEMENTED(); |
| 303 if (mode.get() == snapshot->current_mode()) | 334 } |
| 304 display_info.requested_size = mode->size(); | |
| 305 } | |
| 306 | 335 |
| 307 // Move the origin so that next display is to the right of current display. | 336 void ScreenManagerOzone::CloseMirroringDisplayIfNotNecessary() { |
| 308 next_display_origin_.Offset(display_info.metrics.bounds.width(), 0); | 337 NOTIMPLEMENTED(); |
| 338 } |
| 309 | 339 |
| 310 cached_displays_.push_back(display_info); | 340 void ScreenManagerOzone::PreDisplayConfigurationChange(bool clear_focus) { |
| 311 delegate_->OnDisplayAdded(display_info.id, display_info.metrics); | 341 DVLOG(1) << "PreDisplayConfigurationChange"; |
| 342 } |
| 312 | 343 |
| 313 // If we have no primary display then this one should be it. | 344 void ScreenManagerOzone::PostDisplayConfigurationChange( |
| 314 if (primary_display_id_ == kInvalidDisplayId) { | 345 bool must_clear_window) { |
| 315 primary_display_id_ = id; | 346 // Set primary display if not set yet. |
| 347 if (primary_display_id_ == kInvalidDisplayId) { |
| 348 const Display& primary_display = |
| 349 display_manager_->GetPrimaryDisplayCandidate(); |
| 350 if (primary_display.is_valid()) { |
| 351 primary_display_id_ = primary_display.id(); |
| 352 DVLOG(1) << "Set primary display to " << primary_display_id_; |
| 353 screen_->display_list().UpdateDisplay(primary_display, |
| 354 DisplayList::Type::PRIMARY); |
| 316 delegate_->OnPrimaryDisplayChanged(primary_display_id_); | 355 delegate_->OnPrimaryDisplayChanged(primary_display_id_); |
| 317 } | 356 } |
| 318 } | 357 } |
| 358 |
| 359 DVLOG(1) << "PostDisplayConfigurationChange"; |
| 319 } | 360 } |
| 320 | 361 |
| 321 ScreenManagerOzone::CachedDisplayIterator | 362 ui::DisplayConfigurator* ScreenManagerOzone::display_configurator() { |
| 322 ScreenManagerOzone::GetCachedDisplayIterator(int64_t display_id) { | 363 return &display_configurator_; |
| 323 return std::find_if(cached_displays_.begin(), cached_displays_.end(), | |
| 324 [display_id](const DisplayInfo& display_info) { | |
| 325 return display_info.id == display_id; | |
| 326 }); | |
| 327 } | |
| 328 | |
| 329 ViewportMetrics ScreenManagerOzone::MetricsFromSnapshot( | |
| 330 const ui::DisplaySnapshot& snapshot, | |
| 331 const gfx::Point& origin) { | |
| 332 const ui::DisplayMode* current_mode = snapshot.current_mode(); | |
| 333 DCHECK(current_mode); | |
| 334 | |
| 335 ViewportMetrics metrics; | |
| 336 metrics.pixel_size = current_mode->size(); | |
| 337 metrics.device_scale_factor = FindDeviceScaleFactor( | |
| 338 ComputeDisplayDPI(current_mode->size(), snapshot.physical_size())); | |
| 339 // Get DIP size based on device scale factor. We are assuming the | |
| 340 // ui scale factor is always 1.0 here for now. | |
| 341 gfx::Size scaled_size = gfx::ScaleToRoundedSize( | |
| 342 current_mode->size(), 1.0f / metrics.device_scale_factor); | |
| 343 metrics.bounds = gfx::Rect(origin, scaled_size); | |
| 344 metrics.work_area = metrics.bounds; | |
| 345 return metrics; | |
| 346 } | |
| 347 | |
| 348 void ScreenManagerOzone::OnDisplayModeChanged( | |
| 349 const ui::DisplayConfigurator::DisplayStateList& displays) { | |
| 350 ProcessRemovedDisplays(displays); | |
| 351 ProcessModifiedDisplays(displays); | |
| 352 | |
| 353 // If the primary display is marked as removed we'll try to find a new primary | |
| 354 // display and update the delegate before removing the old primary display. | |
| 355 if (primary_display_id_ == kInvalidDisplayId) { | |
| 356 for (const DisplayInfo& display : cached_displays_) { | |
| 357 if (!display.removed) { | |
| 358 primary_display_id_ = display.id; | |
| 359 delegate_->OnPrimaryDisplayChanged(primary_display_id_); | |
| 360 break; | |
| 361 } | |
| 362 } | |
| 363 } | |
| 364 | |
| 365 UpdateCachedDisplays(); | |
| 366 AddNewDisplays(displays); | |
| 367 | |
| 368 wait_for_display_config_update_ = false; | |
| 369 } | |
| 370 | |
| 371 void ScreenManagerOzone::OnDisplayModeChangeFailed( | |
| 372 const ui::DisplayConfigurator::DisplayStateList& displays, | |
| 373 ui::MultipleDisplayState failed_new_state) { | |
| 374 LOG(ERROR) << "OnDisplayModeChangeFailed from DisplayConfigurator"; | |
| 375 wait_for_display_config_update_ = false; | |
| 376 } | 364 } |
| 377 | 365 |
| 378 void ScreenManagerOzone::Create( | 366 void ScreenManagerOzone::Create( |
| 379 const service_manager::Identity& remote_identity, | 367 const service_manager::Identity& remote_identity, |
| 380 mojom::DisplayControllerRequest request) { | 368 mojom::DisplayControllerRequest request) { |
| 381 controller_bindings_.AddBinding(this, std::move(request)); | 369 controller_bindings_.AddBinding(this, std::move(request)); |
| 382 } | 370 } |
| 383 | 371 |
| 384 ui::MultipleDisplayState ScreenManagerOzone::GetStateForDisplayIds( | |
| 385 const ui::DisplayConfigurator::DisplayStateList& display_states) const { | |
| 386 return (display_states.size() == 1 | |
| 387 ? ui::MULTIPLE_DISPLAY_STATE_SINGLE | |
| 388 : ui::MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED); | |
| 389 } | |
| 390 | |
| 391 bool ScreenManagerOzone::GetResolutionForDisplayId(int64_t display_id, | |
| 392 gfx::Size* size) const { | |
| 393 for (const DisplayInfo& display : cached_displays_) { | |
| 394 if (display.id == display_id) { | |
| 395 *size = display.requested_size; | |
| 396 return true; | |
| 397 } | |
| 398 } | |
| 399 | |
| 400 return false; | |
| 401 } | |
| 402 | |
| 403 void ScreenManagerOzone::Create( | 372 void ScreenManagerOzone::Create( |
| 404 const service_manager::Identity& remote_identity, | 373 const service_manager::Identity& remote_identity, |
| 405 mojom::TestDisplayControllerRequest request) { | 374 mojom::TestDisplayControllerRequest request) { |
| 406 test_bindings_.AddBinding(this, std::move(request)); | 375 test_bindings_.AddBinding(this, std::move(request)); |
| 407 } | 376 } |
| 408 | 377 |
| 409 } // namespace display | 378 } // namespace display |
| OLD | NEW |