summaryrefslogtreecommitdiffstats
path: root/ash
diff options
context:
space:
mode:
authorderat@chromium.org <derat@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-02-28 10:40:06 +0000
committerderat@chromium.org <derat@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-02-28 10:40:06 +0000
commit685442f3419739cc35090343ad7845dc10226fa5 (patch)
tree4babecfa93e550bb21bd133491595d48cf2a414b /ash
parent13413b74727834f0bdf238e5149e99dd26b5225a (diff)
downloadchromium_src-685442f3419739cc35090343ad7845dc10226fa5.zip
chromium_src-685442f3419739cc35090343ad7845dc10226fa5.tar.gz
chromium_src-685442f3419739cc35090343ad7845dc10226fa5.tar.bz2
chromeos: Honor power button when in docked mode.
Ash ignores power button events while the display's brightness is set to 0%. Make it honor them if an external display is still on. BUG=chrome-os-partner:24912 Review URL: https://codereview.chromium.org/177043004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@254087 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ash')
-rw-r--r--ash/shell.cc5
-rw-r--r--ash/wm/lock_state_controller_unittest.cc38
-rw-r--r--ash/wm/power_button_controller.cc35
-rw-r--r--ash/wm/power_button_controller.h29
4 files changed, 98 insertions, 9 deletions
diff --git a/ash/shell.cc b/ash/shell.cc
index 6d561a2..36357d0 100644
--- a/ash/shell.cc
+++ b/ash/shell.cc
@@ -887,6 +887,11 @@ void Shell::Init() {
lock_state_controller_.reset(new LockStateController);
power_button_controller_.reset(new PowerButtonController(
lock_state_controller_.get()));
+#if defined(OS_CHROMEOS) && defined(USE_X11)
+ // Pass the initial display state to PowerButtonController.
+ power_button_controller_->OnDisplayModeChanged(
+ output_configurator_->cached_outputs());
+#endif
AddShellObserver(lock_state_controller_.get());
drag_drop_controller_.reset(new internal::DragDropController);
diff --git a/ash/wm/lock_state_controller_unittest.cc b/ash/wm/lock_state_controller_unittest.cc
index 871682d..b426738 100644
--- a/ash/wm/lock_state_controller_unittest.cc
+++ b/ash/wm/lock_state_controller_unittest.cc
@@ -25,6 +25,11 @@
#include "ui/gfx/rect.h"
#include "ui/gfx/size.h"
+#if defined(OS_CHROMEOS) && defined(USE_X11)
+#include "chromeos/display/output_configurator.h"
+#include "ui/display/display_constants.h"
+#endif
+
#if defined(OS_WIN)
#include "base/win/windows_version.h"
#endif
@@ -979,7 +984,6 @@ TEST_F(LockStateControllerTest, IgnorePowerButtonIfScreenIsOff) {
// When the screen brightness is at 0%, we shouldn't do anything in response
// to power button presses.
controller_->OnScreenBrightnessChanged(0.0);
-
PressPowerButton();
EXPECT_FALSE(test_api_->is_animating_lock());
ReleasePowerButton();
@@ -987,10 +991,42 @@ TEST_F(LockStateControllerTest, IgnorePowerButtonIfScreenIsOff) {
// After increasing the brightness to 10%, we should start the timer like
// usual.
controller_->OnScreenBrightnessChanged(10.0);
+ PressPowerButton();
+ EXPECT_TRUE(test_api_->is_animating_lock());
+ ReleasePowerButton();
+}
+#if defined(OS_CHROMEOS) && defined(USE_X11)
+TEST_F(LockStateControllerTest, HonorPowerButtonInDockedMode) {
+ // Create two outputs, the first internal and the second external.
+ std::vector<chromeos::OutputConfigurator::OutputSnapshot> outputs;
+ chromeos::OutputConfigurator::OutputSnapshot internal_output;
+ internal_output.type = ui::OUTPUT_TYPE_INTERNAL;
+ outputs.push_back(internal_output);
+ chromeos::OutputConfigurator::OutputSnapshot external_output;
+ external_output.type = ui::OUTPUT_TYPE_HDMI;
+ outputs.push_back(external_output);
+
+ // When all of the displays are turned off (e.g. due to user inactivity), the
+ // power button should be ignored.
+ controller_->OnScreenBrightnessChanged(0.0);
+ outputs[0].current_mode = 0;
+ outputs[1].current_mode = 0;
+ controller_->OnDisplayModeChanged(outputs);
+ PressPowerButton();
+ EXPECT_FALSE(test_api_->is_animating_lock());
+ ReleasePowerButton();
+
+ // When the screen brightness is 0% but the external display is still turned
+ // on (indicating either docked mode or the user having manually decreased the
+ // brightness to 0%), the power button should still be handled.
+ outputs[1].current_mode = 1;
+ controller_->OnDisplayModeChanged(outputs);
PressPowerButton();
EXPECT_TRUE(test_api_->is_animating_lock());
+ ReleasePowerButton();
}
+#endif
// Test that hidden background appears and revers correctly on lock/cancel.
// TODO(antrim): Reenable this: http://crbug.com/167048
diff --git a/ash/wm/power_button_controller.cc b/ash/wm/power_button_controller.cc
index 3df7e689..c7eeefa 100644
--- a/ash/wm/power_button_controller.cc
+++ b/ash/wm/power_button_controller.cc
@@ -20,18 +20,25 @@ PowerButtonController::PowerButtonController(
LockStateController* controller)
: power_button_down_(false),
lock_button_down_(false),
- screen_is_off_(false),
+ brightness_is_zero_(false),
+ internal_display_off_and_external_display_on_(false),
has_legacy_power_button_(
CommandLine::ForCurrentProcess()->HasSwitch(
switches::kAuraLegacyPowerButton)),
controller_(controller) {
+#if defined(OS_CHROMEOS) && defined(USE_X11)
+ Shell::GetInstance()->output_configurator()->AddObserver(this);
+#endif
}
PowerButtonController::~PowerButtonController() {
+#if defined(OS_CHROMEOS) && defined(USE_X11)
+ Shell::GetInstance()->output_configurator()->RemoveObserver(this);
+#endif
}
void PowerButtonController::OnScreenBrightnessChanged(double percent) {
- screen_is_off_ = percent <= 0.001;
+ brightness_is_zero_ = percent <= 0.001;
}
void PowerButtonController::OnPowerButtonEvent(
@@ -42,8 +49,9 @@ void PowerButtonController::OnPowerButtonEvent(
return;
// Avoid starting the lock/shutdown sequence if the power button is pressed
- // while the screen is off (http://crbug.com/128451).
- if (screen_is_off_)
+ // while the screen is off (http://crbug.com/128451), unless an external
+ // display is still on (http://crosbug.com/p/24912).
+ if (brightness_is_zero_ && !internal_display_off_and_external_display_on_)
return;
const SessionStateDelegate* session_state_delegate =
@@ -107,4 +115,23 @@ void PowerButtonController::OnLockButtonEvent(
controller_->CancelLockAnimation();
}
+#if defined(OS_CHROMEOS) && defined(USE_X11)
+void PowerButtonController::OnDisplayModeChanged(
+ const std::vector<chromeos::OutputConfigurator::OutputSnapshot>& outputs) {
+ bool internal_display_off = false;
+ bool external_display_on = false;
+ for (size_t i = 0; i < outputs.size(); ++i) {
+ const chromeos::OutputConfigurator::OutputSnapshot& output = outputs[i];
+ if (output.type == ui::OUTPUT_TYPE_INTERNAL) {
+ if (!output.current_mode)
+ internal_display_off = true;
+ } else if (output.current_mode) {
+ external_display_on = true;
+ }
+ }
+ internal_display_off_and_external_display_on_ =
+ internal_display_off && external_display_on;
+}
+#endif
+
} // namespace ash
diff --git a/ash/wm/power_button_controller.h b/ash/wm/power_button_controller.h
index 558bf6d..5c7de09 100644
--- a/ash/wm/power_button_controller.h
+++ b/ash/wm/power_button_controller.h
@@ -9,6 +9,10 @@
#include "ash/wm/session_state_animator.h"
#include "base/basictypes.h"
+#if defined(OS_CHROMEOS) && defined(USE_X11)
+#include "chromeos/display/output_configurator.h"
+#endif
+
namespace gfx {
class Rect;
class Size;
@@ -28,9 +32,14 @@ class LockStateController;
// Displays onscreen animations and locks or suspends the system in response to
// the power button being pressed or released.
-class ASH_EXPORT PowerButtonController {
+class ASH_EXPORT PowerButtonController
+// TODO(derat): Remove these ifdefs after OutputConfigurator becomes
+// cross-platform.
+#if defined(OS_CHROMEOS) && defined(USE_X11)
+ : public chromeos::OutputConfigurator::Observer
+#endif
+ {
public:
-
explicit PowerButtonController(LockStateController* controller);
virtual ~PowerButtonController();
@@ -45,6 +54,13 @@ class ASH_EXPORT PowerButtonController {
void OnPowerButtonEvent(bool down, const base::TimeTicks& timestamp);
void OnLockButtonEvent(bool down, const base::TimeTicks& timestamp);
+#if defined(OS_CHROMEOS) && defined(USE_X11)
+ // Overriden from chromeos::OutputConfigurator::Observer:
+ virtual void OnDisplayModeChanged(
+ const std::vector<chromeos::OutputConfigurator::OutputSnapshot>& outputs)
+ OVERRIDE;
+#endif
+
private:
friend class test::PowerButtonControllerTest;
@@ -52,8 +68,13 @@ class ASH_EXPORT PowerButtonController {
bool power_button_down_;
bool lock_button_down_;
- // Is the screen currently turned off?
- bool screen_is_off_;
+ // Has the screen brightness been reduced to 0%?
+ bool brightness_is_zero_;
+
+ // True if an internal display is off while an external display is on (e.g.
+ // for Chrome OS's docked mode, where a Chromebook's lid is closed while an
+ // external display is connected).
+ bool internal_display_off_and_external_display_on_;
// Was a command-line switch set telling us that we're running on hardware
// that misreports power button releases?