1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "ash/wm/lock_state_controller.h"
6
7 #include <memory>
8 #include <utility>
9
10 #include "ash/public/cpp/ash_switches.h"
11 #include "ash/public/cpp/login_constants.h"
12 #include "ash/public/cpp/shutdown_controller.h"
13 #include "ash/root_window_controller.h"
14 #include "ash/session/session_controller_impl.h"
15 #include "ash/shell.h"
16 #include "ash/shutdown_reason.h"
17 #include "ash/system/power/power_button_controller.h"
18 #include "ash/system/power/power_button_controller_test_api.h"
19 #include "ash/system/power/power_button_test_base.h"
20 #include "ash/touch/touch_devices_controller.h"
21 #include "ash/wallpaper/wallpaper_view.h"
22 #include "ash/wallpaper/wallpaper_widget_controller.h"
23 #include "ash/wm/lock_state_controller_test_api.h"
24 #include "ash/wm/overview/overview_controller.h"
25 #include "ash/wm/session_state_animator.h"
26 #include "ash/wm/test_session_state_animator.h"
27 #include "base/bind.h"
28 #include "base/command_line.h"
29 #include "base/run_loop.h"
30 #include "base/time/time.h"
31 #include "chromeos/dbus/power/fake_power_manager_client.h"
32 #include "ui/display/fake/fake_display_snapshot.h"
33 #include "ui/display/manager/display_configurator.h"
34 #include "ui/display/types/display_constants.h"
35 #include "ui/gfx/geometry/size.h"
36
37 namespace ash {
38 namespace {
39
40 // Shorthand for some long constants.
41 constexpr power_manager::BacklightBrightnessChange_Cause kUserCause =
42 power_manager::BacklightBrightnessChange_Cause_USER_REQUEST;
43 constexpr power_manager::BacklightBrightnessChange_Cause kOtherCause =
44 power_manager::BacklightBrightnessChange_Cause_OTHER;
cursor_visible()45 bool cursor_visible() {
46 return Shell::Get()->cursor_manager()->IsCursorVisible();
47 }
48
CheckCalledCallback(bool * flag)49 void CheckCalledCallback(bool* flag) {
50 if (flag)
51 (*flag) = true;
52 }
53
54 // ShutdownController that tracks how many shutdown requests have been made.
55 class TestShutdownController : public ShutdownController {
56 public:
57 TestShutdownController() = default;
58 ~TestShutdownController() override = default;
59
num_shutdown_requests() const60 int num_shutdown_requests() const { return num_shutdown_requests_; }
61
62 private:
63 // ShutdownController:
SetRebootOnShutdown(bool reboot_on_shutdown)64 void SetRebootOnShutdown(bool reboot_on_shutdown) override {}
ShutDownOrReboot(ShutdownReason reason)65 void ShutDownOrReboot(ShutdownReason reason) override {
66 num_shutdown_requests_++;
67 }
68
69 int num_shutdown_requests_ = 0;
70
71 DISALLOW_COPY_AND_ASSIGN(TestShutdownController);
72 };
73
74 } // namespace
75
76 class LockStateControllerTest : public PowerButtonTestBase {
77 public:
78 LockStateControllerTest() = default;
79 ~LockStateControllerTest() override = default;
80
81 // PowerButtonTestBase:
SetUp()82 void SetUp() override {
83 PowerButtonTestBase::SetUp();
84 InitPowerButtonControllerMembers(
85 chromeos::PowerManagerClient::TabletMode::UNSUPPORTED);
86
87 test_animator_ = new TestSessionStateAnimator;
88 lock_state_controller_->set_animator_for_test(test_animator_);
89
90 shutdown_controller_resetter_ =
91 std::make_unique<ShutdownController::ScopedResetterForTest>();
92 test_shutdown_controller_ = std::make_unique<TestShutdownController>();
93 lock_state_test_api_->set_shutdown_controller(
94 test_shutdown_controller_.get());
95 }
TearDown()96 void TearDown() override {
97 test_shutdown_controller_.reset();
98 shutdown_controller_resetter_.reset();
99 PowerButtonTestBase::TearDown();
100 }
101
102 protected:
NumShutdownRequests()103 int NumShutdownRequests() {
104 return test_shutdown_controller_->num_shutdown_requests();
105 }
106
Advance(SessionStateAnimator::AnimationSpeed speed)107 void Advance(SessionStateAnimator::AnimationSpeed speed) {
108 test_animator_->Advance(test_animator_->GetDuration(speed));
109 }
110
AdvancePartially(SessionStateAnimator::AnimationSpeed speed,float factor)111 void AdvancePartially(SessionStateAnimator::AnimationSpeed speed,
112 float factor) {
113 test_animator_->Advance(test_animator_->GetDuration(speed) * factor);
114 }
115
SendBrightnessChange(double percent,power_manager::BacklightBrightnessChange_Cause cause)116 void SendBrightnessChange(
117 double percent,
118 power_manager::BacklightBrightnessChange_Cause cause) {
119 power_manager::BacklightBrightnessChange change;
120 change.set_percent(percent);
121 change.set_cause(cause);
122 power_manager_client()->SendScreenBrightnessChanged(change);
123 }
124
ExpectPreLockAnimationStarted()125 void ExpectPreLockAnimationStarted() {
126 SCOPED_TRACE("Failure in ExpectPreLockAnimationStarted");
127 EXPECT_LT(0u, test_animator_->GetAnimationCount());
128 EXPECT_TRUE(test_animator_->AreContainersAnimated(
129 SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS,
130 SessionStateAnimator::ANIMATION_LIFT));
131 EXPECT_TRUE(test_animator_->AreContainersAnimated(
132 SessionStateAnimator::SHELF, SessionStateAnimator::ANIMATION_FADE_OUT));
133 EXPECT_TRUE(test_animator_->AreContainersAnimated(
134 SessionStateAnimator::LOCK_SCREEN_CONTAINERS,
135 SessionStateAnimator::ANIMATION_HIDE_IMMEDIATELY));
136 EXPECT_TRUE(lock_state_test_api_->is_animating_lock());
137 }
138
ExpectPreLockAnimationRunning()139 void ExpectPreLockAnimationRunning() {
140 SCOPED_TRACE("Failure in ExpectPreLockAnimationRunning");
141 EXPECT_LT(0u, test_animator_->GetAnimationCount());
142 EXPECT_TRUE(test_animator_->AreContainersAnimated(
143 SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS,
144 SessionStateAnimator::ANIMATION_LIFT));
145 EXPECT_TRUE(test_animator_->AreContainersAnimated(
146 SessionStateAnimator::SHELF, SessionStateAnimator::ANIMATION_FADE_OUT));
147 EXPECT_TRUE(lock_state_test_api_->is_animating_lock());
148 }
149
ExpectPreLockAnimationCancel()150 void ExpectPreLockAnimationCancel() {
151 SCOPED_TRACE("Failure in ExpectPreLockAnimationCancel");
152 EXPECT_LT(0u, test_animator_->GetAnimationCount());
153 EXPECT_TRUE(test_animator_->AreContainersAnimated(
154 SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS,
155 SessionStateAnimator::ANIMATION_UNDO_LIFT));
156 EXPECT_TRUE(test_animator_->AreContainersAnimated(
157 SessionStateAnimator::SHELF, SessionStateAnimator::ANIMATION_FADE_IN));
158 }
159
ExpectPreLockAnimationFinished()160 void ExpectPreLockAnimationFinished() {
161 SCOPED_TRACE("Failure in ExpectPreLockAnimationFinished");
162 EXPECT_FALSE(test_animator_->AreContainersAnimated(
163 SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS,
164 SessionStateAnimator::ANIMATION_LIFT));
165 EXPECT_FALSE(test_animator_->AreContainersAnimated(
166 SessionStateAnimator::SHELF, SessionStateAnimator::ANIMATION_FADE_OUT));
167 EXPECT_FALSE(test_animator_->AreContainersAnimated(
168 SessionStateAnimator::LOCK_SCREEN_CONTAINERS,
169 SessionStateAnimator::ANIMATION_HIDE_IMMEDIATELY));
170 }
171
ExpectPostLockAnimationStarted()172 void ExpectPostLockAnimationStarted() {
173 SCOPED_TRACE("Failure in ExpectPostLockAnimationStarted");
174 EXPECT_LT(0u, test_animator_->GetAnimationCount());
175 EXPECT_TRUE(test_animator_->AreContainersAnimated(
176 SessionStateAnimator::LOCK_SCREEN_CONTAINERS,
177 SessionStateAnimator::ANIMATION_RAISE_TO_SCREEN));
178 EXPECT_TRUE(test_animator_->AreContainersAnimated(
179 SessionStateAnimator::SHELF, SessionStateAnimator::ANIMATION_FADE_IN));
180 }
181
ExpectPostLockAnimationFinished()182 void ExpectPostLockAnimationFinished() {
183 SCOPED_TRACE("Failure in ExpectPostLockAnimationFinished");
184 EXPECT_FALSE(test_animator_->AreContainersAnimated(
185 SessionStateAnimator::LOCK_SCREEN_CONTAINERS,
186 SessionStateAnimator::ANIMATION_RAISE_TO_SCREEN));
187 }
188
ExpectUnlockBeforeUIDestroyedAnimationStarted()189 void ExpectUnlockBeforeUIDestroyedAnimationStarted() {
190 SCOPED_TRACE("Failure in ExpectUnlockBeforeUIDestroyedAnimationStarted");
191 EXPECT_LT(0u, test_animator_->GetAnimationCount());
192 EXPECT_TRUE(test_animator_->AreContainersAnimated(
193 SessionStateAnimator::LOCK_SCREEN_CONTAINERS,
194 SessionStateAnimator::ANIMATION_LIFT));
195 }
196
ExpectUnlockBeforeUIDestroyedAnimationFinished()197 void ExpectUnlockBeforeUIDestroyedAnimationFinished() {
198 SCOPED_TRACE("Failure in ExpectUnlockBeforeUIDestroyedAnimationFinished");
199 EXPECT_FALSE(test_animator_->AreContainersAnimated(
200 SessionStateAnimator::LOCK_SCREEN_CONTAINERS,
201 SessionStateAnimator::ANIMATION_LIFT));
202 }
203
ExpectUnlockAfterUIDestroyedAnimationStarted()204 void ExpectUnlockAfterUIDestroyedAnimationStarted() {
205 SCOPED_TRACE("Failure in ExpectUnlockAfterUIDestroyedAnimationStarted");
206 EXPECT_LT(0u, test_animator_->GetAnimationCount());
207 EXPECT_TRUE(test_animator_->AreContainersAnimated(
208 SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS,
209 SessionStateAnimator::ANIMATION_DROP));
210 EXPECT_TRUE(test_animator_->AreContainersAnimated(
211 SessionStateAnimator::SHELF, SessionStateAnimator::ANIMATION_FADE_IN));
212 }
213
ExpectUnlockAfterUIDestroyedAnimationFinished()214 void ExpectUnlockAfterUIDestroyedAnimationFinished() {
215 SCOPED_TRACE("Failure in ExpectUnlockAfterUIDestroyedAnimationFinished");
216 EXPECT_EQ(0u, test_animator_->GetAnimationCount());
217 EXPECT_FALSE(test_animator_->AreContainersAnimated(
218 SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS,
219 SessionStateAnimator::ANIMATION_DROP));
220 EXPECT_FALSE(test_animator_->AreContainersAnimated(
221 SessionStateAnimator::SHELF, SessionStateAnimator::ANIMATION_FADE_IN));
222 }
223
ExpectShutdownAnimationStarted()224 void ExpectShutdownAnimationStarted() {
225 SCOPED_TRACE("Failure in ExpectShutdownAnimationStarted");
226 EXPECT_LT(0u, test_animator_->GetAnimationCount());
227 EXPECT_TRUE(test_animator_->AreContainersAnimated(
228 SessionStateAnimator::ROOT_CONTAINER,
229 SessionStateAnimator::ANIMATION_GRAYSCALE_BRIGHTNESS));
230 }
231
ExpectShutdownAnimationFinished()232 void ExpectShutdownAnimationFinished() {
233 SCOPED_TRACE("Failure in ExpectShutdownAnimationFinished");
234 EXPECT_EQ(0u, test_animator_->GetAnimationCount());
235 EXPECT_FALSE(test_animator_->AreContainersAnimated(
236 SessionStateAnimator::ROOT_CONTAINER,
237 SessionStateAnimator::ANIMATION_GRAYSCALE_BRIGHTNESS));
238 }
239
ExpectShutdownAnimationCancel()240 void ExpectShutdownAnimationCancel() {
241 SCOPED_TRACE("Failure in ExpectShutdownAnimationCancel");
242 EXPECT_LT(0u, test_animator_->GetAnimationCount());
243 EXPECT_TRUE(test_animator_->AreContainersAnimated(
244 SessionStateAnimator::ROOT_CONTAINER,
245 SessionStateAnimator::ANIMATION_UNDO_GRAYSCALE_BRIGHTNESS));
246 }
247
ExpectWallpaperIsShowing()248 void ExpectWallpaperIsShowing() {
249 SCOPED_TRACE("Failure in ExpectWallpaperIsShowing");
250 EXPECT_LT(0u, test_animator_->GetAnimationCount());
251 EXPECT_TRUE(test_animator_->AreContainersAnimated(
252 SessionStateAnimator::WALLPAPER,
253 SessionStateAnimator::ANIMATION_FADE_IN));
254 }
255
ExpectWallpaperIsHiding()256 void ExpectWallpaperIsHiding() {
257 SCOPED_TRACE("Failure in ExpectWallpaperIsHiding");
258 EXPECT_LT(0u, test_animator_->GetAnimationCount());
259 EXPECT_TRUE(test_animator_->AreContainersAnimated(
260 SessionStateAnimator::WALLPAPER,
261 SessionStateAnimator::ANIMATION_FADE_OUT));
262 }
263
ExpectRestoringWallpaperVisibility()264 void ExpectRestoringWallpaperVisibility() {
265 SCOPED_TRACE("Failure in ExpectRestoringWallpaperVisibility");
266 EXPECT_LT(0u, test_animator_->GetAnimationCount());
267 EXPECT_TRUE(test_animator_->AreContainersAnimated(
268 SessionStateAnimator::WALLPAPER,
269 SessionStateAnimator::ANIMATION_FADE_IN));
270 }
271
ExpectUnlockedState()272 void ExpectUnlockedState() {
273 SCOPED_TRACE("Failure in ExpectUnlockedState");
274 EXPECT_EQ(0u, test_animator_->GetAnimationCount());
275 EXPECT_FALSE(Shell::Get()->session_controller()->IsScreenLocked());
276 }
277
ExpectLockedState()278 void ExpectLockedState() {
279 SCOPED_TRACE("Failure in ExpectLockedState");
280 EXPECT_EQ(0u, test_animator_->GetAnimationCount());
281 EXPECT_TRUE(Shell::Get()->session_controller()->IsScreenLocked());
282 }
283
HideWallpaper()284 void HideWallpaper() { test_animator_->HideWallpaper(); }
285
PressLockButton()286 void PressLockButton() {
287 power_button_controller_->OnLockButtonEvent(true, base::TimeTicks::Now());
288 }
289
ReleaseLockButton()290 void ReleaseLockButton() {
291 power_button_controller_->OnLockButtonEvent(false, base::TimeTicks::Now());
292 }
293
SuccessfulAuthentication(bool * call_flag)294 void SuccessfulAuthentication(bool* call_flag) {
295 base::OnceClosure closure = base::BindOnce(&CheckCalledCallback, call_flag);
296 lock_state_controller_->OnLockScreenHide(std::move(closure));
297 }
298
299 std::unique_ptr<ShutdownController::ScopedResetterForTest>
300 shutdown_controller_resetter_;
301 std::unique_ptr<TestShutdownController> test_shutdown_controller_;
302 TestSessionStateAnimator* test_animator_ = nullptr; // not owned
303
304 private:
305 DISALLOW_COPY_AND_ASSIGN(LockStateControllerTest);
306 };
307
308 // Test the show menu and shutdown flow for non-Chrome-OS hardware that doesn't
309 // correctly report power button releases. We should show menu the first
310 // time the button is pressed and shut down when it's pressed from the locked
311 // state.
TEST_F(LockStateControllerTest,LegacyShowMenuAndShutDown)312 TEST_F(LockStateControllerTest, LegacyShowMenuAndShutDown) {
313 Initialize(ButtonType::LEGACY, LoginStatus::USER);
314
315 ExpectUnlockedState();
316
317 // We should request that the screen be locked immediately after seeing the
318 // power button get pressed.
319 PressPowerButton();
320
321 EXPECT_TRUE(power_button_test_api_->IsMenuOpened());
322
323 // We shouldn't progress towards the shutdown state, however.
324 EXPECT_FALSE(lock_state_test_api_->shutdown_timer_is_running());
325
326 ReleasePowerButton();
327
328 // Hold the button again and check that we start shutting down.
329 PressPowerButton();
330
331 ExpectShutdownAnimationStarted();
332
333 EXPECT_EQ(0, NumShutdownRequests());
334 // Make sure a mouse move event won't show the cursor.
335 GenerateMouseMoveEvent();
336 EXPECT_FALSE(cursor_visible());
337
338 EXPECT_TRUE(lock_state_test_api_->real_shutdown_timer_is_running());
339 lock_state_test_api_->trigger_real_shutdown_timeout();
340 EXPECT_EQ(1, NumShutdownRequests());
341 }
342
343 // Test that we ignore power button presses when the screen is turned off on an
344 // unofficial system.
TEST_F(LockStateControllerTest,LegacyIgnorePowerButtonIfScreenIsOff)345 TEST_F(LockStateControllerTest, LegacyIgnorePowerButtonIfScreenIsOff) {
346 Initialize(ButtonType::LEGACY, LoginStatus::USER);
347
348 // When the screen brightness is at 0%, we shouldn't do anything in response
349 // to power button presses.
350 SendBrightnessChange(0, kUserCause);
351 PressPowerButton();
352 EXPECT_FALSE(power_button_test_api_->IsMenuOpened());
353 ReleasePowerButton();
354
355 // After increasing the brightness to 10%, we should show the menu as usual.
356 SendBrightnessChange(10, kUserCause);
357 PressPowerButton();
358 EXPECT_TRUE(power_button_test_api_->IsMenuOpened());
359 ReleasePowerButton();
360 }
361
TEST_F(LockStateControllerTest,LegacyHonorPowerButtonInDockedMode)362 TEST_F(LockStateControllerTest, LegacyHonorPowerButtonInDockedMode) {
363 Initialize(ButtonType::LEGACY, LoginStatus::USER);
364 // Create two outputs, the first internal and the second external.
365 display::DisplayConfigurator::DisplayStateList outputs;
366
367 std::unique_ptr<display::DisplaySnapshot> internal_display =
368 display::FakeDisplaySnapshot::Builder()
369 .SetId(123)
370 .SetNativeMode(gfx::Size(1, 1))
371 .SetType(display::DISPLAY_CONNECTION_TYPE_INTERNAL)
372 .Build();
373 outputs.push_back(internal_display.get());
374
375 std::unique_ptr<display::DisplaySnapshot> external_display =
376 display::FakeDisplaySnapshot::Builder()
377 .SetId(456)
378 .SetNativeMode(gfx::Size(1, 1))
379 .SetType(display::DISPLAY_CONNECTION_TYPE_HDMI)
380 .Build();
381 outputs.push_back(external_display.get());
382
383 // When all of the displays are turned off (e.g. due to user inactivity), the
384 // power button should be ignored.
385 SendBrightnessChange(0, kUserCause);
386 internal_display->set_current_mode(nullptr);
387 external_display->set_current_mode(nullptr);
388 power_button_controller_->OnDisplayModeChanged(outputs);
389 PressPowerButton();
390 EXPECT_FALSE(power_button_test_api_->IsMenuOpened());
391 ReleasePowerButton();
392
393 // When the screen brightness is 0% but the external display is still turned
394 // on (indicating either docked mode or the user having manually decreased the
395 // brightness to 0%), the power button should still be handled.
396 external_display->set_current_mode(external_display->modes().back().get());
397 power_button_controller_->OnDisplayModeChanged(outputs);
398 PressPowerButton();
399 EXPECT_TRUE(power_button_test_api_->IsMenuOpened());
400 ReleasePowerButton();
401 }
402
403 // Test the basic operation of the lock button (not logged in).
TEST_F(LockStateControllerTest,LockButtonBasicNotLoggedIn)404 TEST_F(LockStateControllerTest, LockButtonBasicNotLoggedIn) {
405 // The lock button shouldn't do anything if we aren't logged in.
406 Initialize(ButtonType::NORMAL, LoginStatus::NOT_LOGGED_IN);
407
408 PressLockButton();
409 EXPECT_FALSE(lock_state_test_api_->is_animating_lock());
410 ReleaseLockButton();
411 EXPECT_FALSE(Shell::Get()->session_controller()->IsScreenLocked());
412 }
413
414 // Test the basic operation of the lock button (guest).
TEST_F(LockStateControllerTest,LockButtonBasicGuest)415 TEST_F(LockStateControllerTest, LockButtonBasicGuest) {
416 // The lock button shouldn't do anything when we're logged in as a guest.
417 Initialize(ButtonType::NORMAL, LoginStatus::GUEST);
418
419 PressLockButton();
420 EXPECT_FALSE(lock_state_test_api_->is_animating_lock());
421 ReleaseLockButton();
422 EXPECT_FALSE(Shell::Get()->session_controller()->IsScreenLocked());
423 }
424
425 // Test the basic operation of the lock button.
TEST_F(LockStateControllerTest,LockButtonBasic)426 TEST_F(LockStateControllerTest, LockButtonBasic) {
427 // If we're logged in as a regular user, we should start the lock timer and
428 // the pre-lock animation.
429 Initialize(ButtonType::NORMAL, LoginStatus::USER);
430
431 PressLockButton();
432 ExpectPreLockAnimationStarted();
433 AdvancePartially(SessionStateAnimator::ANIMATION_SPEED_UNDOABLE, 0.5f);
434 ExpectPreLockAnimationRunning();
435
436 // If the button is released immediately, we shouldn't lock the screen.
437 ReleaseLockButton();
438 ExpectPreLockAnimationCancel();
439 Advance(SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS);
440
441 ExpectUnlockedState();
442 EXPECT_FALSE(Shell::Get()->session_controller()->IsScreenLocked());
443
444 // Press the button again and let the lock timeout fire. We should request
445 // that the screen be locked.
446 PressLockButton();
447 ExpectPreLockAnimationStarted();
448 Advance(SessionStateAnimator::ANIMATION_SPEED_UNDOABLE);
449
450 GetSessionControllerClient()->FlushForTest();
451 EXPECT_TRUE(Shell::Get()->session_controller()->IsScreenLocked());
452
453 // Pressing the lock button while we have a pending lock request shouldn't do
454 // anything.
455 ReleaseLockButton();
456 PressLockButton();
457 ExpectPreLockAnimationFinished();
458 ReleaseLockButton();
459
460 // Pressing the button also shouldn't do anything after the screen is locked.
461 ExpectPostLockAnimationStarted();
462
463 PressLockButton();
464 ReleaseLockButton();
465 ExpectPostLockAnimationStarted();
466
467 Advance(SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS);
468 ExpectPostLockAnimationFinished();
469
470 PressLockButton();
471 ReleaseLockButton();
472 ExpectPostLockAnimationFinished();
473 }
474
475 #if 0
476 // When the screen is locked without going through the usual power-button
477 // slow-close path (e.g. via the wrench menu), test that we still show the
478 // fast-close animation.
479 TEST_F(LockStateControllerTest, LockWithoutButton) {
480 Initialize(ButtonType::NORMAL, LoginStatus::USER);
481 lock_state_controller_->OnStartingLock();
482
483 ExpectPreLockAnimationStarted();
484 EXPECT_FALSE(lock_state_test_api_->is_lock_cancellable());
485 EXPECT_LT(0u, test_animator_->GetAnimationCount());
486
487 test_animator_->CompleteAllAnimations(true);
488 EXPECT_FALSE(Shell::Get()->session_controller()->IsScreenLocked());
489 }
490 #endif
491
492 // When we hear that the process is exiting but we haven't had a chance to
493 // display an animation, we should just blank the screen.
TEST_F(LockStateControllerTest,ShutdownWithoutButton)494 TEST_F(LockStateControllerTest, ShutdownWithoutButton) {
495 Initialize(ButtonType::NORMAL, LoginStatus::USER);
496 lock_state_controller_->OnChromeTerminating();
497
498 EXPECT_TRUE(test_animator_->AreContainersAnimated(
499 SessionStateAnimator::kAllNonRootContainersMask,
500 SessionStateAnimator::ANIMATION_HIDE_IMMEDIATELY));
501 GenerateMouseMoveEvent();
502 EXPECT_FALSE(cursor_visible());
503 }
504
505 // Test that we display the fast-close animation and shut down when we get an
506 // outside request to shut down (e.g. from the login or lock screen).
TEST_F(LockStateControllerTest,RequestShutdownFromLoginScreen)507 TEST_F(LockStateControllerTest, RequestShutdownFromLoginScreen) {
508 Initialize(ButtonType::NORMAL, LoginStatus::NOT_LOGGED_IN);
509
510 lock_state_controller_->RequestShutdown(
511 ShutdownReason::LOGIN_SHUT_DOWN_BUTTON);
512
513 ExpectShutdownAnimationStarted();
514 Advance(SessionStateAnimator::ANIMATION_SPEED_SHUTDOWN);
515
516 GenerateMouseMoveEvent();
517 EXPECT_FALSE(cursor_visible());
518
519 EXPECT_EQ(0, NumShutdownRequests());
520 EXPECT_TRUE(lock_state_test_api_->real_shutdown_timer_is_running());
521 lock_state_test_api_->trigger_real_shutdown_timeout();
522 EXPECT_EQ(1, NumShutdownRequests());
523 }
524
TEST_F(LockStateControllerTest,RequestShutdownFromLockScreen)525 TEST_F(LockStateControllerTest, RequestShutdownFromLockScreen) {
526 Initialize(ButtonType::NORMAL, LoginStatus::USER);
527
528 LockScreen();
529
530 Advance(SessionStateAnimator::ANIMATION_SPEED_SHUTDOWN);
531 ExpectPostLockAnimationFinished();
532
533 lock_state_controller_->RequestShutdown(
534 ShutdownReason::LOGIN_SHUT_DOWN_BUTTON);
535
536 ExpectShutdownAnimationStarted();
537 Advance(SessionStateAnimator::ANIMATION_SPEED_SHUTDOWN);
538
539 GenerateMouseMoveEvent();
540 EXPECT_FALSE(cursor_visible());
541
542 EXPECT_EQ(0, NumShutdownRequests());
543 EXPECT_TRUE(lock_state_test_api_->real_shutdown_timer_is_running());
544 lock_state_test_api_->trigger_real_shutdown_timeout();
545 EXPECT_EQ(1, NumShutdownRequests());
546 }
547
548 // Test that hidden wallpaper appears and reverts correctly on lock/cancel.
TEST_F(LockStateControllerTest,TestHiddenWallpaperLockCancel)549 TEST_F(LockStateControllerTest, TestHiddenWallpaperLockCancel) {
550 Initialize(ButtonType::NORMAL, LoginStatus::USER);
551 HideWallpaper();
552
553 ExpectUnlockedState();
554 PressLockButton();
555
556 ExpectPreLockAnimationStarted();
557 ExpectWallpaperIsShowing();
558
559 // Forward only half way through.
560 AdvancePartially(SessionStateAnimator::ANIMATION_SPEED_UNDOABLE, 0.5f);
561
562 // Release the button before the lock timer fires.
563 ReleaseLockButton();
564 ExpectPreLockAnimationCancel();
565 ExpectWallpaperIsHiding();
566
567 Advance(SessionStateAnimator::ANIMATION_SPEED_UNDO_MOVE_WINDOWS);
568
569 // When the CancelPrelockAnimation sequence finishes it queues up a
570 // restore wallpaper visibility sequence when the wallpaper is hidden.
571 ExpectRestoringWallpaperVisibility();
572
573 Advance(SessionStateAnimator::ANIMATION_SPEED_IMMEDIATE);
574
575 ExpectUnlockedState();
576 }
577
578 // Test that hidden wallpaper appears and revers correctly on lock/unlock.
TEST_F(LockStateControllerTest,TestHiddenWallpaperLockUnlock)579 TEST_F(LockStateControllerTest, TestHiddenWallpaperLockUnlock) {
580 Initialize(ButtonType::NORMAL, LoginStatus::USER);
581 HideWallpaper();
582
583 ExpectUnlockedState();
584
585 // Press the lock button and check that the lock timer is started and that we
586 // start lifting the non-screen-locker containers.
587 PressLockButton();
588
589 ExpectPreLockAnimationStarted();
590 ExpectWallpaperIsShowing();
591
592 Advance(SessionStateAnimator::ANIMATION_SPEED_UNDOABLE);
593
594 ExpectPreLockAnimationFinished();
595
596 LockScreen();
597
598 ReleaseLockButton();
599
600 ExpectPostLockAnimationStarted();
601 Advance(SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS);
602 ExpectPostLockAnimationFinished();
603
604 ExpectLockedState();
605
606 SuccessfulAuthentication(nullptr);
607
608 ExpectUnlockBeforeUIDestroyedAnimationStarted();
609 Advance(SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS);
610 ExpectUnlockBeforeUIDestroyedAnimationFinished();
611
612 UnlockScreen();
613
614 ExpectUnlockAfterUIDestroyedAnimationStarted();
615 ExpectWallpaperIsHiding();
616
617 Advance(SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS);
618
619 // When the StartUnlockAnimationAfterUIDestroyed sequence finishes it queues
620 // up a restore wallpaper visibility sequence when the wallpaper is hidden.
621 ExpectRestoringWallpaperVisibility();
622
623 Advance(SessionStateAnimator::ANIMATION_SPEED_IMMEDIATE);
624
625 ExpectUnlockAfterUIDestroyedAnimationFinished();
626
627 ExpectUnlockedState();
628 }
629
630 // Tests the default behavior of disabling the touchscreen when the screen is
631 // turned off due to user inactivity.
TEST_F(LockStateControllerTest,DisableTouchscreenForScreenOff)632 TEST_F(LockStateControllerTest, DisableTouchscreenForScreenOff) {
633 Initialize(ButtonType::NORMAL, LoginStatus::USER);
634 // Run the event loop so PowerButtonDisplayController will get the initial
635 // backlights-forced-off state from chromeos::PowerManagerClient.
636 base::RunLoop().RunUntilIdle();
637
638 // Manually turn the screen off and check that the touchscreen is enabled.
639 SendBrightnessChange(0, kUserCause);
640 EXPECT_TRUE(Shell::Get()->touch_devices_controller()->GetTouchscreenEnabled(
641 TouchDeviceEnabledSource::GLOBAL));
642
643 // It should be disabled if the screen is turned off due to user inactivity.
644 SendBrightnessChange(100, kUserCause);
645 SendBrightnessChange(0, kOtherCause);
646 EXPECT_FALSE(Shell::Get()->touch_devices_controller()->GetTouchscreenEnabled(
647 TouchDeviceEnabledSource::GLOBAL));
648 }
649
650 // Tests that the kTouchscreenUsableWhileScreenOff switch keeps the touchscreen
651 // enabled when the screen is turned off due to user inactivity.
TEST_F(LockStateControllerTest,TouchscreenUnableWhileScreenOff)652 TEST_F(LockStateControllerTest, TouchscreenUnableWhileScreenOff) {
653 base::CommandLine::ForCurrentProcess()->AppendSwitch(
654 switches::kTouchscreenUsableWhileScreenOff);
655 ResetPowerButtonController();
656 Initialize(ButtonType::NORMAL, LoginStatus::USER);
657 // Run the event loop so PowerButtonDisplayController will get the initial
658 // backlights-forced-off state from chromeos::PowerManagerClient.
659 base::RunLoop().RunUntilIdle();
660
661 // The touchscreen should remain enabled.
662 SendBrightnessChange(0, kOtherCause);
663 EXPECT_TRUE(Shell::Get()->touch_devices_controller()->GetTouchscreenEnabled(
664 TouchDeviceEnabledSource::GLOBAL));
665 }
666
667 // Tests that continue pressing the power button for a while after power menu is
668 // shown should trigger the cancellable pre-shutdown animation.
TEST_F(LockStateControllerTest,ShutDownAfterShowPowerMenu)669 TEST_F(LockStateControllerTest, ShutDownAfterShowPowerMenu) {
670 Initialize(ButtonType::NORMAL, LoginStatus::USER);
671 PressPowerButton();
672 EXPECT_TRUE(power_button_test_api_->IsMenuOpened());
673 ASSERT_TRUE(power_button_test_api_->TriggerPreShutdownTimeout());
674 EXPECT_TRUE(lock_state_test_api_->shutdown_timer_is_running());
675
676 ExpectShutdownAnimationStarted();
677 AdvancePartially(SessionStateAnimator::ANIMATION_SPEED_SHUTDOWN, 0.5f);
678 // Release the power button before the shutdown timer fires.
679 ReleasePowerButton();
680 EXPECT_FALSE(lock_state_test_api_->shutdown_timer_is_running());
681 ExpectShutdownAnimationCancel();
682
683 power_button_controller_->DismissMenu();
684 EXPECT_FALSE(power_button_test_api_->IsMenuOpened());
685
686 // Press the button again and make the shutdown timeout fire this time.
687 // Check that we start the timer for actually requesting the shutdown.
688 PressPowerButton();
689 ASSERT_TRUE(power_button_test_api_->TriggerPreShutdownTimeout());
690 EXPECT_TRUE(lock_state_test_api_->shutdown_timer_is_running());
691
692 Advance(SessionStateAnimator::ANIMATION_SPEED_SHUTDOWN);
693 ExpectShutdownAnimationFinished();
694 lock_state_test_api_->trigger_shutdown_timeout();
695
696 EXPECT_TRUE(lock_state_test_api_->real_shutdown_timer_is_running());
697 EXPECT_EQ(0, NumShutdownRequests());
698
699 // When the timeout fires, we should request a shutdown.
700 lock_state_test_api_->trigger_real_shutdown_timeout();
701 EXPECT_EQ(1, NumShutdownRequests());
702 }
703
TEST_F(LockStateControllerTest,CancelShouldResetWallpaperBlur)704 TEST_F(LockStateControllerTest, CancelShouldResetWallpaperBlur) {
705 Initialize(ButtonType::NORMAL, LoginStatus::USER);
706
707 ExpectUnlockedState();
708
709 auto* wallpaper_view = Shell::Get()
710 ->GetPrimaryRootWindowController()
711 ->wallpaper_widget_controller()
712 ->wallpaper_view();
713
714 auto* overview_controller = Shell::Get()->overview_controller();
715 // Enter Overview and verify wallpaper properties.
716 overview_controller->StartOverview();
717 EXPECT_EQ(wallpaper_constants::kOverviewBlur, wallpaper_view->blur_sigma());
718
719 // Start lock animation and verify wallpaper properties.
720 PressLockButton();
721 ExpectPreLockAnimationStarted();
722 EXPECT_EQ(login_constants::kBlurSigma, wallpaper_view->blur_sigma());
723
724 // Cancel lock animation.
725 AdvancePartially(SessionStateAnimator::ANIMATION_SPEED_UNDOABLE, 0.5f);
726 ReleaseLockButton();
727 ExpectPreLockAnimationCancel();
728 Advance(SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS);
729 ExpectUnlockedState();
730
731 // Verify wallpaper blur are restored to overview's.
732 EXPECT_EQ(wallpaper_constants::kOverviewBlur, wallpaper_view->blur_sigma());
733 }
734
735 } // namespace ash
736