Commit 5982f8d2 authored by Sammie Quon's avatar Sammie Quon Committed by Commit Bot

overview: Move blur logic to separate file.

We are gonna add a flag to introduce a new type of blur animation on
the wallpaper for overview usages. This is a start to make the logics
more encapsulated. No functional changes.

Test: ash_unittests
Bug: none
Change-Id: I98ef63f957f6ebbcc2315a0f9472fcc536128c09
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1838683
Commit-Queue: Sammie Quon <sammiequon@chromium.org>
Reviewed-by: default avatarXiaoqian Dai <xdai@chromium.org>
Cr-Commit-Position: refs/heads/master@{#702995}
parent abaf4c65
......@@ -1185,6 +1185,8 @@ component("ash") {
"wm/overview/overview_test_api.cc",
"wm/overview/overview_utils.cc",
"wm/overview/overview_utils.h",
"wm/overview/overview_wallpaper_controller.cc",
"wm/overview/overview_wallpaper_controller.h",
"wm/overview/overview_window_drag_controller.cc",
"wm/overview/overview_window_drag_controller.h",
"wm/overview/rounded_label_widget.cc",
......
......@@ -7,16 +7,10 @@
#include <algorithm>
#include <utility>
#include "ash/app_list/app_list_controller_impl.h"
#include "ash/keyboard/ui/keyboard_ui_controller.h"
#include "ash/public/cpp/window_properties.h"
#include "ash/root_window_controller.h"
#include "ash/scoped_animation_disabler.h"
#include "ash/session/session_controller_impl.h"
#include "ash/shell.h"
#include "ash/wallpaper/wallpaper_controller_impl.h"
#include "ash/wallpaper/wallpaper_view.h"
#include "ash/wallpaper/wallpaper_widget_controller.h"
#include "ash/wm/mru_window_tracker.h"
#include "ash/wm/overview/delayed_animation_observer_impl.h"
#include "ash/wm/overview/overview_constants.h"
......@@ -24,6 +18,7 @@
#include "ash/wm/overview/overview_item.h"
#include "ash/wm/overview/overview_session.h"
#include "ash/wm/overview/overview_utils.h"
#include "ash/wm/overview/overview_wallpaper_controller.h"
#include "ash/wm/screen_pinning_controller.h"
#include "ash/wm/splitview/split_view_controller.h"
#include "ash/wm/splitview/split_view_utils.h"
......@@ -35,9 +30,8 @@
#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"
#include "base/threading/thread_task_runner_handle.h"
#include "ui/views/widget/widget.h"
#include "ui/wm/core/window_util.h"
#include "ui/wm/public/activation_client.h"
......@@ -45,12 +39,6 @@ namespace ash {
namespace {
// Do not change the wallpaper when entering or exiting overview mode when this
// is true.
bool g_disable_wallpaper_change_for_tests = false;
constexpr int kBlurSlideDurationMs = 250;
// It can take up to two frames until the frame created in the UI thread that
// triggered animation observer is drawn. Wait 50ms in attempt to let its draw
// and swap finish.
......@@ -62,11 +50,6 @@ constexpr base::TimeDelta kOcclusionPauseDurationForStart =
constexpr base::TimeDelta kOcclusionPauseDurationForEnd =
base::TimeDelta::FromMilliseconds(500);
bool IsWallpaperChangeAllowed() {
return !g_disable_wallpaper_change_for_tests &&
Shell::Get()->wallpaper_controller()->IsBlurAllowed();
}
// Returns whether overview mode items should be slid in or out from the top of
// the screen.
bool ShouldSlideInOutOverview(const std::vector<aura::Window*>& windows) {
......@@ -89,173 +72,6 @@ bool ShouldSlideInOutOverview(const std::vector<aura::Window*>& windows) {
} // namespace
// Class that handles of blurring and dimming wallpaper upon entering and
// exiting overview mode. Blurs the wallpaper automatically if the wallpaper is
// not visible prior to entering overview mode (covered by a window), otherwise
// animates the blur and dim.
class OverviewController::OverviewWallpaperController
: public ui::CompositorAnimationObserver,
public aura::WindowObserver {
public:
OverviewWallpaperController() = default;
~OverviewWallpaperController() override {
if (compositor_)
compositor_->RemoveAnimationObserver(this);
for (aura::Window* root : roots_to_animate_)
root->RemoveObserver(this);
}
void Blur(bool animate_only) {
OnBlurChange(WallpaperAnimationState::kAddingBlur, animate_only);
}
void Unblur() {
OnBlurChange(WallpaperAnimationState::kRemovingBlur,
/*animate_only=*/false);
}
bool has_blur() const { return state_ != WallpaperAnimationState::kNormal; }
bool has_blur_animation() const { return !!compositor_; }
private:
enum class WallpaperAnimationState {
kAddingBlur,
kRemovingBlur,
kNormal,
};
void OnAnimationStep(base::TimeTicks timestamp) override {
if (start_time_ == base::TimeTicks()) {
start_time_ = timestamp;
return;
}
const float progress = (timestamp - start_time_).InMilliseconds() /
static_cast<float>(kBlurSlideDurationMs);
const bool adding = state_ == WallpaperAnimationState::kAddingBlur;
if (progress > 1.0f) {
AnimationProgressed(adding ? 1.0f : 0.f);
Stop();
} else {
AnimationProgressed(adding ? progress : 1.f - progress);
}
}
void OnCompositingShuttingDown(ui::Compositor* compositor) override {
if (compositor_ == compositor)
Stop();
}
void Stop() {
if (compositor_) {
compositor_->RemoveAnimationObserver(this);
compositor_ = nullptr;
}
state_ = WallpaperAnimationState::kNormal;
}
void Start() {
DCHECK(!compositor_);
compositor_ = Shell::GetPrimaryRootWindow()->GetHost()->compositor();
compositor_->AddAnimationObserver(this);
start_time_ = base::TimeTicks();
}
void AnimationProgressed(float value) {
// Animate only to even numbers to reduce the load.
int ivalue = static_cast<int>(value * kWallpaperBlurSigma) / 2 * 2;
for (aura::Window* root : roots_to_animate_)
ApplyBlurAndOpacity(root, ivalue);
}
// aura::WindowObserver:
void OnWindowDestroying(aura::Window* window) override {
window->RemoveObserver(this);
auto it =
std::find(roots_to_animate_.begin(), roots_to_animate_.end(), window);
if (it != roots_to_animate_.end())
roots_to_animate_.erase(it);
}
void ApplyBlurAndOpacity(aura::Window* root, int value) {
DCHECK_GE(value, 0);
DCHECK_LE(value, 10);
const float opacity =
gfx::Tween::FloatValueBetween(value / 10.0, 1.f, kShieldOpacity);
auto* wallpaper_widget_controller =
RootWindowController::ForWindow(root)->wallpaper_widget_controller();
if (wallpaper_widget_controller->wallpaper_view()) {
wallpaper_widget_controller->wallpaper_view()->RepaintBlurAndOpacity(
value, opacity);
}
}
// Called when the wallpaper is to be changed. Checks to see which root
// windows should have their wallpaper blurs animated and fills
// |roots_to_animate_| accordingly. Applys blur or unblur immediately if
// the wallpaper does not need blur animation.
// When |animate_only| is true, it'll apply blur only to the root windows that
// requires animation.
void OnBlurChange(WallpaperAnimationState state, bool animate_only) {
Stop();
for (aura::Window* root : roots_to_animate_)
root->RemoveObserver(this);
roots_to_animate_.clear();
state_ = state;
const bool should_blur = state_ == WallpaperAnimationState::kAddingBlur;
if (animate_only)
DCHECK(should_blur);
const float value =
should_blur ? kWallpaperBlurSigma : kWallpaperClearBlurSigma;
OverviewSession* overview_session =
Shell::Get()->overview_controller()->overview_session();
for (aura::Window* root : Shell::Get()->GetAllRootWindows()) {
// No need to animate the blur on exiting as this should only be called
// after overview animations are finished.
if (should_blur) {
DCHECK(overview_session);
OverviewGrid* grid = overview_session->GetGridWithRootWindow(root);
bool should_animate = grid && grid->ShouldAnimateWallpaper();
auto* wallpaper_view = RootWindowController::ForWindow(root)
->wallpaper_widget_controller()
->wallpaper_view();
float blur_sigma =
wallpaper_view ? wallpaper_view->repaint_blur() : 0.f;
if (should_animate && animate_only &&
blur_sigma != kWallpaperBlurSigma) {
root->AddObserver(this);
roots_to_animate_.push_back(root);
continue;
}
if (should_animate == animate_only)
ApplyBlurAndOpacity(root, value);
} else {
ApplyBlurAndOpacity(root, value);
}
}
// Run the animation if one of the roots needs to be animated.
if (roots_to_animate_.empty())
state_ = WallpaperAnimationState::kNormal;
else
Start();
}
ui::Compositor* compositor_ = nullptr;
base::TimeTicks start_time_;
WallpaperAnimationState state_ = WallpaperAnimationState::kNormal;
// Vector which contains the root windows, if any, whose wallpaper should have
// blur animated after Blur or Unblur is called.
std::vector<aura::Window*> roots_to_animate_;
DISALLOW_COPY_AND_ASSIGN(OverviewWallpaperController);
};
OverviewController::OverviewController()
: occlusion_pause_duration_for_end_(kOcclusionPauseDurationForEnd),
overview_wallpaper_controller_(
......@@ -664,7 +480,6 @@ void OverviewController::ToggleOverview(
for (auto& observer : observers_)
observer.OnOverviewModeStarting();
overview_session_->Init(windows, hide_windows);
if (IsWallpaperChangeAllowed())
overview_wallpaper_controller_->Blur(/*animate_only=*/false);
// For app dragging, there are no start animations so add a delay to delay
......@@ -687,11 +502,6 @@ void OverviewController::ToggleOverview(
}
}
// static
void OverviewController::SetDoNotChangeWallpaperForTests() {
g_disable_wallpaper_change_for_tests = true;
}
bool OverviewController::CanEnterOverview() {
// Prevent toggling overview during the split view divider snap animation.
if (Shell::Get()->split_view_controller()->IsDividerAnimating())
......@@ -733,7 +543,7 @@ bool OverviewController::CanEndOverview(
}
void OverviewController::OnStartingAnimationComplete(bool canceled) {
if (IsWallpaperChangeAllowed() && !canceled)
if (!canceled)
overview_wallpaper_controller_->Blur(/*animate_only=*/true);
for (auto& observer : observers_)
......@@ -751,7 +561,7 @@ void OverviewController::OnEndingAnimationComplete(bool canceled) {
// Unblur when animation is completed (or right away if there was no
// delayed animation) unless it's canceled, in which case, we should keep
// the blur.
if (IsWallpaperChangeAllowed() && !canceled)
if (!canceled)
overview_wallpaper_controller_->Unblur();
for (auto& observer : observers_)
......
......@@ -21,6 +21,8 @@
namespace ash {
class OverviewWallpaperController;
// Manages a overview session which displays an overview of all windows and
// allows selecting a window to activate it.
class ASH_EXPORT OverviewController : public OverviewDelegate,
......@@ -110,7 +112,6 @@ class ASH_EXPORT OverviewController : public OverviewDelegate,
std::vector<aura::Window*> GetItemWindowListInOverviewGridsForTest();
private:
class OverviewWallpaperController;
friend class OverviewSessionTest;
FRIEND_TEST_ALL_PREFIXES(TabletModeControllerTest,
DisplayDisconnectionDuringOverview);
......@@ -120,9 +121,6 @@ class ASH_EXPORT OverviewController : public OverviewDelegate,
void ToggleOverview(OverviewSession::EnterExitOverviewType type =
OverviewSession::EnterExitOverviewType::kNormal);
// There is no need to blur or dim the wallpaper for tests.
static void SetDoNotChangeWallpaperForTests();
// Returns true if it's possible to enter or exit overview mode in the current
// configuration. This can be false at certain times, such as when the lock
// screen is visible we can't overview mode.
......
......@@ -38,6 +38,7 @@
#include "ash/wm/overview/overview_item.h"
#include "ash/wm/overview/overview_test_util.h"
#include "ash/wm/overview/overview_utils.h"
#include "ash/wm/overview/overview_wallpaper_controller.h"
#include "ash/wm/overview/overview_window_drag_controller.h"
#include "ash/wm/overview/rounded_label_widget.h"
#include "ash/wm/overview/rounded_rect_view.h"
......@@ -157,7 +158,7 @@ class OverviewSessionTest : public MultiDisplayOverviewAndSplitViewTest {
shelf_view_test_api_->SetAnimationDuration(
base::TimeDelta::FromMilliseconds(1));
ScopedOverviewTransformWindow::SetImmediateCloseForTests();
OverviewController::SetDoNotChangeWallpaperForTests();
OverviewWallpaperController::SetDoNotChangeWallpaperForTests();
FpsCounter::SetForceReportZeroAnimationForTest(true);
ash::PresentationTimeRecorder::SetReportPresentationTimeImmediatelyForTest(
true);
......
// Copyright 2019 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/overview_wallpaper_controller.h"
#include "ash/root_window_controller.h"
#include "ash/shell.h"
#include "ash/wallpaper/wallpaper_controller_impl.h"
#include "ash/wallpaper/wallpaper_view.h"
#include "ash/wallpaper/wallpaper_widget_controller.h"
#include "ash/wm/overview/overview_constants.h"
#include "ash/wm/overview/overview_controller.h"
#include "ash/wm/overview/overview_grid.h"
#include "ui/aura/window_tree_host.h"
namespace ash {
namespace {
// Do not change the wallpaper when entering or exiting overview mode when this
// is true.
bool g_disable_wallpaper_change_for_tests = false;
constexpr int kBlurSlideDurationMs = 250;
bool IsWallpaperChangeAllowed() {
return !g_disable_wallpaper_change_for_tests &&
Shell::Get()->wallpaper_controller()->IsBlurAllowed();
}
} // namespace
OverviewWallpaperController::OverviewWallpaperController() = default;
OverviewWallpaperController::~OverviewWallpaperController() {
if (compositor_)
compositor_->RemoveAnimationObserver(this);
for (aura::Window* root : roots_to_animate_)
root->RemoveObserver(this);
}
// static
void OverviewWallpaperController::SetDoNotChangeWallpaperForTests() {
g_disable_wallpaper_change_for_tests = true;
}
void OverviewWallpaperController::Blur(bool animate_only) {
if (!IsWallpaperChangeAllowed())
return;
OnBlurChange(WallpaperAnimationState::kAddingBlur, animate_only);
}
void OverviewWallpaperController::Unblur() {
if (!IsWallpaperChangeAllowed())
return;
OnBlurChange(WallpaperAnimationState::kRemovingBlur,
/*animate_only=*/false);
}
void OverviewWallpaperController::Stop() {
if (compositor_) {
compositor_->RemoveAnimationObserver(this);
compositor_ = nullptr;
}
state_ = WallpaperAnimationState::kNormal;
}
void OverviewWallpaperController::Start() {
DCHECK(!compositor_);
compositor_ = Shell::GetPrimaryRootWindow()->GetHost()->compositor();
compositor_->AddAnimationObserver(this);
start_time_ = base::TimeTicks();
}
void OverviewWallpaperController::AnimationProgressed(float value) {
// Animate only to even numbers to reduce the load.
int ivalue = static_cast<int>(value * kWallpaperBlurSigma) / 2 * 2;
for (aura::Window* root : roots_to_animate_)
ApplyBlurAndOpacity(root, ivalue);
}
void OverviewWallpaperController::OnAnimationStep(base::TimeTicks timestamp) {
if (start_time_ == base::TimeTicks()) {
start_time_ = timestamp;
return;
}
const float progress = (timestamp - start_time_).InMilliseconds() /
static_cast<float>(kBlurSlideDurationMs);
const bool adding = state_ == WallpaperAnimationState::kAddingBlur;
if (progress > 1.0f) {
AnimationProgressed(adding ? 1.0f : 0.f);
Stop();
} else {
AnimationProgressed(adding ? progress : 1.f - progress);
}
}
void OverviewWallpaperController::OnCompositingShuttingDown(
ui::Compositor* compositor) {
if (compositor_ == compositor)
Stop();
}
void OverviewWallpaperController::OnWindowDestroying(aura::Window* window) {
window->RemoveObserver(this);
auto it =
std::find(roots_to_animate_.begin(), roots_to_animate_.end(), window);
if (it != roots_to_animate_.end())
roots_to_animate_.erase(it);
}
void OverviewWallpaperController::ApplyBlurAndOpacity(aura::Window* root,
int value) {
DCHECK_GE(value, 0);
DCHECK_LE(value, 10);
const float opacity =
gfx::Tween::FloatValueBetween(value / 10.0, 1.f, kShieldOpacity);
auto* wallpaper_widget_controller =
RootWindowController::ForWindow(root)->wallpaper_widget_controller();
if (wallpaper_widget_controller->wallpaper_view()) {
wallpaper_widget_controller->wallpaper_view()->RepaintBlurAndOpacity(
value, opacity);
}
}
void OverviewWallpaperController::OnBlurChange(WallpaperAnimationState state,
bool animate_only) {
Stop();
for (aura::Window* root : roots_to_animate_)
root->RemoveObserver(this);
roots_to_animate_.clear();
state_ = state;
const bool should_blur = state_ == WallpaperAnimationState::kAddingBlur;
if (animate_only)
DCHECK(should_blur);
const float value =
should_blur ? kWallpaperBlurSigma : kWallpaperClearBlurSigma;
OverviewSession* overview_session =
Shell::Get()->overview_controller()->overview_session();
for (aura::Window* root : Shell::Get()->GetAllRootWindows()) {
// No need to animate the blur on exiting as this should only be called
// after overview animations are finished.
if (should_blur) {
DCHECK(overview_session);
OverviewGrid* grid = overview_session->GetGridWithRootWindow(root);
bool should_animate = grid && grid->ShouldAnimateWallpaper();
auto* wallpaper_view = RootWindowController::ForWindow(root)
->wallpaper_widget_controller()
->wallpaper_view();
float blur_sigma = wallpaper_view ? wallpaper_view->repaint_blur() : 0.f;
if (should_animate && animate_only && blur_sigma != kWallpaperBlurSigma) {
root->AddObserver(this);
roots_to_animate_.push_back(root);
continue;
}
if (should_animate == animate_only)
ApplyBlurAndOpacity(root, value);
} else {
ApplyBlurAndOpacity(root, value);
}
}
// Run the animation if one of the roots needs to be animated.
if (roots_to_animate_.empty())
state_ = WallpaperAnimationState::kNormal;
else
Start();
}
} // namespace ash
// Copyright 2019 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.
#ifndef ASH_WM_OVERVIEW_OVERVIEW_WALLPAPER_CONTROLLER_H_
#define ASH_WM_OVERVIEW_OVERVIEW_WALLPAPER_CONTROLLER_H_
#include "ash/ash_export.h"
#include "base/macros.h"
#include "ui/aura/window_observer.h"
#include "ui/compositor/compositor_animation_observer.h"
namespace ui {
class Compositor;
class Window;
} // namespace ui
namespace ash {
// Class that handles of blurring and dimming wallpaper upon entering and
// exiting overview mode. Blurs the wallpaper automatically if the wallpaper is
// not visible prior to entering overview mode (covered by a window), otherwise
// animates the blur and dim.
class ASH_EXPORT OverviewWallpaperController
: public ui::CompositorAnimationObserver,
public aura::WindowObserver {
public:
OverviewWallpaperController();
~OverviewWallpaperController() override;
// There is no need to blur or dim the wallpaper for tests.
static void SetDoNotChangeWallpaperForTests();
void Blur(bool animate_only);
void Unblur();
bool has_blur() const { return state_ != WallpaperAnimationState::kNormal; }
bool has_blur_animation() const { return !!compositor_; }
private:
enum class WallpaperAnimationState {
kAddingBlur,
kRemovingBlur,
kNormal,
};
void Stop();
void Start();
void AnimationProgressed(float value);
// ui::CompositorAnimationObserver:
void OnAnimationStep(base::TimeTicks timestamp) override;
void OnCompositingShuttingDown(ui::Compositor* compositor) override;
// aura::WindowObserver:
void OnWindowDestroying(aura::Window* window) override;
void ApplyBlurAndOpacity(aura::Window* root, int value);
// Called when the wallpaper is to be changed. Checks to see which root
// windows should have their wallpaper blurs animated and fills
// |roots_to_animate_| accordingly. Applies blur or unblur immediately if
// the wallpaper does not need blur animation.
// When |animate_only| is true, it'll apply blur only to the root windows that
// requires animation.
void OnBlurChange(WallpaperAnimationState state, bool animate_only);
ui::Compositor* compositor_ = nullptr;
base::TimeTicks start_time_;
WallpaperAnimationState state_ = WallpaperAnimationState::kNormal;
// Vector which contains the root windows, if any, whose wallpaper should have
// blur animated after Blur or Unblur is called.
std::vector<aura::Window*> roots_to_animate_;
DISALLOW_COPY_AND_ASSIGN(OverviewWallpaperController);
};
} // namespace ash
#endif // ASH_WM_OVERVIEW_OVERVIEW_WALLPAPER_CONTROLLER_H_
......@@ -25,6 +25,7 @@
#include "ash/shell.h"
#include "ash/test/ash_test_base.h"
#include "ash/wm/overview/overview_controller.h"
#include "ash/wm/overview/overview_wallpaper_controller.h"
#include "ash/wm/splitview/multi_display_overview_and_split_view_test.h"
#include "ash/wm/splitview/split_view_controller.h"
#include "ash/wm/splitview/split_view_utils.h"
......@@ -546,7 +547,7 @@ TEST_P(TabletModeControllerTest, VerticalHingeTest) {
// Test if this case does not crash. See http://crbug.com/462806
TEST_P(TabletModeControllerTest, DisplayDisconnectionDuringOverview) {
// Do not animate wallpaper on entering overview.
OverviewController::SetDoNotChangeWallpaperForTests();
OverviewWallpaperController::SetDoNotChangeWallpaperForTests();
UpdateDisplay("800x600,800x600");
std::unique_ptr<aura::Window> w1(
......
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