lock_state_controller.cc 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626
  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. #include "ash/wm/lock_state_controller.h"
  5. #include <algorithm>
  6. #include <memory>
  7. #include <string>
  8. #include <utility>
  9. #include "ash/accessibility/accessibility_controller_impl.h"
  10. #include "ash/cancel_mode.h"
  11. #include "ash/constants/ash_pref_names.h"
  12. #include "ash/public/cpp/shell_window_ids.h"
  13. #include "ash/public/cpp/shutdown_controller.h"
  14. #include "ash/root_window_controller.h"
  15. #include "ash/session/session_controller_impl.h"
  16. #include "ash/shell.h"
  17. #include "ash/shell_delegate.h"
  18. #include "ash/shutdown_reason.h"
  19. #include "ash/utility/occlusion_tracker_pauser.h"
  20. #include "ash/wallpaper/wallpaper_controller_impl.h"
  21. #include "ash/wallpaper/wallpaper_widget_controller.h"
  22. #include "ash/wm/session_state_animator.h"
  23. #include "ash/wm/session_state_animator_impl.h"
  24. #include "base/bind.h"
  25. #include "base/callback_helpers.h"
  26. #include "base/command_line.h"
  27. #include "base/debug/dump_without_crashing.h"
  28. #include "base/json/values_util.h"
  29. #include "base/location.h"
  30. #include "base/logging.h"
  31. #include "base/metrics/histogram_functions.h"
  32. #include "base/metrics/histogram_macros.h"
  33. #include "base/metrics/user_metrics.h"
  34. #include "base/strings/string_util.h"
  35. #include "base/system/sys_info.h"
  36. #include "base/time/default_clock.h"
  37. #include "base/time/time.h"
  38. #include "base/timer/timer.h"
  39. #include "components/prefs/pref_registry_simple.h"
  40. #include "components/prefs/pref_service.h"
  41. #include "ui/aura/window_tree_host.h"
  42. #include "ui/views/controls/menu/menu_controller.h"
  43. #include "ui/wm/core/compound_event_filter.h"
  44. #include "ui/wm/core/cursor_manager.h"
  45. #define UMA_HISTOGRAM_LOCK_TIMES(name, sample) \
  46. UMA_HISTOGRAM_CUSTOM_TIMES(name, sample, base::Milliseconds(1), \
  47. base::Seconds(50), 100)
  48. // TODO(b/228873153): Remove after figuring out the root cause of the bug
  49. #undef ENABLED_VLOG_LEVEL
  50. #define ENABLED_VLOG_LEVEL 1
  51. namespace ash {
  52. namespace {
  53. // ASan/TSan/MSan instrument each memory access. This may slow the execution
  54. // down significantly.
  55. #if defined(MEMORY_SANITIZER)
  56. // For MSan the slowdown depends heavily on the value of msan_track_origins GYP
  57. // flag. The multiplier below corresponds to msan_track_origins=1.
  58. constexpr int kTimeoutMultiplier = 6;
  59. #elif defined(ADDRESS_SANITIZER) || defined(THREAD_SANITIZER)
  60. constexpr int kTimeoutMultiplier = 2;
  61. #else
  62. constexpr int kTimeoutMultiplier = 1;
  63. #endif
  64. constexpr int kMaxShutdownSoundDurationMs = 1500;
  65. // Amount of time to wait for our lock requests to be honored before giving up.
  66. constexpr base::TimeDelta kLockFailTimeout =
  67. base::Seconds(8 * kTimeoutMultiplier);
  68. // Additional time to wait after starting the fast-close shutdown animation
  69. // before actually requesting shutdown, to give the animation time to finish.
  70. constexpr base::TimeDelta kShutdownRequestDelay = base::Milliseconds(50);
  71. } // namespace
  72. // static
  73. const int LockStateController::kPreLockContainersMask =
  74. SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS |
  75. SessionStateAnimator::SHELF;
  76. LockStateController::LockStateController(
  77. ShutdownController* shutdown_controller,
  78. PrefService* local_state)
  79. : animator_(new SessionStateAnimatorImpl()),
  80. shutdown_controller_(shutdown_controller),
  81. scoped_session_observer_(this),
  82. local_state_(local_state) {
  83. DCHECK(shutdown_controller_);
  84. Shell::GetPrimaryRootWindow()->GetHost()->AddObserver(this);
  85. // |local_state_| could be null in tests.
  86. if (local_state_) {
  87. // If kLoginShutdownTimestampPrefName is registered, check the last recorded
  88. // login shutdown timestamp in local state prefs, in case device was shut
  89. // down using shelf button.
  90. auto* login_shutdown_timestamp_pref =
  91. local_state_->FindPreference(prefs::kLoginShutdownTimestampPrefName);
  92. if (login_shutdown_timestamp_pref &&
  93. !login_shutdown_timestamp_pref->IsDefaultValue()) {
  94. base::Time last_recorded_login_shutdown_timestamp =
  95. base::ValueToTime(login_shutdown_timestamp_pref->GetValue()).value();
  96. base::TimeDelta duration = base::DefaultClock::GetInstance()->Now() -
  97. last_recorded_login_shutdown_timestamp;
  98. // Report time delta even if it exceeds histogram limit, to better
  99. // understand fraction of users using the feature.
  100. base::UmaHistogramLongTimes(
  101. "Ash.Shelf.ShutdownConfirmationBubble.TimeToNextBoot."
  102. "LoginShutdownToPowerUpDuration",
  103. duration);
  104. // Reset to the default value after the value is recorded.
  105. local_state_->ClearPref(prefs::kLoginShutdownTimestampPrefName);
  106. }
  107. }
  108. }
  109. LockStateController::~LockStateController() {
  110. Shell::GetPrimaryRootWindow()->GetHost()->RemoveObserver(this);
  111. }
  112. // static
  113. void LockStateController::RegisterPrefs(PrefRegistrySimple* registry) {
  114. registry->RegisterTimePref(prefs::kLoginShutdownTimestampPrefName,
  115. base::Time());
  116. }
  117. void LockStateController::AddObserver(LockStateObserver* observer) {
  118. observers_.AddObserver(observer);
  119. }
  120. void LockStateController::RemoveObserver(LockStateObserver* observer) {
  121. observers_.RemoveObserver(observer);
  122. }
  123. void LockStateController::StartLockAnimation() {
  124. if (animating_lock_)
  125. return;
  126. animating_lock_ = true;
  127. StoreUnlockedProperties();
  128. VLOG(1) << "StartLockAnimation";
  129. PreLockAnimation(SessionStateAnimator::ANIMATION_SPEED_UNDOABLE, true);
  130. DispatchCancelMode();
  131. OnLockStateEvent(LockStateObserver::EVENT_PRELOCK_ANIMATION_STARTED);
  132. }
  133. void LockStateController::StartShutdownAnimation(ShutdownReason reason) {
  134. shutdown_reason_ = reason;
  135. Shell* shell = Shell::Get();
  136. // Hide cursor, but let it reappear if the mouse moves.
  137. if (shell->cursor_manager())
  138. shell->cursor_manager()->HideCursor();
  139. animator_->StartAnimation(
  140. SessionStateAnimator::ROOT_CONTAINER,
  141. SessionStateAnimator::ANIMATION_GRAYSCALE_BRIGHTNESS,
  142. SessionStateAnimator::ANIMATION_SPEED_SHUTDOWN);
  143. StartPreShutdownAnimationTimer();
  144. }
  145. void LockStateController::LockWithoutAnimation() {
  146. if (animating_unlock_) {
  147. CancelUnlockAnimation();
  148. // One would expect a call to
  149. // `Shell::Get()->session_controller()->LockScreen()` at this point,
  150. // however, when execution reaches here, if:
  151. //
  152. // We were running the animations started as part of
  153. // StartUnlockAnimationBeforeLockUIDestroyed, `session_manager` still
  154. // considers the screen to be locked, as we've only executed the part of the
  155. // animations done before the lock screen UI is destroyed.
  156. //
  157. // We were running the animations started as part of
  158. // StartUnlockAnimationAfterLockUIDestroyed, `session_manager` would
  159. // consider the session to be unlocked, and thus we lock it again as part of
  160. // UnlockAnimationAfterLockUIDestroyedFinished.
  161. return;
  162. }
  163. if (animating_lock_)
  164. return;
  165. animating_lock_ = true;
  166. post_lock_immediate_animation_ = true;
  167. animator_->StartAnimation(kPreLockContainersMask,
  168. SessionStateAnimator::ANIMATION_HIDE_IMMEDIATELY,
  169. SessionStateAnimator::ANIMATION_SPEED_IMMEDIATE);
  170. OnLockStateEvent(LockStateObserver::EVENT_LOCK_ANIMATION_STARTED);
  171. Shell::Get()->session_controller()->LockScreen();
  172. }
  173. bool LockStateController::LockRequested() {
  174. return lock_fail_timer_.IsRunning();
  175. }
  176. bool LockStateController::ShutdownRequested() {
  177. return shutting_down_;
  178. }
  179. void LockStateController::CancelLockAnimation() {
  180. VLOG(1) << "CancelLockAnimation";
  181. animating_lock_ = false;
  182. Shell::Get()->wallpaper_controller()->RestoreWallpaperBlurForLockState(
  183. saved_blur_);
  184. auto next_animation_starter =
  185. base::BindOnce(&LockStateController::LockAnimationCancelled,
  186. weak_ptr_factory_.GetWeakPtr());
  187. SessionStateAnimator::AnimationSequence* animation_sequence =
  188. animator_->BeginAnimationSequence(std::move(next_animation_starter));
  189. animation_sequence->StartAnimation(
  190. SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS,
  191. SessionStateAnimator::ANIMATION_UNDO_LIFT,
  192. SessionStateAnimator::ANIMATION_SPEED_UNDO_MOVE_WINDOWS);
  193. animation_sequence->StartAnimation(
  194. SessionStateAnimator::SHELF, SessionStateAnimator::ANIMATION_FADE_IN,
  195. SessionStateAnimator::ANIMATION_SPEED_UNDO_MOVE_WINDOWS);
  196. AnimateWallpaperHidingIfNecessary(
  197. SessionStateAnimator::ANIMATION_SPEED_UNDO_MOVE_WINDOWS,
  198. animation_sequence);
  199. animation_sequence->EndSequence();
  200. }
  201. void LockStateController::CancelUnlockAnimation() {
  202. VLOG(1) << "CancelUnlockAnimation";
  203. pb_pressed_during_unlock_ = true;
  204. }
  205. bool LockStateController::CanCancelShutdownAnimation() {
  206. return pre_shutdown_timer_.IsRunning();
  207. }
  208. void LockStateController::CancelShutdownAnimation() {
  209. if (!CanCancelShutdownAnimation())
  210. return;
  211. animator_->StartAnimation(
  212. SessionStateAnimator::ROOT_CONTAINER,
  213. SessionStateAnimator::ANIMATION_UNDO_GRAYSCALE_BRIGHTNESS,
  214. SessionStateAnimator::ANIMATION_SPEED_REVERT_SHUTDOWN);
  215. pre_shutdown_timer_.Stop();
  216. }
  217. void LockStateController::RequestShutdown(ShutdownReason reason) {
  218. if (shutting_down_)
  219. return;
  220. shutting_down_ = true;
  221. shutdown_reason_ = reason;
  222. if (reason == ShutdownReason::LOGIN_SHUT_DOWN_BUTTON) {
  223. base::Time now_timestamp = base::DefaultClock::GetInstance()->Now();
  224. local_state_->SetTime(prefs::kLoginShutdownTimestampPrefName,
  225. now_timestamp);
  226. }
  227. ::wm::CursorManager* cursor_manager = Shell::Get()->cursor_manager();
  228. cursor_manager->HideCursor();
  229. cursor_manager->LockCursor();
  230. animator_->StartAnimation(
  231. SessionStateAnimator::ROOT_CONTAINER,
  232. SessionStateAnimator::ANIMATION_GRAYSCALE_BRIGHTNESS,
  233. SessionStateAnimator::ANIMATION_SPEED_SHUTDOWN);
  234. StartRealShutdownTimer(true);
  235. }
  236. void LockStateController::OnUnlockAnimationBeforeLockUIDestroyedFinished() {
  237. if (pb_pressed_during_unlock_) {
  238. // Power button was pressed during the unlock animation and
  239. // CancelUnlockAnimation was called, restore UI elements to previous state
  240. // immediately.
  241. animator_->StartAnimation(SessionStateAnimator::SHELF,
  242. SessionStateAnimator::ANIMATION_FADE_IN,
  243. SessionStateAnimator::ANIMATION_SPEED_IMMEDIATE);
  244. animator_->StartAnimation(SessionStateAnimator::LOCK_SCREEN_CONTAINERS,
  245. SessionStateAnimator::ANIMATION_UNDO_LIFT,
  246. SessionStateAnimator::ANIMATION_SPEED_IMMEDIATE);
  247. // We aborted, so we are not animating anymore.
  248. animating_unlock_ = false;
  249. }
  250. std::move(start_unlock_callback_).Run(pb_pressed_during_unlock_);
  251. pb_pressed_during_unlock_ = false;
  252. }
  253. void LockStateController::OnLockScreenHide(
  254. SessionStateAnimator::AnimationCallback callback) {
  255. start_unlock_callback_ = std::move(callback);
  256. StartUnlockAnimationBeforeLockUIDestroyed(base::BindOnce(
  257. &LockStateController::OnUnlockAnimationBeforeLockUIDestroyedFinished,
  258. base::Unretained(this)));
  259. }
  260. void LockStateController::SetLockScreenDisplayedCallback(
  261. base::OnceClosure callback) {
  262. DCHECK(lock_screen_displayed_callback_.is_null());
  263. if (system_is_locked_ && !animating_lock_)
  264. std::move(callback).Run();
  265. else
  266. lock_screen_displayed_callback_ = std::move(callback);
  267. }
  268. void LockStateController::OnHostCloseRequested(aura::WindowTreeHost* host) {
  269. Shell::Get()->session_controller()->RequestSignOut();
  270. }
  271. void LockStateController::OnChromeTerminating() {
  272. // If we hear that Chrome is exiting but didn't request it ourselves, all we
  273. // can really hope for is that we'll have time to clear the screen.
  274. // This is also the case when the user signs off.
  275. if (!shutting_down_) {
  276. shutting_down_ = true;
  277. ::wm::CursorManager* cursor_manager = Shell::Get()->cursor_manager();
  278. cursor_manager->HideCursor();
  279. cursor_manager->LockCursor();
  280. animator_->StartAnimation(SessionStateAnimator::kAllNonRootContainersMask,
  281. SessionStateAnimator::ANIMATION_HIDE_IMMEDIATELY,
  282. SessionStateAnimator::ANIMATION_SPEED_IMMEDIATE);
  283. }
  284. }
  285. void LockStateController::OnLockStateChanged(bool locked) {
  286. // Unpause if lock animations didn't start and ends in 3 seconds.
  287. constexpr base::TimeDelta kPauseTimeout = base::Seconds(3);
  288. DCHECK((lock_fail_timer_.IsRunning() && lock_duration_timer_ != nullptr) ||
  289. (!lock_fail_timer_.IsRunning() && lock_duration_timer_ == nullptr));
  290. VLOG(1) << "OnLockStateChanged called with locked: " << locked
  291. << ", shutting_down_: " << shutting_down_
  292. << ", system_is_locked_: " << system_is_locked_
  293. << ", lock_fail_timer_.IsRunning(): " << lock_fail_timer_.IsRunning();
  294. if (shutting_down_ || (system_is_locked_ == locked))
  295. return;
  296. system_is_locked_ = locked;
  297. Shell::Get()->occlusion_tracker_pauser()->PauseUntilAnimationsEnd(
  298. kPauseTimeout);
  299. if (locked) {
  300. StartPostLockAnimation();
  301. lock_fail_timer_.Stop();
  302. if (lock_duration_timer_) {
  303. UMA_HISTOGRAM_LOCK_TIMES("Ash.WindowManager.Lock.Success",
  304. lock_duration_timer_->Elapsed());
  305. lock_duration_timer_.reset();
  306. }
  307. } else {
  308. StartUnlockAnimationAfterLockUIDestroyed();
  309. }
  310. }
  311. void LockStateController::OnLockFailTimeout() {
  312. UMA_HISTOGRAM_LOCK_TIMES("Ash.WindowManager.Lock.Timeout",
  313. lock_duration_timer_->Elapsed());
  314. lock_duration_timer_.reset();
  315. DCHECK(!system_is_locked_);
  316. // b/228873153: Here we use `LOG(ERROR)` instead of `LOG(FATAL)` because it
  317. // seems like certain users are hitting this timeout causing chrome to crash
  318. // and be restarted from session manager without `--login-manager`
  319. LOG(ERROR) << "Screen lock took too long; Signing out";
  320. base::debug::DumpWithoutCrashing();
  321. Shell::Get()->session_controller()->RequestSignOut();
  322. }
  323. void LockStateController::StartPreShutdownAnimationTimer() {
  324. pre_shutdown_timer_.Stop();
  325. pre_shutdown_timer_.Start(
  326. FROM_HERE,
  327. animator_->GetDuration(SessionStateAnimator::ANIMATION_SPEED_SHUTDOWN),
  328. this, &LockStateController::OnPreShutdownAnimationTimeout);
  329. }
  330. void LockStateController::OnPreShutdownAnimationTimeout() {
  331. VLOG(1) << "OnPreShutdownAnimationTimeout";
  332. shutting_down_ = true;
  333. Shell* shell = Shell::Get();
  334. if (shell->cursor_manager())
  335. shell->cursor_manager()->HideCursor();
  336. StartRealShutdownTimer(false);
  337. }
  338. void LockStateController::StartRealShutdownTimer(bool with_animation_time) {
  339. base::TimeDelta duration = kShutdownRequestDelay;
  340. if (with_animation_time) {
  341. duration +=
  342. animator_->GetDuration(SessionStateAnimator::ANIMATION_SPEED_SHUTDOWN);
  343. }
  344. // Play and get shutdown sound duration from chrome in |sound_duration|. And
  345. // start real shutdown after a delay of |duration|.
  346. base::TimeDelta sound_duration =
  347. std::min(Shell::Get()->accessibility_controller()->PlayShutdownSound(),
  348. base::Milliseconds(kMaxShutdownSoundDurationMs));
  349. duration = std::max(duration, sound_duration);
  350. real_shutdown_timer_.Start(FROM_HERE, duration, this,
  351. &LockStateController::OnRealPowerTimeout);
  352. }
  353. void LockStateController::OnRealPowerTimeout() {
  354. VLOG(1) << "OnRealPowerTimeout";
  355. DCHECK(shutting_down_);
  356. DCHECK(shutdown_reason_);
  357. // Shut down or reboot based on device policy.
  358. shutdown_controller_->ShutDownOrReboot(*shutdown_reason_);
  359. }
  360. void LockStateController::PreLockAnimation(
  361. SessionStateAnimator::AnimationSpeed speed,
  362. bool request_lock_on_completion) {
  363. VLOG(1) << "PreLockAnimation";
  364. saved_blur_ = Shell::GetPrimaryRootWindowController()
  365. ->wallpaper_widget_controller()
  366. ->GetWallpaperBlur();
  367. Shell::Get()->wallpaper_controller()->UpdateWallpaperBlurForLockState(true);
  368. auto next_animation_starter = base::BindOnce(
  369. &LockStateController::PreLockAnimationFinished,
  370. weak_ptr_factory_.GetWeakPtr(), request_lock_on_completion);
  371. SessionStateAnimator::AnimationSequence* animation_sequence =
  372. animator_->BeginAnimationSequence(std::move(next_animation_starter));
  373. animation_sequence->StartAnimation(
  374. SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS,
  375. SessionStateAnimator::ANIMATION_LIFT, speed);
  376. animation_sequence->StartAnimation(SessionStateAnimator::SHELF,
  377. SessionStateAnimator::ANIMATION_FADE_OUT,
  378. speed);
  379. // Hide the screen locker containers so we can raise them later.
  380. animator_->StartAnimation(SessionStateAnimator::LOCK_SCREEN_CONTAINERS,
  381. SessionStateAnimator::ANIMATION_HIDE_IMMEDIATELY,
  382. SessionStateAnimator::ANIMATION_SPEED_IMMEDIATE);
  383. AnimateWallpaperAppearanceIfNecessary(speed, animation_sequence);
  384. animation_sequence->EndSequence();
  385. }
  386. void LockStateController::StartPostLockAnimation() {
  387. VLOG(1) << "StartPostLockAnimation";
  388. auto next_animation_starter =
  389. base::BindOnce(&LockStateController::PostLockAnimationFinished,
  390. weak_ptr_factory_.GetWeakPtr());
  391. SessionStateAnimator::AnimationSequence* animation_sequence =
  392. animator_->BeginAnimationSequence(std::move(next_animation_starter));
  393. animation_sequence->StartAnimation(
  394. SessionStateAnimator::LOCK_SCREEN_CONTAINERS,
  395. SessionStateAnimator::ANIMATION_RAISE_TO_SCREEN,
  396. post_lock_immediate_animation_
  397. ? SessionStateAnimator::ANIMATION_SPEED_IMMEDIATE
  398. : SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS);
  399. // Show the lock screen shelf. This is a no-op if views-based shelf is
  400. // disabled, since shelf is in NonLockScreenContainersContainer.
  401. animation_sequence->StartAnimation(
  402. SessionStateAnimator::SHELF, SessionStateAnimator::ANIMATION_FADE_IN,
  403. post_lock_immediate_animation_
  404. ? SessionStateAnimator::ANIMATION_SPEED_IMMEDIATE
  405. : SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS);
  406. animation_sequence->EndSequence();
  407. }
  408. void LockStateController::StartUnlockAnimationBeforeLockUIDestroyed(
  409. base::OnceClosure callback) {
  410. VLOG(1) << "StartUnlockAnimationBeforeLockUIDestroyed";
  411. animating_unlock_ = true;
  412. // Hide the lock screen shelf. This is a no-op if views-based shelf is
  413. // disabled, since shelf is in NonLockScreenContainersContainer.
  414. animator_->StartAnimation(SessionStateAnimator::SHELF,
  415. SessionStateAnimator::ANIMATION_FADE_OUT,
  416. SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS);
  417. animator_->StartAnimationWithCallback(
  418. SessionStateAnimator::LOCK_SCREEN_CONTAINERS,
  419. SessionStateAnimator::ANIMATION_LIFT,
  420. SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS, std::move(callback));
  421. animator_->StartAnimation(SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS,
  422. SessionStateAnimator::ANIMATION_COPY_LAYER,
  423. SessionStateAnimator::ANIMATION_SPEED_IMMEDIATE);
  424. }
  425. void LockStateController::StartUnlockAnimationAfterLockUIDestroyed() {
  426. VLOG(1) << "StartUnlockAnimationAfterLockUIDestroyed";
  427. auto next_animation_starter = base::BindOnce(
  428. &LockStateController::UnlockAnimationAfterLockUIDestroyedFinished,
  429. weak_ptr_factory_.GetWeakPtr());
  430. SessionStateAnimator::AnimationSequence* animation_sequence =
  431. animator_->BeginAnimationSequence(std::move(next_animation_starter));
  432. animation_sequence->StartAnimation(
  433. SessionStateAnimator::NON_LOCK_SCREEN_CONTAINERS,
  434. SessionStateAnimator::ANIMATION_DROP,
  435. SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS);
  436. animation_sequence->StartAnimation(
  437. SessionStateAnimator::SHELF, SessionStateAnimator::ANIMATION_FADE_IN,
  438. SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS);
  439. AnimateWallpaperHidingIfNecessary(
  440. SessionStateAnimator::ANIMATION_SPEED_MOVE_WINDOWS, animation_sequence);
  441. animation_sequence->EndSequence();
  442. }
  443. void LockStateController::LockAnimationCancelled(bool aborted) {
  444. DVLOG(1) << "LockAnimationCancelled: aborted=" << aborted;
  445. RestoreUnlockedProperties();
  446. }
  447. void LockStateController::PreLockAnimationFinished(bool request_lock,
  448. bool aborted) {
  449. DVLOG(1) << "PreLockAnimationFinished: aborted=" << aborted;
  450. // Aborted in this stage means the locking animation was cancelled by
  451. // `CancelLockAnimation()`, triggered by releasing a lock button before
  452. // finishing animation.
  453. if (aborted)
  454. return;
  455. // Don't do anything (including starting the lock-fail timer) if the screen
  456. // was already locked while the animation was going.
  457. if (system_is_locked_) {
  458. DCHECK(!request_lock) << "Got request to lock already-locked system "
  459. << "at completion of pre-lock animation";
  460. return;
  461. }
  462. if (request_lock) {
  463. base::RecordAction(base::UserMetricsAction("Accel_LockScreen_LockButton"));
  464. Shell::Get()->session_controller()->LockScreen();
  465. }
  466. VLOG(1) << "b/228873153 : Starting lock fail timer";
  467. lock_fail_timer_.Start(FROM_HERE, kLockFailTimeout, this,
  468. &LockStateController::OnLockFailTimeout);
  469. lock_duration_timer_ = std::make_unique<base::ElapsedTimer>();
  470. }
  471. void LockStateController::PostLockAnimationFinished(bool aborted) {
  472. DVLOG(1) << "PostLockAnimationFinished: aborted=" << aborted;
  473. animating_lock_ = false;
  474. OnLockStateEvent(LockStateObserver::EVENT_LOCK_ANIMATION_FINISHED);
  475. if (!lock_screen_displayed_callback_.is_null())
  476. std::move(lock_screen_displayed_callback_).Run();
  477. CHECK(!views::MenuController::GetActiveInstance());
  478. }
  479. void LockStateController::UnlockAnimationAfterLockUIDestroyedFinished(
  480. bool aborted) {
  481. DVLOG(1) << "UnlockAnimationAfterLockUIDestroyedFinished: aborted="
  482. << aborted;
  483. animating_unlock_ = false;
  484. if (pb_pressed_during_unlock_) {
  485. Shell::Get()->session_controller()->LockScreen();
  486. pb_pressed_during_unlock_ = false;
  487. } else {
  488. Shell::Get()->wallpaper_controller()->UpdateWallpaperBlurForLockState(
  489. false);
  490. RestoreUnlockedProperties();
  491. }
  492. }
  493. void LockStateController::StoreUnlockedProperties() {
  494. if (!unlocked_properties_) {
  495. unlocked_properties_ = std::make_unique<UnlockedStateProperties>();
  496. unlocked_properties_->wallpaper_is_hidden = animator_->IsWallpaperHidden();
  497. }
  498. if (unlocked_properties_->wallpaper_is_hidden) {
  499. // Hide wallpaper so that it can be animated later.
  500. animator_->StartAnimation(SessionStateAnimator::WALLPAPER,
  501. SessionStateAnimator::ANIMATION_HIDE_IMMEDIATELY,
  502. SessionStateAnimator::ANIMATION_SPEED_IMMEDIATE);
  503. animator_->ShowWallpaper();
  504. }
  505. }
  506. void LockStateController::RestoreUnlockedProperties() {
  507. if (!unlocked_properties_)
  508. return;
  509. if (unlocked_properties_->wallpaper_is_hidden) {
  510. animator_->HideWallpaper();
  511. // Restore wallpaper visibility.
  512. animator_->StartAnimation(SessionStateAnimator::WALLPAPER,
  513. SessionStateAnimator::ANIMATION_FADE_IN,
  514. SessionStateAnimator::ANIMATION_SPEED_IMMEDIATE);
  515. }
  516. unlocked_properties_.reset();
  517. }
  518. void LockStateController::AnimateWallpaperAppearanceIfNecessary(
  519. SessionStateAnimator::AnimationSpeed speed,
  520. SessionStateAnimator::AnimationSequence* animation_sequence) {
  521. if (unlocked_properties_.get() && unlocked_properties_->wallpaper_is_hidden) {
  522. animation_sequence->StartAnimation(SessionStateAnimator::WALLPAPER,
  523. SessionStateAnimator::ANIMATION_FADE_IN,
  524. speed);
  525. }
  526. }
  527. void LockStateController::AnimateWallpaperHidingIfNecessary(
  528. SessionStateAnimator::AnimationSpeed speed,
  529. SessionStateAnimator::AnimationSequence* animation_sequence) {
  530. if (unlocked_properties_.get() && unlocked_properties_->wallpaper_is_hidden) {
  531. animation_sequence->StartAnimation(SessionStateAnimator::WALLPAPER,
  532. SessionStateAnimator::ANIMATION_FADE_OUT,
  533. speed);
  534. }
  535. }
  536. void LockStateController::OnLockStateEvent(LockStateObserver::EventType event) {
  537. if (shutting_down_)
  538. return;
  539. for (auto& observer : observers_)
  540. observer.OnLockStateEvent(event);
  541. }
  542. } // namespace ash