Skip to content

Commit e801fae

Browse files
Min ChenMin Chen
authored andcommitted
[Merge to M67]ash: Start pre-shutdown animation if long press power button when menu is already shown.
[email protected] - Don't dismiss the menu if pressing power button when menu is already shown. Wait for 650ms to start the pre-shutdown animation and request focus for 'power off' item instead. - Turn screen off for convertible device / in tablet mode if "ModeSpecificPowerButton" is set when menu is not fully shown or second press before starting the pre-shutdown animation. Test=PowerButtonControllerTest* (cherry picked from commit b432b7c) Bug: 826057 Change-Id: I1f906e2bcf5d91960180742bf558c00784fbaa1e Reviewed-on: https://chromium-review.googlesource.com/1011590 Commit-Queue: Min Chen <[email protected]> Reviewed-by: Qiang Xu <[email protected]> Reviewed-by: Dan Erat <[email protected]> Cr-Original-Commit-Position: refs/heads/master@{#550785} Reviewed-on: https://chromium-review.googlesource.com/1015524 Reviewed-by: Min Chen <[email protected]> Cr-Commit-Position: refs/branch-heads/3396@{#52} Cr-Branched-From: 9ef2aa8-refs/heads/master@{#550428}
1 parent ad7ddfe commit e801fae

File tree

3 files changed

+95
-13
lines changed

3 files changed

+95
-13
lines changed

ash/system/power/power_button_controller.cc

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,14 @@ PowerButtonController::~PowerButtonController() {
167167
this);
168168
}
169169

