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
3 // found in the LICENSE file.
4
5 #include "ash/wm/power_button_controller.h"
6
7 #include "ash/ash_switches.h"
8 #include "ash/session_state_delegate.h"
9 #include "ash/shell.h"
10 #include "ash/shell_window_ids.h"
11 #include "ash/wm/lock_state_controller.h"
12 #include "ash/wm/session_state_animator.h"
13 #include "base/command_line.h"
14 #include "ui/aura/root_window.h"
15 #include "ui/views/corewm/compound_event_filter.h"
16
17 namespace ash {
18
PowerButtonController(LockStateController * controller)19 PowerButtonController::PowerButtonController(
20 LockStateController* controller)
21 : power_button_down_(false),
22 lock_button_down_(false),
23 screen_is_off_(false),
24 has_legacy_power_button_(
25 CommandLine::ForCurrentProcess()->HasSwitch(
26 switches::kAuraLegacyPowerButton)),
27 controller_(controller) {
28 }
29
~PowerButtonController()30 PowerButtonController::~PowerButtonController() {
31 }
32
OnScreenBrightnessChanged(double percent)33 void PowerButtonController::OnScreenBrightnessChanged(double percent) {
34 screen_is_off_ = percent <= 0.001;
35 }
36
OnPowerButtonEvent(bool down,const base::TimeTicks & timestamp)37 void PowerButtonController::OnPowerButtonEvent(
38 bool down, const base::TimeTicks& timestamp) {
39 power_button_down_ = down;
40
41 if (controller_->ShutdownRequested())
42 return;
43
44 // Avoid starting the lock/shutdown sequence if the power button is pressed
45 // while the screen is off (http://crbug.com/128451).
46 if (screen_is_off_)
47 return;
48
49 const SessionStateDelegate* session_state_delegate =
50 Shell::GetInstance()->session_state_delegate();
51 if (has_legacy_power_button_) {
52 // If power button releases won't get reported correctly because we're not
53 // running on official hardware, just lock the screen or shut down
54 // immediately.
55 if (down) {
56 if (session_state_delegate->CanLockScreen() &&
57 !session_state_delegate->IsScreenLocked() &&
58 !controller_->LockRequested()) {
59 controller_->StartLockAnimationAndLockImmediately();
60 } else {
61 controller_->RequestShutdown();
62 }
63 }
64 } else { // !has_legacy_power_button_
65 if (down) {
66 // If we already have a pending request to lock the screen, wait.
67 if (controller_->LockRequested())
68 return;
69
70 if (session_state_delegate->CanLockScreen() &&
71 !session_state_delegate->IsScreenLocked()) {
72 controller_->StartLockAnimation(true);
73 } else {
74 controller_->StartShutdownAnimation();
75 }
76 } else { // Button is up.
77 if (controller_->CanCancelLockAnimation())
78 controller_->CancelLockAnimation();
79 else if (controller_->CanCancelShutdownAnimation())
80 controller_->CancelShutdownAnimation();
81 }
82 }
83 }
84
OnLockButtonEvent(bool down,const base::TimeTicks & timestamp)85 void PowerButtonController::OnLockButtonEvent(
86 bool down, const base::TimeTicks& timestamp) {
87 lock_button_down_ = down;
88
89 const SessionStateDelegate* session_state_delegate =
90 Shell::GetInstance()->session_state_delegate();
91 if (!session_state_delegate->CanLockScreen() ||
92 session_state_delegate->IsScreenLocked() ||
93 controller_->LockRequested() ||
94 controller_->ShutdownRequested()) {
95 return;
96 }
97
98 // Give the power button precedence over the lock button (we don't expect both
99 // buttons to be present, so this is just making sure that we don't do
100 // something completely stupid if that assumption changes later).
101 if (power_button_down_)
102 return;
103
104 if (down)
105 controller_->StartLockAnimation(false);
106 else
107 controller_->CancelLockAnimation();
108 }
109
110 } // namespace ash
111