1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
  132
  133
  134
  135
  136
  137
  138
  139
  140
  141
  142
  143
  144
  145
  146
  147
  148
  149
  150
  151
  152
  153
  154
  155
  156
  157
  158
  159
  160
  161
  162
  163
  164
  165
  166
  167
  168
  169
  170
  171
  172
  173
  174
  175
  176
  177
  178
  179
  180
  181
  182
  183
  184
  185
  186
  187
  188
  189
  190
  191
  192
  193
  194
  195
  196
  197
  198
  199
  200
  201
  202
  203
  204
  205
  206
  207
  208
  209
  210
  211
  212
  213
  214
  215
  216
  217
  218
  219
  220
  221
  222
  223
  224
  225
  226
  227
  228
  229
  230

ash / wm / overview / scoped_overview_animation_settings.cc [blame]

// Copyright 2014 The Chromium Authors
// 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/public/cpp/metrics_util.h"
#include "ash/wm/overview/overview_constants.h"
#include "base/functional/bind.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::Milliseconds(100);

// The time duration for scaling down when an item is closed.
constexpr base::TimeDelta kCloseScale = base::Milliseconds(100);

// The time duration for widgets to fade in.
constexpr base::TimeDelta kFadeInDelay = base::Milliseconds(83);
constexpr base::TimeDelta kFadeIn = base::Milliseconds(167);

// The time duration for informed restore dialog to fade in.
constexpr base::TimeDelta kShowInformedRestoreDialog = base::Milliseconds(800);

// The time duration for widgets to fade out.
constexpr base::TimeDelta kFadeOut = base::Milliseconds(100);

// The time duration for birch bar to fade out.
constexpr base::TimeDelta kBirchBarFadeOut = base::Milliseconds(50);

constexpr base::TimeDelta kFromHomeLauncherDelay = base::Milliseconds(250);
constexpr base::TimeDelta kHomeLauncherTransition = base::Milliseconds(350);

// Time duration of the show animation of the drop target.
constexpr base::TimeDelta kDropTargetFade = base::Milliseconds(250);

// Time duration to fade in overview windows when a window drag slows down or
// stops.
constexpr base::TimeDelta kFadeInOnWindowDrag = base::Milliseconds(350);

constexpr base::TimeDelta kWindowRestoreDuration = base::Milliseconds(350);

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_SHOW_INFORMED_RESTORE_DIALOG_ON_ENTER:
      return kShowInformedRestoreDialog;
    case OVERVIEW_ANIMATION_LAYOUT_OVERVIEW_ITEMS_ON_EXIT:
      return kWindowRestoreDuration;
    case OVERVIEW_ANIMATION_LAYOUT_OVERVIEW_ITEMS_ON_ENTER:
    case OVERVIEW_ANIMATION_LAYOUT_OVERVIEW_ITEMS_IN_OVERVIEW:
    case OVERVIEW_ANIMATION_RESTORE_WINDOW:
    case OVERVIEW_ANIMATION_RESTORE_WINDOW_ZERO:
    case OVERVIEW_ANIMATION_SPAWN_ITEM_IN_OVERVIEW:
      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:
      return kDropTargetFade;
    case OVERVIEW_ANIMATION_NO_RECENTS_FADE:
      return kTransition;
    case OVERVIEW_ANIMATION_OPACITY_ON_WINDOW_DRAG:
      return kFadeInOnWindowDrag;
    case OVERVIEW_ANIMATION_EXIT_OVERVIEW_MODE_SAVED_DESK_GRID_FADE_OUT:
      return kFadeOut;
    case OVERVIEW_ANIMATION_EXIT_OVERVIEW_MODE_BIRCH_BAR_FADE_OUT:
      return kBirchBarFadeOut;
  }
}

void ReportCloseSmoothness(int smoothness) {
  UMA_HISTOGRAM_PERCENTAGE_IN_CLAMSHELL(
      "Ash.Overview.AnimationSmoothness.Close.ClamshellMode", smoothness);
  UMA_HISTOGRAM_PERCENTAGE_IN_TABLET(
      "Ash.Overview.AnimationSmoothness.Close.TabletMode", smoothness);
}

}  // 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_SHOW_INFORMED_RESTORE_DIALOG_ON_ENTER:
      animation_settings_->SetTweenType(gfx::Tween::EASE_IN_OUT_EMPHASIZED);
      animation_settings_->SetPreemptionStrategy(
          ui::LayerAnimator::REPLACE_QUEUED_ANIMATIONS);
      break;
    case OVERVIEW_ANIMATION_LAYOUT_OVERVIEW_ITEMS_ON_EXIT:
      animation_settings_->SetTweenType(gfx::Tween::ACCEL_20_DECEL_100);
      animation_settings_->SetPreemptionStrategy(
          ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
      break;
    case OVERVIEW_ANIMATION_LAYOUT_OVERVIEW_ITEMS_ON_ENTER:
    case OVERVIEW_ANIMATION_LAYOUT_OVERVIEW_ITEMS_IN_OVERVIEW:
    case OVERVIEW_ANIMATION_RESTORE_WINDOW:
    case OVERVIEW_ANIMATION_SPAWN_ITEM_IN_OVERVIEW:
      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);
      // Add animation delay when entering from home launcher.
      animator->SchedulePauseForProperties(kFromHomeLauncherDelay,
                                           ui::LayerAnimationElement::OPACITY);
      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:
      animation_settings_->SetTweenType(gfx::Tween::EASE_IN);
      animation_settings_->SetPreemptionStrategy(
          ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
      break;
    case OVERVIEW_ANIMATION_NO_RECENTS_FADE:
      animation_settings_->SetTweenType(gfx::Tween::EASE_IN_OUT);
      animation_settings_->SetPreemptionStrategy(
          ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
      break;
    case OVERVIEW_ANIMATION_OPACITY_ON_WINDOW_DRAG:
      animation_settings_->SetTweenType(gfx::Tween::FAST_OUT_SLOW_IN);
      animation_settings_->SetPreemptionStrategy(
          ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
      break;
    case OVERVIEW_ANIMATION_EXIT_OVERVIEW_MODE_SAVED_DESK_GRID_FADE_OUT:
      animation_settings_->SetTweenType(gfx::Tween::LINEAR);
      animation_settings_->SetPreemptionStrategy(
          ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
      break;
    case OVERVIEW_ANIMATION_EXIT_OVERVIEW_MODE_BIRCH_BAR_FADE_OUT:
      animation_settings_->SetTweenType(gfx::Tween::LINEAR);
      animation_settings_->SetPreemptionStrategy(
          ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
      break;
  }
  animation_settings_->SetTransitionDuration(
      GetAnimationDuration(animation_type));
  if (animation_type == OVERVIEW_ANIMATION_CLOSING_OVERVIEW_ITEM ||
      animation_type == OVERVIEW_ANIMATION_CLOSE_OVERVIEW_ITEM) {
    close_reporter_.emplace(animation_settings_->GetAnimator(),
                            metrics_util::ForSmoothnessV3(
                                base::BindRepeating(&ReportCloseSmoothness)));
  }
}

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();
}

ui::LayerAnimator* ScopedOverviewAnimationSettings::GetAnimator() {
  return animation_settings_->GetAnimator();
}

}  // namespace ash