summaryrefslogtreecommitdiffstats
path: root/ash/display/display_controller.cc
diff options
context:
space:
mode:
authoroshima@chromium.org <oshima@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-01-12 21:47:25 +0000
committeroshima@chromium.org <oshima@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-01-12 21:47:25 +0000
commit45ad7197ae1b016fe27f795a75e62fb55de08696 (patch)
treefafa8a8cee3bbd0241509bf31fc9f29d6735ac32 /ash/display/display_controller.cc
parent68ce2c15d892acc384f573cb2f40e043cff18cdb (diff)
downloadchromium_src-45ad7197ae1b016fe27f795a75e62fb55de08696.zip
chromium_src-45ad7197ae1b016fe27f795a75e62fb55de08696.tar.gz
chromium_src-45ad7197ae1b016fe27f795a75e62fb55de08696.tar.bz2
Limit how quickly a user can change display configuration
Add --ash-disable-display-change-limitter to disable throttling This doesn't fix the gpu crash, but we should throttle how quickly a user can change the display settings anyway. BUG=168950 TEST=manually tested on device. See bug for repro step. Review URL: https://chromiumcodereview.appspot.com/11882006 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@176595 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ash/display/display_controller.cc')
-rw-r--r--ash/display/display_controller.cc86
1 files changed, 85 insertions, 1 deletions
diff --git a/ash/display/display_controller.cc b/ash/display/display_controller.cc
index ee3d391..6a98522 100644
--- a/ash/display/display_controller.cc
+++ b/ash/display/display_controller.cc
@@ -9,6 +9,7 @@
#include "ash/ash_switches.h"
#include "ash/display/display_manager.h"
#include "ash/root_window_controller.h"
+#include "ash/screen_ash.h"
#include "ash/shell.h"
#include "ash/wm/coordinate_conversion.h"
#include "ash/wm/property_util.h"
@@ -27,8 +28,12 @@
#include "ui/gfx/screen.h"
#if defined(OS_CHROMEOS)
+#include "ash/display/output_configurator_animation.h"
#include "base/chromeos/chromeos_version.h"
-#endif
+#include "base/time.h"
+#include "chromeos/display/output_configurator.h"
+#endif // defined(OS_CHROMEOS)
+
namespace ash {
namespace {
@@ -51,6 +56,16 @@ const int kMaxValidOffset = 10000;
// in case that the offset value is too large.
const int kMinimumOverlapForInvalidOffset = 100;
+// Specifies how long the display change should have been disabled
+// after each display change operations.
+// |kCycleDisplayThrottleTimeoutMs| is set to be longer to avoid
+// changing the settings while the system is still configurating
+// displays. It will be overriden by |kAfterDisplayChangeThrottleTimeoutMs|
+// when the display change happens, so the actual timeout is much shorter.
+const int64 kAfterDisplayChangeThrottleTimeoutMs = 500;
+const int64 kCycleDisplayThrottleTimeoutMs = 4000;
+const int64 kSwapDisplayThrottleTimeoutMs = 500;
+
bool GetPositionFromString(const base::StringPiece& position,
DisplayLayout::Position* field) {
if (position == "top") {
@@ -90,6 +105,9 @@ internal::DisplayManager* GetDisplayManager() {
} // namespace
+////////////////////////////////////////////////////////////////////////////////
+// DisplayLayout
+
DisplayLayout::DisplayLayout()
: position(RIGHT),
offset(0) {}
@@ -160,9 +178,35 @@ void DisplayLayout::RegisterJSONConverter(
converter->RegisterIntField("offset", &DisplayLayout::offset);
}
+////////////////////////////////////////////////////////////////////////////////
+// DisplayChangeLimiter
+
+DisplayController::DisplayChangeLimiter::DisplayChangeLimiter()
+ : throttle_timeout_(base::Time::Now()) {
+}
+
+void DisplayController::DisplayChangeLimiter::SetThrottleTimeout(
+ int64 throttle_ms) {
+ throttle_timeout_ =
+ base::Time::Now() + base::TimeDelta::FromMilliseconds(throttle_ms);
+}
+
+bool DisplayController::DisplayChangeLimiter::IsThrottled() const {
+ return base::Time::Now() < throttle_timeout_;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// DisplayController
+
DisplayController::DisplayController()
: desired_primary_display_id_(gfx::Display::kInvalidDisplayID),
primary_root_window_for_replace_(NULL) {
+#if defined(OS_CHROMEOS)
+ CommandLine* command_line = CommandLine::ForCurrentProcess();
+ if (!command_line->HasSwitch(switches::kAshDisableDisplayChangeLimiter) &&
+ base::chromeos::IsRunningOnChromeOS())
+ limiter_.reset(new DisplayChangeLimiter);
+#endif
// Reset primary display to make sure that tests don't use
// stale display info from previous tests.
primary_display_id = gfx::Display::kInvalidDisplayID;
@@ -376,6 +420,37 @@ const DisplayLayout& DisplayController::GetCurrentDisplayLayout() const {
return default_display_layout_;
}
+void DisplayController::CycleDisplayMode() {
+ if (limiter_.get()) {
+ if (limiter_->IsThrottled())
+ return;
+ limiter_->SetThrottleTimeout(kCycleDisplayThrottleTimeoutMs);
+ }
+#if defined(OS_CHROMEOS)
+ Shell* shell = Shell::GetInstance();
+ if (!base::chromeos::IsRunningOnChromeOS()) {
+ internal::DisplayManager::CycleDisplay();
+ } else if (shell->output_configurator()->connected_output_count() > 1) {
+ internal::OutputConfiguratorAnimation* animation =
+ shell->output_configurator_animation();
+ animation->StartFadeOutAnimation(base::Bind(
+ base::IgnoreResult(&chromeos::OutputConfigurator::CycleDisplayMode),
+ base::Unretained(shell->output_configurator())));
+ }
+#endif
+}
+
+void DisplayController::SwapPrimaryDisplay() {
+ if (limiter_.get()) {
+ if (limiter_->IsThrottled())
+ return;
+ limiter_->SetThrottleTimeout(kSwapDisplayThrottleTimeoutMs);
+ }
+
+ if (Shell::GetScreen()->GetNumDisplays() > 1)
+ SetPrimaryDisplay(ScreenAsh::GetSecondaryDisplay());
+}
+
void DisplayController::SetPrimaryDisplayId(int64 id) {
desired_primary_display_id_ = id;
@@ -460,12 +535,18 @@ gfx::Display* DisplayController::GetSecondaryDisplay() {
}
void DisplayController::OnDisplayBoundsChanged(const gfx::Display& display) {
+ if (limiter_.get())
+ limiter_->SetThrottleTimeout(kAfterDisplayChangeThrottleTimeoutMs);
+
NotifyDisplayConfigurationChanging();
UpdateDisplayBoundsForLayout();
root_windows_[display.id()]->SetHostBounds(display.bounds_in_pixel());
}
void DisplayController::OnDisplayAdded(const gfx::Display& display) {
+ if (limiter_.get())
+ limiter_->SetThrottleTimeout(kAfterDisplayChangeThrottleTimeoutMs);
+
NotifyDisplayConfigurationChanging();
if (primary_root_window_for_replace_) {
DCHECK(root_windows_.empty());
@@ -487,6 +568,9 @@ void DisplayController::OnDisplayAdded(const gfx::Display& display) {
}
void DisplayController::OnDisplayRemoved(const gfx::Display& display) {
+ if (limiter_.get())
+ limiter_->SetThrottleTimeout(kAfterDisplayChangeThrottleTimeoutMs);
+
aura::RootWindow* root_to_delete = root_windows_[display.id()];
DCHECK(root_to_delete) << display.ToString();
NotifyDisplayConfigurationChanging();