15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/wm/power_button_controller.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/ash_switches.h" 85c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "ash/session/session_state_delegate.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/shell.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/shell_window_ids.h" 11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "ash/wm/lock_state_controller.h" 121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "ash/wm/maximize_mode/maximize_mode_controller.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/wm/session_state_animator.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h" 15a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/aura/window_event_dispatcher.h" 161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "ui/display/types/display_snapshot.h" 171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "ui/events/event_handler.h" 18a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/wm/core/compound_event_filter.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ash { 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)PowerButtonController::PowerButtonController( 23868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) LockStateController* controller) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : power_button_down_(false), 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lock_button_down_(false), 261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci volume_down_pressed_(false), 27a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) brightness_is_zero_(false), 28a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) internal_display_off_and_external_display_on_(false), 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) has_legacy_power_button_( 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CommandLine::ForCurrentProcess()->HasSwitch( 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switches::kAuraLegacyPowerButton)), 321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci enable_quick_lock_(CommandLine::ForCurrentProcess()->HasSwitch( 331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci switches::kAshEnablePowerButtonQuickLock)), 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) controller_(controller) { 35effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#if defined(OS_CHROMEOS) 36c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch Shell::GetInstance()->display_configurator()->AddObserver(this); 37a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#endif 381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Shell::GetInstance()->PrependPreTargetHandler(this); 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PowerButtonController::~PowerButtonController() { 42effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#if defined(OS_CHROMEOS) 43c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch Shell::GetInstance()->display_configurator()->RemoveObserver(this); 44a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#endif 451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Shell::GetInstance()->RemovePreTargetHandler(this); 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PowerButtonController::OnScreenBrightnessChanged(double percent) { 49a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) brightness_is_zero_ = percent <= 0.001; 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PowerButtonController::OnPowerButtonEvent( 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool down, const base::TimeTicks& timestamp) { 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) power_button_down_ = down; 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (controller_->ShutdownRequested()) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Avoid starting the lock/shutdown sequence if the power button is pressed 60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // while the screen is off (http://crbug.com/128451), unless an external 61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // display is still on (http://crosbug.com/p/24912). 62a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (brightness_is_zero_ && !internal_display_off_and_external_display_on_) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (volume_down_pressed_ && down && 661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Shell::GetInstance()->maximize_mode_controller()-> 671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci IsMaximizeModeWindowManagerEnabled()) { 681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Shell::GetInstance()->accelerator_controller()->PerformAction( 691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ash::TAKE_SCREENSHOT, ui::Accelerator()); 701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const SessionStateDelegate* session_state_delegate = 74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Shell::GetInstance()->session_state_delegate(); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (has_legacy_power_button_) { 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If power button releases won't get reported correctly because we're not 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // running on official hardware, just lock the screen or shut down 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // immediately. 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (down) { 80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (session_state_delegate->CanLockScreen() && 81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) !session_state_delegate->IsScreenLocked() && 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) !controller_->LockRequested()) { 831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci controller_->StartLockAnimationAndLockImmediately(false); 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) controller_->RequestShutdown(); 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { // !has_legacy_power_button_ 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (down) { 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we already have a pending request to lock the screen, wait. 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (controller_->LockRequested()) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (session_state_delegate->CanLockScreen() && 95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) !session_state_delegate->IsScreenLocked()) { 961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (Shell::GetInstance()->maximize_mode_controller()-> 971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci IsMaximizeModeWindowManagerEnabled() && enable_quick_lock_) 981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci controller_->StartLockAnimationAndLockImmediately(true); 991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci else 1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci controller_->StartLockAnimation(true); 101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else { 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) controller_->StartShutdownAnimation(); 103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { // Button is up. 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (controller_->CanCancelLockAnimation()) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) controller_->CancelLockAnimation(); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (controller_->CanCancelShutdownAnimation()) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) controller_->CancelShutdownAnimation(); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PowerButtonController::OnLockButtonEvent( 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool down, const base::TimeTicks& timestamp) { 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lock_button_down_ = down; 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const SessionStateDelegate* session_state_delegate = 118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Shell::GetInstance()->session_state_delegate(); 119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!session_state_delegate->CanLockScreen() || 120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) session_state_delegate->IsScreenLocked() || 121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) controller_->LockRequested() || 122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) controller_->ShutdownRequested()) { 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Give the power button precedence over the lock button. 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (power_button_down_) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (down) 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) controller_->StartLockAnimation(false); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) controller_->CancelLockAnimation(); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid PowerButtonController::OnKeyEvent(ui::KeyEvent* event) { 1371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (event->key_code() == ui::VKEY_VOLUME_DOWN) { 1381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci volume_down_pressed_ = event->type() == ui::ET_KEY_PRESSED || 1391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci event->type() == ui::ET_TRANSLATED_KEY_PRESS; 1401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 1411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 143effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#if defined(OS_CHROMEOS) 144a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void PowerButtonController::OnDisplayModeChanged( 145c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const ui::DisplayConfigurator::DisplayStateList& display_states) { 146a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool internal_display_off = false; 147a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool external_display_on = false; 148c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch for (size_t i = 0; i < display_states.size(); ++i) { 149c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const ui::DisplayConfigurator::DisplayState& state = display_states[i]; 150c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (state.display->type() == ui::DISPLAY_CONNECTION_TYPE_INTERNAL) { 151c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (!state.display->current_mode()) 152a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) internal_display_off = true; 153c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } else if (state.display->current_mode()) { 154a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) external_display_on = true; 155a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 156a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 157a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) internal_display_off_and_external_display_on_ = 158a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) internal_display_off && external_display_on; 159a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 160a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#endif 161a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace ash 163