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

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: cr based on 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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698