blob: 6e96c651dc5ba2ea47d4f44015dd3d9b3559fe74 [file] [log] [blame]
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001// 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
3// found in the LICENSE file.
4
5#include "ash/wm/power_button_controller.h"
6
7#include "ash/ash_switches.h"
Bo Liu5c02ac12014-05-01 10:37:37 -07008#include "ash/session/session_state_delegate.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +00009#include "ash/shell.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000010#include "ash/shell_window_ids.h"
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010011#include "ash/wm/lock_state_controller.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000012#include "ash/wm/session_state_animator.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000013#include "base/command_line.h"
Torne (Richard Coles)a1401312014-03-18 10:20:56 +000014#include "ui/aura/window_event_dispatcher.h"
Ben Murdocha02191e2014-04-16 11:17:03 +010015#include "ui/display/types/chromeos/display_snapshot.h"
Torne (Richard Coles)a1401312014-03-18 10:20:56 +000016#include "ui/wm/core/compound_event_filter.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000017
18namespace ash {
19
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010020PowerButtonController::PowerButtonController(
21 LockStateController* controller)
Torne (Richard Coles)58218062012-11-14 11:43:16 +000022 : power_button_down_(false),
23 lock_button_down_(false),
Torne (Richard Coles)a1401312014-03-18 10:20:56 +000024 brightness_is_zero_(false),
25 internal_display_off_and_external_display_on_(false),
Torne (Richard Coles)58218062012-11-14 11:43:16 +000026 has_legacy_power_button_(
27 CommandLine::ForCurrentProcess()->HasSwitch(
28 switches::kAuraLegacyPowerButton)),
29 controller_(controller) {
Ben Murdocheffb81e2014-03-31 11:51:25 +010030#if defined(OS_CHROMEOS)
Ben Murdochc5cede92014-04-10 11:22:14 +010031 Shell::GetInstance()->display_configurator()->AddObserver(this);
Torne (Richard Coles)a1401312014-03-18 10:20:56 +000032#endif
Torne (Richard Coles)58218062012-11-14 11:43:16 +000033}
34
35PowerButtonController::~PowerButtonController() {
Ben Murdocheffb81e2014-03-31 11:51:25 +010036#if defined(OS_CHROMEOS)
Ben Murdochc5cede92014-04-10 11:22:14 +010037 Shell::GetInstance()->display_configurator()->RemoveObserver(this);
Torne (Richard Coles)a1401312014-03-18 10:20:56 +000038#endif
Torne (Richard Coles)58218062012-11-14 11:43:16 +000039}
40
41void PowerButtonController::OnScreenBrightnessChanged(double percent) {
Torne (Richard Coles)a1401312014-03-18 10:20:56 +000042 brightness_is_zero_ = percent <= 0.001;
Torne (Richard Coles)58218062012-11-14 11:43:16 +000043}
44
45void PowerButtonController::OnPowerButtonEvent(
46 bool down, const base::TimeTicks& timestamp) {
47 power_button_down_ = down;
48
49 if (controller_->ShutdownRequested())
50 return;
51
52 // Avoid starting the lock/shutdown sequence if the power button is pressed
Torne (Richard Coles)a1401312014-03-18 10:20:56 +000053 // while the screen is off (http://crbug.com/128451), unless an external
54 // display is still on (http://crosbug.com/p/24912).
55 if (brightness_is_zero_ && !internal_display_off_and_external_display_on_)
Torne (Richard Coles)58218062012-11-14 11:43:16 +000056 return;
57
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010058 const SessionStateDelegate* session_state_delegate =
59 Shell::GetInstance()->session_state_delegate();
Torne (Richard Coles)58218062012-11-14 11:43:16 +000060 if (has_legacy_power_button_) {
61 // If power button releases won't get reported correctly because we're not
62 // running on official hardware, just lock the screen or shut down
63 // immediately.
64 if (down) {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010065 if (session_state_delegate->CanLockScreen() &&
66 !session_state_delegate->IsScreenLocked() &&
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000067 !controller_->LockRequested()) {
Torne (Richard Coles)58218062012-11-14 11:43:16 +000068 controller_->StartLockAnimationAndLockImmediately();
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000069 } else {
Torne (Richard Coles)58218062012-11-14 11:43:16 +000070 controller_->RequestShutdown();
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000071 }
Torne (Richard Coles)58218062012-11-14 11:43:16 +000072 }
73 } else { // !has_legacy_power_button_
74 if (down) {
75 // If we already have a pending request to lock the screen, wait.
76 if (controller_->LockRequested())
77 return;
78
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010079 if (session_state_delegate->CanLockScreen() &&
80 !session_state_delegate->IsScreenLocked()) {
Torne (Richard Coles)58218062012-11-14 11:43:16 +000081 controller_->StartLockAnimation(true);
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010082 } else {
Torne (Richard Coles)58218062012-11-14 11:43:16 +000083 controller_->StartShutdownAnimation();
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010084 }
Torne (Richard Coles)58218062012-11-14 11:43:16 +000085 } else { // Button is up.
86 if (controller_->CanCancelLockAnimation())
87 controller_->CancelLockAnimation();
88 else if (controller_->CanCancelShutdownAnimation())
89 controller_->CancelShutdownAnimation();
90 }
91 }
92}
93
94void PowerButtonController::OnLockButtonEvent(
95 bool down, const base::TimeTicks& timestamp) {
96 lock_button_down_ = down;
97
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010098 const SessionStateDelegate* session_state_delegate =
99 Shell::GetInstance()->session_state_delegate();
100 if (!session_state_delegate->CanLockScreen() ||
101 session_state_delegate->IsScreenLocked() ||
102 controller_->LockRequested() ||
103 controller_->ShutdownRequested()) {
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000104 return;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000105 }
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000106
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000107 // Give the power button precedence over the lock button (we don't expect both
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000108 // buttons to be present, so this is just making sure that we don't do
109 // something completely stupid if that assumption changes later).
110 if (power_button_down_)
111 return;
112
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000113 if (down)
114 controller_->StartLockAnimation(false);
115 else
116 controller_->CancelLockAnimation();
117}
118
Ben Murdocheffb81e2014-03-31 11:51:25 +0100119#if defined(OS_CHROMEOS)
Torne (Richard Coles)a1401312014-03-18 10:20:56 +0000120void PowerButtonController::OnDisplayModeChanged(
Ben Murdochc5cede92014-04-10 11:22:14 +0100121 const ui::DisplayConfigurator::DisplayStateList& display_states) {
Torne (Richard Coles)a1401312014-03-18 10:20:56 +0000122 bool internal_display_off = false;
123 bool external_display_on = false;
Ben Murdochc5cede92014-04-10 11:22:14 +0100124 for (size_t i = 0; i < display_states.size(); ++i) {
125 const ui::DisplayConfigurator::DisplayState& state = display_states[i];
126 if (state.display->type() == ui::DISPLAY_CONNECTION_TYPE_INTERNAL) {
127 if (!state.display->current_mode())
Torne (Richard Coles)a1401312014-03-18 10:20:56 +0000128 internal_display_off = true;
Ben Murdochc5cede92014-04-10 11:22:14 +0100129 } else if (state.display->current_mode()) {
Torne (Richard Coles)a1401312014-03-18 10:20:56 +0000130 external_display_on = true;
131 }
132 }
133 internal_display_off_and_external_display_on_ =
134 internal_display_off && external_display_on;
135}
136#endif
137
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000138} // namespace ash