OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "ash/display/display_manager.h" | 5 #include "ash/display/display_manager.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <cmath> | 8 #include <cmath> |
9 #include <limits> | 9 #include <limits> |
10 #include <map> | 10 #include <map> |
11 #include <set> | 11 #include <set> |
12 #include <string> | 12 #include <string> |
13 #include <utility> | 13 #include <utility> |
14 #include <vector> | 14 #include <vector> |
15 | 15 |
16 #include "ash/common/ash_switches.h" | 16 #include "ash/common/ash_switches.h" |
17 #include "ash/display/display_util.h" | 17 #include "ash/display/display_util.h" |
18 #include "ash/display/screen_ash.h" | |
19 #include "ash/screen_util.h" | 18 #include "ash/screen_util.h" |
20 #include "ash/shell.h" | 19 #include "ash/shell.h" |
21 #include "base/auto_reset.h" | 20 #include "base/auto_reset.h" |
22 #include "base/command_line.h" | 21 #include "base/command_line.h" |
23 #include "base/logging.h" | 22 #include "base/logging.h" |
24 #include "base/memory/ptr_util.h" | 23 #include "base/memory/ptr_util.h" |
25 #include "base/metrics/histogram.h" | 24 #include "base/metrics/histogram.h" |
26 #include "base/run_loop.h" | 25 #include "base/run_loop.h" |
27 #include "base/strings/string_number_conversions.h" | 26 #include "base/strings/string_number_conversions.h" |
28 #include "base/strings/string_split.h" | 27 #include "base/strings/string_split.h" |
(...skipping 21 matching lines...) Expand all Loading... |
50 #endif | 49 #endif |
51 | 50 |
52 #if defined(OS_WIN) | 51 #if defined(OS_WIN) |
53 #include "base/win/windows_version.h" | 52 #include "base/win/windows_version.h" |
54 #endif | 53 #endif |
55 | 54 |
56 namespace ash { | 55 namespace ash { |
57 | 56 |
58 namespace { | 57 namespace { |
59 | 58 |
60 // We need to keep this in order for unittests to tell if | |
61 // the object in display::Screen::GetScreenByType is for shutdown. | |
62 display::Screen* screen_for_shutdown = nullptr; | |
63 | |
64 // The number of pixels to overlap between the primary and secondary displays, | 59 // The number of pixels to overlap between the primary and secondary displays, |
65 // in case that the offset value is too large. | 60 // in case that the offset value is too large. |
66 const int kMinimumOverlapForInvalidOffset = 100; | 61 const int kMinimumOverlapForInvalidOffset = 100; |
67 | 62 |
68 struct DisplaySortFunctor { | 63 struct DisplaySortFunctor { |
69 bool operator()(const display::Display& a, const display::Display& b) { | 64 bool operator()(const display::Display& a, const display::Display& b) { |
70 return display::CompareDisplayIds(a.id(), b.id()); | 65 return display::CompareDisplayIds(a.id(), b.id()); |
71 } | 66 } |
72 }; | 67 }; |
73 | 68 |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
124 } | 119 } |
125 | 120 |
126 } // namespace | 121 } // namespace |
127 | 122 |
128 using std::string; | 123 using std::string; |
129 using std::vector; | 124 using std::vector; |
130 | 125 |
131 // static | 126 // static |
132 int64_t DisplayManager::kUnifiedDisplayId = -10; | 127 int64_t DisplayManager::kUnifiedDisplayId = -10; |
133 | 128 |
134 DisplayManager::DisplayManager() | 129 DisplayManager::DisplayManager(std::unique_ptr<display::Screen> screen) |
135 : delegate_(nullptr), | 130 : delegate_(nullptr), |
136 screen_(new ScreenAsh), | 131 screen_(std::move(screen)), |
137 layout_store_(new display::DisplayLayoutStore), | 132 layout_store_(new display::DisplayLayoutStore), |
138 first_display_id_(display::Display::kInvalidDisplayID), | 133 first_display_id_(display::Display::kInvalidDisplayID), |
139 num_connected_displays_(0), | 134 num_connected_displays_(0), |
140 force_bounds_changed_(false), | 135 force_bounds_changed_(false), |
141 change_display_upon_host_resize_(false), | 136 change_display_upon_host_resize_(false), |
142 multi_display_mode_(EXTENDED), | 137 multi_display_mode_(EXTENDED), |
143 current_default_multi_display_mode_(EXTENDED), | 138 current_default_multi_display_mode_(EXTENDED), |
144 mirroring_display_id_(display::Display::kInvalidDisplayID), | 139 mirroring_display_id_(display::Display::kInvalidDisplayID), |
145 registered_internal_display_rotation_lock_(false), | 140 registered_internal_display_rotation_lock_(false), |
146 registered_internal_display_rotation_(display::Display::ROTATE_0), | 141 registered_internal_display_rotation_(display::Display::ROTATE_0), |
147 unified_desktop_enabled_(false), | 142 unified_desktop_enabled_(false), |
148 weak_ptr_factory_(this) { | 143 weak_ptr_factory_(this) { |
149 #if defined(OS_CHROMEOS) | 144 #if defined(OS_CHROMEOS) |
150 change_display_upon_host_resize_ = !base::SysInfo::IsRunningOnChromeOS(); | 145 change_display_upon_host_resize_ = !base::SysInfo::IsRunningOnChromeOS(); |
151 unified_desktop_enabled_ = base::CommandLine::ForCurrentProcess()->HasSwitch( | 146 unified_desktop_enabled_ = base::CommandLine::ForCurrentProcess()->HasSwitch( |
152 switches::kAshEnableUnifiedDesktop); | 147 switches::kAshEnableUnifiedDesktop); |
153 #endif | 148 #endif |
154 display::Screen* current = display::Screen::GetScreen(); | |
155 // If there is no native, or the native was for shutdown, | |
156 // use ash's screen. | |
157 if (!current || current == screen_for_shutdown) | |
158 display::Screen::SetScreenInstance(screen_.get()); | |
159 } | 149 } |
160 | 150 |
161 DisplayManager::~DisplayManager() { | 151 DisplayManager::~DisplayManager() { |
162 #if defined(OS_CHROMEOS) | 152 #if defined(OS_CHROMEOS) |
163 // Reset the font params. | 153 // Reset the font params. |
164 gfx::SetFontRenderParamsDeviceScaleFactor(1.0f); | 154 gfx::SetFontRenderParamsDeviceScaleFactor(1.0f); |
165 #endif | 155 #endif |
166 } | 156 } |
167 | 157 |
168 bool DisplayManager::InitFromCommandLine() { | 158 bool DisplayManager::InitFromCommandLine() { |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
257 | 247 |
258 layout_store_->RegisterLayoutForDisplayIdList(list, std::move(layout)); | 248 layout_store_->RegisterLayoutForDisplayIdList(list, std::move(layout)); |
259 if (delegate_) | 249 if (delegate_) |
260 delegate_->PreDisplayConfigurationChange(false); | 250 delegate_->PreDisplayConfigurationChange(false); |
261 | 251 |
262 // TODO(oshima): Call UpdateDisplays instead. | 252 // TODO(oshima): Call UpdateDisplays instead. |
263 std::vector<int64_t> updated_ids; | 253 std::vector<int64_t> updated_ids; |
264 ApplyDisplayLayout(GetCurrentDisplayLayout(), &active_display_list_, | 254 ApplyDisplayLayout(GetCurrentDisplayLayout(), &active_display_list_, |
265 &updated_ids); | 255 &updated_ids); |
266 for (int64_t id : updated_ids) { | 256 for (int64_t id : updated_ids) { |
267 screen_->NotifyMetricsChanged( | 257 NotifyMetricsChanged( |
268 GetDisplayForId(id), | 258 GetDisplayForId(id), |
269 display::DisplayObserver::DISPLAY_METRIC_BOUNDS | | 259 display::DisplayObserver::DISPLAY_METRIC_BOUNDS | |
270 display::DisplayObserver::DISPLAY_METRIC_WORK_AREA); | 260 display::DisplayObserver::DISPLAY_METRIC_WORK_AREA); |
271 } | 261 } |
272 | 262 |
273 if (delegate_) | 263 if (delegate_) |
274 delegate_->PostDisplayConfigurationChange(); | 264 delegate_->PostDisplayConfigurationChange(); |
275 } | 265 } |
276 | 266 |
277 const display::Display& DisplayManager::GetDisplayForId(int64_t id) const { | 267 const display::Display& DisplayManager::GetDisplayForId(int64_t id) const { |
(...skipping 10 matching lines...) Expand all Loading... |
288 } | 278 } |
289 | 279 |
290 bool DisplayManager::UpdateWorkAreaOfDisplay(int64_t display_id, | 280 bool DisplayManager::UpdateWorkAreaOfDisplay(int64_t display_id, |
291 const gfx::Insets& insets) { | 281 const gfx::Insets& insets) { |
292 display::Display* display = FindDisplayForId(display_id); | 282 display::Display* display = FindDisplayForId(display_id); |
293 DCHECK(display); | 283 DCHECK(display); |
294 gfx::Rect old_work_area = display->work_area(); | 284 gfx::Rect old_work_area = display->work_area(); |
295 display->UpdateWorkAreaFromInsets(insets); | 285 display->UpdateWorkAreaFromInsets(insets); |
296 bool workarea_changed = old_work_area != display->work_area(); | 286 bool workarea_changed = old_work_area != display->work_area(); |
297 if (workarea_changed) { | 287 if (workarea_changed) { |
298 screen_->NotifyMetricsChanged( | 288 NotifyMetricsChanged(*display, |
299 *display, display::DisplayObserver::DISPLAY_METRIC_WORK_AREA); | 289 display::DisplayObserver::DISPLAY_METRIC_WORK_AREA); |
300 } | 290 } |
301 return workarea_changed; | 291 return workarea_changed; |
302 } | 292 } |
303 | 293 |
304 void DisplayManager::SetOverscanInsets(int64_t display_id, | 294 void DisplayManager::SetOverscanInsets(int64_t display_id, |
305 const gfx::Insets& insets_in_dip) { | 295 const gfx::Insets& insets_in_dip) { |
306 bool update = false; | 296 bool update = false; |
307 DisplayInfoList display_info_list; | 297 DisplayInfoList display_info_list; |
308 for (const auto& display : active_display_list_) { | 298 for (const auto& display : active_display_list_) { |
309 display::ManagedDisplayInfo info = GetDisplayInfo(display.id()); | 299 display::ManagedDisplayInfo info = GetDisplayInfo(display.id()); |
(...skipping 490 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
800 base::AutoReset<bool> resetter(&change_display_upon_host_resize_, false); | 790 base::AutoReset<bool> resetter(&change_display_upon_host_resize_, false); |
801 | 791 |
802 int active_display_list_size = active_display_list_.size(); | 792 int active_display_list_size = active_display_list_.size(); |
803 is_updating_display_list_ = true; | 793 is_updating_display_list_ = true; |
804 // Temporarily add displays to be removed because display object | 794 // Temporarily add displays to be removed because display object |
805 // being removed are accessed during shutting down the root. | 795 // being removed are accessed during shutting down the root. |
806 active_display_list_.insert(active_display_list_.end(), | 796 active_display_list_.insert(active_display_list_.end(), |
807 removed_displays.begin(), removed_displays.end()); | 797 removed_displays.begin(), removed_displays.end()); |
808 | 798 |
809 for (const auto& display : removed_displays) | 799 for (const auto& display : removed_displays) |
810 screen_->NotifyDisplayRemoved(display); | 800 NotifyDisplayRemoved(display); |
811 | 801 |
812 for (size_t index : added_display_indices) | 802 for (size_t index : added_display_indices) |
813 screen_->NotifyDisplayAdded(active_display_list_[index]); | 803 NotifyDisplayAdded(active_display_list_[index]); |
814 | 804 |
815 active_display_list_.resize(active_display_list_size); | 805 active_display_list_.resize(active_display_list_size); |
816 is_updating_display_list_ = false; | 806 is_updating_display_list_ = false; |
817 | 807 |
818 bool notify_primary_change = | 808 bool notify_primary_change = |
819 delegate_ ? old_primary.id() != screen_->GetPrimaryDisplay().id() : false; | 809 delegate_ ? old_primary.id() != screen_->GetPrimaryDisplay().id() : false; |
820 | 810 |
821 for (std::map<size_t, uint32_t>::iterator iter = display_changes.begin(); | 811 for (std::map<size_t, uint32_t>::iterator iter = display_changes.begin(); |
822 iter != display_changes.end(); ++iter) { | 812 iter != display_changes.end(); ++iter) { |
823 uint32_t metrics = iter->second; | 813 uint32_t metrics = iter->second; |
824 const display::Display& updated_display = active_display_list_[iter->first]; | 814 const display::Display& updated_display = active_display_list_[iter->first]; |
825 | 815 |
826 if (notify_primary_change && | 816 if (notify_primary_change && |
827 updated_display.id() == screen_->GetPrimaryDisplay().id()) { | 817 updated_display.id() == screen_->GetPrimaryDisplay().id()) { |
828 metrics |= display::DisplayObserver::DISPLAY_METRIC_PRIMARY; | 818 metrics |= display::DisplayObserver::DISPLAY_METRIC_PRIMARY; |
829 notify_primary_change = false; | 819 notify_primary_change = false; |
830 } | 820 } |
831 screen_->NotifyMetricsChanged(updated_display, metrics); | 821 NotifyMetricsChanged(updated_display, metrics); |
832 } | 822 } |
833 | 823 |
834 if (notify_primary_change) { | 824 if (notify_primary_change) { |
835 // This happens when a primary display has moved to anther display without | 825 // This happens when a primary display has moved to anther display without |
836 // bounds change. | 826 // bounds change. |
837 const display::Display& primary = screen_->GetPrimaryDisplay(); | 827 const display::Display& primary = screen_->GetPrimaryDisplay(); |
838 if (primary.id() != old_primary.id()) { | 828 if (primary.id() != old_primary.id()) { |
839 uint32_t metrics = display::DisplayObserver::DISPLAY_METRIC_PRIMARY; | 829 uint32_t metrics = display::DisplayObserver::DISPLAY_METRIC_PRIMARY; |
840 if (primary.size() != old_primary.size()) { | 830 if (primary.size() != old_primary.size()) { |
841 metrics |= (display::DisplayObserver::DISPLAY_METRIC_BOUNDS | | 831 metrics |= (display::DisplayObserver::DISPLAY_METRIC_BOUNDS | |
842 display::DisplayObserver::DISPLAY_METRIC_WORK_AREA); | 832 display::DisplayObserver::DISPLAY_METRIC_WORK_AREA); |
843 } | 833 } |
844 if (primary.device_scale_factor() != old_primary.device_scale_factor()) | 834 if (primary.device_scale_factor() != old_primary.device_scale_factor()) |
845 metrics |= display::DisplayObserver::DISPLAY_METRIC_DEVICE_SCALE_FACTOR; | 835 metrics |= display::DisplayObserver::DISPLAY_METRIC_DEVICE_SCALE_FACTOR; |
846 | 836 |
847 screen_->NotifyMetricsChanged(primary, metrics); | 837 NotifyMetricsChanged(primary, metrics); |
848 } | 838 } |
849 } | 839 } |
850 | 840 |
851 if (delegate_) | 841 if (delegate_) |
852 delegate_->PostDisplayConfigurationChange(); | 842 delegate_->PostDisplayConfigurationChange(); |
853 | 843 |
854 #if defined(USE_X11) && defined(OS_CHROMEOS) | 844 #if defined(USE_X11) && defined(OS_CHROMEOS) |
855 if (!display_changes.empty() && base::SysInfo::IsRunningOnChromeOS()) | 845 if (!display_changes.empty() && base::SysInfo::IsRunningOnChromeOS()) |
856 ui::ClearX11DefaultRootWindow(); | 846 ui::ClearX11DefaultRootWindow(); |
857 #endif | 847 #endif |
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1043 | 1033 |
1044 bool DisplayManager::UpdateDisplayBounds(int64_t display_id, | 1034 bool DisplayManager::UpdateDisplayBounds(int64_t display_id, |
1045 const gfx::Rect& new_bounds) { | 1035 const gfx::Rect& new_bounds) { |
1046 if (change_display_upon_host_resize_) { | 1036 if (change_display_upon_host_resize_) { |
1047 display_info_[display_id].SetBounds(new_bounds); | 1037 display_info_[display_id].SetBounds(new_bounds); |
1048 // Don't notify observers if the mirrored window has changed. | 1038 // Don't notify observers if the mirrored window has changed. |
1049 if (software_mirroring_enabled() && mirroring_display_id_ == display_id) | 1039 if (software_mirroring_enabled() && mirroring_display_id_ == display_id) |
1050 return false; | 1040 return false; |
1051 display::Display* display = FindDisplayForId(display_id); | 1041 display::Display* display = FindDisplayForId(display_id); |
1052 display->SetSize(display_info_[display_id].size_in_pixel()); | 1042 display->SetSize(display_info_[display_id].size_in_pixel()); |
1053 screen_->NotifyMetricsChanged( | 1043 NotifyMetricsChanged(*display, |
1054 *display, display::DisplayObserver::DISPLAY_METRIC_BOUNDS); | 1044 display::DisplayObserver::DISPLAY_METRIC_BOUNDS); |
1055 return true; | 1045 return true; |
1056 } | 1046 } |
1057 return false; | 1047 return false; |
1058 } | 1048 } |
1059 | 1049 |
1060 void DisplayManager::CreateMirrorWindowAsyncIfAny() { | 1050 void DisplayManager::CreateMirrorWindowAsyncIfAny() { |
1061 // Do not post a task if the software mirroring doesn't exist, or | 1051 // Do not post a task if the software mirroring doesn't exist, or |
1062 // during initialization when compositor's init task isn't posted yet. | 1052 // during initialization when compositor's init task isn't posted yet. |
1063 // ash::Shell::Init() will call this after the compositor is initialized. | 1053 // ash::Shell::Init() will call this after the compositor is initialized. |
1064 if (software_mirroring_display_list_.empty() || !delegate_) | 1054 if (software_mirroring_display_list_.empty() || !delegate_) |
1065 return; | 1055 return; |
1066 base::ThreadTaskRunnerHandle::Get()->PostTask( | 1056 base::ThreadTaskRunnerHandle::Get()->PostTask( |
1067 FROM_HERE, base::Bind(&DisplayManager::CreateMirrorWindowIfAny, | 1057 FROM_HERE, base::Bind(&DisplayManager::CreateMirrorWindowIfAny, |
1068 weak_ptr_factory_.GetWeakPtr())); | 1058 weak_ptr_factory_.GetWeakPtr())); |
1069 } | 1059 } |
1070 | 1060 |
1071 void DisplayManager::CreateScreenForShutdown() const { | |
1072 delete screen_for_shutdown; | |
1073 screen_for_shutdown = screen_->CloneForShutdown(); | |
1074 display::Screen::SetScreenInstance(screen_for_shutdown); | |
1075 } | |
1076 | |
1077 void DisplayManager::UpdateInternalManagedDisplayModeListForTest() { | 1061 void DisplayManager::UpdateInternalManagedDisplayModeListForTest() { |
1078 if (!display::Display::HasInternalDisplay() || | 1062 if (!display::Display::HasInternalDisplay() || |
1079 display_info_.count(display::Display::InternalDisplayId()) == 0) | 1063 display_info_.count(display::Display::InternalDisplayId()) == 0) |
1080 return; | 1064 return; |
1081 display::ManagedDisplayInfo* info = | 1065 display::ManagedDisplayInfo* info = |
1082 &display_info_[display::Display::InternalDisplayId()]; | 1066 &display_info_[display::Display::InternalDisplayId()]; |
1083 SetInternalManagedDisplayModeList(info); | 1067 SetInternalManagedDisplayModeList(info); |
1084 } | 1068 } |
1085 | 1069 |
1086 bool DisplayManager::ZoomInternalDisplay(bool up) { | 1070 bool DisplayManager::ZoomInternalDisplay(bool up) { |
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1392 std::vector<int64_t>* updated_ids) { | 1376 std::vector<int64_t>* updated_ids) { |
1393 layout.ApplyToDisplayList(display_list, updated_ids, | 1377 layout.ApplyToDisplayList(display_list, updated_ids, |
1394 kMinimumOverlapForInvalidOffset); | 1378 kMinimumOverlapForInvalidOffset); |
1395 } | 1379 } |
1396 | 1380 |
1397 void DisplayManager::RunPendingTasksForTest() { | 1381 void DisplayManager::RunPendingTasksForTest() { |
1398 if (!software_mirroring_display_list_.empty()) | 1382 if (!software_mirroring_display_list_.empty()) |
1399 base::RunLoop().RunUntilIdle(); | 1383 base::RunLoop().RunUntilIdle(); |
1400 } | 1384 } |
1401 | 1385 |
| 1386 void DisplayManager::NotifyMetricsChanged(const display::Display& display, |
| 1387 uint32_t metrics) { |
| 1388 FOR_EACH_OBSERVER(display::DisplayObserver, observers_, |
| 1389 OnDisplayMetricsChanged(display, metrics)); |
| 1390 } |
| 1391 |
| 1392 void DisplayManager::NotifyDisplayAdded(const display::Display& display) { |
| 1393 FOR_EACH_OBSERVER(display::DisplayObserver, observers_, |
| 1394 OnDisplayAdded(display)); |
| 1395 } |
| 1396 |
| 1397 void DisplayManager::NotifyDisplayRemoved(const display::Display& display) { |
| 1398 FOR_EACH_OBSERVER(display::DisplayObserver, observers_, |
| 1399 OnDisplayRemoved(display)); |
| 1400 } |
| 1401 |
| 1402 void DisplayManager::AddObserver(display::DisplayObserver* observer) { |
| 1403 observers_.AddObserver(observer); |
| 1404 } |
| 1405 |
| 1406 void DisplayManager::RemoveObserver(display::DisplayObserver* observer) { |
| 1407 observers_.RemoveObserver(observer); |
| 1408 } |
| 1409 |
1402 } // namespace ash | 1410 } // namespace ash |
OLD | NEW |