6d94c361699ee5dea61ee4365162e66ea7a90b2b
[platform/framework/web/crosswalk.git] / src / ash / wm / power_button_controller.cc
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/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/maximize_mode/maximize_mode_controller.h"
13 #include "ash/wm/session_state_animator.h"
14 #include "base/command_line.h"
15 #include "ui/aura/window_event_dispatcher.h"
16 #include "ui/display/types/display_snapshot.h"
17 #include "ui/events/event_handler.h"
18 #include "ui/wm/core/compound_event_filter.h"
19
20 namespace ash {
21
22 PowerButtonController::PowerButtonController(
23     LockStateController* controller)
24     : power_button_down_(false),
25       lock_button_down_(false),
26       volume_down_pressed_(false),
27       brightness_is_zero_(false),
28       internal_display_off_and_external_display_on_(false),
29       has_legacy_power_button_(
30           CommandLine::ForCurrentProcess()->HasSwitch(
31               switches::kAuraLegacyPowerButton)),
32       enable_quick_lock_(CommandLine::ForCurrentProcess()->HasSwitch(
33           switches::kAshEnablePowerButtonQuickLock)),
34       controller_(controller) {
35 #if defined(OS_CHROMEOS)
36   Shell::GetInstance()->display_configurator()->AddObserver(this);
37 #endif
38   Shell::GetInstance()->PrependPreTargetHandler(this);
39 }
40
41 PowerButtonController::~PowerButtonController() {
42 #if defined(OS_CHROMEOS)
43   Shell::GetInstance()->display_configurator()->RemoveObserver(this);
44 #endif
45   Shell::GetInstance()->RemovePreTargetHandler(this);
46 }
47
48 void PowerButtonController::OnScreenBrightnessChanged(double percent) {
49   brightness_is_zero_ = percent <= 0.001;
50 }
51
52 void PowerButtonController::OnPowerButtonEvent(
53     bool down, const base::TimeTicks& timestamp) {
54   power_button_down_ = down;
55
56   if (controller_->ShutdownRequested())
57     return;
58
59   // Avoid starting the lock/shutdown sequence if the power button is pressed
60   // while the screen is off (http://crbug.com/128451), unless an external
61   // display is still on (http://crosbug.com/p/24912).
62   if (brightness_is_zero_ && !internal_display_off_and_external_display_on_)
63     return;
64
65   if (volume_down_pressed_ && down &&
66       Shell::GetInstance()->maximize_mode_controller()->
67         IsMaximizeModeWindowManagerEnabled()) {
68     Shell::GetInstance()->accelerator_controller()->PerformAction(
69         ash::TAKE_SCREENSHOT, ui::Accelerator());
70     return;
71   }
72
73   const SessionStateDelegate* session_state_delegate =
74       Shell::GetInstance()->session_state_delegate();
75   if (has_legacy_power_button_) {
76     // If power button releases won't get reported correctly because we're not
77     // running on official hardware, just lock the screen or shut down
78     // immediately.
79     if (down) {
80       if (session_state_delegate->CanLockScreen() &&
81           !session_state_delegate->IsScreenLocked() &&
82           !controller_->LockRequested()) {
83         controller_->StartLockAnimationAndLockImmediately(false);
84       } else {
85         controller_->RequestShutdown();
86       }
87     }
88   } else {  // !has_legacy_power_button_
89     if (down) {
90       // If we already have a pending request to lock the screen, wait.
91       if (controller_->LockRequested())
92         return;
93
94       if (session_state_delegate->CanLockScreen() &&
95           !session_state_delegate->IsScreenLocked()) {
96         if (Shell::GetInstance()->maximize_mode_controller()->
97             IsMaximizeModeWindowManagerEnabled() && enable_quick_lock_)
98           controller_->StartLockAnimationAndLockImmediately(true);
99         else
100           controller_->StartLockAnimation(true);
101       } else {
102         controller_->StartShutdownAnimation();
103       }
104     } else {  // Button is up.
105       if (controller_->CanCancelLockAnimation())
106         controller_->CancelLockAnimation();
107       else if (controller_->CanCancelShutdownAnimation())
108         controller_->CancelShutdownAnimation();
109     }
110   }
111 }
112
113 void PowerButtonController::OnLockButtonEvent(
114     bool down, const base::TimeTicks& timestamp) {
115   lock_button_down_ = down;
116
117   const SessionStateDelegate* session_state_delegate =
118       Shell::GetInstance()->session_state_delegate();
119   if (!session_state_delegate->CanLockScreen() ||
120       session_state_delegate->IsScreenLocked() ||
121       controller_->LockRequested() ||
122       controller_->ShutdownRequested()) {
123     return;
124   }
125
126   // Give the power button precedence over the lock button.
127   if (power_button_down_)
128     return;
129
130   if (down)
131     controller_->StartLockAnimation(false);
132   else
133     controller_->CancelLockAnimation();
134 }
135
136 void PowerButtonController::OnKeyEvent(ui::KeyEvent* event) {
137   if (event->key_code() == ui::VKEY_VOLUME_DOWN) {
138     volume_down_pressed_ = event->type() == ui::ET_KEY_PRESSED ||
139                            event->type() == ui::ET_TRANSLATED_KEY_PRESS;
140   }
141 }
142
143 #if defined(OS_CHROMEOS)
144 void PowerButtonController::OnDisplayModeChanged(
145     const ui::DisplayConfigurator::DisplayStateList& display_states) {
146   bool internal_display_off = false;
147   bool external_display_on = false;
148   for (size_t i = 0; i < display_states.size(); ++i) {
149     const ui::DisplayConfigurator::DisplayState& state = display_states[i];
150     if (state.display->type() == ui::DISPLAY_CONNECTION_TYPE_INTERNAL) {
151       if (!state.display->current_mode())
152         internal_display_off = true;
153     } else if (state.display->current_mode()) {
154       external_display_on = true;
155     }
156   }
157   internal_display_off_and_external_display_on_ =
158       internal_display_off && external_display_on;
159 }
160 #endif
161
162 }  // namespace ash