overview_controller.cc 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574
  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/overview/overview_controller.h"
  5. #include <algorithm>
  6. #include <utility>
  7. #include "ash/frame_throttler/frame_throttling_controller.h"
  8. #include "ash/keyboard/ui/keyboard_ui_controller.h"
  9. #include "ash/public/cpp/window_properties.h"
  10. #include "ash/session/session_controller_impl.h"
  11. #include "ash/shell.h"
  12. #include "ash/wm/desks/desks_controller.h"
  13. #include "ash/wm/mru_window_tracker.h"
  14. #include "ash/wm/overview/delayed_animation_observer_impl.h"
  15. #include "ash/wm/overview/overview_constants.h"
  16. #include "ash/wm/overview/overview_grid.h"
  17. #include "ash/wm/overview/overview_item.h"
  18. #include "ash/wm/overview/overview_session.h"
  19. #include "ash/wm/overview/overview_utils.h"
  20. #include "ash/wm/overview/overview_wallpaper_controller.h"
  21. #include "ash/wm/screen_pinning_controller.h"
  22. #include "ash/wm/splitview/split_view_controller.h"
  23. #include "ash/wm/tablet_mode/tablet_mode_controller.h"
  24. #include "ash/wm/window_state.h"
  25. #include "ash/wm/window_util.h"
  26. #include "base/bind.h"
  27. #include "base/containers/cxx20_erase.h"
  28. #include "base/containers/unique_ptr_adapters.h"
  29. #include "base/metrics/histogram_macros.h"
  30. #include "base/threading/thread_task_runner_handle.h"
  31. #include "base/trace_event/trace_event.h"
  32. #include "ui/views/widget/widget.h"
  33. #include "ui/wm/core/window_util.h"
  34. #include "ui/wm/public/activation_client.h"
  35. namespace ash {
  36. namespace {
  37. // It can take up to two frames until the frame created in the UI thread that
  38. // triggered animation observer is drawn. Wait 50ms in attempt to let its draw
  39. // and swap finish.
  40. constexpr base::TimeDelta kOcclusionPauseDurationForStart =
  41. base::Milliseconds(50);
  42. // Wait longer when exiting overview mode in case when a user may re-enter
  43. // overview mode immediately, contents are ready.
  44. constexpr base::TimeDelta kOcclusionPauseDurationForEnd =
  45. base::Milliseconds(500);
  46. bool IsSplitViewDividerDraggedOrAnimated() {
  47. SplitViewController* split_view_controller =
  48. SplitViewController::Get(Shell::GetPrimaryRootWindow());
  49. return split_view_controller->is_resizing() ||
  50. split_view_controller->IsDividerAnimating();
  51. }
  52. // Returns the enter/exit type that should be used if kNormal enter/exit type
  53. // was originally requested - if the overview is expected to transition to/from
  54. // the home screen, the normal enter/exit mode is expected to be overridden by
  55. // either slide, or fade to home modes.
  56. // |enter| - Whether |original_type| is used for entering overview.
  57. // |windows| - The list of windows that are displayed in the overview UI.
  58. OverviewEnterExitType MaybeOverrideEnterExitTypeForHomeScreen(
  59. OverviewEnterExitType original_type,
  60. bool enter,
  61. const std::vector<aura::Window*>& windows) {
  62. if (original_type != OverviewEnterExitType::kNormal)
  63. return original_type;
  64. // Use normal type if home launcher is not available.
  65. if (!Shell::Get()->tablet_mode_controller()->InTabletMode())
  66. return original_type;
  67. // Transition to home screen only if all windows are minimized.
  68. for (const aura::Window* window : windows) {
  69. if (!WindowState::Get(window)->IsMinimized()) {
  70. return original_type;
  71. }
  72. }
  73. // The original type is overridden even if the list of windows is empty so
  74. // home screen knows to animate in during overview exit animation (home screen
  75. // controller uses different show/hide animations depending on the overview
  76. // exit/enter types).
  77. return enter ? OverviewEnterExitType::kFadeInEnter
  78. : OverviewEnterExitType::kFadeOutExit;
  79. }
  80. } // namespace
  81. OverviewController::OverviewController()
  82. : occlusion_pause_duration_for_end_(kOcclusionPauseDurationForEnd),
  83. overview_wallpaper_controller_(
  84. std::make_unique<OverviewWallpaperController>()),
  85. delayed_animation_task_delay_(kTransition) {
  86. Shell::Get()->activation_client()->AddObserver(this);
  87. }
  88. OverviewController::~OverviewController() {
  89. Shell::Get()->activation_client()->RemoveObserver(this);
  90. overview_wallpaper_controller_.reset();
  91. // Destroy widgets that may be still animating if shell shuts down soon after
  92. // exiting overview mode.
  93. for (auto& animation_observer : delayed_animations_)
  94. animation_observer->Shutdown();
  95. for (auto& animation_observer : start_animations_)
  96. animation_observer->Shutdown();
  97. if (overview_session_) {
  98. overview_session_->Shutdown();
  99. overview_session_.reset();
  100. }
  101. }
  102. bool OverviewController::StartOverview(OverviewStartAction action,
  103. OverviewEnterExitType type) {
  104. // No need to start overview if overview is currently active.
  105. if (InOverviewSession())
  106. return true;
  107. if (!CanEnterOverview())
  108. return false;
  109. ToggleOverview(type);
  110. RecordOverviewStartAction(action);
  111. return true;
  112. }
  113. bool OverviewController::EndOverview(OverviewEndAction action,
  114. OverviewEnterExitType type) {
  115. // No need to end overview if overview is already ended.
  116. if (!InOverviewSession())
  117. return true;
  118. if (!CanEndOverview(type))
  119. return false;
  120. ToggleOverview(type);
  121. RecordOverviewEndAction(action);
  122. // If there is an undo toast active and the toast was created when ChromeVox
  123. // was enabled, then we need to close the toast when overview closes.
  124. DesksController::Get()->MaybeDismissPersistentDeskRemovalToast();
  125. return true;
  126. }
  127. bool OverviewController::InOverviewSession() const {
  128. return overview_session_ && !overview_session_->is_shutting_down();
  129. }
  130. void OverviewController::IncrementSelection(bool forward) {
  131. DCHECK(InOverviewSession());
  132. overview_session_->IncrementSelection(forward);
  133. }
  134. bool OverviewController::AcceptSelection() {
  135. DCHECK(InOverviewSession());
  136. return overview_session_->AcceptSelection();
  137. }
  138. bool OverviewController::IsInStartAnimation() {
  139. return !start_animations_.empty();
  140. }
  141. bool OverviewController::IsCompletingShutdownAnimations() const {
  142. return !delayed_animations_.empty();
  143. }
  144. void OverviewController::PauseOcclusionTracker() {
  145. if (occlusion_tracker_pauser_)
  146. return;
  147. reset_pauser_task_.Cancel();
  148. occlusion_tracker_pauser_ =
  149. std::make_unique<aura::WindowOcclusionTracker::ScopedPause>();
  150. }
  151. void OverviewController::UnpauseOcclusionTracker(base::TimeDelta delay) {
  152. reset_pauser_task_.Reset(base::BindOnce(&OverviewController::ResetPauser,
  153. weak_ptr_factory_.GetWeakPtr()));
  154. base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
  155. FROM_HERE, reset_pauser_task_.callback(), delay);
  156. }
  157. void OverviewController::AddObserver(OverviewObserver* observer) {
  158. observers_.AddObserver(observer);
  159. }
  160. void OverviewController::RemoveObserver(OverviewObserver* observer) {
  161. observers_.RemoveObserver(observer);
  162. }
  163. void OverviewController::DelayedUpdateRoundedCornersAndShadow() {
  164. base::ThreadTaskRunnerHandle::Get()->PostTask(
  165. FROM_HERE,
  166. base::BindOnce(&OverviewController::UpdateRoundedCornersAndShadow,
  167. weak_ptr_factory_.GetWeakPtr()));
  168. }
  169. void OverviewController::AddExitAnimationObserver(
  170. std::unique_ptr<DelayedAnimationObserver> animation_observer) {
  171. // No delayed animations should be created when overview mode is set to exit
  172. // immediately.
  173. DCHECK(IsCompletingShutdownAnimations() ||
  174. overview_session_->enter_exit_overview_type() !=
  175. OverviewEnterExitType::kImmediateExit);
  176. animation_observer->SetOwner(this);
  177. delayed_animations_.push_back(std::move(animation_observer));
  178. }
  179. void OverviewController::RemoveAndDestroyExitAnimationObserver(
  180. DelayedAnimationObserver* animation_observer) {
  181. const bool previous_empty = delayed_animations_.empty();
  182. base::EraseIf(delayed_animations_,
  183. base::MatchesUniquePtr(animation_observer));
  184. // If something has been removed and its the last observer, unblur the
  185. // wallpaper and let observers know. This function may be called while still
  186. // in overview (ie. splitview restores one window but leaves overview active)
  187. // so check that |overview_session_| is null before notifying.
  188. if (!overview_session_ && !previous_empty && delayed_animations_.empty())
  189. OnEndingAnimationComplete(/*canceled=*/false);
  190. }
  191. void OverviewController::AddEnterAnimationObserver(
  192. std::unique_ptr<DelayedAnimationObserver> animation_observer) {
  193. animation_observer->SetOwner(this);
  194. start_animations_.push_back(std::move(animation_observer));
  195. }
  196. void OverviewController::RemoveAndDestroyEnterAnimationObserver(
  197. DelayedAnimationObserver* animation_observer) {
  198. const bool previous_empty = start_animations_.empty();
  199. base::EraseIf(start_animations_, base::MatchesUniquePtr(animation_observer));
  200. if (!previous_empty && start_animations_.empty())
  201. OnStartingAnimationComplete(/*canceled=*/false);
  202. }
  203. void OverviewController::OnWindowActivating(ActivationReason reason,
  204. aura::Window* gained_active,
  205. aura::Window* lost_active) {
  206. if (InOverviewSession())
  207. overview_session_->OnWindowActivating(reason, gained_active, lost_active);
  208. }
  209. std::vector<aura::Window*>
  210. OverviewController::GetWindowsListInOverviewGridsForTest() {
  211. std::vector<aura::Window*> windows;
  212. for (const std::unique_ptr<OverviewGrid>& grid :
  213. overview_session_->grid_list()) {
  214. for (const auto& overview_item : grid->window_list())
  215. windows.push_back(overview_item->GetWindow());
  216. }
  217. return windows;
  218. }
  219. void OverviewController::ToggleOverview(OverviewEnterExitType type) {
  220. // Hide the virtual keyboard as it obstructs the overview mode.
  221. // Don't need to hide if it's the a11y keyboard, as overview mode
  222. // can accept text input and it resizes correctly with the a11y keyboard.
  223. keyboard::KeyboardUIController::Get()->HideKeyboardImplicitlyByUser();
  224. auto windows =
  225. Shell::Get()->mru_window_tracker()->BuildMruWindowList(kActiveDesk);
  226. // Hidden windows are a subset of the window excluded from overview in
  227. // window_util::ShouldExcludeForOverview. Excluded window won't be on the grid
  228. // but their visibility will remain untouched. Hidden windows will be also
  229. // excluded and their visibility will be set to false for the duration of
  230. // overview mode.
  231. auto should_hide_for_overview = [](aura::Window* w) -> bool {
  232. // Explicity hidden windows always get hidden.
  233. if (w->GetProperty(kHideInOverviewKey))
  234. return true;
  235. // Since overview allows moving windows, don't show window that can't be
  236. // moved. If they are a transient ancestor of a postionable window then they
  237. // can be shown and moved with their transient root.
  238. return w == wm::GetTransientRoot(w) &&
  239. !WindowState::Get(w)->IsUserPositionable();
  240. };
  241. std::vector<aura::Window*> hide_windows(windows.size());
  242. auto end = std::copy_if(windows.begin(), windows.end(), hide_windows.begin(),
  243. should_hide_for_overview);
  244. hide_windows.resize(end - hide_windows.begin());
  245. base::EraseIf(windows, window_util::ShouldExcludeForOverview);
  246. // Overview windows will handle showing their transient related windows, so if
  247. // a window in |windows| has a transient root also in |windows|, we can remove
  248. // it as the transient root will handle showing the window.
  249. // Additionally, |windows| may contain transient children and not their
  250. // transient root. This can lead to situations where the transient child is
  251. // destroyed causing its respective overview item to be destroyed, leaving its
  252. // transient root with no overview item. Creating the overview item with the
  253. // transient root instead of the transient child fixes this. See
  254. // crbug.com/972015.
  255. window_util::EnsureTransientRoots(&windows);
  256. if (InOverviewSession()) {
  257. DCHECK(CanEndOverview(type));
  258. TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("ui", "OverviewController::ExitOverview",
  259. this);
  260. // Suspend occlusion tracker until the exit animation is complete.
  261. PauseOcclusionTracker();
  262. // We may want to slide out the overview grid in some cases, even if not
  263. // explicitly stated.
  264. OverviewEnterExitType new_type =
  265. MaybeOverrideEnterExitTypeForHomeScreen(type, /*enter=*/false, windows);
  266. overview_session_->set_enter_exit_overview_type(new_type);
  267. overview_session_->set_is_shutting_down(true);
  268. if (!start_animations_.empty())
  269. OnStartingAnimationComplete(/*canceled=*/true);
  270. start_animations_.clear();
  271. if (type == OverviewEnterExitType::kFadeOutExit) {
  272. // FadeOutExit is used for transition to the home launcher. Minimize the
  273. // windows without animations to prevent them from getting maximized
  274. // during overview exit. Minimized widgets will get created in their
  275. // place, and those widgets will fade out of overview.
  276. std::vector<aura::Window*> windows_to_minimize(windows.size());
  277. auto it =
  278. std::copy_if(windows.begin(), windows.end(),
  279. windows_to_minimize.begin(), [](aura::Window* window) {
  280. return !WindowState::Get(window)->IsMinimized();
  281. });
  282. windows_to_minimize.resize(
  283. std::distance(windows_to_minimize.begin(), it));
  284. window_util::MinimizeAndHideWithoutAnimation(windows_to_minimize);
  285. }
  286. // Do not show mask and show during overview shutdown.
  287. overview_session_->UpdateRoundedCornersAndShadow();
  288. for (auto& observer : observers_)
  289. observer.OnOverviewModeEnding(overview_session_.get());
  290. overview_session_->Shutdown();
  291. const bool should_end_immediately =
  292. overview_session_->enter_exit_overview_type() ==
  293. OverviewEnterExitType::kImmediateExit;
  294. if (should_end_immediately) {
  295. for (const auto& animation : delayed_animations_)
  296. animation->Shutdown();
  297. delayed_animations_.clear();
  298. OnEndingAnimationComplete(/*canceled=*/false);
  299. }
  300. // Don't delete |overview_session_| yet since the stack is still using it.
  301. base::ThreadTaskRunnerHandle::Get()->DeleteSoon(
  302. FROM_HERE, overview_session_.release());
  303. last_overview_session_time_ = base::Time::Now();
  304. for (auto& observer : observers_)
  305. observer.OnOverviewModeEnded();
  306. if (!should_end_immediately && delayed_animations_.empty())
  307. OnEndingAnimationComplete(/*canceled=*/false);
  308. } else {
  309. DCHECK(CanEnterOverview());
  310. TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("ui", "OverviewController::EnterOverview",
  311. this);
  312. auto* active_window = window_util::GetActiveWindow();
  313. if (active_window) {
  314. auto* active_widget =
  315. views::Widget::GetWidgetForNativeView(active_window);
  316. if (active_widget)
  317. paint_as_active_lock_ = active_widget->LockPaintAsActive();
  318. }
  319. Shell::Get()->frame_throttling_controller()->StartThrottling(windows);
  320. // Clear any animations that may be running from last overview end.
  321. for (const auto& animation : delayed_animations_)
  322. animation->Shutdown();
  323. if (!delayed_animations_.empty())
  324. OnEndingAnimationComplete(/*canceled=*/true);
  325. delayed_animations_.clear();
  326. for (auto& observer : observers_)
  327. observer.OnOverviewModeWillStart();
  328. should_focus_overview_ = true;
  329. const SplitViewController::State split_view_state =
  330. SplitViewController::Get(Shell::GetPrimaryRootWindow())->state();
  331. // Prevent overview from stealing focus if |split_view_state| is
  332. // |SplitViewController::State::kLeftSnapped| or
  333. // |SplitViewController::State::kRightSnapped|. Here are all the cases where
  334. // |split_view_state| will now have one of those two values:
  335. // 1. The active window is maximized in tablet mode. The user presses Alt+[.
  336. // 2. The active window is maximized in tablet mode. The user presses Alt+].
  337. // 3. The active window is snapped on the right in tablet split view.
  338. // Another window is snapped on the left in tablet split view. The user
  339. // presses Alt+[.
  340. // 4. The active window is snapped on the left in tablet split view. Another
  341. // window is snapped on the right in tablet split view. The user presses
  342. // Alt+].
  343. // 5. Overview starts because of a snapped window carrying over from
  344. // clamshell mode to tablet mode.
  345. // 6. Overview starts on transition between user sessions.
  346. //
  347. // Note: We have to check the split view state before
  348. // |SplitViewController::OnOverviewModeStarting|, because in case of
  349. // |SplitViewController::State::kBothSnapped|, that function will insert one
  350. // of the two snapped windows to overview.
  351. if (split_view_state == SplitViewController::State::kLeftSnapped ||
  352. split_view_state == SplitViewController::State::kRightSnapped) {
  353. should_focus_overview_ = false;
  354. } else {
  355. // Avoid stealing activation from a dragged active window.
  356. aura::Window* active_window = window_util::GetActiveWindow();
  357. if (active_window && WindowState::Get(active_window)->is_dragged()) {
  358. DCHECK(window_util::ShouldExcludeForOverview(active_window));
  359. should_focus_overview_ = false;
  360. }
  361. }
  362. // Suspend occlusion tracker until the enter animation is complete.
  363. PauseOcclusionTracker();
  364. overview_session_ = std::make_unique<OverviewSession>(this);
  365. // We may want to slide in the overview grid in some cases, even if not
  366. // explicitly stated.
  367. OverviewEnterExitType new_type =
  368. MaybeOverrideEnterExitTypeForHomeScreen(type, /*enter=*/true, windows);
  369. overview_session_->set_enter_exit_overview_type(new_type);
  370. for (auto& observer : observers_)
  371. observer.OnOverviewModeStarting();
  372. overview_session_->Init(windows, hide_windows);
  373. // When fading in from home, start animating blur immediately (if animation
  374. // is required) - with this transition the item widgets are positioned in
  375. // the overview immediately, so delaying blur start until start animations
  376. // finish looks janky.
  377. overview_wallpaper_controller_->Blur(
  378. /*animate=*/new_type == OverviewEnterExitType::kFadeInEnter);
  379. // For app dragging, there are no start animations so add a delay to delay
  380. // animations observing when the start animation ends, such as the shelf,
  381. // shadow and rounded corners.
  382. if (new_type == OverviewEnterExitType::kImmediateEnter &&
  383. !delayed_animation_task_delay_.is_zero()) {
  384. auto force_delay_observer =
  385. std::make_unique<ForceDelayObserver>(delayed_animation_task_delay_);
  386. AddEnterAnimationObserver(std::move(force_delay_observer));
  387. }
  388. if (start_animations_.empty())
  389. OnStartingAnimationComplete(/*canceled=*/false);
  390. if (!last_overview_session_time_.is_null()) {
  391. UMA_HISTOGRAM_LONG_TIMES("Ash.Overview.TimeBetweenUse",
  392. base::Time::Now() - last_overview_session_time_);
  393. }
  394. }
  395. }
  396. bool OverviewController::CanEnterOverview() {
  397. // Prevent entering overview while the divider is dragged or animated.
  398. if (IsSplitViewDividerDraggedOrAnimated())
  399. return false;
  400. // Prevent entering overview if a desk animation is underway. The overview
  401. // animation would be completely covered anyway, and doing so could put us in
  402. // a strange state. Note that exiting overview is allowed as it is part of the
  403. // animation.
  404. if (DesksController::Get()->animation()) {
  405. // The one exception to this rule is in tablet mode, having a window snapped
  406. // to one side. Moving to this desk, we will want to open overview on the
  407. // other side. For clamshell we don't need to enter overview as having a
  408. // window snapped to one side and showing the wallpaper on the other is
  409. // fine.
  410. auto* split_view_controller =
  411. SplitViewController::Get(Shell::GetPrimaryRootWindow());
  412. if (!split_view_controller->InTabletSplitViewMode() ||
  413. split_view_controller->state() ==
  414. SplitViewController::State::kBothSnapped) {
  415. return false;
  416. }
  417. }
  418. // Don't allow a window overview if the user session is not active (e.g.
  419. // locked or in user-adding screen) or a modal dialog is open or running in
  420. // kiosk app session.
  421. SessionControllerImpl* session_controller =
  422. Shell::Get()->session_controller();
  423. return session_controller->GetSessionState() ==
  424. session_manager::SessionState::ACTIVE &&
  425. !Shell::IsSystemModalWindowOpen() &&
  426. !Shell::Get()->screen_pinning_controller()->IsPinned() &&
  427. !session_controller->IsRunningInAppMode();
  428. }
  429. bool OverviewController::CanEndOverview(OverviewEnterExitType type) {
  430. // Prevent ending overview while the divider is dragged or animated.
  431. if (IsSplitViewDividerDraggedOrAnimated())
  432. return false;
  433. // Do not allow ending overview if we're in single split mode unless swiping
  434. // up from the shelf in tablet mode, or ending overview immediately without
  435. // animations.
  436. SplitViewController* split_view_controller =
  437. SplitViewController::Get(Shell::GetPrimaryRootWindow());
  438. if (split_view_controller->InTabletSplitViewMode() &&
  439. split_view_controller->state() !=
  440. SplitViewController::State::kBothSnapped &&
  441. InOverviewSession() && overview_session_->IsEmpty() &&
  442. type != OverviewEnterExitType::kImmediateExit) {
  443. return false;
  444. }
  445. return true;
  446. }
  447. void OverviewController::OnStartingAnimationComplete(bool canceled) {
  448. DCHECK(overview_session_);
  449. // For kFadeInEnter, wallpaper blur is initiated on transition start,
  450. // so it doesn't have to be requested again on starting animation end.
  451. if (!canceled && overview_session_->enter_exit_overview_type() !=
  452. OverviewEnterExitType::kFadeInEnter) {
  453. overview_wallpaper_controller_->Blur(/*animate=*/true);
  454. }
  455. for (auto& observer : observers_)
  456. observer.OnOverviewModeStartingAnimationComplete(canceled);
  457. // Observers should not do anything which may cause overview to quit
  458. // explicitly (i.e. ToggleOverview()) or implicity (i.e. activation change).
  459. DCHECK(overview_session_);
  460. overview_session_->OnStartingAnimationComplete(canceled,
  461. should_focus_overview_);
  462. UnpauseOcclusionTracker(kOcclusionPauseDurationForStart);
  463. TRACE_EVENT_NESTABLE_ASYNC_END1("ui", "OverviewController::EnterOverview",
  464. this, "canceled", canceled);
  465. }
  466. void OverviewController::OnEndingAnimationComplete(bool canceled) {
  467. for (auto& observer : observers_)
  468. observer.OnOverviewModeEndingAnimationComplete(canceled);
  469. UnpauseOcclusionTracker(occlusion_pause_duration_for_end_);
  470. // Unblur when animation is completed (or right away if there was no
  471. // delayed animation) unless it's canceled, in which case, we should keep
  472. // the blur. Also resume the activation frame state.
  473. if (!canceled) {
  474. overview_wallpaper_controller_->Unblur();
  475. paint_as_active_lock_.reset();
  476. }
  477. // Ends the manual frame throttling at the end of overview exit.
  478. Shell::Get()->frame_throttling_controller()->EndThrottling();
  479. TRACE_EVENT_NESTABLE_ASYNC_END1("ui", "OverviewController::ExitOverview",
  480. this, "canceled", canceled);
  481. }
  482. void OverviewController::ResetPauser() {
  483. occlusion_tracker_pauser_.reset();
  484. }
  485. void OverviewController::UpdateRoundedCornersAndShadow() {
  486. if (overview_session_)
  487. overview_session_->UpdateRoundedCornersAndShadow();
  488. }
  489. } // namespace ash