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" |
11 #include "ash/common/system/tray/system_tray.h" | 11 #include "ash/common/system/tray/system_tray.h" |
12 #include "ash/common/wm/maximize_mode/maximize_mode_controller.h" | 12 #include "ash/common/wm/maximize_mode/maximize_mode_controller.h" |
13 #include "ash/common/wm_shell.h" | 13 #include "ash/common/wm_shell.h" |
14 #include "ash/public/cpp/shell_window_ids.h" | 14 #include "ash/public/cpp/shell_window_ids.h" |
15 #include "ash/shell.h" | 15 #include "ash/shell.h" |
16 #include "ash/wm/lock_state_controller.h" | 16 #include "ash/wm/lock_state_controller.h" |
17 #include "ash/wm/session_state_animator.h" | 17 #include "ash/wm/session_state_animator.h" |
18 #include "base/command_line.h" | 18 #include "base/command_line.h" |
19 #include "ui/aura/window_event_dispatcher.h" | 19 #include "ui/aura/window_event_dispatcher.h" |
20 #include "ui/display/types/display_snapshot.h" | 20 #include "ui/display/types/display_snapshot.h" |
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 "ash/wm/tablet_power_state_delegate_chromeos.h" | |
25 #include "chromeos/audio/cras_audio_handler.h" | 26 #include "chromeos/audio/cras_audio_handler.h" |
26 #include "chromeos/dbus/dbus_thread_manager.h" | 27 #include "chromeos/dbus/dbus_thread_manager.h" |
27 #endif | 28 #endif |
28 | 29 |
29 namespace ash { | 30 namespace ash { |
30 | 31 |
32 namespace { | |
33 // 1s timer before starting shutdown animation. If power button released event | |
34 // is not received before timeout, |controller_| will take the duty to start | |
35 // shutdown animation. | |
36 const int kTabletPreStartShutdownAnimationTimeoutMs = 1000; | |
37 } // namespace | |
38 | |
39 PowerButtonController::TestApi::TestApi(PowerButtonController* controller) | |
40 : controller_(controller) {} | |
41 | |
42 PowerButtonController::TestApi::~TestApi() {} | |
43 | |
31 PowerButtonController::PowerButtonController(LockStateController* controller) | 44 PowerButtonController::PowerButtonController(LockStateController* controller) |
32 : power_button_down_(false), | 45 : power_button_down_(false), |
33 lock_button_down_(false), | 46 lock_button_down_(false), |
34 volume_down_pressed_(false), | 47 volume_down_pressed_(false), |
35 #if defined(OS_CHROMEOS) | 48 #if defined(OS_CHROMEOS) |
36 volume_percent_before_screenshot_(0), | 49 volume_percent_before_screenshot_(0), |
37 #endif | 50 #endif |
38 brightness_is_zero_(false), | 51 brightness_is_zero_(false), |
39 internal_display_off_and_external_display_on_(false), | 52 internal_display_off_and_external_display_on_(false), |
40 has_legacy_power_button_( | 53 has_legacy_power_button_( |
41 base::CommandLine::ForCurrentProcess()->HasSwitch( | 54 base::CommandLine::ForCurrentProcess()->HasSwitch( |
42 switches::kAuraLegacyPowerButton)), | 55 switches::kAuraLegacyPowerButton)), |
43 #if defined(OS_CHROMEOS) | 56 #if defined(OS_CHROMEOS) |
44 enable_quick_lock_(base::CommandLine::ForCurrentProcess()->HasSwitch( | 57 enable_quick_lock_(base::CommandLine::ForCurrentProcess()->HasSwitch( |
45 switches::kAshEnableTouchView)), | 58 switches::kAshEnableTouchView)), |
46 #else | 59 #else |
47 enable_quick_lock_(false), | 60 enable_quick_lock_(false), |
48 #endif | 61 #endif |
49 controller_(controller) { | 62 controller_(controller), |
63 pressed_on_screen_off_(false), | |
64 backlights_forced_off_(false) { | |
50 #if defined(OS_CHROMEOS) | 65 #if defined(OS_CHROMEOS) |
51 chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->AddObserver( | 66 chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->AddObserver( |
52 this); | 67 this); |
53 Shell::GetInstance()->display_configurator()->AddObserver(this); | 68 Shell::GetInstance()->display_configurator()->AddObserver(this); |
54 #endif | 69 #endif |
55 Shell::GetInstance()->PrependPreTargetHandler(this); | 70 Shell::GetInstance()->PrependPreTargetHandler(this); |
71 #if defined(OS_CHROMEOS) | |
72 tablet_power_state_delegate_ = | |
73 base::MakeUnique<TabletPowerStateDelegateChromeos>(); | |
Daniel Erat
2016/11/03 21:28:08
i don't understand the reason for this delegate.
Qiang(Joe) Xu
2016/11/04 01:14:03
done, thanks. I was thinking using |delegate_| ini
| |
74 #endif | |
75 | |
76 base::ThreadTaskRunnerHandle::Get()->PostTask( | |
Daniel Erat
2016/11/03 21:28:08
what's the reason for posting this instead of just
Qiang(Joe) Xu
2016/11/04 01:14:04
I think just GetInitialBacklightsForcedOff should
| |
77 FROM_HERE, | |
78 base::Bind(&PowerButtonController::GetInitialBacklightsForcedOff, | |
79 base::Unretained(this))); | |
56 } | 80 } |
57 | 81 |
58 PowerButtonController::~PowerButtonController() { | 82 PowerButtonController::~PowerButtonController() { |
83 #if defined(OS_CHROMEOS) | |
84 tablet_power_state_delegate_.reset(); | |
85 #endif | |
59 Shell::GetInstance()->RemovePreTargetHandler(this); | 86 Shell::GetInstance()->RemovePreTargetHandler(this); |
60 #if defined(OS_CHROMEOS) | 87 #if defined(OS_CHROMEOS) |
61 Shell::GetInstance()->display_configurator()->RemoveObserver(this); | 88 Shell::GetInstance()->display_configurator()->RemoveObserver(this); |
62 chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->RemoveObserver( | 89 chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->RemoveObserver( |
63 this); | 90 this); |
64 #endif | 91 #endif |
65 } | 92 } |
66 | 93 |
67 void PowerButtonController::OnScreenBrightnessChanged(double percent) { | 94 void PowerButtonController::OnScreenBrightnessChanged(double percent) { |
68 brightness_is_zero_ = percent <= 0.001; | 95 brightness_is_zero_ = percent <= 0.001; |
69 } | 96 } |
70 | 97 |
71 void PowerButtonController::OnPowerButtonEvent( | 98 void PowerButtonController::OnPowerButtonEvent( |
72 bool down, | 99 bool down, |
73 const base::TimeTicks& timestamp) { | 100 const base::TimeTicks& timestamp) { |
74 power_button_down_ = down; | 101 power_button_down_ = down; |
75 | 102 |
76 if (controller_->ShutdownRequested()) | 103 if (controller_->ShutdownRequested()) |
77 return; | 104 return; |
78 | 105 |
106 if (!has_legacy_power_button_ && !MaybeTakeScreenshot(down) && | |
Daniel Erat
2016/11/03 21:28:07
instead of calling this helper method twice, why n
Qiang(Joe) Xu
2016/11/04 01:14:04
Done.
| |
107 WmShell::Get()->maximize_mode_controller()->CanEnterMaximizeMode()) { | |
108 OnTabletPowerButtonEvent(down, timestamp); | |
109 return; | |
110 } | |
111 | |
79 // Avoid starting the lock/shutdown sequence if the power button is pressed | 112 // 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 | 113 // while the screen is off (http://crbug.com/128451), unless an external |
81 // display is still on (http://crosbug.com/p/24912). | 114 // display is still on (http://crosbug.com/p/24912). |
82 if (brightness_is_zero_ && !internal_display_off_and_external_display_on_) | 115 if (brightness_is_zero_ && !internal_display_off_and_external_display_on_) |
83 return; | 116 return; |
84 | 117 |
85 if (volume_down_pressed_ && down && | 118 if (MaybeTakeScreenshot(down)) { |
86 WmShell::Get() | |
87 ->maximize_mode_controller() | |
88 ->IsMaximizeModeWindowManagerEnabled()) { | |
89 SystemTray* system_tray = Shell::GetInstance()->GetPrimarySystemTray(); | 119 SystemTray* system_tray = Shell::GetInstance()->GetPrimarySystemTray(); |
90 if (system_tray && system_tray->GetTrayAudio()) | 120 if (system_tray && system_tray->GetTrayAudio()) |
91 system_tray->GetTrayAudio()->HideDetailedView(false); | 121 system_tray->GetTrayAudio()->HideDetailedView(false); |
92 | 122 |
93 WmShell::Get()->accelerator_controller()->PerformActionIfEnabled( | 123 WmShell::Get()->accelerator_controller()->PerformActionIfEnabled( |
94 TAKE_SCREENSHOT); | 124 TAKE_SCREENSHOT); |
95 | 125 |
96 #if defined(OS_CHROMEOS) | 126 #if defined(OS_CHROMEOS) |
97 // Restore volume. | 127 // Restore volume. |
98 chromeos::CrasAudioHandler* audio_handler = | 128 chromeos::CrasAudioHandler* audio_handler = |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
163 if (power_button_down_) | 193 if (power_button_down_) |
164 return; | 194 return; |
165 | 195 |
166 if (down) | 196 if (down) |
167 controller_->StartLockAnimation(false); | 197 controller_->StartLockAnimation(false); |
168 else | 198 else |
169 controller_->CancelLockAnimation(); | 199 controller_->CancelLockAnimation(); |
170 } | 200 } |
171 | 201 |
172 void PowerButtonController::OnKeyEvent(ui::KeyEvent* event) { | 202 void PowerButtonController::OnKeyEvent(ui::KeyEvent* event) { |
203 WakeOnLaptopMode(); | |
173 if (event->key_code() == ui::VKEY_VOLUME_DOWN) { | 204 if (event->key_code() == ui::VKEY_VOLUME_DOWN) { |
174 volume_down_pressed_ = event->type() == ui::ET_KEY_PRESSED; | 205 volume_down_pressed_ = event->type() == ui::ET_KEY_PRESSED; |
175 #if defined(OS_CHROMEOS) | 206 #if defined(OS_CHROMEOS) |
176 if (!event->is_repeat()) { | 207 if (!event->is_repeat()) { |
177 chromeos::CrasAudioHandler* audio_handler = | 208 chromeos::CrasAudioHandler* audio_handler = |
178 chromeos::CrasAudioHandler::Get(); | 209 chromeos::CrasAudioHandler::Get(); |
179 volume_percent_before_screenshot_ = | 210 volume_percent_before_screenshot_ = |
180 audio_handler->GetOutputVolumePercent(); | 211 audio_handler->GetOutputVolumePercent(); |
181 } | 212 } |
182 #endif | 213 #endif |
183 } | 214 } |
184 } | 215 } |
185 | 216 |
217 void PowerButtonController::OnMouseEvent(ui::MouseEvent* event) { | |
218 WakeOnLaptopMode(); | |
219 } | |
220 | |
186 #if defined(OS_CHROMEOS) | 221 #if defined(OS_CHROMEOS) |
187 void PowerButtonController::OnDisplayModeChanged( | 222 void PowerButtonController::OnDisplayModeChanged( |
188 const ui::DisplayConfigurator::DisplayStateList& display_states) { | 223 const ui::DisplayConfigurator::DisplayStateList& display_states) { |
189 bool internal_display_off = false; | 224 bool internal_display_off = false; |
190 bool external_display_on = false; | 225 bool external_display_on = false; |
191 for (const ui::DisplaySnapshot* display : display_states) { | 226 for (const ui::DisplaySnapshot* display : display_states) { |
192 if (display->type() == ui::DISPLAY_CONNECTION_TYPE_INTERNAL) { | 227 if (display->type() == ui::DISPLAY_CONNECTION_TYPE_INTERNAL) { |
193 if (!display->current_mode()) | 228 if (!display->current_mode()) |
194 internal_display_off = true; | 229 internal_display_off = true; |
195 } else if (display->current_mode()) { | 230 } else if (display->current_mode()) { |
196 external_display_on = true; | 231 external_display_on = true; |
197 } | 232 } |
198 } | 233 } |
199 internal_display_off_and_external_display_on_ = | 234 internal_display_off_and_external_display_on_ = |
200 internal_display_off && external_display_on; | 235 internal_display_off && external_display_on; |
201 } | 236 } |
202 | 237 |
203 void PowerButtonController::PowerButtonEventReceived( | 238 void PowerButtonController::PowerButtonEventReceived( |
204 bool down, | 239 bool down, |
205 const base::TimeTicks& timestamp) { | 240 const base::TimeTicks& timestamp) { |
206 OnPowerButtonEvent(down, timestamp); | 241 OnPowerButtonEvent(down, timestamp); |
207 } | 242 } |
208 #endif // defined(OS_CHROMEOS) | 243 #endif // defined(OS_CHROMEOS) |
209 | 244 |
245 void PowerButtonController::OnTabletPowerButtonEvent( | |
246 bool down, | |
247 const base::TimeTicks& timestamp) { | |
248 if (!tablet_power_state_delegate_) | |
249 return; | |
250 | |
251 // When screen is off, SetBacklightsForcedOff(false) takes action on power | |
252 // button pressed. | |
253 // When screen is on, SetBacklightsForcedOff(true) takes action when power | |
254 // button is released before the |tablet_pre_start_shutdown_animation_timer_| | |
255 // is timeout. | |
256 if (down) { | |
257 if (backlights_forced_off_ || brightness_is_zero_) { | |
258 pressed_on_screen_off_ = true; | |
Daniel Erat
2016/11/03 21:28:07
it seems a bit safer to set this unconditionally h
Qiang(Joe) Xu
2016/11/04 01:14:03
done. If backlights_forced_off_is true, brightness
Daniel Erat
2016/11/04 16:12:51
i think that 2 is much better, since it ensures th
Qiang(Joe) Xu
2016/11/04 19:29:51
Done.
| |
259 SetBacklightsForcedOff(false); | |
260 } | |
261 StartTabletPreStartShutdownAnimationTimer(); | |
262 } else { | |
263 if (pressed_on_screen_off_) { | |
264 if (tablet_pre_start_shutdown_animation_timer_.IsRunning()) | |
265 tablet_pre_start_shutdown_animation_timer_.Stop(); | |
266 pressed_on_screen_off_ = false; | |
267 } else { | |
268 if (tablet_pre_start_shutdown_animation_timer_.IsRunning()) { | |
269 tablet_pre_start_shutdown_animation_timer_.Stop(); | |
270 SetBacklightsForcedOff(true); | |
271 LockScreenIfRequired(); | |
272 } | |
273 } | |
274 // When power button is released, Cancel Shutdown animation whenever it is | |
275 // still cancellable. | |
276 if (controller_->CanCancelShutdownAnimation()) | |
277 controller_->CancelShutdownAnimation(); | |
278 } | |
279 } | |
280 | |
281 void PowerButtonController::SetBacklightsForcedOff(bool forced_off) { | |
282 if (!tablet_power_state_delegate_ || backlights_forced_off_ == forced_off) | |
283 return; | |
284 | |
285 tablet_power_state_delegate_->SetBacklightsForcedOff(forced_off); | |
286 backlights_forced_off_ = forced_off; | |
287 } | |
288 | |
289 void PowerButtonController::GetInitialBacklightsForcedOff() { | |
290 if (!tablet_power_state_delegate_) | |
291 return; | |
292 | |
293 tablet_power_state_delegate_->GetBacklightsForcedOff( | |
294 base::Bind(&PowerButtonController::HandleInitialBacklightsForcedOff, | |
295 base::Unretained(this))); | |
296 } | |
297 | |
298 void PowerButtonController::HandleInitialBacklightsForcedOff( | |
299 bool is_forced_off) { | |
300 backlights_forced_off_ = is_forced_off; | |
301 if (is_forced_off) | |
302 SetBacklightsForcedOff(false); | |
Daniel Erat
2016/11/03 21:28:07
i don't understand why this call is needed. the ba
Qiang(Joe) Xu
2016/11/04 01:14:03
I thought when constructed, user should face non-f
| |
303 } | |
304 | |
305 void PowerButtonController::StartTabletPreStartShutdownAnimationTimer() { | |
306 tablet_pre_start_shutdown_animation_timer_.Stop(); | |
Daniel Erat
2016/11/03 21:28:08
you don't need this call to Stop(); Start() alread
Qiang(Joe) Xu
2016/11/04 01:14:03
Done.
| |
307 tablet_pre_start_shutdown_animation_timer_.Start( | |
308 FROM_HERE, base::TimeDelta::FromMilliseconds( | |
309 kTabletPreStartShutdownAnimationTimeoutMs), | |
310 this, &PowerButtonController::OnTabletPreStartShutdownAnimationTimeout); | |
311 } | |
312 | |
313 void PowerButtonController::OnTabletPreStartShutdownAnimationTimeout() { | |
314 controller_->StartShutdownAnimation(); | |
315 } | |
316 | |
317 void PowerButtonController::LockScreenIfRequired() { | |
318 SessionStateDelegate* session_state_delegate = | |
319 WmShell::Get()->GetSessionStateDelegate(); | |
320 if (session_state_delegate->ShouldLockScreenAutomatically() && | |
321 session_state_delegate->CanLockScreen() && | |
322 !session_state_delegate->IsUserSessionBlocked() && | |
323 !controller_->LockRequested()) { | |
324 session_state_delegate->LockScreen(); | |
325 } | |
326 } | |
327 | |
328 void PowerButtonController::WakeOnLaptopMode() { | |
Daniel Erat
2016/11/03 21:28:07
using the word "wake" here seems a bit inaccurate;
Qiang(Joe) Xu
2016/11/04 01:14:03
Done.
| |
329 MaximizeModeController* maximize_mode_controller = | |
330 WmShell::Get()->maximize_mode_controller(); | |
331 if (maximize_mode_controller && | |
332 maximize_mode_controller->CanEnterMaximizeMode() && | |
333 !maximize_mode_controller->IsMaximizeModeWindowManagerEnabled() && | |
Daniel Erat
2016/11/03 21:28:07
i find all of these references to MaximizeModeCont
Qiang(Joe) Xu
2016/11/04 01:14:03
Done.
| |
334 (backlights_forced_off_ || brightness_is_zero_)) { | |
Daniel Erat
2016/11/03 21:28:07
i don't understand the brightness_is_zero_ check h
Qiang(Joe) Xu
2016/11/04 01:14:03
Yes, brightness_is_zero_ is not needed. Thanks!
| |
335 SetBacklightsForcedOff(false); | |
336 } | |
337 } | |
338 | |
339 bool PowerButtonController::MaybeTakeScreenshot(bool power_button_pressed) { | |
340 return volume_down_pressed_ && power_button_pressed && | |
341 WmShell::Get() | |
342 ->maximize_mode_controller() | |
343 ->IsMaximizeModeWindowManagerEnabled(); | |
344 } | |
345 | |
210 } // namespace ash | 346 } // namespace ash |
OLD | NEW |