| 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 |