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 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 30 PowerButtonController::~PowerButtonController() { 31 } 32 33 void PowerButtonController::OnScreenBrightnessChanged(double percent) { 34 screen_is_off_ = percent <= 0.001; 35 } 36 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 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