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.
5 #include "ash/wm/power_button_controller.h"
7 #include "ash/ash_switches.h"
8 #include "ash/session/session_state_delegate.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/window_event_dispatcher.h"
15 #include "ui/display/types/chromeos/display_snapshot.h"
16 #include "ui/wm/core/compound_event_filter.h"
20 PowerButtonController::PowerButtonController(
21 LockStateController
* controller
)
22 : power_button_down_(false),
23 lock_button_down_(false),
24 brightness_is_zero_(false),
25 internal_display_off_and_external_display_on_(false),
26 has_legacy_power_button_(
27 CommandLine::ForCurrentProcess()->HasSwitch(
28 switches::kAuraLegacyPowerButton
)),
29 controller_(controller
) {
30 #if defined(OS_CHROMEOS)
31 Shell::GetInstance()->display_configurator()->AddObserver(this);
35 PowerButtonController::~PowerButtonController() {
36 #if defined(OS_CHROMEOS)
37 Shell::GetInstance()->display_configurator()->RemoveObserver(this);
41 void PowerButtonController::OnScreenBrightnessChanged(double percent
) {
42 brightness_is_zero_
= percent
<= 0.001;
45 void PowerButtonController::OnPowerButtonEvent(
46 bool down
, const base::TimeTicks
& timestamp
) {
47 power_button_down_
= down
;
49 if (controller_
->ShutdownRequested())
52 // Avoid starting the lock/shutdown sequence if the power button is pressed
53 // 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_
)
58 const SessionStateDelegate
* session_state_delegate
=
59 Shell::GetInstance()->session_state_delegate();
60 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
65 if (session_state_delegate
->CanLockScreen() &&
66 !session_state_delegate
->IsScreenLocked() &&
67 !controller_
->LockRequested()) {
68 controller_
->StartLockAnimationAndLockImmediately();
70 controller_
->RequestShutdown();
73 } else { // !has_legacy_power_button_
75 // If we already have a pending request to lock the screen, wait.
76 if (controller_
->LockRequested())
79 if (session_state_delegate
->CanLockScreen() &&
80 !session_state_delegate
->IsScreenLocked()) {
81 controller_
->StartLockAnimation(true);
83 controller_
->StartShutdownAnimation();
85 } else { // Button is up.
86 if (controller_
->CanCancelLockAnimation())
87 controller_
->CancelLockAnimation();
88 else if (controller_
->CanCancelShutdownAnimation())
89 controller_
->CancelShutdownAnimation();
94 void PowerButtonController::OnLockButtonEvent(
95 bool down
, const base::TimeTicks
& timestamp
) {
96 lock_button_down_
= down
;
98 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()) {
107 // Give the power button precedence over the lock button (we don't expect both
108 // 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_
)
114 controller_
->StartLockAnimation(false);
116 controller_
->CancelLockAnimation();
119 #if defined(OS_CHROMEOS)
120 void PowerButtonController::OnDisplayModeChanged(
121 const ui::DisplayConfigurator::DisplayStateList
& display_states
) {
122 bool internal_display_off
= false;
123 bool external_display_on
= false;
124 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())
128 internal_display_off
= true;
129 } else if (state
.display
->current_mode()) {
130 external_display_on
= true;
133 internal_display_off_and_external_display_on_
=
134 internal_display_off
&& external_display_on
;