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