170+
void PowerButtonController::OnPreShutdownTimeout() {
171+
lock_state_controller_->StartShutdownAnimation(ShutdownReason::POWER_BUTTON);
172+
DCHECK(menu_widget_);
173+
static_cast<PowerButtonMenuScreenView*>(menu_widget_->GetContentsView())
174+
->power_button_menu_view()
175+
->FocusPowerOffButton();
176+
}
177+
170178
void PowerButtonController::OnPowerButtonEvent(
171179
bool down,
172180
const base::TimeTicks& timestamp) {
@@ -203,7 +211,7 @@ void PowerButtonController::OnPowerButtonEvent(
203211
}
204212

205213
if (down) {
206-
show_menu_animation_done_ = false;
214+
force_off_on_button_up_ = false;
207215
if (ShouldTurnScreenOffForTap()) {
208216
force_off_on_button_up_ = true;
209217

@@ -226,8 +234,15 @@ void PowerButtonController::OnPowerButtonEvent(
226234
}
227235

228236
screen_off_when_power_button_down_ = !display_controller_->IsScreenOn();
237+
menu_shown_when_power_button_down_ = show_menu_animation_done_;
229238
display_controller_->SetBacklightsForcedOff(false);
230239

240+
if (menu_shown_when_power_button_down_) {
241+
pre_shutdown_timer_.Start(FROM_HERE, kStartShutdownAnimationTimeout, this,
242+
&PowerButtonController::OnPreShutdownTimeout);
243+
return;
244+
}
245+
231246
if (!ShouldTurnScreenOffForTap()) {
232247
StartPowerMenuAnimation();
233248
} else {
@@ -247,6 +262,7 @@ void PowerButtonController::OnPowerButtonEvent(
247262
last_button_up_time_ = timestamp;
248263

249264
const bool menu_timer_was_running = power_button_menu_timer_.IsRunning();
265+
const bool pre_shutdown_timer_was_running = pre_shutdown_timer_.IsRunning();
250266
power_button_menu_timer_.Stop();
251267
pre_shutdown_timer_.Stop();
252268

@@ -262,8 +278,11 @@ void PowerButtonController::OnPowerButtonEvent(
262278
if (timestamp - previous_up_time <= kIgnoreRepeatedButtonUpDelay)
263279
return;
264280

265-
if (menu_timer_was_running && !screen_off_when_power_button_down_ &&
266-
force_off_on_button_up_) {
281+
if (screen_off_when_power_button_down_ || !force_off_on_button_up_)
282+
return;
283+
284+
if (menu_timer_was_running || (menu_shown_when_power_button_down_ &&
285+
pre_shutdown_timer_was_running)) {
267286
display_controller_->SetBacklightsForcedOff(true);
268287
LockScreenIfRequired();
269288
}
@@ -307,6 +326,7 @@ void PowerButtonController::DismissMenu() {
307326
if (IsMenuOpened())
308327
menu_widget_->Hide();
309328

329+
show_menu_animation_done_ = false;
310330
active_window_widget_controller_.reset();
311331
}
312332

@@ -493,13 +513,8 @@ void PowerButtonController::SetShowMenuAnimationDone() {
493513
->power_button_menu_view()
494514
->FocusPowerOffButton();
495515

496-
pre_shutdown_timer_.Start(
497-
FROM_HERE, kStartShutdownAnimationTimeout,
498-
base::BindRepeating(
499-
[](LockStateController* controller) {
500-
controller->StartShutdownAnimation(ShutdownReason::POWER_BUTTON);
501-
},
502-
lock_state_controller_));
516+
pre_shutdown_timer_.Start(FROM_HERE, kStartShutdownAnimationTimeout, this,
517+
&PowerButtonController::OnPreShutdownTimeout);
503518
}
504519

505520
void PowerButtonController::ParsePowerButtonPositionSwitch() {

ash/system/power/power_button_controller.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,10 @@ class ASH_EXPORT PowerButtonController
159159
// button is pressed or when |power_button_menu_timer_| fires.
160160
void StartPowerMenuAnimation();
161161

162+
// Called by |pre_shutdown_timer_| to start the cancellable pre-shutdown
163+
// animation.
164+
void OnPreShutdownTimeout();
165+
162166
// Updates |button_type_| and |force_clamshell_power_button_| based on the
163167
// current command line.
164168
void ProcessCommandLine();
@@ -218,6 +222,9 @@ class ASH_EXPORT PowerButtonController
218222
// True if the screen was off when the power button was pressed.
219223
bool screen_off_when_power_button_down_ = false;
220224

225+
// True if power menu is already shown when pressing the power button.
226+
bool menu_shown_when_power_button_down_ = false;
227+
221228
// True if the next button release event should force the display off.
222229
bool force_off_on_button_up_ = false;
223230

ash/system/power/power_button_controller_unittest.cc

Lines changed: 63 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,13 @@ TEST_F(PowerButtonControllerTest, TappingPowerButtonOfClamshell) {
218218
EXPECT_FALSE(power_manager_client_->backlights_forced_off());
219219
// Power button menu should keep opened if showing animation has finished.
220220
EXPECT_TRUE(power_button_test_api_->IsMenuOpened());
221+
222+
// Tapping power button when menu is already shown should not turn screen off.
223+
AdvanceClockToAvoidIgnoring();
224+
PressPowerButton();
225+
ReleasePowerButton();
226+
EXPECT_FALSE(power_manager_client_->backlights_forced_off());
227+
EXPECT_TRUE(power_button_test_api_->IsMenuOpened());
221228
}
222229

223230
// Tests that tapping power button of a device that has tablet mode switch.
@@ -240,6 +247,7 @@ TEST_F(PowerButtonControllerTest, TappingPowerButtonOfTablet) {
240247

241248
// Showing power menu animation should start until power menu timer is
242249
// timeout.
250+
AdvanceClockToAvoidIgnoring();
243251
PressPowerButton();
244252
power_button_test_api_->SetShowMenuAnimationDone(false);
245253
EXPECT_TRUE(power_button_test_api_->TriggerPowerButtonMenuTimeout());
@@ -250,8 +258,23 @@ TEST_F(PowerButtonControllerTest, TappingPowerButtonOfTablet) {
250258
// release the power button.
251259
EXPECT_TRUE(power_button_test_api_->IsMenuOpened());
252260

261+
// Tapping power button when menu is already shown should still turn screen
262+
// off and dismiss the menu.
263+
AdvanceClockToAvoidIgnoring();
264+
PressPowerButton();
265+
EXPECT_TRUE(power_button_test_api_->PreShutdownTimerIsRunning());
266+
ReleasePowerButton();
267+
EXPECT_FALSE(power_button_test_api_->PreShutdownTimerIsRunning());
268+
EXPECT_TRUE(power_manager_client_->backlights_forced_off());
269+
EXPECT_FALSE(power_button_test_api_->IsMenuOpened());
270+
271+
// Should turn screen on if screen is off.
272+
AdvanceClockToAvoidIgnoring();
273+
TappingPowerButtonWhenScreenIsIdleOff();
274+
253275
// Should not turn screen off if clamshell-like power button behavior is
254276
// requested.
277+
AdvanceClockToAvoidIgnoring();
255278
ForceClamshellPowerButton();
256279
SetTabletModeSwitchState(PowerManagerClient::TabletMode::ON);
257280
AdvanceClockToAvoidIgnoring();
@@ -292,6 +315,17 @@ TEST_F(PowerButtonControllerTest, ModeSpecificPowerButton) {
292315
EXPECT_TRUE(power_button_test_api_->IsMenuOpened());
293316
ReleasePowerButton();
294317
EXPECT_FALSE(power_manager_client_->backlights_forced_off());
318+
319+
// Tapping power button again in laptop mode when menu is opened should not
320+
// turn the screen off.
321+
EXPECT_TRUE(power_button_test_api_->IsMenuOpened());
322+
AdvanceClockToAvoidIgnoring();
323+
PressPowerButton();
324+
EXPECT_FALSE(power_button_test_api_->PowerButtonMenuTimerIsRunning());
325+
EXPECT_TRUE(power_button_test_api_->PreShutdownTimerIsRunning());
326+
ReleasePowerButton();
327+
EXPECT_FALSE(power_manager_client_->backlights_forced_off());
328+
EXPECT_TRUE(power_button_test_api_->IsMenuOpened());
295329
}
296330

297331
// Tests that release power button after menu is opened but before trigger
@@ -839,11 +873,37 @@ TEST_F(PowerButtonControllerTest, MenuItemsToLoginStatus) {
839873
EXPECT_TRUE(power_button_test_api_->MenuHasSignOutItem());
840874
}
841875

842-
// Repeat long press should redisplay the menu.
843-
TEST_F(PowerButtonControllerTest, PressButtonWhenMenuIsOpened) {
876+
// Tests long-pressing the power button when the menu is open.
877+
TEST_F(PowerButtonControllerTest, LongPressButtonWhenMenuIsOpened) {
844878
OpenPowerButtonMenu();
845879
AdvanceClockToAvoidIgnoring();
846-
OpenPowerButtonMenu();
880+
881+
// Long pressing the power button when menu is opened should not dismiss the
882+
// menu but trigger the pre-shutdown animation instead. Menu should stay
883+
// opened if releasing the button can cancel the animation.
884+
PressPowerButton();
885+
EXPECT_FALSE(power_button_test_api_->PowerButtonMenuTimerIsRunning());
886+
ASSERT_TRUE(power_button_test_api_->TriggerPreShutdownTimeout());
887+
EXPECT_TRUE(lock_state_test_api_->shutdown_timer_is_running());
888+
ReleasePowerButton();
889+
EXPECT_FALSE(lock_state_test_api_->shutdown_timer_is_running());
890+
EXPECT_TRUE(power_button_test_api_->IsMenuOpened());
891+
892+
// Change focus to 'sign out'
893+
PressKey(ui::VKEY_TAB);
894+
EXPECT_TRUE(power_button_test_api_->GetPowerButtonMenuView()
895+
->sign_out_item_for_test()
896+
->HasFocus());
897+
898+
// Long press when menu is opened with focus on 'sign out' item will change
899+
// the focus to 'power off' after starting the pre-shutdown animation.
900+
PressPowerButton();
901+
ASSERT_TRUE(power_button_test_api_->TriggerPreShutdownTimeout());
902+
EXPECT_TRUE(lock_state_test_api_->shutdown_timer_is_running());
903+
EXPECT_TRUE(power_button_test_api_->GetPowerButtonMenuView()
904+
->power_off_item_for_test()
905+
->HasFocus());
906+
ReleasePowerButton();
847907
}
848908

849909
// Tests that switches between laptop mode and tablet mode should dismiss the

0 commit comments

Comments
 (0)