Chromium Code Reviews| 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 void SwapRecursive(const std::map<int64_t, DisplayPlacement*>& id_to_placement, |
|
rjkroege
2016/12/13 23:56:36
Please write more expansive docs about what this d
kylechar
2016/12/16 21:25:08
It's swapping DisplayPlacements owned by the Displ
| |
| 34 int64_t current_primary_id, | |
| 35 int64_t display_id) { | |
| 36 if (display_id == current_primary_id) | |
| 37 return; | |
| 28 | 38 |
| 29 float ComputeDisplayDPI(const gfx::Size& pixel_size, | 39 DCHECK(id_to_placement.count(display_id)); |
| 30 const gfx::Size& physical_size) { | 40 DisplayPlacement* placement = id_to_placement.at(display_id); |
| 31 // The physical_size is broken for some devices, return standard DPI. See | 41 DCHECK(placement); |
| 32 // crbug.com/669554. | 42 SwapRecursive(id_to_placement, current_primary_id, |
| 33 if (physical_size.IsEmpty()) { | 43 placement->parent_display_id); |
| 34 LOG(ERROR) << "Display has empty phsical_size"; | 44 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 } | 45 } |
| 54 | 46 |
| 55 } // namespace | 47 } // namespace |
| 56 | 48 |
| 57 // static | 49 // static |
| 58 std::unique_ptr<ScreenManager> ScreenManager::Create() { | 50 std::unique_ptr<ScreenManager> ScreenManager::Create() { |
| 59 return base::MakeUnique<ScreenManagerOzone>(); | 51 return base::MakeUnique<ScreenManagerOzone>(); |
| 60 } | 52 } |
| 61 | 53 |
| 62 ScreenManagerOzone::ScreenManagerOzone() {} | 54 ScreenManagerOzone::ScreenManagerOzone() {} |
| 63 | 55 |
| 64 ScreenManagerOzone::~ScreenManagerOzone() { | 56 ScreenManagerOzone::~ScreenManagerOzone() { |
|
rjkroege
2016/12/13 23:56:36
should we insert the configuration of the external
kylechar
2016/12/16 21:25:08
Maybe.. You mean shit+ctrl+f2 console right? Isn't
| |
| 65 // We are shutting down and don't want to make anymore display changes. | 57 // We are shutting down and don't want to make anymore display changes. |
| 66 fake_display_controller_ = nullptr; | 58 fake_display_controller_ = nullptr; |
| 67 display_configurator_.RemoveObserver(this); | 59 |
| 60 if (display_manager_) | |
| 61 display_manager_->RemoveObserver(this); | |
| 62 | |
| 63 if (display_change_observer_) { | |
| 64 display_configurator_.RemoveObserver(display_change_observer_.get()); | |
| 65 display_change_observer_.reset(); | |
| 66 } | |
| 67 | |
| 68 if (display_manager_) | |
| 69 display_manager_.reset(); | |
| 70 } | |
| 71 | |
| 72 void ScreenManagerOzone::SetPrimaryDisplayId(int64_t display_id) { | |
| 73 DCHECK_NE(kInvalidDisplayId, display_id); | |
| 74 if (primary_display_id_ == display_id) | |
| 75 return; | |
| 76 | |
| 77 const Display& new_primary_display = | |
| 78 display_manager_->GetDisplayForId(display_id); | |
| 79 if (!new_primary_display.is_valid()) { | |
| 80 LOG(ERROR) << "Invalid or non-existent display is requested:" | |
| 81 << new_primary_display.ToString(); | |
| 82 return; | |
| 83 } | |
| 84 | |
| 85 int64_t old_primary_display_id = primary_display_id_; | |
| 86 | |
| 87 const DisplayLayout& layout = display_manager_->GetCurrentDisplayLayout(); | |
| 88 // The requested primary id can be same as one in the stored layout | |
| 89 // when the primary id is set after new displays are connected. | |
| 90 // Only update the layout if it is requested to swap primary display. | |
| 91 if (layout.primary_id != new_primary_display.id()) { | |
| 92 std::unique_ptr<DisplayLayout> swapped_layout(layout.Copy()); | |
| 93 | |
| 94 std::map<int64_t, DisplayPlacement*> id_to_placement; | |
| 95 for (auto& placement : swapped_layout->placement_list) | |
| 96 id_to_placement[placement.display_id] = &placement; | |
| 97 SwapRecursive(id_to_placement, primary_display_id_, | |
| 98 new_primary_display.id()); | |
| 99 | |
| 100 std::sort(swapped_layout->placement_list.begin(), | |
| 101 swapped_layout->placement_list.end(), | |
| 102 [](const DisplayPlacement& d1, const DisplayPlacement& d2) { | |
| 103 return d1.display_id < d2.display_id; | |
| 104 }); | |
| 105 | |
| 106 swapped_layout->primary_id = new_primary_display.id(); | |
| 107 DisplayIdList list = display_manager_->GetCurrentDisplayIdList(); | |
| 108 display_manager_->layout_store()->RegisterLayoutForDisplayIdList( | |
| 109 list, std::move(swapped_layout)); | |
| 110 } | |
| 111 | |
| 112 primary_display_id_ = new_primary_display.id(); | |
| 113 screen_->display_list().UpdateDisplay(new_primary_display, | |
| 114 DisplayList::Type::PRIMARY); | |
| 115 | |
| 116 // Force updating display bounds for new primary display. | |
| 117 display_manager_->set_force_bounds_changed(true); | |
| 118 display_manager_->UpdateDisplays(); | |
| 119 display_manager_->set_force_bounds_changed(false); | |
| 120 | |
| 121 DVLOG(1) << "Primary display changed from " << old_primary_display_id | |
| 122 << " to " << primary_display_id_; | |
| 123 delegate_->OnPrimaryDisplayChanged(primary_display_id_); | |
| 68 } | 124 } |
| 69 | 125 |
| 70 void ScreenManagerOzone::AddInterfaces( | 126 void ScreenManagerOzone::AddInterfaces( |
| 71 service_manager::InterfaceRegistry* registry) { | 127 service_manager::InterfaceRegistry* registry) { |
| 72 registry->AddInterface<mojom::DisplayController>(this); | 128 registry->AddInterface<mojom::DisplayController>(this); |
| 73 registry->AddInterface<mojom::TestDisplayController>(this); | 129 registry->AddInterface<mojom::TestDisplayController>(this); |
| 74 } | 130 } |
| 75 | 131 |
| 76 void ScreenManagerOzone::Init(ScreenManagerDelegate* delegate) { | 132 void ScreenManagerOzone::Init(ScreenManagerDelegate* delegate) { |
| 77 DCHECK(delegate); | 133 DCHECK(delegate); |
| 78 delegate_ = delegate; | 134 delegate_ = delegate; |
| 79 | 135 |
| 80 std::unique_ptr<ui::NativeDisplayDelegate> native_display_delegate = | 136 // Tests may inject a NDD, otherwise get it from OzonePlatform. |
| 81 ui::OzonePlatform::GetInstance()->CreateNativeDisplayDelegate(); | 137 if (!native_display_delegate_) { |
| 138 native_display_delegate_ = | |
| 139 ui::OzonePlatform::GetInstance()->CreateNativeDisplayDelegate(); | |
| 140 } | |
| 82 | 141 |
| 83 // The FakeDisplayController gives us a way to make the NativeDisplayDelegate | 142 // The FakeDisplayController gives us a way to make the NativeDisplayDelegate |
| 84 // pretend something display related has happened. | 143 // pretend something display related has happened. |
| 85 if (!base::SysInfo::IsRunningOnChromeOS()) { | 144 if (!base::SysInfo::IsRunningOnChromeOS()) { |
| 86 fake_display_controller_ = | 145 fake_display_controller_ = |
| 87 native_display_delegate->GetFakeDisplayController(); | 146 native_display_delegate_->GetFakeDisplayController(); |
| 88 } | 147 } |
| 89 | 148 |
| 149 // Create a new Screen instance. | |
| 150 std::unique_ptr<ScreenBase> screen = base::MakeUnique<ScreenBase>(); | |
| 151 Screen::SetScreenInstance(screen.get()); | |
| 152 screen_ = screen.get(); | |
| 153 | |
| 154 // Configure display manager. ScreenManager acts as an observer to find out | |
| 155 // display changes and as a delegate to find out when changes start/stop. | |
| 156 display_manager_ = base::MakeUnique<DisplayManager>(std::move(screen)); | |
| 157 display_manager_->set_configure_displays(true); | |
| 158 display_manager_->AddObserver(this); | |
| 159 display_manager_->set_delegate(this); | |
| 160 | |
| 161 // DisplayChangeObserver observes DisplayConfigurator and sends updates to | |
| 162 // DisplayManager. | |
| 163 display_change_observer_ = base::MakeUnique<DisplayChangeObserver>( | |
| 164 &display_configurator_, display_manager_.get()); | |
| 165 | |
| 90 // We want display configuration to happen even off device to keep the control | 166 // We want display configuration to happen even off device to keep the control |
| 91 // flow similar. | 167 // flow similar. |
| 92 display_configurator_.set_configure_display(true); | 168 display_configurator_.set_configure_display(true); |
| 93 display_configurator_.AddObserver(this); | 169 display_configurator_.AddObserver(display_change_observer_.get()); |
| 94 display_configurator_.set_state_controller(this); | 170 display_configurator_.set_state_controller(display_change_observer_.get()); |
| 95 display_configurator_.Init(std::move(native_display_delegate), false); | 171 display_configurator_.set_mirroring_controller(display_manager_.get()); |
| 172 | |
| 173 // Perform initial configuration. | |
| 174 display_configurator_.Init(std::move(native_display_delegate_), false); | |
| 96 display_configurator_.ForceInitialConfigure(kChromeOsBootColor); | 175 display_configurator_.ForceInitialConfigure(kChromeOsBootColor); |
| 97 } | 176 } |
| 98 | 177 |
| 99 void ScreenManagerOzone::RequestCloseDisplay(int64_t display_id) { | 178 void ScreenManagerOzone::RequestCloseDisplay(int64_t display_id) { |
| 100 if (!fake_display_controller_ || wait_for_display_config_update_) | 179 if (!fake_display_controller_) |
| 101 return; | 180 return; |
| 102 | 181 |
| 103 CachedDisplayIterator iter = GetCachedDisplayIterator(display_id); | 182 // Tell the NDD to remove the display. ScreenManager will get an update |
| 104 if (iter != cached_displays_.end()) { | 183 // 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 | 184 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 } | 185 } |
| 111 | 186 |
| 112 int64_t ScreenManagerOzone::GetPrimaryDisplayId() const { | 187 int64_t ScreenManagerOzone::GetPrimaryDisplayId() const { |
| 113 return primary_display_id_; | 188 return primary_display_id_; |
| 114 } | 189 } |
| 115 | 190 |
| 116 void ScreenManagerOzone::ToggleAddRemoveDisplay() { | 191 void ScreenManagerOzone::ToggleAddRemoveDisplay() { |
| 117 if (!fake_display_controller_ || wait_for_display_config_update_) | 192 if (!fake_display_controller_) |
| 118 return; | 193 return; |
| 194 DVLOG(1) << "ToggleAddRemoveDisplay"; | |
| 119 | 195 |
| 120 if (cached_displays_.size() == 1) { | 196 int num_displays = display_manager_->GetNumDisplays(); |
| 121 const gfx::Size& pixel_size = cached_displays_[0].metrics.pixel_size; | 197 if (num_displays == 1) { |
| 122 wait_for_display_config_update_ = | 198 const gfx::Size& pixel_size = |
| 123 fake_display_controller_->AddDisplay(pixel_size) != kInvalidDisplayId; | 199 display_manager_->GetDisplayInfo(display_manager_->GetDisplayAt(0).id()) |
| 124 } else if (cached_displays_.size() > 1) { | 200 .bounds_in_native() |
| 125 wait_for_display_config_update_ = | 201 .size(); |
| 126 fake_display_controller_->RemoveDisplay(cached_displays_.back().id); | 202 fake_display_controller_->AddDisplay(pixel_size); |
| 127 } else { | 203 } else if (num_displays > 1) { |
| 128 NOTREACHED(); | 204 DisplayIdList displays = display_manager_->GetCurrentDisplayIdList(); |
| 205 fake_display_controller_->RemoveDisplay(displays.back()); | |
| 129 } | 206 } |
| 130 } | 207 } |
| 131 | 208 |
| 132 void ScreenManagerOzone::ToggleDisplayResolution() { | 209 void ScreenManagerOzone::ToggleDisplayResolution() { |
| 133 DisplayInfo& display = cached_displays_[0]; | 210 if (primary_display_id_ == kInvalidDisplayId) |
| 211 return; | |
| 134 | 212 |
| 135 // Toggle the display size to use. | 213 // Internal displays don't have alternate resolutions. |
| 136 size_t num_sizes = display.supported_sizes.size(); | 214 if (Display::HasInternalDisplay() && |
|
rjkroege
2016/12/13 23:56:36
Observation not needing to be addressed: why is Ha
kylechar
2016/12/16 21:25:08
That would make things too easy probably :)
| |
| 137 for (size_t i = 0; i < num_sizes; i++) { | 215 primary_display_id_ == Display::InternalDisplayId()) |
| 138 if (display.supported_sizes[i] == display.requested_size) { | 216 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 | 217 |
| 147 display_configurator_.OnConfigurationChanged(); | 218 DVLOG(1) << "ToggleDisplayResolution"; |
| 219 | |
| 220 const ManagedDisplayInfo& info = | |
|
rjkroege
2016/12/13 23:56:36
Managed* should (ideally) become an internal detai
kylechar
2016/12/16 21:25:08
I don't think we'll be able to get away from using
| |
| 221 display_manager_->GetDisplayInfo(primary_display_id_); | |
| 222 scoped_refptr<ManagedDisplayMode> mode = | |
| 223 GetDisplayModeForNextResolution(info, true); | |
| 224 | |
| 225 // Loop back to first mode from last. | |
| 226 if (mode->size() == info.bounds_in_native().size()) | |
| 227 mode = info.display_modes()[0]; | |
| 228 | |
| 229 // Set mode only if it's different from current. | |
| 230 if (mode->size() != info.bounds_in_native().size()) | |
| 231 display_manager_->SetDisplayMode(primary_display_id_, mode); | |
| 148 } | 232 } |
| 149 | 233 |
| 150 void ScreenManagerOzone::IncreaseInternalDisplayZoom() { | 234 void ScreenManagerOzone::IncreaseInternalDisplayZoom() { |
| 151 NOTIMPLEMENTED(); | 235 if (Display::HasInternalDisplay()) |
| 236 display_manager_->ZoomInternalDisplay(false); | |
| 152 } | 237 } |
| 153 | 238 |
| 154 void ScreenManagerOzone::DecreaseInternalDisplayZoom() { | 239 void ScreenManagerOzone::DecreaseInternalDisplayZoom() { |
| 155 NOTIMPLEMENTED(); | 240 if (Display::HasInternalDisplay()) |
| 241 display_manager_->ZoomInternalDisplay(true); | |
| 156 } | 242 } |
| 157 | 243 |
| 158 void ScreenManagerOzone::ResetInternalDisplayZoom() { | 244 void ScreenManagerOzone::ResetInternalDisplayZoom() { |
| 159 NOTIMPLEMENTED(); | 245 if (Display::HasInternalDisplay()) |
| 246 display_manager_->ResetInternalDisplayZoom(); | |
| 160 } | 247 } |
| 161 | 248 |
| 162 void ScreenManagerOzone::RotateCurrentDisplayCW() { | 249 void ScreenManagerOzone::RotateCurrentDisplayCW() { |
| 163 NOTIMPLEMENTED(); | 250 NOTIMPLEMENTED(); |
| 164 } | 251 } |
| 165 | 252 |
| 166 void ScreenManagerOzone::SwapPrimaryDisplay() { | 253 void ScreenManagerOzone::SwapPrimaryDisplay() { |
| 167 const size_t num_displays = cached_displays_.size(); | 254 // Can't swap if there is only 1 display and swapping isn't supported for 3 or |
| 168 if (num_displays <= 1) | 255 // more displays. |
| 256 if (display_manager_->GetNumDisplays() != 2) | |
| 169 return; | 257 return; |
| 170 | 258 |
| 171 // Find index of current primary display. | 259 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 | 260 |
| 180 // Set next display index as primary, or loop back to first display if last. | 261 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 | 262 |
| 187 delegate_->OnPrimaryDisplayChanged(primary_display_id_); | 263 // Find the next primary display. |
| 264 if (primary_display_id_ == display_ids[0]) | |
| 265 SetPrimaryDisplayId(display_ids[1]); | |
| 266 else | |
| 267 SetPrimaryDisplayId(display_ids[0]); | |
| 188 } | 268 } |
| 189 | 269 |
| 190 void ScreenManagerOzone::ToggleMirrorMode() { | 270 void ScreenManagerOzone::ToggleMirrorMode() { |
| 191 NOTIMPLEMENTED(); | 271 NOTIMPLEMENTED(); |
| 192 } | 272 } |
| 193 | 273 |
| 194 void ScreenManagerOzone::SetDisplayWorkArea(int64_t display_id, | 274 void ScreenManagerOzone::SetDisplayWorkArea(int64_t display_id, |
| 195 const gfx::Size& size, | 275 const gfx::Size& size, |
| 196 const gfx::Insets& insets) { | 276 const gfx::Insets& insets) { |
| 197 CachedDisplayIterator iter = GetCachedDisplayIterator(display_id); | 277 // TODO(kylechar): Check the size of the display matches the current size. |
| 198 if (iter == cached_displays_.end()) { | 278 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 } | |
| 216 | |
| 217 ScreenManagerOzone::DisplayInfo::DisplayInfo() = default; | |
| 218 ScreenManagerOzone::DisplayInfo::DisplayInfo(const DisplayInfo& other) = | |
| 219 default; | |
| 220 ScreenManagerOzone::DisplayInfo::~DisplayInfo() = default; | |
| 221 | |
| 222 void ScreenManagerOzone::ProcessRemovedDisplays( | |
| 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 } | |
| 238 | |
| 239 void ScreenManagerOzone::ProcessModifiedDisplays( | |
| 240 const ui::DisplayConfigurator::DisplayStateList& snapshots) { | |
| 241 for (ui::DisplaySnapshot* snapshot : snapshots) { | |
| 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 | |
| 249 if (new_metrics != display_info.metrics) { | |
| 250 display_info.metrics = new_metrics; | |
| 251 display_info.modified = true; | |
| 252 } | |
| 253 } | |
| 254 } | |
| 255 } | |
| 256 | |
| 257 void ScreenManagerOzone::UpdateCachedDisplays() { | |
| 258 // Walk through cached displays after processing the snapshots to find any | |
| 259 // removed or modified displays. This ensures that we only send one update per | |
| 260 // display to the delegate. | |
| 261 next_display_origin_.SetPoint(0, 0); | |
| 262 for (auto iter = cached_displays_.begin(); iter != cached_displays_.end();) { | |
| 263 DisplayInfo& display_info = *iter; | |
| 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 } | |
| 286 | |
| 287 void ScreenManagerOzone::AddNewDisplays( | |
| 288 const ui::DisplayConfigurator::DisplayStateList& snapshots) { | |
| 289 for (ui::DisplaySnapshot* snapshot : snapshots) { | |
| 290 const int64_t id = snapshot->display_id(); | |
| 291 | |
| 292 // Check if display already exists and skip. | |
| 293 if (GetCachedDisplayIterator(id) != cached_displays_.end()) | |
| 294 continue; | |
| 295 | |
| 296 DisplayInfo display_info; | |
| 297 display_info.id = snapshot->display_id(); | |
| 298 display_info.metrics = MetricsFromSnapshot(*snapshot, next_display_origin_); | |
| 299 | |
| 300 // Store the display mode sizes so we can toggle through them. | |
| 301 for (auto& mode : snapshot->modes()) { | |
| 302 display_info.supported_sizes.push_back(mode->size()); | |
| 303 if (mode.get() == snapshot->current_mode()) | |
| 304 display_info.requested_size = mode->size(); | |
| 305 } | |
| 306 | |
| 307 // Move the origin so that next display is to the right of current display. | |
| 308 next_display_origin_.Offset(display_info.metrics.bounds.width(), 0); | |
| 309 | |
| 310 cached_displays_.push_back(display_info); | |
| 311 delegate_->OnDisplayAdded(display_info.id, display_info.metrics); | |
| 312 | |
| 313 // If we have no primary display then this one should be it. | |
| 314 if (primary_display_id_ == kInvalidDisplayId) { | |
| 315 primary_display_id_ = id; | |
| 316 delegate_->OnPrimaryDisplayChanged(primary_display_id_); | |
| 317 } | |
| 318 } | |
| 319 } | |
| 320 | |
| 321 ScreenManagerOzone::CachedDisplayIterator | |
| 322 ScreenManagerOzone::GetCachedDisplayIterator(int64_t display_id) { | |
| 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 } | 279 } |
| 377 | 280 |
| 378 void ScreenManagerOzone::Create( | 281 void ScreenManagerOzone::Create( |
| 379 const service_manager::Identity& remote_identity, | 282 const service_manager::Identity& remote_identity, |
| 380 mojom::DisplayControllerRequest request) { | 283 mojom::DisplayControllerRequest request) { |
| 381 controller_bindings_.AddBinding(this, std::move(request)); | 284 controller_bindings_.AddBinding(this, std::move(request)); |
| 382 } | 285 } |
| 383 | 286 |
| 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( | 287 void ScreenManagerOzone::Create( |
| 404 const service_manager::Identity& remote_identity, | 288 const service_manager::Identity& remote_identity, |
| 405 mojom::TestDisplayControllerRequest request) { | 289 mojom::TestDisplayControllerRequest request) { |
| 406 test_bindings_.AddBinding(this, std::move(request)); | 290 test_bindings_.AddBinding(this, std::move(request)); |
| 407 } | 291 } |
| 408 | 292 |
| 293 ViewportMetrics ScreenManagerOzone::GetViewportMetricsForDisplay( | |
| 294 const Display& display) { | |
| 295 const ManagedDisplayInfo& managed_info = | |
|
rjkroege
2016/12/13 23:56:36
same comment about ManagedDisplayInfo as above.
| |
| 296 display_manager_->GetDisplayInfo(display.id()); | |
| 297 | |
| 298 ViewportMetrics metrics; | |
| 299 metrics.bounds = display.bounds(); | |
| 300 metrics.work_area = display.work_area(); | |
| 301 metrics.pixel_size = managed_info.bounds_in_native().size(); | |
| 302 metrics.rotation = display.rotation(); | |
| 303 metrics.touch_support = display.touch_support(); | |
| 304 metrics.device_scale_factor = display.device_scale_factor(); | |
| 305 metrics.ui_scale_factor = managed_info.configured_ui_scale(); | |
| 306 | |
| 307 return metrics; | |
| 308 } | |
| 309 | |
| 310 void ScreenManagerOzone::CreateOrUpdateMirroringDisplay( | |
| 311 const DisplayInfoList& display_info_list) { | |
| 312 NOTIMPLEMENTED(); | |
| 313 } | |
| 314 | |
| 315 void ScreenManagerOzone::CloseMirroringDisplayIfNotNecessary() { | |
| 316 NOTIMPLEMENTED(); | |
| 317 } | |
| 318 | |
| 319 void ScreenManagerOzone::PreDisplayConfigurationChange(bool clear_focus) { | |
| 320 DVLOG(1) << "PreDisplayConfigurationChange"; | |
| 321 } | |
| 322 | |
| 323 void ScreenManagerOzone::PostDisplayConfigurationChange( | |
|
rjkroege
2016/12/13 23:56:36
I think we need some UML sequence diagrams for thi
kylechar
2016/12/16 21:25:08
Agreed :)
| |
| 324 bool must_clear_window) { | |
| 325 // Set primary display if not set yet. | |
| 326 if (primary_display_id_ == kInvalidDisplayId) { | |
| 327 const Display& primary_display = | |
| 328 display_manager_->GetPrimaryDisplayCandidate(); | |
| 329 if (primary_display.is_valid()) { | |
| 330 primary_display_id_ = primary_display.id(); | |
| 331 DVLOG(1) << "Set primary display to " << primary_display_id_; | |
| 332 screen_->display_list().UpdateDisplay(primary_display, | |
| 333 DisplayList::Type::PRIMARY); | |
| 334 delegate_->OnPrimaryDisplayChanged(primary_display_id_); | |
| 335 } | |
| 336 } | |
| 337 | |
| 338 DVLOG(1) << "PostDisplayConfigurationChange"; | |
| 339 } | |
| 340 | |
| 341 ui::DisplayConfigurator* ScreenManagerOzone::display_configurator() { | |
| 342 return &display_configurator_; | |
| 343 } | |
| 344 | |
| 345 void ScreenManagerOzone::OnDisplayAdded(const Display& display) { | |
| 346 ViewportMetrics metrics = GetViewportMetricsForDisplay(display); | |
| 347 DVLOG(1) << "OnDisplayAdded " << display.ToString() << ", " | |
| 348 << metrics.ToString(); | |
| 349 screen_->display_list().AddDisplay(display, DisplayList::Type::NOT_PRIMARY); | |
| 350 delegate_->OnDisplayAdded(display.id(), metrics); | |
| 351 } | |
| 352 | |
| 353 void ScreenManagerOzone::OnDisplayRemoved(const Display& display) { | |
| 354 // TODO(kylechar): If we're removing the primary display we need to first set | |
| 355 // a new primary display. This will crash until then. | |
| 356 | |
| 357 DVLOG(1) << "OnDisplayRemoved " << display.ToString(); | |
| 358 screen_->display_list().RemoveDisplay(display.id()); | |
| 359 delegate_->OnDisplayRemoved(display.id()); | |
| 360 } | |
| 361 | |
| 362 void ScreenManagerOzone::OnDisplayMetricsChanged(const Display& display, | |
| 363 uint32_t changed_metrics) { | |
| 364 ViewportMetrics metrics = GetViewportMetricsForDisplay(display); | |
| 365 DVLOG(1) << "OnDisplayModified " << display.ToString() << ", " | |
| 366 << metrics.ToString(); | |
| 367 screen_->display_list().UpdateDisplay(display); | |
| 368 delegate_->OnDisplayModified(display.id(), metrics); | |
| 369 } | |
| 370 | |
| 409 } // namespace display | 371 } // namespace display |
| OLD | NEW |