Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(690)

Side by Side Diff: ash/wm/power_button_controller.cc

Issue 2474913004: Tablet-like power button behavior on Convertible/Tablet ChromeOS devices (Closed)
Patch Set: based on Daniel's comments Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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 // 1s timer before starting shutdown animation. If power button released event
33 // is not received before timeout, |controller_| will take the duty to start
34 // shutdown animation.
35 const int kTabletPreStartShutdownAnimationTimeoutMs = 1000;
Daniel Erat 2016/11/04 16:12:52 // Amount of time the power button must be held to
Qiang(Joe) Xu 2016/11/04 19:29:51 Done.
36
Daniel Erat 2016/11/04 16:12:52 either remove blank line here or add a blank line
Qiang(Joe) Xu 2016/11/04 19:29:51 Done.
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 power_button_down_while_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
72 GetInitialBacklightsForcedOff();
56 } 73 }
57 74
58 PowerButtonController::~PowerButtonController() { 75 PowerButtonController::~PowerButtonController() {
59 Shell::GetInstance()->RemovePreTargetHandler(this); 76 Shell::GetInstance()->RemovePreTargetHandler(this);
60 #if defined(OS_CHROMEOS) 77 #if defined(OS_CHROMEOS)
61 Shell::GetInstance()->display_configurator()->RemoveObserver(this); 78 Shell::GetInstance()->display_configurator()->RemoveObserver(this);
62 chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->RemoveObserver( 79 chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->RemoveObserver(
63 this); 80 this);
64 #endif 81 #endif
65 } 82 }
66 83
67 void PowerButtonController::OnScreenBrightnessChanged(double percent) { 84 void PowerButtonController::OnScreenBrightnessChanged(double percent) {
68 brightness_is_zero_ = percent <= 0.001; 85 brightness_is_zero_ = percent <= 0.001;
69 } 86 }
70 87
71 void PowerButtonController::OnPowerButtonEvent( 88 void PowerButtonController::OnPowerButtonEvent(
72 bool down, 89 bool down,
73 const base::TimeTicks& timestamp) { 90 const base::TimeTicks& timestamp) {
74 power_button_down_ = down; 91 power_button_down_ = down;
75 92
76 if (controller_->ShutdownRequested()) 93 if (controller_->ShutdownRequested())
77 return; 94 return;
78 95
96 bool should_take_screenshot =
97 down && volume_down_pressed_ && IsTabletModeActive();
98
99 if (down) {
100 power_button_down_while_screen_off_ =
101 backlights_forced_off_ || brightness_is_zero_;
Daniel Erat 2016/11/04 16:12:52 after updating tests, you can change this to just
Qiang(Joe) Xu 2016/11/04 19:29:51 We cannot clear the state on button-up here becaus
102 }
103
104 if (!has_legacy_power_button_ && !should_take_screenshot &&
105 IsTabletModeSupported()) {
106 OnTabletPowerButtonEvent(down, timestamp);
107 return;
108 }
109
79 // Avoid starting the lock/shutdown sequence if the power button is pressed 110 // 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 111 // while the screen is off (http://crbug.com/128451), unless an external
81 // display is still on (http://crosbug.com/p/24912). 112 // display is still on (http://crosbug.com/p/24912).
82 if (brightness_is_zero_ && !internal_display_off_and_external_display_on_) 113 if (brightness_is_zero_ && !internal_display_off_and_external_display_on_)
83 return; 114 return;
84 115
85 if (volume_down_pressed_ && down && 116 if (should_take_screenshot) {
86 WmShell::Get()
87 ->maximize_mode_controller()
88 ->IsMaximizeModeWindowManagerEnabled()) {
89 SystemTray* system_tray = Shell::GetInstance()->GetPrimarySystemTray(); 117 SystemTray* system_tray = Shell::GetInstance()->GetPrimarySystemTray();
90 if (system_tray && system_tray->GetTrayAudio()) 118 if (system_tray && system_tray->GetTrayAudio())
91 system_tray->GetTrayAudio()->HideDetailedView(false); 119 system_tray->GetTrayAudio()->HideDetailedView(false);
92 120
93 WmShell::Get()->accelerator_controller()->PerformActionIfEnabled( 121 WmShell::Get()->accelerator_controller()->PerformActionIfEnabled(
94 TAKE_SCREENSHOT); 122 TAKE_SCREENSHOT);
95 123
96 #if defined(OS_CHROMEOS) 124 #if defined(OS_CHROMEOS)
97 // Restore volume. 125 // Restore volume.
98 chromeos::CrasAudioHandler* audio_handler = 126 chromeos::CrasAudioHandler* audio_handler =
(...skipping 21 matching lines...) Expand all
120 } 148 }
121 } 149 }
122 } else { // !has_legacy_power_button_ 150 } else { // !has_legacy_power_button_
123 if (down) { 151 if (down) {
124 // If we already have a pending request to lock the screen, wait. 152 // If we already have a pending request to lock the screen, wait.
125 if (controller_->LockRequested()) 153 if (controller_->LockRequested())
126 return; 154 return;
127 155
128 if (session_state_delegate->CanLockScreen() && 156 if (session_state_delegate->CanLockScreen() &&
129 !session_state_delegate->IsUserSessionBlocked()) { 157 !session_state_delegate->IsUserSessionBlocked()) {
130 if (WmShell::Get() 158 if (IsTabletModeActive() && enable_quick_lock_)
Daniel Erat 2016/11/04 16:12:52 enable_quick_lock_ looks like it's true when --ash
Qiang(Joe) Xu 2016/11/04 19:29:51 mm.. yes, do we still need quick lock here? I thin
131 ->maximize_mode_controller()
132 ->IsMaximizeModeWindowManagerEnabled() &&
133 enable_quick_lock_)
134 controller_->StartLockAnimationAndLockImmediately(true); 159 controller_->StartLockAnimationAndLockImmediately(true);
135 else 160 else
136 controller_->StartLockAnimation(true); 161 controller_->StartLockAnimation(true);
137 } else { 162 } else {
138 controller_->StartShutdownAnimation(); 163 controller_->StartShutdownAnimation();
139 } 164 }
140 } else { // Button is up. 165 } else { // Button is up.
141 if (controller_->CanCancelLockAnimation()) 166 if (controller_->CanCancelLockAnimation())
142 controller_->CancelLockAnimation(); 167 controller_->CancelLockAnimation();
143 else if (controller_->CanCancelShutdownAnimation()) 168 else if (controller_->CanCancelShutdownAnimation())
(...skipping 19 matching lines...) Expand all
163 if (power_button_down_) 188 if (power_button_down_)
164 return; 189 return;
165 190
166 if (down) 191 if (down)
167 controller_->StartLockAnimation(false); 192 controller_->StartLockAnimation(false);
168 else 193 else
169 controller_->CancelLockAnimation(); 194 controller_->CancelLockAnimation();
170 } 195 }
171 196
172 void PowerButtonController::OnKeyEvent(ui::KeyEvent* event) { 197 void PowerButtonController::OnKeyEvent(ui::KeyEvent* event) {
198 if (IsTabletModeSupported() && !IsTabletModeActive() &&
Daniel Erat 2016/11/04 16:12:52 this can just be: if (!IsTabletModeActive() &&
Qiang(Joe) Xu 2016/11/04 19:29:51 yes, done.
199 backlights_forced_off_) {
200 SetBacklightsForcedOff(false);
201 return;
202 }
203
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 if (IsTabletModeSupported() && !IsTabletModeActive() &&
Daniel Erat 2016/11/04 16:12:52 same comment here
Qiang(Joe) Xu 2016/11/04 19:29:51 Done.
219 backlights_forced_off_) {
220 SetBacklightsForcedOff(false);
221 }
222 }
223
186 #if defined(OS_CHROMEOS) 224 #if defined(OS_CHROMEOS)
187 void PowerButtonController::OnDisplayModeChanged( 225 void PowerButtonController::OnDisplayModeChanged(
188 const ui::DisplayConfigurator::DisplayStateList& display_states) { 226 const ui::DisplayConfigurator::DisplayStateList& display_states) {
189 bool internal_display_off = false; 227 bool internal_display_off = false;
190 bool external_display_on = false; 228 bool external_display_on = false;
191 for (const ui::DisplaySnapshot* display : display_states) { 229 for (const ui::DisplaySnapshot* display : display_states) {
192 if (display->type() == ui::DISPLAY_CONNECTION_TYPE_INTERNAL) { 230 if (display->type() == ui::DISPLAY_CONNECTION_TYPE_INTERNAL) {
193 if (!display->current_mode()) 231 if (!display->current_mode())
194 internal_display_off = true; 232 internal_display_off = true;
195 } else if (display->current_mode()) { 233 } else if (display->current_mode()) {
196 external_display_on = true; 234 external_display_on = true;
197 } 235 }
198 } 236 }
199 internal_display_off_and_external_display_on_ = 237 internal_display_off_and_external_display_on_ =
200 internal_display_off && external_display_on; 238 internal_display_off && external_display_on;
201 } 239 }
202 240
203 void PowerButtonController::PowerButtonEventReceived( 241 void PowerButtonController::PowerButtonEventReceived(
204 bool down, 242 bool down,
205 const base::TimeTicks& timestamp) { 243 const base::TimeTicks& timestamp) {
206 OnPowerButtonEvent(down, timestamp); 244 OnPowerButtonEvent(down, timestamp);
207 } 245 }
208 #endif // defined(OS_CHROMEOS) 246 #endif // defined(OS_CHROMEOS)
209 247
248 void PowerButtonController::OnTabletPowerButtonEvent(
249 bool down,
250 const base::TimeTicks& timestamp) {
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) {
Daniel Erat 2016/11/04 16:12:52 i think that this could be changed to: if (down
Qiang(Joe) Xu 2016/11/04 19:29:51 Done.
257 if (backlights_forced_off_ || brightness_is_zero_)
258 SetBacklightsForcedOff(false);
259 StartTabletPreStartShutdownAnimationTimer();
260 } else {
261 if (power_button_down_while_screen_off_) {
Daniel Erat 2016/11/04 16:12:52 seems simpler to move the timer check to the outer
Qiang(Joe) Xu 2016/11/04 19:29:51 done, yes, it is clear.
262 if (tablet_pre_start_shutdown_animation_timer_.IsRunning())
263 tablet_pre_start_shutdown_animation_timer_.Stop();
264 power_button_down_while_screen_off_ = false;
Daniel Erat 2016/11/04 16:12:52 i'd remove this line; it's better to only set the
Qiang(Joe) Xu 2016/11/04 19:29:51 See the comment OnPowerButtonEvent. If you don't l
265 } else {
266 if (tablet_pre_start_shutdown_animation_timer_.IsRunning()) {
267 tablet_pre_start_shutdown_animation_timer_.Stop();
268 SetBacklightsForcedOff(true);
269 LockScreenIfRequired();
270 }
271 }
272 // When power button is released, Cancel Shutdown animation whenever it is
273 // still cancellable.
274 if (controller_->CanCancelShutdownAnimation())
275 controller_->CancelShutdownAnimation();
276 }
277 }
278
279 void PowerButtonController::SetBacklightsForcedOff(bool forced_off) {
280 if (backlights_forced_off_ == forced_off)
281 return;
282
283 #if defined(OS_CHROMEOS)
284 chromeos::DBusThreadManager::Get()
285 ->GetPowerManagerClient()
286 ->SetBacklightsForcedOff(forced_off);
287 backlights_forced_off_ = forced_off;
288 #endif
289 }
290
291 void PowerButtonController::GetInitialBacklightsForcedOff() {
292 #if defined(OS_CHROMEOS)
293 chromeos::DBusThreadManager::Get()
294 ->GetPowerManagerClient()
295 ->GetBacklightsForcedOff(
296 base::Bind(&PowerButtonController::HandleInitialBacklightsForcedOff,
297 base::Unretained(this)));
298 #endif
299 }
300
301 void PowerButtonController::HandleInitialBacklightsForcedOff(
302 bool is_forced_off) {
303 backlights_forced_off_ = is_forced_off;
304 }
305
306 void PowerButtonController::StartTabletPreStartShutdownAnimationTimer() {
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 bool PowerButtonController::IsTabletModeSupported() const {
329 MaximizeModeController* maximize_mode_controller =
330 WmShell::Get()->maximize_mode_controller();
331 return maximize_mode_controller &&
332 maximize_mode_controller->CanEnterMaximizeMode();
333 }
334
335 bool PowerButtonController::IsTabletModeActive() const {
336 MaximizeModeController* maximize_mode_controller =
337 WmShell::Get()->maximize_mode_controller();
338 return maximize_mode_controller &&
339 maximize_mode_controller->IsMaximizeModeWindowManagerEnabled();
340 }
341
210 } // namespace ash 342 } // namespace ash
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698