blob: 3ceed60105b56535860a9a2b269f67f1402643b2 [file] [log] [blame]
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ash/wm/overview/scoped_overview_animation_settings.h"
#include "ash/metrics/histogram_macros.h"
#include "ash/wm/overview/overview_constants.h"
#include "base/lazy_instance.h"
#include "base/metrics/histogram_macros.h"
#include "base/time/time.h"
#include "ui/aura/window.h"
#include "ui/compositor/layer.h"
#include "ui/compositor/layer_animation_observer.h"
#include "ui/compositor/scoped_layer_animation_settings.h"
#include "ui/gfx/animation/tween.h"
namespace ash {
namespace {
// The time duration for fading out when closing an item.
constexpr base::TimeDelta kCloseFadeOut =
base::TimeDelta::FromMilliseconds(100);
// The time duration for scaling down when an item is closed.
constexpr base::TimeDelta kCloseScale = base::TimeDelta::FromMilliseconds(100);
// The time duration for widgets to fade in.
constexpr base::TimeDelta kFadeInDelay = base::TimeDelta::FromMilliseconds(83);
constexpr base::TimeDelta kFadeIn = base::TimeDelta::FromMilliseconds(167);
// The time duration for widgets to fade out.
constexpr base::TimeDelta kFadeOut = base::TimeDelta::FromMilliseconds(100);
constexpr base::TimeDelta kFromHomeLauncherDelay =
base::TimeDelta::FromMilliseconds(250);
constexpr base::TimeDelta kHomeLauncherTransition =
base::TimeDelta::FromMilliseconds(250);
// Time it takes for the selector widget to move to the next target. The same
// time is used for fading out shield widget when the overview mode is opened
// or closed.
constexpr base::TimeDelta kOverviewSelectorTransition =
base::TimeDelta::FromMilliseconds(250);
// Time duration of the show animation of the drop target.
constexpr base::TimeDelta kDropTargetFadeIn =
base::TimeDelta::FromMilliseconds(250);
base::TimeDelta GetAnimationDuration(OverviewAnimationType animation_type) {
switch (animation_type) {
case OVERVIEW_ANIMATION_NONE:
return base::TimeDelta();
case OVERVIEW_ANIMATION_ENTER_OVERVIEW_MODE_FADE_IN:
return kFadeIn;
case OVERVIEW_ANIMATION_EXIT_OVERVIEW_MODE_FADE_OUT:
return kFadeOut;
case OVERVIEW_ANIMATION_LAYOUT_OVERVIEW_ITEMS_ON_ENTER:
case OVERVIEW_ANIMATION_LAYOUT_OVERVIEW_ITEMS_IN_OVERVIEW:
case OVERVIEW_ANIMATION_LAYOUT_OVERVIEW_ITEMS_ON_EXIT:
case OVERVIEW_ANIMATION_RESTORE_WINDOW:
case OVERVIEW_ANIMATION_RESTORE_WINDOW_ZERO:
return kTransition;
case OVERVIEW_ANIMATION_CLOSING_OVERVIEW_ITEM:
return kCloseScale;
case OVERVIEW_ANIMATION_CLOSE_OVERVIEW_ITEM:
return kCloseFadeOut;
case OVERVIEW_ANIMATION_ENTER_FROM_HOME_LAUNCHER:
case OVERVIEW_ANIMATION_EXIT_TO_HOME_LAUNCHER:
return kHomeLauncherTransition;
case OVERVIEW_ANIMATION_DROP_TARGET_FADE_IN:
return kDropTargetFadeIn;
case OVERVIEW_ANIMATION_NO_RECENTS_FADE:
case OVERVIEW_ANIMATION_SELECTION_WINDOW_SHADOW:
case OVERVIEW_ANIMATION_SELECTION_WINDOW:
return kOverviewSelectorTransition;
}
NOTREACHED();
return base::TimeDelta();
}
class OverviewEnterMetricsReporter : public ui::AnimationMetricsReporter {
public:
OverviewEnterMetricsReporter() = default;
~OverviewEnterMetricsReporter() override = default;
void Report(int value) override {
UMA_HISTOGRAM_PERCENTAGE("Ash.WindowSelector.AnimationSmoothness.Enter",
value);
}
private:
DISALLOW_COPY_AND_ASSIGN(OverviewEnterMetricsReporter);
};
class OverviewExitMetricsReporter : public ui::AnimationMetricsReporter {
public:
OverviewExitMetricsReporter() = default;
~OverviewExitMetricsReporter() override = default;
void Report(int value) override {
UMA_HISTOGRAM_PERCENTAGE("Ash.WindowSelector.AnimationSmoothness.Exit",
value);
}
private:
DISALLOW_COPY_AND_ASSIGN(OverviewExitMetricsReporter);
};
class OverviewCloseMetricsReporter : public ui::AnimationMetricsReporter {
public:
OverviewCloseMetricsReporter() = default;
~OverviewCloseMetricsReporter() override = default;
void Report(int value) override {
UMA_HISTOGRAM_PERCENTAGE("Ash.WindowSelector.AnimationSmoothness.Close",
value);
UMA_HISTOGRAM_PERCENTAGE_IN_CLAMSHELL(
"Ash.Overview.AnimationSmoothness.Close.ClamshellMode", value);
UMA_HISTOGRAM_PERCENTAGE_IN_TABLET(
"Ash.Overview.AnimationSmoothness.Close.TabletMode", value);
}
private:
DISALLOW_COPY_AND_ASSIGN(OverviewCloseMetricsReporter);
};
base::LazyInstance<OverviewEnterMetricsReporter>::Leaky g_reporter_enter =
LAZY_INSTANCE_INITIALIZER;
base::LazyInstance<OverviewExitMetricsReporter>::Leaky g_reporter_exit =
LAZY_INSTANCE_INITIALIZER;
base::LazyInstance<OverviewCloseMetricsReporter>::Leaky g_reporter_close =
LAZY_INSTANCE_INITIALIZER;
ui::AnimationMetricsReporter* GetMetricsReporter(
OverviewAnimationType animation_type) {
switch (animation_type) {
case OVERVIEW_ANIMATION_NONE:
case OVERVIEW_ANIMATION_LAYOUT_OVERVIEW_ITEMS_IN_OVERVIEW:
case OVERVIEW_ANIMATION_DROP_TARGET_FADE_IN:
case OVERVIEW_ANIMATION_NO_RECENTS_FADE:
case OVERVIEW_ANIMATION_SELECTION_WINDOW_SHADOW:
case OVERVIEW_ANIMATION_SELECTION_WINDOW:
return nullptr;
case OVERVIEW_ANIMATION_ENTER_OVERVIEW_MODE_FADE_IN:
case OVERVIEW_ANIMATION_LAYOUT_OVERVIEW_ITEMS_ON_ENTER:
case OVERVIEW_ANIMATION_ENTER_FROM_HOME_LAUNCHER:
return g_reporter_enter.Pointer();
case OVERVIEW_ANIMATION_EXIT_OVERVIEW_MODE_FADE_OUT:
case OVERVIEW_ANIMATION_RESTORE_WINDOW:
case OVERVIEW_ANIMATION_RESTORE_WINDOW_ZERO:
case OVERVIEW_ANIMATION_LAYOUT_OVERVIEW_ITEMS_ON_EXIT:
case OVERVIEW_ANIMATION_EXIT_TO_HOME_LAUNCHER:
return g_reporter_exit.Pointer();
case OVERVIEW_ANIMATION_CLOSING_OVERVIEW_ITEM:
case OVERVIEW_ANIMATION_CLOSE_OVERVIEW_ITEM:
return g_reporter_close.Pointer();
}
NOTREACHED();
return nullptr;
}
} // namespace
ScopedOverviewAnimationSettings::ScopedOverviewAnimationSettings(
OverviewAnimationType animation_type,
aura::Window* window)
: ScopedOverviewAnimationSettings(animation_type,
window->layer()->GetAnimator()) {}
ScopedOverviewAnimationSettings::ScopedOverviewAnimationSettings(
OverviewAnimationType animation_type,
ui::LayerAnimator* animator)
: animation_settings_(
std::make_unique<ui::ScopedLayerAnimationSettings>(animator)) {
switch (animation_type) {
case OVERVIEW_ANIMATION_NONE:
animation_settings_->SetPreemptionStrategy(
ui::LayerAnimator::REPLACE_QUEUED_ANIMATIONS);
break;
case OVERVIEW_ANIMATION_ENTER_OVERVIEW_MODE_FADE_IN:
animation_settings_->SetTweenType(gfx::Tween::FAST_OUT_SLOW_IN);
animation_settings_->SetPreemptionStrategy(
ui::LayerAnimator::REPLACE_QUEUED_ANIMATIONS);
animator->SchedulePauseForProperties(kFadeInDelay,
ui::LayerAnimationElement::OPACITY);
break;
case OVERVIEW_ANIMATION_EXIT_OVERVIEW_MODE_FADE_OUT:
animation_settings_->SetTweenType(gfx::Tween::FAST_OUT_SLOW_IN);
animation_settings_->SetPreemptionStrategy(
ui::LayerAnimator::REPLACE_QUEUED_ANIMATIONS);
break;
case OVERVIEW_ANIMATION_LAYOUT_OVERVIEW_ITEMS_ON_ENTER:
case OVERVIEW_ANIMATION_LAYOUT_OVERVIEW_ITEMS_IN_OVERVIEW:
case OVERVIEW_ANIMATION_LAYOUT_OVERVIEW_ITEMS_ON_EXIT:
case OVERVIEW_ANIMATION_RESTORE_WINDOW:
animation_settings_->SetTweenType(gfx::Tween::EASE_OUT);
animation_settings_->SetPreemptionStrategy(
ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
break;
case OVERVIEW_ANIMATION_RESTORE_WINDOW_ZERO:
animation_settings_->SetTweenType(gfx::Tween::ZERO);
animation_settings_->SetPreemptionStrategy(
ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
break;
case OVERVIEW_ANIMATION_CLOSING_OVERVIEW_ITEM:
case OVERVIEW_ANIMATION_CLOSE_OVERVIEW_ITEM:
animation_settings_->SetTweenType(gfx::Tween::EASE_OUT);
animation_settings_->SetPreemptionStrategy(
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);
animator->SchedulePauseForProperties(
kFromHomeLauncherDelay, 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(
ui::LayerAnimator::REPLACE_QUEUED_ANIMATIONS);
break;
case OVERVIEW_ANIMATION_DROP_TARGET_FADE_IN:
animation_settings_->SetTweenType(gfx::Tween::EASE_IN);
animation_settings_->SetPreemptionStrategy(
ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
break;
case OVERVIEW_ANIMATION_NO_RECENTS_FADE:
case OVERVIEW_ANIMATION_SELECTION_WINDOW_SHADOW:
animation_settings_->SetTweenType(gfx::Tween::EASE_IN_OUT);
animation_settings_->SetPreemptionStrategy(
ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
break;
case OVERVIEW_ANIMATION_SELECTION_WINDOW:
animation_settings_->SetTweenType(gfx::Tween::EASE_OUT);
animation_settings_->SetPreemptionStrategy(
ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
break;
}
animation_settings_->SetTransitionDuration(
GetAnimationDuration(animation_type));
animation_settings_->SetAnimationMetricsReporter(
GetMetricsReporter(animation_type));
}
ScopedOverviewAnimationSettings::~ScopedOverviewAnimationSettings() = default;
void ScopedOverviewAnimationSettings::AddObserver(
ui::ImplicitAnimationObserver* observer) {
animation_settings_->AddObserver(observer);
}
void ScopedOverviewAnimationSettings::CacheRenderSurface() {
animation_settings_->CacheRenderSurface();
}
void ScopedOverviewAnimationSettings::DeferPaint() {
animation_settings_->DeferPaint();
}
void ScopedOverviewAnimationSettings::TrilinearFiltering() {
animation_settings_->TrilinearFiltering();
}
} // namespace ash