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 <set> | 9 #include <set> |
10 #include <string> | 10 #include <string> |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
44 | 44 |
45 #if defined(OS_CHROMEOS) | 45 #if defined(OS_CHROMEOS) |
46 #include "ash/display/display_configurator_animation.h" | 46 #include "ash/display/display_configurator_animation.h" |
47 #include "base/sys_info.h" | 47 #include "base/sys_info.h" |
48 #endif | 48 #endif |
49 | 49 |
50 #if defined(OS_WIN) | 50 #if defined(OS_WIN) |
51 #include "base/win/windows_version.h" | 51 #include "base/win/windows_version.h" |
52 #endif | 52 #endif |
53 | 53 |
54 #include "base/debug/stack_trace.h" | |
55 | |
56 namespace ash { | 54 namespace ash { |
57 typedef std::vector<gfx::Display> DisplayList; | 55 typedef std::vector<gfx::Display> DisplayList; |
58 typedef std::vector<DisplayInfo> DisplayInfoList; | 56 typedef std::vector<DisplayInfo> DisplayInfoList; |
59 | 57 |
60 namespace { | 58 namespace { |
61 | 59 |
62 // We need to keep this in order for unittests to tell if | 60 // We need to keep this in order for unittests to tell if |
63 // the object in gfx::Screen::GetScreenByType is for shutdown. | 61 // the object in gfx::Screen::GetScreenByType is for shutdown. |
64 gfx::Screen* screen_for_shutdown = NULL; | 62 gfx::Screen* screen_for_shutdown = NULL; |
65 | 63 |
66 // The number of pixels to overlap between the primary and secondary displays, | 64 // The number of pixels to overlap between the primary and secondary displays, |
67 // in case that the offset value is too large. | 65 // in case that the offset value is too large. |
68 const int kMinimumOverlapForInvalidOffset = 100; | 66 const int kMinimumOverlapForInvalidOffset = 100; |
69 | 67 |
70 struct DisplaySortFunctor { | 68 struct DisplaySortFunctor { |
71 bool operator()(const gfx::Display& a, const gfx::Display& b) { | 69 bool operator()(const gfx::Display& a, const gfx::Display& b) { |
72 return a.id() < b.id(); | 70 return CompareDisplayIds(a.id(), b.id()); |
73 } | 71 } |
74 }; | 72 }; |
75 | 73 |
76 struct DisplayInfoSortFunctor { | 74 struct DisplayInfoSortFunctor { |
77 bool operator()(const DisplayInfo& a, const DisplayInfo& b) { | 75 bool operator()(const DisplayInfo& a, const DisplayInfo& b) { |
78 return a.id() < b.id(); | 76 return CompareDisplayIds(a.id(), b.id()); |
79 } | 77 } |
80 }; | 78 }; |
81 | 79 |
82 gfx::Display& GetInvalidDisplay() { | 80 gfx::Display& GetInvalidDisplay() { |
83 static gfx::Display* invalid_display = new gfx::Display(); | 81 static gfx::Display* invalid_display = new gfx::Display(); |
84 return *invalid_display; | 82 return *invalid_display; |
85 } | 83 } |
86 | 84 |
87 std::vector<DisplayMode>::const_iterator FindDisplayMode( | 85 std::vector<DisplayMode>::const_iterator FindDisplayMode( |
88 const DisplayInfo& info, | 86 const DisplayInfo& info, |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
130 | 128 |
131 DisplayManager::DisplayManager() | 129 DisplayManager::DisplayManager() |
132 : delegate_(NULL), | 130 : delegate_(NULL), |
133 screen_(new ScreenAsh), | 131 screen_(new ScreenAsh), |
134 layout_store_(new DisplayLayoutStore), | 132 layout_store_(new DisplayLayoutStore), |
135 first_display_id_(gfx::Display::kInvalidDisplayID), | 133 first_display_id_(gfx::Display::kInvalidDisplayID), |
136 num_connected_displays_(0), | 134 num_connected_displays_(0), |
137 force_bounds_changed_(false), | 135 force_bounds_changed_(false), |
138 change_display_upon_host_resize_(false), | 136 change_display_upon_host_resize_(false), |
139 multi_display_mode_(EXTENDED), | 137 multi_display_mode_(EXTENDED), |
140 default_multi_display_mode_(EXTENDED), | 138 current_default_multi_display_mode_(EXTENDED), |
141 mirroring_display_id_(gfx::Display::kInvalidDisplayID), | 139 mirroring_display_id_(gfx::Display::kInvalidDisplayID), |
142 registered_internal_display_rotation_lock_(false), | 140 registered_internal_display_rotation_lock_(false), |
143 registered_internal_display_rotation_(gfx::Display::ROTATE_0), | 141 registered_internal_display_rotation_(gfx::Display::ROTATE_0), |
| 142 unified_desktop_enabled_(false), |
144 weak_ptr_factory_(this) { | 143 weak_ptr_factory_(this) { |
145 #if defined(OS_CHROMEOS) | 144 #if defined(OS_CHROMEOS) |
146 change_display_upon_host_resize_ = !base::SysInfo::IsRunningOnChromeOS(); | 145 change_display_upon_host_resize_ = !base::SysInfo::IsRunningOnChromeOS(); |
| 146 unified_desktop_enabled_ = base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 147 switches::kAshEnableUnifiedDesktop); |
147 #endif | 148 #endif |
148 gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_ALTERNATE, screen_.get()); | 149 gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_ALTERNATE, screen_.get()); |
149 gfx::Screen* current_native = | 150 gfx::Screen* current_native = |
150 gfx::Screen::GetScreenByType(gfx::SCREEN_TYPE_NATIVE); | 151 gfx::Screen::GetScreenByType(gfx::SCREEN_TYPE_NATIVE); |
151 // If there is no native, or the native was for shutdown, | 152 // If there is no native, or the native was for shutdown, |
152 // use ash's screen. | 153 // use ash's screen. |
153 if (!current_native || | 154 if (!current_native || |
154 current_native == screen_for_shutdown) { | 155 current_native == screen_for_shutdown) { |
155 gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE, screen_.get()); | 156 gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE, screen_.get()); |
156 } | 157 } |
(...skipping 457 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
614 // active again. | 615 // active again. |
615 gfx::Display::Rotation user_rotation = | 616 gfx::Display::Rotation user_rotation = |
616 display_info_[gfx::Display::InternalDisplayId()].GetRotation( | 617 display_info_[gfx::Display::InternalDisplayId()].GetRotation( |
617 gfx::Display::ROTATION_SOURCE_USER); | 618 gfx::Display::ROTATION_SOURCE_USER); |
618 display_info_[gfx::Display::InternalDisplayId()].SetRotation( | 619 display_info_[gfx::Display::InternalDisplayId()].SetRotation( |
619 user_rotation, gfx::Display::ROTATION_SOURCE_USER); | 620 user_rotation, gfx::Display::ROTATION_SOURCE_USER); |
620 } | 621 } |
621 } | 622 } |
622 | 623 |
623 #if defined(OS_CHROMEOS) | 624 #if defined(OS_CHROMEOS) |
624 if (new_display_info_list.size() > 1) { | 625 if (!base::SysInfo::IsRunningOnChromeOS() && |
625 std::sort(new_display_info_list.begin(), new_display_info_list.end(), | 626 new_display_info_list.size() > 1) { |
626 DisplayInfoSortFunctor()); | |
627 DisplayIdPair pair = CreateDisplayIdPair(new_display_info_list[0].id(), | 627 DisplayIdPair pair = CreateDisplayIdPair(new_display_info_list[0].id(), |
628 new_display_info_list[1].id()); | 628 new_display_info_list[1].id()); |
629 DisplayLayout layout = layout_store_->GetRegisteredDisplayLayout(pair); | 629 DisplayLayout layout = layout_store_->GetRegisteredDisplayLayout(pair); |
630 default_multi_display_mode_ = | |
631 (layout.default_unified && switches::UnifiedDesktopEnabled()) | |
632 ? UNIFIED | |
633 : EXTENDED; | |
634 // Mirror mode is set by DisplayConfigurator on the device. | 630 // Mirror mode is set by DisplayConfigurator on the device. |
635 // Emulate it when running on linux desktop. | 631 // Emulate it when running on linux desktop. |
636 if (!base::SysInfo::IsRunningOnChromeOS() && layout.mirrored) | 632 if (layout.mirrored) |
637 SetMultiDisplayMode(MIRRORING); | 633 SetMultiDisplayMode(MIRRORING); |
638 } | 634 } |
639 #endif | 635 #endif |
640 | 636 |
641 UpdateDisplays(new_display_info_list); | 637 UpdateDisplays(new_display_info_list); |
642 } | 638 } |
643 | 639 |
644 void DisplayManager::UpdateDisplays() { | 640 void DisplayManager::UpdateDisplays() { |
645 DisplayInfoList display_info_list; | 641 DisplayInfoList display_info_list; |
646 for (const auto& display : active_display_list_) | 642 for (const auto& display : active_display_list_) |
(...skipping 10 matching lines...) Expand all Loading... |
657 "skip (don't disable) the test using SupportsMultipleDisplays()"; | 653 "skip (don't disable) the test using SupportsMultipleDisplays()"; |
658 #endif | 654 #endif |
659 | 655 |
660 DisplayInfoList new_display_info_list = updated_display_info_list; | 656 DisplayInfoList new_display_info_list = updated_display_info_list; |
661 std::sort(active_display_list_.begin(), active_display_list_.end(), | 657 std::sort(active_display_list_.begin(), active_display_list_.end(), |
662 DisplaySortFunctor()); | 658 DisplaySortFunctor()); |
663 std::sort(new_display_info_list.begin(), | 659 std::sort(new_display_info_list.begin(), |
664 new_display_info_list.end(), | 660 new_display_info_list.end(), |
665 DisplayInfoSortFunctor()); | 661 DisplayInfoSortFunctor()); |
666 | 662 |
| 663 if (new_display_info_list.size() > 1) { |
| 664 DisplayIdPair pair = CreateDisplayIdPair(new_display_info_list[0].id(), |
| 665 new_display_info_list[1].id()); |
| 666 DisplayLayout layout = layout_store_->GetRegisteredDisplayLayout(pair); |
| 667 current_default_multi_display_mode_ = |
| 668 (layout.default_unified && unified_desktop_enabled_) ? UNIFIED |
| 669 : EXTENDED; |
| 670 } |
| 671 |
667 if (multi_display_mode_ != MIRRORING) | 672 if (multi_display_mode_ != MIRRORING) |
668 multi_display_mode_ = default_multi_display_mode_; | 673 multi_display_mode_ = current_default_multi_display_mode_; |
669 | 674 |
670 CreateSoftwareMirroringDisplayInfo(&new_display_info_list); | 675 CreateSoftwareMirroringDisplayInfo(&new_display_info_list); |
671 | 676 |
672 // Close the mirroring window if any here to avoid creating two compositor on | 677 // Close the mirroring window if any here to avoid creating two compositor on |
673 // one display. | 678 // one display. |
674 if (delegate_) | 679 if (delegate_) |
675 delegate_->CloseMirroringDisplayIfNotNecessary(); | 680 delegate_->CloseMirroringDisplayIfNotNecessary(); |
676 | 681 |
677 DisplayList new_displays; | 682 DisplayList new_displays; |
678 DisplayList removed_displays; | 683 DisplayList removed_displays; |
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
864 } | 869 } |
865 | 870 |
866 size_t DisplayManager::GetNumDisplays() const { | 871 size_t DisplayManager::GetNumDisplays() const { |
867 return active_display_list_.size(); | 872 return active_display_list_.size(); |
868 } | 873 } |
869 | 874 |
870 bool DisplayManager::IsInMirrorMode() const { | 875 bool DisplayManager::IsInMirrorMode() const { |
871 return mirroring_display_id_ != gfx::Display::kInvalidDisplayID; | 876 return mirroring_display_id_ != gfx::Display::kInvalidDisplayID; |
872 } | 877 } |
873 | 878 |
| 879 void DisplayManager::SetUnifiedDesktopEnabled(bool enable) { |
| 880 unified_desktop_enabled_ = enable; |
| 881 ReconfigureDisplays(); |
| 882 } |
| 883 |
874 bool DisplayManager::IsInUnifiedMode() const { | 884 bool DisplayManager::IsInUnifiedMode() const { |
875 return multi_display_mode_ == UNIFIED && | 885 return multi_display_mode_ == UNIFIED && |
876 !software_mirroring_display_list_.empty(); | 886 !software_mirroring_display_list_.empty(); |
877 } | 887 } |
878 | 888 |
879 const DisplayInfo& DisplayManager::GetDisplayInfo(int64 display_id) const { | 889 const DisplayInfo& DisplayManager::GetDisplayInfo(int64 display_id) const { |
880 DCHECK_NE(gfx::Display::kInvalidDisplayID, display_id); | 890 DCHECK_NE(gfx::Display::kInvalidDisplayID, display_id); |
881 | 891 |
882 std::map<int64, DisplayInfo>::const_iterator iter = | 892 std::map<int64, DisplayInfo>::const_iterator iter = |
883 display_info_.find(display_id); | 893 display_info_.find(display_id); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
918 if (num_connected_displays() <= 1) | 928 if (num_connected_displays() <= 1) |
919 return; | 929 return; |
920 | 930 |
921 if (base::SysInfo::IsRunningOnChromeOS()) { | 931 if (base::SysInfo::IsRunningOnChromeOS()) { |
922 ui::MultipleDisplayState new_state = | 932 ui::MultipleDisplayState new_state = |
923 mirror ? ui::MULTIPLE_DISPLAY_STATE_DUAL_MIRROR | 933 mirror ? ui::MULTIPLE_DISPLAY_STATE_DUAL_MIRROR |
924 : ui::MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED; | 934 : ui::MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED; |
925 Shell::GetInstance()->display_configurator()->SetDisplayMode(new_state); | 935 Shell::GetInstance()->display_configurator()->SetDisplayMode(new_state); |
926 return; | 936 return; |
927 } | 937 } |
928 multi_display_mode_ = mirror ? MIRRORING : default_multi_display_mode_; | 938 multi_display_mode_ = |
| 939 mirror ? MIRRORING : current_default_multi_display_mode_; |
929 ReconfigureDisplays(); | 940 ReconfigureDisplays(); |
930 if (Shell::GetInstance()->display_configurator_animation()) { | 941 if (Shell::GetInstance()->display_configurator_animation()) { |
931 Shell::GetInstance()->display_configurator_animation()-> | 942 Shell::GetInstance()->display_configurator_animation()-> |
932 StartFadeInAnimation(); | 943 StartFadeInAnimation(); |
933 } | 944 } |
934 RunPendingTasksForTest(); | 945 RunPendingTasksForTest(); |
935 #endif | 946 #endif |
936 } | 947 } |
937 | 948 |
938 void DisplayManager::AddRemoveDisplay() { | 949 void DisplayManager::AddRemoveDisplay() { |
(...skipping 29 matching lines...) Expand all Loading... |
968 display_info.set_device_scale_factor( | 979 display_info.set_device_scale_factor( |
969 display_info.device_scale_factor() == 1.0f ? 2.0f : 1.0f); | 980 display_info.device_scale_factor() == 1.0f ? 2.0f : 1.0f); |
970 new_display_info_list.push_back(display_info); | 981 new_display_info_list.push_back(display_info); |
971 } | 982 } |
972 AddMirrorDisplayInfoIfAny(&new_display_info_list); | 983 AddMirrorDisplayInfoIfAny(&new_display_info_list); |
973 UpdateDisplays(new_display_info_list); | 984 UpdateDisplays(new_display_info_list); |
974 } | 985 } |
975 | 986 |
976 #if defined(OS_CHROMEOS) | 987 #if defined(OS_CHROMEOS) |
977 void DisplayManager::SetSoftwareMirroring(bool enabled) { | 988 void DisplayManager::SetSoftwareMirroring(bool enabled) { |
978 SetMultiDisplayMode(enabled ? MIRRORING : default_multi_display_mode_); | 989 SetMultiDisplayMode(enabled ? MIRRORING |
| 990 : current_default_multi_display_mode_); |
979 } | 991 } |
980 | 992 |
981 bool DisplayManager::SoftwareMirroringEnabled() const { | 993 bool DisplayManager::SoftwareMirroringEnabled() const { |
982 return software_mirroring_enabled(); | 994 return software_mirroring_enabled(); |
983 } | 995 } |
984 #endif | 996 #endif |
985 | 997 |
| 998 void DisplayManager::SetDefaultMultiDisplayModeForCurrentDisplays( |
| 999 MultiDisplayMode mode) { |
| 1000 DCHECK_NE(MIRRORING, mode); |
| 1001 DisplayIdPair pair = GetCurrentDisplayIdPair(); |
| 1002 layout_store_->UpdateMultiDisplayState(pair, IsInMirrorMode(), |
| 1003 mode == UNIFIED); |
| 1004 } |
| 1005 |
986 void DisplayManager::SetMultiDisplayMode(MultiDisplayMode mode) { | 1006 void DisplayManager::SetMultiDisplayMode(MultiDisplayMode mode) { |
987 multi_display_mode_ = mode; | 1007 multi_display_mode_ = mode; |
988 mirroring_display_id_ = gfx::Display::kInvalidDisplayID; | 1008 mirroring_display_id_ = gfx::Display::kInvalidDisplayID; |
989 software_mirroring_display_list_.clear(); | 1009 software_mirroring_display_list_.clear(); |
990 } | 1010 } |
991 | 1011 |
992 void DisplayManager::SetDefaultMultiDisplayMode(MultiDisplayMode mode) { | |
993 DCHECK_NE(mode, MIRRORING); | |
994 default_multi_display_mode_ = mode; | |
995 } | |
996 | |
997 void DisplayManager::ReconfigureDisplays() { | 1012 void DisplayManager::ReconfigureDisplays() { |
998 DisplayInfoList display_info_list; | 1013 DisplayInfoList display_info_list; |
999 for (DisplayList::const_iterator iter = active_display_list_.begin(); | 1014 for (DisplayList::const_iterator iter = active_display_list_.begin(); |
1000 (display_info_list.size() < 2 && iter != active_display_list_.end()); | 1015 (display_info_list.size() < 2 && iter != active_display_list_.end()); |
1001 ++iter) { | 1016 ++iter) { |
1002 if (iter->id() == kUnifiedDisplayId) | 1017 if (iter->id() == kUnifiedDisplayId) |
1003 continue; | 1018 continue; |
1004 display_info_list.push_back(GetDisplayInfo(iter->id())); | 1019 display_info_list.push_back(GetDisplayInfo(iter->id())); |
1005 } | 1020 } |
1006 for (auto iter = software_mirroring_display_list_.begin(); | 1021 for (auto iter = software_mirroring_display_list_.begin(); |
(...skipping 379 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1386 gfx::Rect(new_secondary_origin, secondary_bounds.size())); | 1401 gfx::Rect(new_secondary_origin, secondary_bounds.size())); |
1387 secondary_display->UpdateWorkAreaFromInsets(insets); | 1402 secondary_display->UpdateWorkAreaFromInsets(insets); |
1388 } | 1403 } |
1389 | 1404 |
1390 void DisplayManager::RunPendingTasksForTest() { | 1405 void DisplayManager::RunPendingTasksForTest() { |
1391 if (!software_mirroring_display_list_.empty()) | 1406 if (!software_mirroring_display_list_.empty()) |
1392 base::RunLoop().RunUntilIdle(); | 1407 base::RunLoop().RunUntilIdle(); |
1393 } | 1408 } |
1394 | 1409 |
1395 } // namespace ash | 1410 } // namespace ash |
OLD | NEW |