Commit 317deb56 authored by Sammie Quon's avatar Sammie Quon Committed by Commit Bot

overview: Introduce OnOverviewModeEndingAnimationCompelete shell observer.

The first usage will be full screen applist, so it doesnt show up while
overview windows are moving around.

Also move blur to after animations, and fix a bug with app list overview
animation pause, and add a pause for homecher -> overview window
animations.

Test: manual
Bug: 873394, 871875, 880613
Change-Id: Id9ede4b412c609cff6a1ec4c841b20aaab9aa5e2
Reviewed-on: https://chromium-review.googlesource.com/1199814Reviewed-by: default avatarXiyuan Xia <xiyuan@chromium.org>
Reviewed-by: default avatarXiaoqian Dai <xdai@chromium.org>
Reviewed-by: default avatarWeidong Guo <weidongg@chromium.org>
Commit-Queue: Sammie Quon <sammiequon@chromium.org>
Cr-Commit-Position: refs/heads/master@{#589186}
parent 62898a13
......@@ -503,12 +503,23 @@ void AppListControllerImpl::OnOverviewModeEnding() {
if (!IsHomeLauncherEnabledInTabletMode())
return;
// Only animate the app list when overview mode is using slide animation.
presenter_.ScheduleOverviewModeAnimation(
false /* start */, Shell::Get()
->window_selector_controller()
->window_selector()
->use_slide_animation() /* animate */);
// Animate the launcher if overview mode is sliding out. Let
// OnOverviewModeEndingAnimationComplete handle showing the launcher after
// overview mode finishes animating. WindowSelector however is nullptr by the
// time the animations are finished, so we need to check the animation type
// here.
use_slide_to_exit_overview_mode_ = Shell::Get()
->window_selector_controller()
->window_selector()
->use_slide_animation();
}
void AppListControllerImpl::OnOverviewModeEndingAnimationComplete() {
if (!IsHomeLauncherEnabledInTabletMode())
return;
presenter_.ScheduleOverviewModeAnimation(/*start=*/false,
use_slide_to_exit_overview_mode_);
}
void AppListControllerImpl::OnTabletModeStarted() {
......
......@@ -188,6 +188,7 @@ class ASH_EXPORT AppListControllerImpl
// ShellObserver:
void OnOverviewModeStarting() override;
void OnOverviewModeEnding() override;
void OnOverviewModeEndingAnimationComplete() override;
// TabletModeObserver:
void OnTabletModeStarted() override;
......@@ -267,6 +268,11 @@ class ASH_EXPORT AppListControllerImpl
// should be hidden during overview mode.
bool in_overview_mode_ = false;
// Each time overview mode is exited, set this variable based on whether
// overview mode is sliding out, so the home launcher knows what to do when
// overview mode exit animations are finished.
bool use_slide_to_exit_overview_mode_ = false;
// Whether the wallpaper is being previewed. The home launcher (if enabled)
// should be hidden during wallpaper preview.
bool in_wallpaper_preview_ = false;
......
......@@ -35,10 +35,6 @@ namespace {
// The y offset for app list animation when overview mode toggles.
constexpr int kOverviewAnimationYOffset = 100;
// The delay in milliseconds for app list animation when overview mode ends
constexpr base::TimeDelta kOverviewEndAnimationDelay =
base::TimeDelta::FromMilliseconds(250);
// The duration in milliseconds for app list animation when overview mode
// toggles.
constexpr base::TimeDelta kOverviewAnimationDuration =
......@@ -48,8 +44,7 @@ inline ui::Layer* GetLayer(views::Widget* widget) {
return widget->GetNativeView()->layer();
}
void UpdateOverviewSettings(bool end_overview,
ui::AnimationMetricsReporter* reporter,
void UpdateOverviewSettings(ui::AnimationMetricsReporter* reporter,
ui::ScopedLayerAnimationSettings* settings) {
settings->SetTransitionDuration(kOverviewAnimationDuration);
settings->SetTweenType(gfx::Tween::FAST_OUT_SLOW_IN);
......@@ -58,13 +53,6 @@ void UpdateOverviewSettings(bool end_overview,
DCHECK(reporter);
settings->SetAnimationMetricsReporter(reporter);
if (end_overview) {
settings->GetAnimator()->SchedulePauseForProperties(
kOverviewEndAnimationDelay,
ui::LayerAnimationElement::AnimatableProperty::OPACITY |
ui::LayerAnimationElement::AnimatableProperty::TRANSFORM);
}
}
class StateAnimationMetricsReporter : public ui::AnimationMetricsReporter {
......@@ -270,7 +258,7 @@ void AppListPresenterImpl::ScheduleOverviewModeAnimation(bool start,
}
UpdateYPositionAndOpacityForHomeLauncher(
start ? kOverviewAnimationYOffset : 0, start ? 0.f : 1.f,
animate ? base::BindRepeating(&UpdateOverviewSettings, start,
animate ? base::BindRepeating(&UpdateOverviewSettings,
state_animation_metrics_reporter_.get())
: base::NullCallback());
}
......
......@@ -626,6 +626,11 @@ void Shell::NotifyOverviewModeEnded() {
observer.OnOverviewModeEnded();
}
void Shell::NotifyOverviewModeEndingAnimationComplete() {
for (auto& observer : shell_observers_)
observer.OnOverviewModeEndingAnimationComplete();
}
void Shell::NotifySplitViewModeStarting() {
for (auto& observer : shell_observers_)
observer.OnSplitViewModeStarting();
......
......@@ -625,6 +625,9 @@ class ASH_EXPORT Shell : public SessionObserver,
// Notifies observers that overview mode has ended.
void NotifyOverviewModeEnded();
// Notifies observers that the end overivew mode animation has completed.
void NotifyOverviewModeEndingAnimationComplete();
// Notifies observers that split view mode is about to be started (before the
// window gets snapped and activated).
void NotifySplitViewModeStarting();
......
......@@ -52,7 +52,11 @@ class ASH_EXPORT ShellObserver {
// Called after overview mode has ended.
virtual void OnOverviewModeEnded() {}
// Called when the split view mode is about to be started (before the window
// Called after the animations that happen when overview mode is ended are
// complete.
virtual void OnOverviewModeEndingAnimationComplete() {}
// Called when the split view mode is about to be started before the window
// gets snapped and activated).
virtual void OnSplitViewModeStarting() {}
......
......@@ -162,10 +162,8 @@ void FadeOutWidgetAndMaybeSlideOnExit(std::unique_ptr<views::Widget> widget,
// window selector controller which has longer lifetime so that animations can
// continue even after the overview mode is shut down.
views::Widget* widget_ptr = widget.get();
std::unique_ptr<CleanupAnimationObserver> observer(
new CleanupAnimationObserver(std::move(widget)));
auto observer = std::make_unique<CleanupAnimationObserver>(std::move(widget));
animation_settings.AddObserver(observer.get());
controller->AddDelayedAnimationObserver(std::move(observer));
widget_ptr->SetOpacity(0.f);
if (slide) {
......
......@@ -33,6 +33,7 @@ constexpr int kFadeInMs = 167;
// The time duration for widgets to fade out.
constexpr int kFadeOutMs = 100;
constexpr int kFromHomeLauncherDelayMs = 250;
constexpr int kHomeLauncherTransitionMs = 250;
base::TimeDelta GetAnimationDuration(OverviewAnimationType animation_type) {
......@@ -179,6 +180,14 @@ ScopedOverviewAnimationSettings::ScopedOverviewAnimationSettings(
ui::LayerAnimator::ENQUEUE_NEW_ANIMATION);
break;
case OVERVIEW_ANIMATION_ENTER_FROM_HOME_LAUNCHER:
animation_settings_->SetTweenType(gfx::Tween::FAST_OUT_SLOW_IN);
animation_settings_->SetPreemptionStrategy(
ui::LayerAnimator::ENQUEUE_NEW_ANIMATION);
window->layer()->GetAnimator()->SchedulePauseForProperties(
base::TimeDelta::FromMilliseconds(kFromHomeLauncherDelayMs),
ui::LayerAnimationElement::OPACITY |
ui::LayerAnimationElement::TRANSFORM);
break;
case OVERVIEW_ANIMATION_EXIT_TO_HOME_LAUNCHER:
animation_settings_->SetTweenType(gfx::Tween::FAST_OUT_SLOW_IN);
animation_settings_->SetPreemptionStrategy(
......
......@@ -23,8 +23,10 @@
#include "ash/wm/splitview/split_view_controller.h"
#include "ash/wm/window_state.h"
#include "ash/wm/window_util.h"
#include "base/containers/unique_ptr_adapters.h"
#include "base/metrics/histogram_macros.h"
#include "base/metrics/user_metrics.h"
#include "base/stl_util.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/gfx/animation/animation_delegate.h"
#include "ui/gfx/animation/slide_animation.h"
......@@ -193,16 +195,20 @@ class WindowSelectorController::OverviewBlurController
WindowSelector* window_selector =
Shell::Get()->window_selector_controller()->window_selector();
DCHECK(window_selector);
for (aura::Window* root : Shell::Get()->GetAllRootWindows()) {
if (window_selector->ShouldAnimateWallpaper(root)) {
root->AddObserver(this);
roots_to_animate_.push_back(root);
} else {
animation_.Reset(should_blur ? 1.0 : 0.0);
ApplyBlur(root, value);
// No need to animate the blur on exiting as this should only be called
// after overview animations are finished.
if (should_blur) {
DCHECK(window_selector);
if (window_selector->ShouldAnimateWallpaper(root)) {
root->AddObserver(this);
roots_to_animate_.push_back(root);
continue;
}
}
animation_.Reset(should_blur ? 1.0 : 0.0);
ApplyBlur(root, value);
}
// Run the animation if one of the roots needs to be animated.
......@@ -301,7 +307,12 @@ bool WindowSelectorController::ToggleOverview(bool toggled_from_home_launcher) {
if (!CanSelect())
return false;
window_selector_.reset(new WindowSelector(this));
// Clear any animations that may be running from last overview end.
for (const auto& animation : delayed_animations_)
animation->Shutdown();
delayed_animations_.clear();
window_selector_ = std::make_unique<WindowSelector>(this);
window_selector_->set_use_slide_animation(should_slide_overview);
Shell::Get()->NotifyOverviewModeStarting();
window_selector_->Init(windows, hide_windows);
......@@ -445,13 +456,13 @@ WindowSelectorController::GetWindowsListInOverviewGridsForTesting() {
void WindowSelectorController::OnSelectionEnded() {
if (is_shutting_down_)
return;
if (IsBlurAllowed())
overview_blur_controller_->Unblur();
is_shutting_down_ = true;
Shell::Get()->NotifyOverviewModeEnding();
auto* window_selector = window_selector_.release();
window_selector->Shutdown();
// There may be no delayed animations in tests, so unblur right away.
if (delayed_animations_.empty() && IsBlurAllowed())
overview_blur_controller_->Unblur();
// Don't delete |window_selector_| yet since the stack is still using it.
base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, window_selector);
last_selection_time_ = base::Time::Now();
......@@ -467,21 +478,17 @@ void WindowSelectorController::AddDelayedAnimationObserver(
void WindowSelectorController::RemoveAndDestroyAnimationObserver(
DelayedAnimationObserver* animation_observer) {
class IsEqual {
public:
explicit IsEqual(DelayedAnimationObserver* animation_observer)
: animation_observer_(animation_observer) {}
bool operator()(const std::unique_ptr<DelayedAnimationObserver>& other) {
return (other.get() == animation_observer_);
}
const bool previous_empty = delayed_animations_.empty();
base::EraseIf(delayed_animations_,
base::MatchesUniquePtr(animation_observer));
private:
const DelayedAnimationObserver* animation_observer_;
};
delayed_animations_.erase(
std::remove_if(delayed_animations_.begin(), delayed_animations_.end(),
IsEqual(animation_observer)),
delayed_animations_.end());
// If something has been removed and its the last observer, unblur the
// wallpaper and let observers know.
if (!previous_empty && delayed_animations_.empty()) {
if (IsBlurAllowed())
overview_blur_controller_->Unblur();
Shell::Get()->NotifyOverviewModeEndingAnimationComplete();
}
}
// static
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment