OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ash/wm/power_button_controller.h" | 5 #include "ash/wm/power_button_controller.h" |
6 | 6 |
7 #include "ash/common/accelerators/accelerator_controller.h" | 7 #include "ash/common/accelerators/accelerator_controller.h" |
8 #include "ash/common/ash_switches.h" | 8 #include "ash/common/ash_switches.h" |
9 #include "ash/common/session/session_state_delegate.h" | 9 #include "ash/common/session/session_state_delegate.h" |
10 #include "ash/common/system/audio/tray_audio.h" | 10 #include "ash/common/system/audio/tray_audio.h" |
(...skipping 10 matching lines...) Expand all Loading... | |
21 #include "ui/events/event_handler.h" | 21 #include "ui/events/event_handler.h" |
22 #include "ui/wm/core/compound_event_filter.h" | 22 #include "ui/wm/core/compound_event_filter.h" |
23 | 23 |
24 #if defined(OS_CHROMEOS) | 24 #if defined(OS_CHROMEOS) |
25 #include "chromeos/audio/cras_audio_handler.h" | 25 #include "chromeos/audio/cras_audio_handler.h" |
26 #include "chromeos/dbus/dbus_thread_manager.h" | 26 #include "chromeos/dbus/dbus_thread_manager.h" |
27 #endif | 27 #endif |
28 | 28 |
29 namespace ash { | 29 namespace ash { |
30 | 30 |
31 namespace { | |
32 | |
33 // Amount of time the power button must be held to start the pre-shutdown | |
34 // animation when in tablet mode. | |
35 constexpr int kTabletShutdownTimeoutMs = 1000; | |
36 | |
37 } // namespace | |
38 | |
39 PowerButtonController::TestApi::TestApi(PowerButtonController* controller) | |
40 : controller_(controller) {} | |
41 | |
42 PowerButtonController::TestApi::~TestApi() {} | |
43 | |
44 bool PowerButtonController::TestApi::TabletPowerButtonTimerIsRunning() const { | |
45 return controller_->tablet_power_button_timer_.IsRunning(); | |
46 } | |
47 | |
48 void PowerButtonController::TestApi::TriggerTabletPowerButtonTimeout() { | |
49 controller_->OnTabletPowerButtonTimeout(); | |
50 controller_->tablet_power_button_timer_.Stop(); | |
51 } | |
52 | |
31 PowerButtonController::PowerButtonController(LockStateController* controller) | 53 PowerButtonController::PowerButtonController(LockStateController* controller) |
32 : power_button_down_(false), | 54 : power_button_down_(false), |
33 lock_button_down_(false), | 55 lock_button_down_(false), |
34 volume_down_pressed_(false), | 56 volume_down_pressed_(false), |
35 #if defined(OS_CHROMEOS) | 57 #if defined(OS_CHROMEOS) |
36 volume_percent_before_screenshot_(0), | 58 volume_percent_before_screenshot_(0), |
37 #endif | 59 #endif |
38 brightness_is_zero_(false), | 60 brightness_is_zero_(false), |
39 internal_display_off_and_external_display_on_(false), | 61 internal_display_off_and_external_display_on_(false), |
40 has_legacy_power_button_( | 62 has_legacy_power_button_( |
41 base::CommandLine::ForCurrentProcess()->HasSwitch( | 63 base::CommandLine::ForCurrentProcess()->HasSwitch( |
42 switches::kAuraLegacyPowerButton)), | 64 switches::kAuraLegacyPowerButton)), |
43 #if defined(OS_CHROMEOS) | 65 #if defined(OS_CHROMEOS) |
44 enable_quick_lock_(base::CommandLine::ForCurrentProcess()->HasSwitch( | 66 enable_quick_lock_(base::CommandLine::ForCurrentProcess()->HasSwitch( |
45 switches::kAshEnableTouchView)), | 67 switches::kAshEnableTouchView)), |
46 #else | 68 #else |
47 enable_quick_lock_(false), | 69 enable_quick_lock_(false), |
48 #endif | 70 #endif |
49 controller_(controller) { | 71 controller_(controller), |
72 power_button_down_while_screen_off_(false), | |
73 backlights_forced_off_(false) { | |
50 #if defined(OS_CHROMEOS) | 74 #if defined(OS_CHROMEOS) |
51 chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->AddObserver( | 75 chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->AddObserver( |
52 this); | 76 this); |
53 Shell::GetInstance()->display_configurator()->AddObserver(this); | 77 Shell::GetInstance()->display_configurator()->AddObserver(this); |
54 #endif | 78 #endif |
55 Shell::GetInstance()->PrependPreTargetHandler(this); | 79 Shell::GetInstance()->PrependPreTargetHandler(this); |
80 | |
81 GetInitialBacklightsForcedOff(); | |
56 } | 82 } |
57 | 83 |
58 PowerButtonController::~PowerButtonController() { | 84 PowerButtonController::~PowerButtonController() { |
59 Shell::GetInstance()->RemovePreTargetHandler(this); | 85 Shell::GetInstance()->RemovePreTargetHandler(this); |
60 #if defined(OS_CHROMEOS) | 86 #if defined(OS_CHROMEOS) |
61 Shell::GetInstance()->display_configurator()->RemoveObserver(this); | 87 Shell::GetInstance()->display_configurator()->RemoveObserver(this); |
62 chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->RemoveObserver( | 88 chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->RemoveObserver( |
63 this); | 89 this); |
64 #endif | 90 #endif |
65 } | 91 } |
66 | 92 |
67 void PowerButtonController::OnScreenBrightnessChanged(double percent) { | 93 void PowerButtonController::OnScreenBrightnessChanged(double percent) { |
68 brightness_is_zero_ = percent <= 0.001; | 94 brightness_is_zero_ = percent <= 0.001; |
69 } | 95 } |
70 | 96 |
71 void PowerButtonController::OnPowerButtonEvent( | 97 void PowerButtonController::OnPowerButtonEvent( |
72 bool down, | 98 bool down, |
73 const base::TimeTicks& timestamp) { | 99 const base::TimeTicks& timestamp) { |
74 power_button_down_ = down; | 100 power_button_down_ = down; |
75 | 101 |
76 if (controller_->ShutdownRequested()) | 102 if (controller_->ShutdownRequested()) |
77 return; | 103 return; |
78 | 104 |
105 bool should_take_screenshot = | |
106 down && volume_down_pressed_ && IsTabletModeActive(); | |
107 | |
108 if (down) | |
109 power_button_down_while_screen_off_ = brightness_is_zero_; | |
110 | |
111 if (!has_legacy_power_button_ && !should_take_screenshot && | |
112 IsTabletModeSupported()) { | |
113 OnTabletPowerButtonEvent(down, timestamp); | |
114 return; | |
115 } | |
116 | |
79 // Avoid starting the lock/shutdown sequence if the power button is pressed | 117 // Avoid starting the lock/shutdown sequence if the power button is pressed |
80 // while the screen is off (http://crbug.com/128451), unless an external | 118 // while the screen is off (http://crbug.com/128451), unless an external |
81 // display is still on (http://crosbug.com/p/24912). | 119 // display is still on (http://crosbug.com/p/24912). |
82 if (brightness_is_zero_ && !internal_display_off_and_external_display_on_) | 120 if (brightness_is_zero_ && !internal_display_off_and_external_display_on_) |
83 return; | 121 return; |
84 | 122 |
85 if (volume_down_pressed_ && down && | 123 if (should_take_screenshot) { |
86 WmShell::Get() | |
87 ->maximize_mode_controller() | |
88 ->IsMaximizeModeWindowManagerEnabled()) { | |
89 SystemTray* system_tray = Shell::GetInstance()->GetPrimarySystemTray(); | 124 SystemTray* system_tray = Shell::GetInstance()->GetPrimarySystemTray(); |
90 if (system_tray && system_tray->GetTrayAudio()) | 125 if (system_tray && system_tray->GetTrayAudio()) |
91 system_tray->GetTrayAudio()->HideDetailedView(false); | 126 system_tray->GetTrayAudio()->HideDetailedView(false); |
92 | 127 |
93 WmShell::Get()->accelerator_controller()->PerformActionIfEnabled( | 128 WmShell::Get()->accelerator_controller()->PerformActionIfEnabled( |
94 TAKE_SCREENSHOT); | 129 TAKE_SCREENSHOT); |
95 | 130 |
96 #if defined(OS_CHROMEOS) | 131 #if defined(OS_CHROMEOS) |
97 // Restore volume. | 132 // Restore volume. |
98 chromeos::CrasAudioHandler* audio_handler = | 133 chromeos::CrasAudioHandler* audio_handler = |
(...skipping 21 matching lines...) Expand all Loading... | |
120 } | 155 } |
121 } | 156 } |
122 } else { // !has_legacy_power_button_ | 157 } else { // !has_legacy_power_button_ |
123 if (down) { | 158 if (down) { |
124 // If we already have a pending request to lock the screen, wait. | 159 // If we already have a pending request to lock the screen, wait. |
125 if (controller_->LockRequested()) | 160 if (controller_->LockRequested()) |
126 return; | 161 return; |
127 | 162 |
128 if (session_state_delegate->CanLockScreen() && | 163 if (session_state_delegate->CanLockScreen() && |
129 !session_state_delegate->IsUserSessionBlocked()) { | 164 !session_state_delegate->IsUserSessionBlocked()) { |
130 if (WmShell::Get() | 165 if (IsTabletModeActive() && enable_quick_lock_) |
131 ->maximize_mode_controller() | |
132 ->IsMaximizeModeWindowManagerEnabled() && | |
133 enable_quick_lock_) | |
134 controller_->StartLockAnimationAndLockImmediately(true); | 166 controller_->StartLockAnimationAndLockImmediately(true); |
135 else | 167 else |
136 controller_->StartLockAnimation(true); | 168 controller_->StartLockAnimation(true); |
137 } else { | 169 } else { |
138 controller_->StartShutdownAnimation(); | 170 controller_->StartShutdownAnimation(); |
139 } | 171 } |
140 } else { // Button is up. | 172 } else { // Button is up. |
141 if (controller_->CanCancelLockAnimation()) | 173 if (controller_->CanCancelLockAnimation()) |
142 controller_->CancelLockAnimation(); | 174 controller_->CancelLockAnimation(); |
143 else if (controller_->CanCancelShutdownAnimation()) | 175 else if (controller_->CanCancelShutdownAnimation()) |
(...skipping 19 matching lines...) Expand all Loading... | |
163 if (power_button_down_) | 195 if (power_button_down_) |
164 return; | 196 return; |
165 | 197 |
166 if (down) | 198 if (down) |
167 controller_->StartLockAnimation(false); | 199 controller_->StartLockAnimation(false); |
168 else | 200 else |
169 controller_->CancelLockAnimation(); | 201 controller_->CancelLockAnimation(); |
170 } | 202 } |
171 | 203 |
172 void PowerButtonController::OnKeyEvent(ui::KeyEvent* event) { | 204 void PowerButtonController::OnKeyEvent(ui::KeyEvent* event) { |
205 if (!IsTabletModeActive() && backlights_forced_off_) { | |
206 SetBacklightsForcedOff(false); | |
207 return; | |
208 } | |
209 | |
173 if (event->key_code() == ui::VKEY_VOLUME_DOWN) { | 210 if (event->key_code() == ui::VKEY_VOLUME_DOWN) { |
174 volume_down_pressed_ = event->type() == ui::ET_KEY_PRESSED; | 211 volume_down_pressed_ = event->type() == ui::ET_KEY_PRESSED; |
175 #if defined(OS_CHROMEOS) | 212 #if defined(OS_CHROMEOS) |
176 if (!event->is_repeat()) { | 213 if (!event->is_repeat()) { |
177 chromeos::CrasAudioHandler* audio_handler = | 214 chromeos::CrasAudioHandler* audio_handler = |
178 chromeos::CrasAudioHandler::Get(); | 215 chromeos::CrasAudioHandler::Get(); |
179 volume_percent_before_screenshot_ = | 216 volume_percent_before_screenshot_ = |
180 audio_handler->GetOutputVolumePercent(); | 217 audio_handler->GetOutputVolumePercent(); |
181 } | 218 } |
182 #endif | 219 #endif |
183 } | 220 } |
184 } | 221 } |
185 | 222 |
223 void PowerButtonController::OnMouseEvent(ui::MouseEvent* event) { | |
224 if (!IsTabletModeActive() && backlights_forced_off_) { | |
225 SetBacklightsForcedOff(false); | |
226 } | |
227 } | |
228 | |
186 #if defined(OS_CHROMEOS) | 229 #if defined(OS_CHROMEOS) |
187 void PowerButtonController::OnDisplayModeChanged( | 230 void PowerButtonController::OnDisplayModeChanged( |
188 const ui::DisplayConfigurator::DisplayStateList& display_states) { | 231 const ui::DisplayConfigurator::DisplayStateList& display_states) { |
189 bool internal_display_off = false; | 232 bool internal_display_off = false; |
190 bool external_display_on = false; | 233 bool external_display_on = false; |
191 for (const ui::DisplaySnapshot* display : display_states) { | 234 for (const ui::DisplaySnapshot* display : display_states) { |
192 if (display->type() == ui::DISPLAY_CONNECTION_TYPE_INTERNAL) { | 235 if (display->type() == ui::DISPLAY_CONNECTION_TYPE_INTERNAL) { |
193 if (!display->current_mode()) | 236 if (!display->current_mode()) |
194 internal_display_off = true; | 237 internal_display_off = true; |
195 } else if (display->current_mode()) { | 238 } else if (display->current_mode()) { |
196 external_display_on = true; | 239 external_display_on = true; |
197 } | 240 } |
198 } | 241 } |
199 internal_display_off_and_external_display_on_ = | 242 internal_display_off_and_external_display_on_ = |
200 internal_display_off && external_display_on; | 243 internal_display_off && external_display_on; |
201 } | 244 } |
202 | 245 |
203 void PowerButtonController::PowerButtonEventReceived( | 246 void PowerButtonController::PowerButtonEventReceived( |
204 bool down, | 247 bool down, |
205 const base::TimeTicks& timestamp) { | 248 const base::TimeTicks& timestamp) { |
206 OnPowerButtonEvent(down, timestamp); | 249 OnPowerButtonEvent(down, timestamp); |
207 } | 250 } |
208 #endif // defined(OS_CHROMEOS) | 251 #endif // defined(OS_CHROMEOS) |
209 | 252 |
253 void PowerButtonController::OnTabletPowerButtonEvent( | |
Daniel Erat
2016/11/04 20:18:34
hmm... so i've noticed that the tablet power butto
Qiang(Joe) Xu
2016/11/04 23:18:21
Actually there are some overlaps. Like TabletPower
| |
254 bool down, | |
255 const base::TimeTicks& timestamp) { | |
256 if (down) { | |
257 SetBacklightsForcedOff(false); | |
258 StartTabletPowerButtonTimer(); | |
259 } else { | |
260 if (tablet_power_button_timer_.IsRunning()) { | |
261 tablet_power_button_timer_.Stop(); | |
262 if (!power_button_down_while_screen_off_) { | |
263 SetBacklightsForcedOff(true); | |
264 LockScreenIfRequired(); | |
265 } | |
266 } | |
267 power_button_down_while_screen_off_ = false; | |
268 | |
269 // When power button is released, Cancel Shutdown animation whenever it is | |
270 // still cancellable. | |
271 if (controller_->CanCancelShutdownAnimation()) | |
272 controller_->CancelShutdownAnimation(); | |
273 } | |
274 } | |
275 | |
276 void PowerButtonController::SetBacklightsForcedOff(bool forced_off) { | |
277 if (backlights_forced_off_ == forced_off) | |
278 return; | |
279 | |
280 #if defined(OS_CHROMEOS) | |
281 chromeos::DBusThreadManager::Get() | |
282 ->GetPowerManagerClient() | |
283 ->SetBacklightsForcedOff(forced_off); | |
284 backlights_forced_off_ = forced_off; | |
285 #endif | |
286 } | |
287 | |
288 void PowerButtonController::GetInitialBacklightsForcedOff() { | |
289 #if defined(OS_CHROMEOS) | |
290 chromeos::DBusThreadManager::Get() | |
291 ->GetPowerManagerClient() | |
292 ->GetBacklightsForcedOff( | |
293 base::Bind(&PowerButtonController::OnGotInitialBacklightsForcedOff, | |
294 base::Unretained(this))); | |
295 #endif | |
296 } | |
297 | |
298 void PowerButtonController::OnGotInitialBacklightsForcedOff( | |
299 bool is_forced_off) { | |
300 backlights_forced_off_ = is_forced_off; | |
301 } | |
302 | |
303 void PowerButtonController::StartTabletPowerButtonTimer() { | |
304 tablet_power_button_timer_.Start( | |
305 FROM_HERE, base::TimeDelta::FromMilliseconds(kTabletShutdownTimeoutMs), | |
306 this, &PowerButtonController::OnTabletPowerButtonTimeout); | |
307 } | |
308 | |
309 void PowerButtonController::OnTabletPowerButtonTimeout() { | |
310 controller_->StartShutdownAnimation(); | |
311 } | |
312 | |
313 void PowerButtonController::LockScreenIfRequired() { | |
314 SessionStateDelegate* session_state_delegate = | |
315 WmShell::Get()->GetSessionStateDelegate(); | |
316 if (session_state_delegate->ShouldLockScreenAutomatically() && | |
317 session_state_delegate->CanLockScreen() && | |
318 !session_state_delegate->IsUserSessionBlocked() && | |
319 !controller_->LockRequested()) { | |
320 session_state_delegate->LockScreen(); | |
321 } | |
322 } | |
323 | |
324 bool PowerButtonController::IsTabletModeSupported() const { | |
325 MaximizeModeController* maximize_mode_controller = | |
326 WmShell::Get()->maximize_mode_controller(); | |
327 return maximize_mode_controller && | |
328 maximize_mode_controller->CanEnterMaximizeMode(); | |
329 } | |
330 | |
331 bool PowerButtonController::IsTabletModeActive() const { | |
332 MaximizeModeController* maximize_mode_controller = | |
333 WmShell::Get()->maximize_mode_controller(); | |
334 return maximize_mode_controller && | |
335 maximize_mode_controller->IsMaximizeModeWindowManagerEnabled(); | |
336 } | |
337 | |
210 } // namespace ash | 338 } // namespace ash |
OLD | NEW |