| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "ui/display/chromeos/display_configurator.h" | 5 #include "ui/display/chromeos/display_configurator.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/sys_info.h" | 10 #include "base/sys_info.h" |
| (...skipping 14 matching lines...) Expand all Loading... |
| 25 // The delay to perform configuration after RRNotify. See the comment for | 25 // The delay to perform configuration after RRNotify. See the comment for |
| 26 // |configure_timer_|. | 26 // |configure_timer_|. |
| 27 const int kConfigureDelayMs = 500; | 27 const int kConfigureDelayMs = 500; |
| 28 | 28 |
| 29 // The delay spent before reading the display configuration after coming out of | 29 // The delay spent before reading the display configuration after coming out of |
| 30 // suspend. While coming out of suspend the display state may be updating. This | 30 // suspend. While coming out of suspend the display state may be updating. This |
| 31 // is used to wait until the hardware had a chance to update the display state | 31 // is used to wait until the hardware had a chance to update the display state |
| 32 // such that we read an up to date state. | 32 // such that we read an up to date state. |
| 33 const int kResumeDelayMs = 500; | 33 const int kResumeDelayMs = 500; |
| 34 | 34 |
| 35 void DoNothing(bool status) { |
| 36 } |
| 37 |
| 35 } // namespace | 38 } // namespace |
| 36 | 39 |
| 37 | 40 |
| 38 const int DisplayConfigurator::kSetDisplayPowerNoFlags = 0; | 41 const int DisplayConfigurator::kSetDisplayPowerNoFlags = 0; |
| 39 const int DisplayConfigurator::kSetDisplayPowerForceProbe = 1 << 0; | 42 const int DisplayConfigurator::kSetDisplayPowerForceProbe = 1 << 0; |
| 40 const int | 43 const int |
| 41 DisplayConfigurator::kSetDisplayPowerOnlyIfSingleInternalDisplay = 1 << 1; | 44 DisplayConfigurator::kSetDisplayPowerOnlyIfSingleInternalDisplay = 1 << 1; |
| 42 | 45 |
| 43 DisplayConfigurator::DisplayState::DisplayState() | 46 DisplayConfigurator::DisplayState::DisplayState() |
| 44 : display(NULL), | 47 : display(NULL), |
| (...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 453 force_configure_(false), | 456 force_configure_(false), |
| 454 next_display_protection_client_id_(1), | 457 next_display_protection_client_id_(1), |
| 455 display_externally_controlled_(false), | 458 display_externally_controlled_(false), |
| 456 layout_manager_(new DisplayLayoutManagerImpl(this)), | 459 layout_manager_(new DisplayLayoutManagerImpl(this)), |
| 457 weak_ptr_factory_(this) { | 460 weak_ptr_factory_(this) { |
| 458 } | 461 } |
| 459 | 462 |
| 460 DisplayConfigurator::~DisplayConfigurator() { | 463 DisplayConfigurator::~DisplayConfigurator() { |
| 461 if (native_display_delegate_) | 464 if (native_display_delegate_) |
| 462 native_display_delegate_->RemoveObserver(this); | 465 native_display_delegate_->RemoveObserver(this); |
| 466 |
| 467 CallAndClearPendingCallbacks(false); |
| 468 CallAndClearQueuedCallbacks(false); |
| 463 } | 469 } |
| 464 | 470 |
| 465 void DisplayConfigurator::SetDelegateForTesting( | 471 void DisplayConfigurator::SetDelegateForTesting( |
| 466 scoped_ptr<NativeDisplayDelegate> display_delegate) { | 472 scoped_ptr<NativeDisplayDelegate> display_delegate) { |
| 467 DCHECK(!native_display_delegate_); | 473 DCHECK(!native_display_delegate_); |
| 468 | 474 |
| 469 native_display_delegate_ = display_delegate.Pass(); | 475 native_display_delegate_ = display_delegate.Pass(); |
| 470 configure_display_ = true; | 476 configure_display_ = true; |
| 471 } | 477 } |
| 472 | 478 |
| (...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 752 | 758 |
| 753 return false; | 759 return false; |
| 754 } | 760 } |
| 755 | 761 |
| 756 void DisplayConfigurator::PrepareForExit() { | 762 void DisplayConfigurator::PrepareForExit() { |
| 757 configure_display_ = false; | 763 configure_display_ = false; |
| 758 } | 764 } |
| 759 | 765 |
| 760 void DisplayConfigurator::SetDisplayPower( | 766 void DisplayConfigurator::SetDisplayPower( |
| 761 chromeos::DisplayPowerState power_state, | 767 chromeos::DisplayPowerState power_state, |
| 762 int flags) { | 768 int flags, |
| 763 if (!configure_display_ || display_externally_controlled_) | 769 const ConfigurationCallback& callback) { |
| 770 if (!configure_display_ || display_externally_controlled_) { |
| 771 callback.Run(false); |
| 764 return; | 772 return; |
| 773 } |
| 765 | 774 |
| 766 VLOG(1) << "SetDisplayPower: power_state=" | 775 VLOG(1) << "SetDisplayPower: power_state=" |
| 767 << DisplayPowerStateToString(power_state) << " flags=" << flags | 776 << DisplayPowerStateToString(power_state) << " flags=" << flags |
| 768 << ", configure timer=" | 777 << ", configure timer=" |
| 769 << (configure_timer_.IsRunning() ? "Running" : "Stopped"); | 778 << (configure_timer_.IsRunning() ? "Running" : "Stopped"); |
| 770 if (power_state == requested_power_state_ && | 779 if (power_state == requested_power_state_ && |
| 771 !(flags & kSetDisplayPowerForceProbe)) | 780 !(flags & kSetDisplayPowerForceProbe)) { |
| 781 callback.Run(true); |
| 772 return; | 782 return; |
| 783 } |
| 773 | 784 |
| 774 requested_power_state_ = power_state; | 785 requested_power_state_ = power_state; |
| 775 requested_power_state_change_ = true; | 786 requested_power_state_change_ = true; |
| 776 requested_power_flags_ = flags; | 787 requested_power_flags_ = flags; |
| 788 queued_configuration_callbacks_.push_back(callback); |
| 777 | 789 |
| 778 RunPendingConfiguration(); | 790 RunPendingConfiguration(); |
| 779 } | 791 } |
| 780 | 792 |
| 781 void DisplayConfigurator::SetDisplayMode(MultipleDisplayState new_state) { | 793 void DisplayConfigurator::SetDisplayMode(MultipleDisplayState new_state) { |
| 782 if (!configure_display_ || display_externally_controlled_) | 794 if (!configure_display_ || display_externally_controlled_) |
| 783 return; | 795 return; |
| 784 | 796 |
| 785 VLOG(1) << "SetDisplayMode: state=" | 797 VLOG(1) << "SetDisplayMode: state=" |
| 786 << MultipleDisplayStateToString(new_state); | 798 << MultipleDisplayStateToString(new_state); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 829 } | 841 } |
| 830 | 842 |
| 831 void DisplayConfigurator::SuspendDisplays() { | 843 void DisplayConfigurator::SuspendDisplays() { |
| 832 // If the display is off due to user inactivity and there's only a single | 844 // If the display is off due to user inactivity and there's only a single |
| 833 // internal display connected, switch to the all-on state before | 845 // internal display connected, switch to the all-on state before |
| 834 // suspending. This shouldn't be very noticeable to the user since the | 846 // suspending. This shouldn't be very noticeable to the user since the |
| 835 // backlight is off at this point, and doing this lets us resume directly | 847 // backlight is off at this point, and doing this lets us resume directly |
| 836 // into the "on" state, which greatly reduces resume times. | 848 // into the "on" state, which greatly reduces resume times. |
| 837 if (requested_power_state_ == chromeos::DISPLAY_POWER_ALL_OFF) { | 849 if (requested_power_state_ == chromeos::DISPLAY_POWER_ALL_OFF) { |
| 838 SetDisplayPower(chromeos::DISPLAY_POWER_ALL_ON, | 850 SetDisplayPower(chromeos::DISPLAY_POWER_ALL_ON, |
| 839 kSetDisplayPowerOnlyIfSingleInternalDisplay); | 851 kSetDisplayPowerOnlyIfSingleInternalDisplay, |
| 852 base::Bind(&DoNothing)); |
| 840 | 853 |
| 841 // We need to make sure that the monitor configuration we just did actually | 854 // We need to make sure that the monitor configuration we just did actually |
| 842 // completes before we return, because otherwise the X message could be | 855 // completes before we return, because otherwise the X message could be |
| 843 // racing with the HandleSuspendReadiness message. | 856 // racing with the HandleSuspendReadiness message. |
| 844 native_display_delegate_->SyncWithServer(); | 857 native_display_delegate_->SyncWithServer(); |
| 845 } | 858 } |
| 846 } | 859 } |
| 847 | 860 |
| 848 void DisplayConfigurator::ResumeDisplays() { | 861 void DisplayConfigurator::ResumeDisplays() { |
| 849 configure_timer_.Start( | 862 configure_timer_.Start( |
| (...skipping 13 matching lines...) Expand all Loading... |
| 863 | 876 |
| 864 void DisplayConfigurator::RunPendingConfiguration() { | 877 void DisplayConfigurator::RunPendingConfiguration() { |
| 865 // Configuration task is currently running. Do not start a second | 878 // Configuration task is currently running. Do not start a second |
| 866 // configuration. | 879 // configuration. |
| 867 if (configuration_task_) | 880 if (configuration_task_) |
| 868 return; | 881 return; |
| 869 | 882 |
| 870 if (!ShouldRunConfigurationTask()) { | 883 if (!ShouldRunConfigurationTask()) { |
| 871 LOG(ERROR) << "Called RunPendingConfiguration without any changes" | 884 LOG(ERROR) << "Called RunPendingConfiguration without any changes" |
| 872 " requested"; | 885 " requested"; |
| 886 CallAndClearQueuedCallbacks(true); |
| 873 return; | 887 return; |
| 874 } | 888 } |
| 875 | 889 |
| 876 configuration_task_.reset(new UpdateDisplayConfigurationTask( | 890 configuration_task_.reset(new UpdateDisplayConfigurationTask( |
| 877 native_display_delegate_.get(), layout_manager_.get(), | 891 native_display_delegate_.get(), layout_manager_.get(), |
| 878 requested_display_state_, requested_power_state_, requested_power_flags_, | 892 requested_display_state_, requested_power_state_, requested_power_flags_, |
| 879 0, force_configure_, base::Bind(&DisplayConfigurator::OnConfigured, | 893 0, force_configure_, base::Bind(&DisplayConfigurator::OnConfigured, |
| 880 weak_ptr_factory_.GetWeakPtr()))); | 894 weak_ptr_factory_.GetWeakPtr()))); |
| 881 | 895 |
| 882 // Reset the flags before running the task; otherwise it may end up scheduling | 896 // Reset the flags before running the task; otherwise it may end up scheduling |
| 883 // another configuration. | 897 // another configuration. |
| 884 force_configure_ = false; | 898 force_configure_ = false; |
| 885 requested_power_flags_ = kSetDisplayPowerNoFlags; | 899 requested_power_flags_ = kSetDisplayPowerNoFlags; |
| 886 requested_power_state_change_ = false; | 900 requested_power_state_change_ = false; |
| 887 requested_display_state_ = MULTIPLE_DISPLAY_STATE_INVALID; | 901 requested_display_state_ = MULTIPLE_DISPLAY_STATE_INVALID; |
| 888 | 902 |
| 903 DCHECK(pending_configuration_callbacks_.empty()); |
| 904 pending_configuration_callbacks_.swap(queued_configuration_callbacks_); |
| 905 |
| 889 configuration_task_->Run(); | 906 configuration_task_->Run(); |
| 890 } | 907 } |
| 891 | 908 |
| 892 void DisplayConfigurator::OnConfigured( | 909 void DisplayConfigurator::OnConfigured( |
| 893 bool success, | 910 bool success, |
| 894 const std::vector<DisplayState>& displays, | 911 const std::vector<DisplayState>& displays, |
| 895 const gfx::Size& framebuffer_size, | 912 const gfx::Size& framebuffer_size, |
| 896 MultipleDisplayState new_display_state, | 913 MultipleDisplayState new_display_state, |
| 897 chromeos::DisplayPowerState new_power_state) { | 914 chromeos::DisplayPowerState new_power_state) { |
| 898 VLOG(1) << "OnConfigured: success=" << success << " new_display_state=" | 915 VLOG(1) << "OnConfigured: success=" << success << " new_display_state=" |
| 899 << MultipleDisplayStateToString(new_display_state) | 916 << MultipleDisplayStateToString(new_display_state) |
| 900 << " new_power_state=" << DisplayPowerStateToString(new_power_state); | 917 << " new_power_state=" << DisplayPowerStateToString(new_power_state); |
| 901 | 918 |
| 902 cached_displays_ = displays; | 919 cached_displays_ = displays; |
| 903 if (success) { | 920 if (success) { |
| 904 current_display_state_ = new_display_state; | 921 current_display_state_ = new_display_state; |
| 905 current_power_state_ = new_power_state; | 922 current_power_state_ = new_power_state; |
| 906 framebuffer_size_ = framebuffer_size; | 923 framebuffer_size_ = framebuffer_size; |
| 907 // If the requested power state hasn't changed then make sure that value | 924 // If the requested power state hasn't changed then make sure that value |
| 908 // gets updated as well since the last requested value may have been | 925 // gets updated as well since the last requested value may have been |
| 909 // dependent on certain conditions (ie: if only the internal monitor was | 926 // dependent on certain conditions (ie: if only the internal monitor was |
| 910 // present). | 927 // present). |
| 911 if (!requested_power_state_change_) | 928 if (!requested_power_state_change_) |
| 912 requested_power_state_ = new_power_state; | 929 requested_power_state_ = new_power_state; |
| 913 } | 930 } |
| 914 | 931 |
| 915 configuration_task_.reset(); | 932 configuration_task_.reset(); |
| 916 NotifyObservers(success, new_display_state); | 933 NotifyObservers(success, new_display_state); |
| 934 CallAndClearPendingCallbacks(success); |
| 917 | 935 |
| 918 if (success && !configure_timer_.IsRunning() && | 936 if (success && !configure_timer_.IsRunning() && |
| 919 ShouldRunConfigurationTask()) { | 937 ShouldRunConfigurationTask()) { |
| 920 configure_timer_.Start(FROM_HERE, | 938 configure_timer_.Start(FROM_HERE, |
| 921 base::TimeDelta::FromMilliseconds(kConfigureDelayMs), | 939 base::TimeDelta::FromMilliseconds(kConfigureDelayMs), |
| 922 this, &DisplayConfigurator::RunPendingConfiguration); | 940 this, &DisplayConfigurator::RunPendingConfiguration); |
| 941 } else { |
| 942 // If a new configuration task isn't scheduled respond to all queued |
| 943 // callbacks (for example if requested state is current state). |
| 944 if (!configure_timer_.IsRunning()) |
| 945 CallAndClearQueuedCallbacks(success); |
| 923 } | 946 } |
| 924 } | 947 } |
| 925 | 948 |
| 926 bool DisplayConfigurator::ShouldRunConfigurationTask() const { | 949 bool DisplayConfigurator::ShouldRunConfigurationTask() const { |
| 927 if (force_configure_) | 950 if (force_configure_) |
| 928 return true; | 951 return true; |
| 929 | 952 |
| 930 // Schedule if there is a request to change the display state. | 953 // Schedule if there is a request to change the display state. |
| 931 if (requested_display_state_ != current_display_state_ && | 954 if (requested_display_state_ != current_display_state_ && |
| 932 requested_display_state_ != MULTIPLE_DISPLAY_STATE_INVALID) | 955 requested_display_state_ != MULTIPLE_DISPLAY_STATE_INVALID) |
| 933 return true; | 956 return true; |
| 934 | 957 |
| 935 // Schedule if there is a request to change the power state. | 958 // Schedule if there is a request to change the power state. |
| 936 if (requested_power_state_change_) | 959 if (requested_power_state_change_) |
| 937 return true; | 960 return true; |
| 938 | 961 |
| 939 return false; | 962 return false; |
| 940 } | 963 } |
| 941 | 964 |
| 965 void DisplayConfigurator::CallAndClearPendingCallbacks(bool success) { |
| 966 for (const auto& callback : pending_configuration_callbacks_) |
| 967 callback.Run(success); |
| 968 |
| 969 pending_configuration_callbacks_.clear(); |
| 970 } |
| 971 |
| 972 void DisplayConfigurator::CallAndClearQueuedCallbacks(bool success) { |
| 973 for (const auto& callback : queued_configuration_callbacks_) |
| 974 callback.Run(success); |
| 975 |
| 976 queued_configuration_callbacks_.clear(); |
| 977 } |
| 978 |
| 942 void DisplayConfigurator::RestoreRequestedPowerStateAfterResume() { | 979 void DisplayConfigurator::RestoreRequestedPowerStateAfterResume() { |
| 943 // Force probing to ensure that we pick up any changes that were made while | 980 // Force probing to ensure that we pick up any changes that were made while |
| 944 // the system was suspended. | 981 // the system was suspended. |
| 945 SetDisplayPower(requested_power_state_, kSetDisplayPowerForceProbe); | 982 SetDisplayPower(requested_power_state_, kSetDisplayPowerForceProbe, |
| 983 base::Bind(&DoNothing)); |
| 946 } | 984 } |
| 947 | 985 |
| 948 void DisplayConfigurator::NotifyObservers( | 986 void DisplayConfigurator::NotifyObservers( |
| 949 bool success, | 987 bool success, |
| 950 MultipleDisplayState attempted_state) { | 988 MultipleDisplayState attempted_state) { |
| 951 if (success) { | 989 if (success) { |
| 952 FOR_EACH_OBSERVER( | 990 FOR_EACH_OBSERVER( |
| 953 Observer, observers_, OnDisplayModeChanged(cached_displays_)); | 991 Observer, observers_, OnDisplayModeChanged(cached_displays_)); |
| 954 } else { | 992 } else { |
| 955 FOR_EACH_OBSERVER( | 993 FOR_EACH_OBSERVER( |
| 956 Observer, observers_, OnDisplayModeChangeFailed(attempted_state)); | 994 Observer, observers_, OnDisplayModeChangeFailed(attempted_state)); |
| 957 } | 995 } |
| 958 } | 996 } |
| 959 | 997 |
| 960 } // namespace ui | 998 } // namespace ui |
| OLD | NEW |