Chromium Code Reviews| 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 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 42 | 42 |
| 43 #if defined(OS_CHROMEOS) | 43 #if defined(OS_CHROMEOS) |
| 44 #include "ash/display/display_configurator_animation.h" | 44 #include "ash/display/display_configurator_animation.h" |
| 45 #include "base/sys_info.h" | 45 #include "base/sys_info.h" |
| 46 #endif | 46 #endif |
| 47 | 47 |
| 48 #if defined(OS_WIN) | 48 #if defined(OS_WIN) |
| 49 #include "base/win/windows_version.h" | 49 #include "base/win/windows_version.h" |
| 50 #endif | 50 #endif |
| 51 | 51 |
| 52 #include "base/debug/stack_trace.h" | |
| 53 | |
| 52 namespace ash { | 54 namespace ash { |
| 53 typedef std::vector<gfx::Display> DisplayList; | 55 typedef std::vector<gfx::Display> DisplayList; |
| 54 typedef std::vector<DisplayInfo> DisplayInfoList; | 56 typedef std::vector<DisplayInfo> DisplayInfoList; |
| 55 | 57 |
| 56 namespace { | 58 namespace { |
| 57 | 59 |
| 58 // 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 |
| 59 // the object in gfx::Screen::GetScreenByType is for shutdown. | 61 // the object in gfx::Screen::GetScreenByType is for shutdown. |
| 60 gfx::Screen* screen_for_shutdown = NULL; | 62 gfx::Screen* screen_for_shutdown = NULL; |
| 61 | 63 |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 108 | 110 |
| 109 bool IsInternalDisplayId(int64 id) { | 111 bool IsInternalDisplayId(int64 id) { |
| 110 return gfx::Display::InternalDisplayId() == id; | 112 return gfx::Display::InternalDisplayId() == id; |
| 111 } | 113 } |
| 112 | 114 |
| 113 } // namespace | 115 } // namespace |
| 114 | 116 |
| 115 using std::string; | 117 using std::string; |
| 116 using std::vector; | 118 using std::vector; |
| 117 | 119 |
| 120 // static | |
| 121 int64 DisplayManager::kUnifiedDisplayId = -10; | |
| 122 | |
| 118 DisplayManager::DisplayManager() | 123 DisplayManager::DisplayManager() |
| 119 : delegate_(NULL), | 124 : delegate_(NULL), |
| 120 screen_(new ScreenAsh), | 125 screen_(new ScreenAsh), |
| 121 layout_store_(new DisplayLayoutStore), | 126 layout_store_(new DisplayLayoutStore), |
| 122 first_display_id_(gfx::Display::kInvalidDisplayID), | 127 first_display_id_(gfx::Display::kInvalidDisplayID), |
| 123 num_connected_displays_(0), | 128 num_connected_displays_(0), |
| 124 force_bounds_changed_(false), | 129 force_bounds_changed_(false), |
| 125 change_display_upon_host_resize_(false), | 130 change_display_upon_host_resize_(false), |
| 126 second_display_mode_(EXTENDED), | 131 multi_display_mode_(EXTENDED), |
| 132 default_multi_display_mode_(EXTENDED), | |
| 127 mirroring_display_id_(gfx::Display::kInvalidDisplayID), | 133 mirroring_display_id_(gfx::Display::kInvalidDisplayID), |
| 128 registered_internal_display_rotation_lock_(false), | 134 registered_internal_display_rotation_lock_(false), |
| 129 registered_internal_display_rotation_(gfx::Display::ROTATE_0), | 135 registered_internal_display_rotation_(gfx::Display::ROTATE_0), |
| 130 weak_ptr_factory_(this) { | 136 weak_ptr_factory_(this) { |
| 131 #if defined(OS_CHROMEOS) | 137 #if defined(OS_CHROMEOS) |
| 132 // Enable only on the device so that DisplayManagerFontTest passes. | 138 // Enable only on the device so that DisplayManagerFontTest passes. |
| 133 if (base::SysInfo::IsRunningOnChromeOS()) | 139 if (base::SysInfo::IsRunningOnChromeOS()) |
| 134 DisplayInfo::SetUse125DSFForUIScaling(true); | 140 DisplayInfo::SetUse125DSFForUIScaling(true); |
| 135 | 141 |
| 142 if (switches::UnifiedDesktopEnabled()) | |
| 143 multi_display_mode_ = default_multi_display_mode_ = UNIFIED; | |
| 144 | |
| 136 change_display_upon_host_resize_ = !base::SysInfo::IsRunningOnChromeOS(); | 145 change_display_upon_host_resize_ = !base::SysInfo::IsRunningOnChromeOS(); |
| 137 #endif | 146 #endif |
| 138 gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_ALTERNATE, screen_.get()); | 147 gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_ALTERNATE, screen_.get()); |
| 139 gfx::Screen* current_native = | 148 gfx::Screen* current_native = |
| 140 gfx::Screen::GetScreenByType(gfx::SCREEN_TYPE_NATIVE); | 149 gfx::Screen::GetScreenByType(gfx::SCREEN_TYPE_NATIVE); |
| 141 // If there is no native, or the native was for shutdown, | 150 // If there is no native, or the native was for shutdown, |
| 142 // use ash's screen. | 151 // use ash's screen. |
| 143 if (!current_native || | 152 if (!current_native || |
| 144 current_native == screen_for_shutdown) { | 153 current_native == screen_for_shutdown) { |
| 145 gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE, screen_.get()); | 154 gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE, screen_.get()); |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 163 vector<string> parts; | 172 vector<string> parts; |
| 164 base::SplitString(size_str, ',', &parts); | 173 base::SplitString(size_str, ',', &parts); |
| 165 for (vector<string>::const_iterator iter = parts.begin(); | 174 for (vector<string>::const_iterator iter = parts.begin(); |
| 166 iter != parts.end(); ++iter) { | 175 iter != parts.end(); ++iter) { |
| 167 info_list.push_back(DisplayInfo::CreateFromSpec(*iter)); | 176 info_list.push_back(DisplayInfo::CreateFromSpec(*iter)); |
| 168 info_list.back().set_native(true); | 177 info_list.back().set_native(true); |
| 169 } | 178 } |
| 170 MaybeInitInternalDisplay(&info_list[0]); | 179 MaybeInitInternalDisplay(&info_list[0]); |
| 171 if (info_list.size() > 1 && | 180 if (info_list.size() > 1 && |
| 172 command_line->HasSwitch(switches::kAshEnableSoftwareMirroring)) { | 181 command_line->HasSwitch(switches::kAshEnableSoftwareMirroring)) { |
| 173 SetSecondDisplayMode(MIRRORING); | 182 SetMultiDisplayMode(MIRRORING); |
| 174 } | 183 } |
| 175 OnNativeDisplaysChanged(info_list); | 184 OnNativeDisplaysChanged(info_list); |
| 176 return true; | 185 return true; |
| 177 } | 186 } |
| 178 | 187 |
| 179 void DisplayManager::InitDefaultDisplay() { | 188 void DisplayManager::InitDefaultDisplay() { |
| 180 DisplayInfoList info_list; | 189 DisplayInfoList info_list; |
| 181 info_list.push_back(DisplayInfo::CreateFromSpec(std::string())); | 190 info_list.push_back(DisplayInfo::CreateFromSpec(std::string())); |
| 182 info_list.back().set_native(true); | 191 info_list.back().set_native(true); |
| 183 MaybeInitInternalDisplay(&info_list[0]); | 192 MaybeInitInternalDisplay(&info_list[0]); |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 212 } | 221 } |
| 213 NOTREACHED() << "DisplayLayout is requested for single display"; | 222 NOTREACHED() << "DisplayLayout is requested for single display"; |
| 214 // On release build, just fallback to default instead of blowing up. | 223 // On release build, just fallback to default instead of blowing up. |
| 215 DisplayLayout layout = | 224 DisplayLayout layout = |
| 216 layout_store_->default_display_layout(); | 225 layout_store_->default_display_layout(); |
| 217 layout.primary_id = active_display_list_[0].id(); | 226 layout.primary_id = active_display_list_[0].id(); |
| 218 return layout; | 227 return layout; |
| 219 } | 228 } |
| 220 | 229 |
| 221 DisplayIdPair DisplayManager::GetCurrentDisplayIdPair() const { | 230 DisplayIdPair DisplayManager::GetCurrentDisplayIdPair() const { |
| 222 if (IsInMirrorMode()) { | 231 if (IsInUnifiedMode()) { |
| 232 return std::make_pair(software_mirroring_display_list_[0].id(), | |
| 233 software_mirroring_display_list_[1].id()); | |
| 234 } else if (IsInMirrorMode()) { | |
| 223 if (software_mirroring_enabled()) { | 235 if (software_mirroring_enabled()) { |
| 224 CHECK_EQ(2u, num_connected_displays()); | 236 CHECK_EQ(2u, num_connected_displays()); |
| 225 // This comment is to make it easy to distinguish the crash | 237 // This comment is to make it easy to distinguish the crash |
| 226 // between two checks. | 238 // between two checks. |
| 227 CHECK_EQ(1u, active_display_list_.size()); | 239 CHECK_EQ(1u, active_display_list_.size()); |
| 228 } | 240 } |
| 229 return std::make_pair(active_display_list_[0].id(), mirroring_display_id_); | 241 return std::make_pair(active_display_list_[0].id(), mirroring_display_id_); |
| 230 } else { | 242 } else { |
| 231 CHECK_LE(2u, active_display_list_.size()); | 243 CHECK_LE(2u, active_display_list_.size()); |
| 232 int64 id_at_zero = active_display_list_[0].id(); | 244 int64 id_at_zero = active_display_list_[0].id(); |
| (...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 586 VLOG(1) << "OnNativeDisplaysChanged(1):" << updated_displays[0].ToString(); | 598 VLOG(1) << "OnNativeDisplaysChanged(1):" << updated_displays[0].ToString(); |
| 587 } else { | 599 } else { |
| 588 VLOG(1) << "OnNativeDisplaysChanged(" << updated_displays.size() | 600 VLOG(1) << "OnNativeDisplaysChanged(" << updated_displays.size() |
| 589 << ") [0]=" << updated_displays[0].ToString() | 601 << ") [0]=" << updated_displays[0].ToString() |
| 590 << ", [1]=" << updated_displays[1].ToString(); | 602 << ", [1]=" << updated_displays[1].ToString(); |
| 591 } | 603 } |
| 592 | 604 |
| 593 bool internal_display_connected = false; | 605 bool internal_display_connected = false; |
| 594 num_connected_displays_ = updated_displays.size(); | 606 num_connected_displays_ = updated_displays.size(); |
| 595 mirroring_display_id_ = gfx::Display::kInvalidDisplayID; | 607 mirroring_display_id_ = gfx::Display::kInvalidDisplayID; |
| 596 software_mirroring_display_ = gfx::Display(); | 608 software_mirroring_display_list_.clear(); |
| 597 DisplayInfoList new_display_info_list; | 609 DisplayInfoList new_display_info_list; |
| 598 for (DisplayInfoList::const_iterator iter = updated_displays.begin(); | 610 for (DisplayInfoList::const_iterator iter = updated_displays.begin(); |
| 599 iter != updated_displays.end(); | 611 iter != updated_displays.end(); |
| 600 ++iter) { | 612 ++iter) { |
| 601 if (!internal_display_connected) | 613 if (!internal_display_connected) |
| 602 internal_display_connected = IsInternalDisplayId(iter->id()); | 614 internal_display_connected = IsInternalDisplayId(iter->id()); |
| 603 // Mirrored monitors have the same origins. | 615 // Mirrored monitors have the same origins. |
| 604 gfx::Point origin = iter->bounds_in_native().origin(); | 616 gfx::Point origin = iter->bounds_in_native().origin(); |
| 605 if (origins.find(origin) != origins.end()) { | 617 if (origins.find(origin) != origins.end()) { |
| 606 InsertAndUpdateDisplayInfo(*iter); | 618 InsertAndUpdateDisplayInfo(*iter); |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 661 std::sort(active_display_list_.begin(), active_display_list_.end(), | 673 std::sort(active_display_list_.begin(), active_display_list_.end(), |
| 662 DisplaySortFunctor()); | 674 DisplaySortFunctor()); |
| 663 std::sort(new_display_info_list.begin(), | 675 std::sort(new_display_info_list.begin(), |
| 664 new_display_info_list.end(), | 676 new_display_info_list.end(), |
| 665 DisplayInfoSortFunctor()); | 677 DisplayInfoSortFunctor()); |
| 666 // Close the mirroring window if any here to avoid creating two compositor on | 678 // Close the mirroring window if any here to avoid creating two compositor on |
| 667 // one display. | 679 // one display. |
| 668 if (delegate_) | 680 if (delegate_) |
| 669 delegate_->CloseMirroringDisplay(); | 681 delegate_->CloseMirroringDisplay(); |
| 670 | 682 |
| 671 if (second_display_mode_ == MIRRORING && new_display_info_list.size() == 2) | 683 CreateSoftwareMirroringDisplay(&new_display_info_list); |
| 672 CreateSoftwareMirroringDisplay(&new_display_info_list); | |
| 673 | 684 |
| 674 DisplayList new_displays; | 685 DisplayList new_displays; |
| 675 DisplayList removed_displays; | 686 DisplayList removed_displays; |
| 676 std::map<size_t, uint32_t> display_changes; | 687 std::map<size_t, uint32_t> display_changes; |
| 677 std::vector<size_t> added_display_indices; | 688 std::vector<size_t> added_display_indices; |
| 678 | 689 |
| 679 DisplayList::iterator curr_iter = active_display_list_.begin(); | 690 DisplayList::iterator curr_iter = active_display_list_.begin(); |
| 680 DisplayInfoList::const_iterator new_info_iter = new_display_info_list.begin(); | 691 DisplayInfoList::const_iterator new_info_iter = new_display_info_list.begin(); |
| 681 | 692 |
| 682 while (curr_iter != active_display_list_.end() || | 693 while (curr_iter != active_display_list_.end() || |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 863 } | 874 } |
| 864 | 875 |
| 865 size_t DisplayManager::GetNumDisplays() const { | 876 size_t DisplayManager::GetNumDisplays() const { |
| 866 return active_display_list_.size(); | 877 return active_display_list_.size(); |
| 867 } | 878 } |
| 868 | 879 |
| 869 bool DisplayManager::IsInMirrorMode() const { | 880 bool DisplayManager::IsInMirrorMode() const { |
| 870 return mirroring_display_id_ != gfx::Display::kInvalidDisplayID; | 881 return mirroring_display_id_ != gfx::Display::kInvalidDisplayID; |
| 871 } | 882 } |
| 872 | 883 |
| 884 bool DisplayManager::IsInUnifiedMode() const { | |
| 885 return multi_display_mode_ == UNIFIED && | |
| 886 !software_mirroring_display_list_.empty(); | |
| 887 } | |
| 888 | |
| 873 const DisplayInfo& DisplayManager::GetDisplayInfo(int64 display_id) const { | 889 const DisplayInfo& DisplayManager::GetDisplayInfo(int64 display_id) const { |
| 874 DCHECK_NE(gfx::Display::kInvalidDisplayID, display_id); | 890 DCHECK_NE(gfx::Display::kInvalidDisplayID, display_id); |
| 875 | 891 |
| 876 std::map<int64, DisplayInfo>::const_iterator iter = | 892 std::map<int64, DisplayInfo>::const_iterator iter = |
| 877 display_info_.find(display_id); | 893 display_info_.find(display_id); |
| 878 CHECK(iter != display_info_.end()) << display_id; | 894 CHECK(iter != display_info_.end()) << display_id; |
| 879 return iter->second; | 895 return iter->second; |
| 880 } | 896 } |
| 881 | 897 |
| 898 const gfx::Display DisplayManager::GetMirroringDisplayById( | |
| 899 int64 display_id) const { | |
| 900 auto iter = std::find_if(software_mirroring_display_list_.begin(), | |
| 901 software_mirroring_display_list_.end(), | |
| 902 [display_id](const gfx::Display& display) { | |
| 903 return display.id() == display_id; | |
| 904 }); | |
| 905 return iter == software_mirroring_display_list_.end() ? gfx::Display() | |
| 906 : *iter; | |
| 907 } | |
| 908 | |
| 882 std::string DisplayManager::GetDisplayNameForId(int64 id) { | 909 std::string DisplayManager::GetDisplayNameForId(int64 id) { |
| 883 if (id == gfx::Display::kInvalidDisplayID) | 910 if (id == gfx::Display::kInvalidDisplayID) |
| 884 return l10n_util::GetStringUTF8(IDS_ASH_STATUS_TRAY_UNKNOWN_DISPLAY_NAME); | 911 return l10n_util::GetStringUTF8(IDS_ASH_STATUS_TRAY_UNKNOWN_DISPLAY_NAME); |
| 885 | 912 |
| 886 std::map<int64, DisplayInfo>::const_iterator iter = display_info_.find(id); | 913 std::map<int64, DisplayInfo>::const_iterator iter = display_info_.find(id); |
| 887 if (iter != display_info_.end() && !iter->second.name().empty()) | 914 if (iter != display_info_.end() && !iter->second.name().empty()) |
| 888 return iter->second.name(); | 915 return iter->second.name(); |
| 889 | 916 |
| 890 return base::StringPrintf("Display %d", static_cast<int>(id)); | 917 return base::StringPrintf("Display %d", static_cast<int>(id)); |
| 891 } | 918 } |
| 892 | 919 |
| 893 int64 DisplayManager::GetDisplayIdForUIScaling() const { | 920 int64 DisplayManager::GetDisplayIdForUIScaling() const { |
| 894 // UI Scaling is effective only on internal display. | 921 // UI Scaling is effective only on internal display. |
| 895 int64 display_id = gfx::Display::InternalDisplayId(); | 922 int64 display_id = gfx::Display::InternalDisplayId(); |
| 896 #if defined(OS_WIN) | 923 #if defined(OS_WIN) |
| 897 display_id = first_display_id(); | 924 display_id = first_display_id(); |
| 898 #endif | 925 #endif |
| 899 return display_id; | 926 return display_id; |
| 900 } | 927 } |
| 901 | 928 |
| 902 void DisplayManager::SetMirrorMode(bool mirrored) { | 929 void DisplayManager::SetMirrorMode(bool mirror) { |
| 930 #if defined(OS_CHROMEOS) | |
| 903 if (num_connected_displays() <= 1) | 931 if (num_connected_displays() <= 1) |
| 904 return; | 932 return; |
| 905 | 933 |
| 906 #if defined(OS_CHROMEOS) | |
| 907 if (base::SysInfo::IsRunningOnChromeOS()) { | 934 if (base::SysInfo::IsRunningOnChromeOS()) { |
| 908 ui::MultipleDisplayState new_state = | 935 ui::MultipleDisplayState new_state = |
| 909 mirrored ? ui::MULTIPLE_DISPLAY_STATE_DUAL_MIRROR : | 936 mirror ? ui::MULTIPLE_DISPLAY_STATE_DUAL_MIRROR |
| 910 ui::MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED; | 937 : ui::MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED; |
| 911 Shell::GetInstance()->display_configurator()->SetDisplayMode(new_state); | 938 Shell::GetInstance()->display_configurator()->SetDisplayMode(new_state); |
| 912 return; | 939 return; |
| 913 } | 940 } |
| 914 #endif | 941 |
| 915 // This is fallback path to emulate mirroroing on desktop. | 942 // This is fallback path to emulate mirroroing on desktop. |
| 916 SetSecondDisplayMode(mirrored ? MIRRORING : EXTENDED); | |
| 917 DisplayInfoList display_info_list; | 943 DisplayInfoList display_info_list; |
| 918 int count = 0; | 944 for (DisplayList::const_iterator iter = active_display_list_.begin(); |
| 919 for (std::map<int64, DisplayInfo>::const_iterator iter = | 945 (display_info_list.size() < 2 && iter != active_display_list_.end()); |
| 920 display_info_.begin(); | 946 ++iter) { |
| 921 count < 2; ++iter, ++count) { | 947 if (iter->id() == kUnifiedDisplayId) |
| 922 display_info_list.push_back(GetDisplayInfo(iter->second.id())); | 948 continue; |
| 949 display_info_list.push_back(GetDisplayInfo(iter->id())); | |
| 923 } | 950 } |
| 951 for (auto iter = software_mirroring_display_list_.begin(); | |
| 952 (display_info_list.size() < 2 && | |
| 953 iter != software_mirroring_display_list_.end()); | |
| 954 ++iter) { | |
| 955 display_info_list.push_back(GetDisplayInfo(iter->id())); | |
| 956 } | |
| 957 | |
| 958 SetSoftwareMirroring(mirror); | |
| 924 UpdateDisplays(display_info_list); | 959 UpdateDisplays(display_info_list); |
| 925 #if defined(OS_CHROMEOS) | |
| 926 if (Shell::GetInstance()->display_configurator_animation()) { | 960 if (Shell::GetInstance()->display_configurator_animation()) { |
| 927 Shell::GetInstance()->display_configurator_animation()-> | 961 Shell::GetInstance()->display_configurator_animation()-> |
| 928 StartFadeInAnimation(); | 962 StartFadeInAnimation(); |
| 929 } | 963 } |
| 930 #endif | 964 #endif |
| 931 } | 965 } |
| 932 | 966 |
| 933 void DisplayManager::AddRemoveDisplay() { | 967 void DisplayManager::AddRemoveDisplay() { |
| 934 DCHECK(!active_display_list_.empty()); | 968 DCHECK(!active_display_list_.empty()); |
| 935 std::vector<DisplayInfo> new_display_info_list; | 969 std::vector<DisplayInfo> new_display_info_list; |
| 936 const DisplayInfo& first_display = | 970 const DisplayInfo& first_display = |
| 937 GetDisplayInfo(active_display_list_[0].id()); | 971 IsInUnifiedMode() |
| 972 ? GetDisplayInfo(software_mirroring_display_list_[0].id()) | |
| 973 : GetDisplayInfo(active_display_list_[0].id()); | |
| 938 new_display_info_list.push_back(first_display); | 974 new_display_info_list.push_back(first_display); |
| 939 // Add if there is only one display connected. | 975 // Add if there is only one display connected. |
| 940 if (num_connected_displays() == 1) { | 976 if (num_connected_displays() == 1) { |
| 941 // Layout the 2nd display below the primary as with the real device. | 977 // Layout the 2nd display below the primary as with the real device. |
| 942 gfx::Rect host_bounds = first_display.bounds_in_native(); | 978 gfx::Rect host_bounds = first_display.bounds_in_native(); |
| 943 new_display_info_list.push_back(DisplayInfo::CreateFromSpec( | 979 new_display_info_list.push_back(DisplayInfo::CreateFromSpec( |
| 944 base::StringPrintf( | 980 base::StringPrintf( |
| 945 "%d+%d-500x400", host_bounds.x(), host_bounds.bottom()))); | 981 "%d+%d-500x400", host_bounds.x(), host_bounds.bottom()))); |
| 946 } | 982 } |
| 947 num_connected_displays_ = new_display_info_list.size(); | 983 num_connected_displays_ = new_display_info_list.size(); |
| 948 mirroring_display_id_ = gfx::Display::kInvalidDisplayID; | 984 mirroring_display_id_ = gfx::Display::kInvalidDisplayID; |
| 949 software_mirroring_display_ = gfx::Display(); | 985 software_mirroring_display_list_.clear(); |
| 950 UpdateDisplays(new_display_info_list); | 986 UpdateDisplays(new_display_info_list); |
| 951 } | 987 } |
| 952 | 988 |
| 953 void DisplayManager::ToggleDisplayScaleFactor() { | 989 void DisplayManager::ToggleDisplayScaleFactor() { |
| 954 DCHECK(!active_display_list_.empty()); | 990 DCHECK(!active_display_list_.empty()); |
| 955 std::vector<DisplayInfo> new_display_info_list; | 991 std::vector<DisplayInfo> new_display_info_list; |
| 956 for (DisplayList::const_iterator iter = active_display_list_.begin(); | 992 for (DisplayList::const_iterator iter = active_display_list_.begin(); |
| 957 iter != active_display_list_.end(); ++iter) { | 993 iter != active_display_list_.end(); ++iter) { |
| 958 DisplayInfo display_info = GetDisplayInfo(iter->id()); | 994 DisplayInfo display_info = GetDisplayInfo(iter->id()); |
| 959 display_info.set_device_scale_factor( | 995 display_info.set_device_scale_factor( |
| 960 display_info.device_scale_factor() == 1.0f ? 2.0f : 1.0f); | 996 display_info.device_scale_factor() == 1.0f ? 2.0f : 1.0f); |
| 961 new_display_info_list.push_back(display_info); | 997 new_display_info_list.push_back(display_info); |
| 962 } | 998 } |
| 963 AddMirrorDisplayInfoIfAny(&new_display_info_list); | 999 AddMirrorDisplayInfoIfAny(&new_display_info_list); |
| 964 UpdateDisplays(new_display_info_list); | 1000 UpdateDisplays(new_display_info_list); |
| 965 } | 1001 } |
| 966 | 1002 |
| 967 #if defined(OS_CHROMEOS) | 1003 #if defined(OS_CHROMEOS) |
| 968 void DisplayManager::SetSoftwareMirroring(bool enabled) { | 1004 void DisplayManager::SetSoftwareMirroring(bool enabled) { |
| 969 SetSecondDisplayMode(enabled ? MIRRORING : EXTENDED); | 1005 SetMultiDisplayMode(enabled ? MIRRORING : default_multi_display_mode_); |
| 970 } | 1006 } |
| 971 | 1007 |
| 972 bool DisplayManager::SoftwareMirroringEnabled() const { | 1008 bool DisplayManager::SoftwareMirroringEnabled() const { |
| 973 return software_mirroring_enabled(); | 1009 return software_mirroring_enabled(); |
| 974 } | 1010 } |
| 975 #endif | 1011 #endif |
| 976 | 1012 |
| 977 void DisplayManager::SetSecondDisplayMode(SecondDisplayMode mode) { | 1013 void DisplayManager::SetMultiDisplayMode(MultiDisplayMode mode) { |
| 978 second_display_mode_ = mode; | 1014 multi_display_mode_ = mode; |
| 979 mirroring_display_id_ = gfx::Display::kInvalidDisplayID; | 1015 mirroring_display_id_ = gfx::Display::kInvalidDisplayID; |
| 980 software_mirroring_display_ = gfx::Display(); | 1016 software_mirroring_display_list_.clear(); |
| 1017 } | |
| 1018 | |
| 1019 void DisplayManager::SetDefaultMultiDisplayMode(MultiDisplayMode mode) { | |
| 1020 // TODO(oshima): Remove this constrain. | |
| 1021 DCHECK_EQ(default_multi_display_mode_, EXTENDED); | |
| 1022 DCHECK_EQ(mode, UNIFIED); | |
| 1023 default_multi_display_mode_ = mode; | |
| 981 } | 1024 } |
| 982 | 1025 |
| 983 bool DisplayManager::UpdateDisplayBounds(int64 display_id, | 1026 bool DisplayManager::UpdateDisplayBounds(int64 display_id, |
| 984 const gfx::Rect& new_bounds) { | 1027 const gfx::Rect& new_bounds) { |
| 985 if (change_display_upon_host_resize_) { | 1028 if (change_display_upon_host_resize_) { |
| 986 display_info_[display_id].SetBounds(new_bounds); | 1029 display_info_[display_id].SetBounds(new_bounds); |
| 987 // Don't notify observers if the mirrored window has changed. | 1030 // Don't notify observers if the mirrored window has changed. |
| 988 if (software_mirroring_enabled() && mirroring_display_id_ == display_id) | 1031 if (software_mirroring_enabled() && mirroring_display_id_ == display_id) |
| 989 return false; | 1032 return false; |
| 990 gfx::Display* display = FindDisplayForId(display_id); | 1033 gfx::Display* display = FindDisplayForId(display_id); |
| 991 display->SetSize(display_info_[display_id].size_in_pixel()); | 1034 display->SetSize(display_info_[display_id].size_in_pixel()); |
| 992 screen_->NotifyMetricsChanged(*display, | 1035 screen_->NotifyMetricsChanged(*display, |
| 993 gfx::DisplayObserver::DISPLAY_METRIC_BOUNDS); | 1036 gfx::DisplayObserver::DISPLAY_METRIC_BOUNDS); |
| 994 return true; | 1037 return true; |
| 995 } | 1038 } |
| 996 return false; | 1039 return false; |
| 997 } | 1040 } |
| 998 | 1041 |
| 999 void DisplayManager::CreateMirrorWindowAsyncIfAny() { | 1042 void DisplayManager::CreateMirrorWindowAsyncIfAny() { |
| 1000 // Do not post a task if the software mirroring doesn't exist, or | 1043 // Do not post a task if the software mirroring doesn't exist, or |
| 1001 // during initialization when compositor's init task isn't posted yet. | 1044 // during initialization when compositor's init task isn't posted yet. |
| 1002 // ash::Shell::Init() will call this after the compositor is initialized. | 1045 // ash::Shell::Init() will call this after the compositor is initialized. |
| 1003 if (!software_mirroring_display_.is_valid() || !delegate_) | 1046 if (software_mirroring_display_list_.empty() || !delegate_) |
| 1004 return; | 1047 return; |
| 1005 base::MessageLoopForUI::current()->PostTask( | 1048 base::MessageLoopForUI::current()->PostTask( |
| 1006 FROM_HERE, | 1049 FROM_HERE, |
| 1007 base::Bind(&DisplayManager::CreateMirrorWindowIfAny, | 1050 base::Bind(&DisplayManager::CreateMirrorWindowIfAny, |
| 1008 weak_ptr_factory_.GetWeakPtr())); | 1051 weak_ptr_factory_.GetWeakPtr())); |
| 1009 } | 1052 } |
| 1010 | 1053 |
| 1011 scoped_ptr<MouseWarpController> DisplayManager::CreateMouseWarpController( | 1054 scoped_ptr<MouseWarpController> DisplayManager::CreateMouseWarpController( |
| 1012 aura::Window* drag_source) const { | 1055 aura::Window* drag_source) const { |
| 1013 // Extra check for |num_connected_displays()| is for SystemDisplayApiTest | 1056 // Extra check for |num_connected_displays()| is for SystemDisplayApiTest |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 1036 DisplayInfo* info = &display_info_[gfx::Display::InternalDisplayId()]; | 1079 DisplayInfo* info = &display_info_[gfx::Display::InternalDisplayId()]; |
| 1037 SetInternalDisplayModeList(info); | 1080 SetInternalDisplayModeList(info); |
| 1038 } | 1081 } |
| 1039 | 1082 |
| 1040 void DisplayManager::CreateSoftwareMirroringDisplay( | 1083 void DisplayManager::CreateSoftwareMirroringDisplay( |
| 1041 DisplayInfoList* display_info_list) { | 1084 DisplayInfoList* display_info_list) { |
| 1042 // Use the internal display or 1st as the mirror source, then scale | 1085 // Use the internal display or 1st as the mirror source, then scale |
| 1043 // the root window so that it matches the external display's | 1086 // the root window so that it matches the external display's |
| 1044 // resolution. This is necessary in order for scaling to work while | 1087 // resolution. This is necessary in order for scaling to work while |
| 1045 // mirrored. | 1088 // mirrored. |
| 1089 // int64 mirroring_display_id = gfx::Display::kInvalidDisplayID; | |
| 1090 if (display_info_list->size() == 2) { | |
| 1091 switch (multi_display_mode_) { | |
| 1092 case MIRRORING: { | |
| 1093 bool zero_is_source = | |
| 1094 first_display_id_ == (*display_info_list)[0].id() || | |
| 1095 gfx::Display::InternalDisplayId() == (*display_info_list)[0].id(); | |
| 1096 DCHECK_EQ(MIRRORING, multi_display_mode_); | |
| 1097 mirroring_display_id_ = | |
| 1098 (*display_info_list)[zero_is_source ? 1 : 0].id(); | |
| 1099 | |
| 1100 int64 display_id = mirroring_display_id_; | |
| 1101 auto iter = | |
| 1102 std::find_if(display_info_list->begin(), display_info_list->end(), | |
| 1103 [display_id](const DisplayInfo& info) { | |
| 1104 return info.id() == display_id; | |
| 1105 }); | |
| 1106 DCHECK(iter != display_info_list->end()); | |
| 1107 | |
| 1108 DisplayInfo info = *iter; | |
| 1109 info.SetOverscanInsets(gfx::Insets()); | |
| 1110 InsertAndUpdateDisplayInfo(info); | |
| 1111 software_mirroring_display_list_.push_back( | |
| 1112 CreateDisplayFromDisplayInfoById(mirroring_display_id_)); | |
| 1113 display_info_list->erase(iter); | |
| 1114 } break; | |
|
Jun Mukai
2015/04/26 23:45:08
I prefer to write
break;
}
order.
oshima
2015/04/27 17:48:38
Done.
| |
| 1115 case UNIFIED: { | |
| 1116 gfx::Rect unified_bounds; | |
| 1117 software_mirroring_display_list_.clear(); | |
| 1118 for (auto& info : *display_info_list) { | |
| 1119 InsertAndUpdateDisplayInfo(info); | |
| 1120 software_mirroring_display_list_.push_back( | |
| 1121 CreateDisplayFromDisplayInfoById(info.id())); | |
| 1122 gfx::Point origin(unified_bounds.right(), 0); | |
| 1123 unified_bounds.Union(gfx::Rect(origin, info.size_in_pixel())); | |
| 1124 } | |
| 1125 // first_display_id_ = kUnifiedDisplayId; | |
| 1126 DisplayInfo info(kUnifiedDisplayId, "Unified Desktop", false); | |
| 1127 info.SetBounds(unified_bounds); | |
| 1128 display_info_list->clear(); | |
| 1129 display_info_list->push_back(info); | |
| 1130 } break; | |
| 1131 case EXTENDED: | |
| 1132 break; | |
| 1133 } | |
| 1134 } | |
| 1135 #if 0 | |
| 1136 // Use the internal display or 1st as the mirror source, then scale | |
| 1137 // the root window so that it matches the external display's | |
| 1138 // resolution. This is necessary in order for scaling to work while | |
| 1139 // mirrored. | |
| 1046 bool zero_is_source = | 1140 bool zero_is_source = |
| 1047 first_display_id_ == (*display_info_list)[0].id() || | 1141 first_display_id_ == (*display_info_list)[0].id() || |
| 1048 gfx::Display::InternalDisplayId() == (*display_info_list)[0].id(); | 1142 gfx::Display::InternalDisplayId() == (*display_info_list)[0].id(); |
| 1049 DCHECK_EQ(MIRRORING, second_display_mode_); | 1143 DCHECK_EQ(MIRRORING, multi_display_mode_); |
| 1050 mirroring_display_id_ = (*display_info_list)[zero_is_source ? 1 : 0].id(); | 1144 mirroring_display_id_ = (*display_info_list)[zero_is_source ? 1 : 0].id(); |
| 1051 int64 display_id = mirroring_display_id_; | 1145 int64 display_id = mirroring_display_id_; |
| 1052 auto iter = std::find_if(display_info_list->begin(), display_info_list->end(), | 1146 auto iter = std::find_if(display_info_list->begin(), display_info_list->end(), |
| 1053 [display_id](const DisplayInfo& info) { | 1147 [display_id](const DisplayInfo& info) { |
| 1054 return info.id() == display_id; | 1148 return info.id() == display_id; |
| 1055 }); | 1149 }); |
| 1056 DCHECK(iter != display_info_list->end()); | 1150 DCHECK(iter != display_info_list->end()); |
| 1057 DisplayInfo info = *iter; | 1151 DisplayInfo info = *iter; |
| 1058 info.SetOverscanInsets(gfx::Insets()); | 1152 info.SetOverscanInsets(gfx::Insets()); |
| 1059 InsertAndUpdateDisplayInfo(info); | 1153 InsertAndUpdateDisplayInfo(info); |
| 1060 software_mirroring_display_ = | 1154 software_mirroring_display_ = |
| 1061 CreateDisplayFromDisplayInfoById(mirroring_display_id_); | 1155 CreateDisplayFromDisplayInfoById(mirroring_display_id_); |
| 1062 display_info_list->erase(iter); | 1156 display_info_list->erase(iter); |
| 1157 #endif | |
|
oshima
2015/04/27 17:48:38
oops, I forgot to remove this. Removed.
| |
| 1063 } | 1158 } |
| 1064 | 1159 |
| 1065 gfx::Display* DisplayManager::FindDisplayForId(int64 id) { | 1160 gfx::Display* DisplayManager::FindDisplayForId(int64 id) { |
| 1066 auto iter = std::find_if( | 1161 auto iter = std::find_if( |
| 1067 active_display_list_.begin(), active_display_list_.end(), | 1162 active_display_list_.begin(), active_display_list_.end(), |
| 1068 [id](const gfx::Display& display) { return display.id() == id; }); | 1163 [id](const gfx::Display& display) { return display.id() == id; }); |
| 1069 if (iter != active_display_list_.end()) | 1164 if (iter != active_display_list_.end()) |
| 1070 return &(*iter); | 1165 return &(*iter); |
| 1071 DLOG(WARNING) << "Could not find display:" << id; | 1166 // TODO(oshima): This happens when a windows in unified desktop have |
| 1167 // been moved to normal window. Fix this. | |
| 1168 if (id != kUnifiedDisplayId) | |
| 1169 DLOG(WARNING) << "Could not find display:" << id; | |
| 1072 return NULL; | 1170 return NULL; |
| 1073 } | 1171 } |
| 1074 | 1172 |
| 1075 void DisplayManager::AddMirrorDisplayInfoIfAny( | 1173 void DisplayManager::AddMirrorDisplayInfoIfAny( |
| 1076 std::vector<DisplayInfo>* display_info_list) { | 1174 std::vector<DisplayInfo>* display_info_list) { |
| 1077 if (software_mirroring_enabled() && IsInMirrorMode()) | 1175 if (software_mirroring_enabled() && IsInMirrorMode()) |
| 1078 display_info_list->push_back(GetDisplayInfo(mirroring_display_id_)); | 1176 display_info_list->push_back(GetDisplayInfo(mirroring_display_id_)); |
| 1079 } | 1177 } |
| 1080 | 1178 |
| 1081 void DisplayManager::InsertAndUpdateDisplayInfo(const DisplayInfo& new_info) { | 1179 void DisplayManager::InsertAndUpdateDisplayInfo(const DisplayInfo& new_info) { |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 1095 #if defined(OS_CHROMEOS) | 1193 #if defined(OS_CHROMEOS) |
| 1096 ui::ColorCalibrationProfile color_profile = display_info.color_profile(); | 1194 ui::ColorCalibrationProfile color_profile = display_info.color_profile(); |
| 1097 if (color_profile != ui::COLOR_PROFILE_STANDARD) { | 1195 if (color_profile != ui::COLOR_PROFILE_STANDARD) { |
| 1098 Shell::GetInstance()->display_configurator()->SetColorCalibrationProfile( | 1196 Shell::GetInstance()->display_configurator()->SetColorCalibrationProfile( |
| 1099 display_info.id(), color_profile); | 1197 display_info.id(), color_profile); |
| 1100 } | 1198 } |
| 1101 #endif | 1199 #endif |
| 1102 } | 1200 } |
| 1103 | 1201 |
| 1104 gfx::Display DisplayManager::CreateDisplayFromDisplayInfoById(int64 id) { | 1202 gfx::Display DisplayManager::CreateDisplayFromDisplayInfoById(int64 id) { |
| 1105 DCHECK(display_info_.find(id) != display_info_.end()); | 1203 DCHECK(display_info_.find(id) != display_info_.end()) << "id=" << id; |
| 1106 const DisplayInfo& display_info = display_info_[id]; | 1204 const DisplayInfo& display_info = display_info_[id]; |
| 1107 | 1205 |
| 1108 gfx::Display new_display(display_info.id()); | 1206 gfx::Display new_display(display_info.id()); |
| 1109 gfx::Rect bounds_in_native(display_info.size_in_pixel()); | 1207 gfx::Rect bounds_in_native(display_info.size_in_pixel()); |
| 1110 float device_scale_factor = display_info.GetEffectiveDeviceScaleFactor(); | 1208 float device_scale_factor = display_info.GetEffectiveDeviceScaleFactor(); |
| 1111 | 1209 |
| 1112 // Simply set the origin to (0,0). The primary display's origin is | 1210 // Simply set the origin to (0,0). The primary display's origin is |
| 1113 // always (0,0) and the bounds of non-primary display(s) will be updated | 1211 // always (0,0) and the bounds of non-primary display(s) will be updated |
| 1114 // in |UpdateNonPrimaryDisplayBoundsForLayout| called in |UpdateDisplay|. | 1212 // in |UpdateNonPrimaryDisplayBoundsForLayout| called in |UpdateDisplay|. |
| 1115 new_display.SetScaleAndBounds( | 1213 new_display.SetScaleAndBounds( |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1169 GetDisplayForId(displays->at(secondary_index).id()).bounds(); | 1267 GetDisplayForId(displays->at(secondary_index).id()).bounds(); |
| 1170 UpdateDisplayBoundsForLayout( | 1268 UpdateDisplayBoundsForLayout( |
| 1171 layout, displays->at(primary_index), &displays->at(secondary_index)); | 1269 layout, displays->at(primary_index), &displays->at(secondary_index)); |
| 1172 updated_indices->push_back(secondary_index); | 1270 updated_indices->push_back(secondary_index); |
| 1173 return bounds != displays->at(secondary_index).bounds(); | 1271 return bounds != displays->at(secondary_index).bounds(); |
| 1174 } | 1272 } |
| 1175 return false; | 1273 return false; |
| 1176 } | 1274 } |
| 1177 | 1275 |
| 1178 void DisplayManager::CreateMirrorWindowIfAny() { | 1276 void DisplayManager::CreateMirrorWindowIfAny() { |
| 1179 if (software_mirroring_display_.is_valid() && delegate_) { | 1277 if (software_mirroring_display_list_.empty() || !delegate_) |
| 1180 DisplayInfo display_info = GetDisplayInfo(software_mirroring_display_.id()); | 1278 return; |
| 1181 delegate_->CreateOrUpdateMirroringDisplay(display_info); | 1279 DisplayInfoList list; |
| 1182 } | 1280 for (auto& display : software_mirroring_display_list_) |
| 1281 list.push_back(GetDisplayInfo(display.id())); | |
| 1282 delegate_->CreateOrUpdateMirroringDisplay(list); | |
| 1183 } | 1283 } |
| 1184 | 1284 |
| 1185 // static | 1285 // static |
| 1186 void DisplayManager::UpdateDisplayBoundsForLayout( | 1286 void DisplayManager::UpdateDisplayBoundsForLayout( |
| 1187 const DisplayLayout& layout, | 1287 const DisplayLayout& layout, |
| 1188 const gfx::Display& primary_display, | 1288 const gfx::Display& primary_display, |
| 1189 gfx::Display* secondary_display) { | 1289 gfx::Display* secondary_display) { |
| 1190 DCHECK_EQ("0,0", primary_display.bounds().origin().ToString()); | 1290 DCHECK_EQ("0,0", primary_display.bounds().origin().ToString()); |
| 1191 | 1291 |
| 1192 const gfx::Rect& primary_bounds = primary_display.bounds(); | 1292 const gfx::Rect& primary_bounds = primary_display.bounds(); |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 1223 new_secondary_origin.Offset(-secondary_bounds.width(), offset); | 1323 new_secondary_origin.Offset(-secondary_bounds.width(), offset); |
| 1224 break; | 1324 break; |
| 1225 } | 1325 } |
| 1226 gfx::Insets insets = secondary_display->GetWorkAreaInsets(); | 1326 gfx::Insets insets = secondary_display->GetWorkAreaInsets(); |
| 1227 secondary_display->set_bounds( | 1327 secondary_display->set_bounds( |
| 1228 gfx::Rect(new_secondary_origin, secondary_bounds.size())); | 1328 gfx::Rect(new_secondary_origin, secondary_bounds.size())); |
| 1229 secondary_display->UpdateWorkAreaFromInsets(insets); | 1329 secondary_display->UpdateWorkAreaFromInsets(insets); |
| 1230 } | 1330 } |
| 1231 | 1331 |
| 1232 void DisplayManager::RunPendingTasksForTest() { | 1332 void DisplayManager::RunPendingTasksForTest() { |
| 1233 if (software_mirroring_display_.is_valid()) | 1333 if (!software_mirroring_display_list_.empty()) |
| 1234 base::RunLoop().RunUntilIdle(); | 1334 base::RunLoop().RunUntilIdle(); |
| 1235 } | 1335 } |
| 1236 | 1336 |
| 1237 } // namespace ash | 1337 } // namespace ash |
| OLD | NEW |