Commit e9ce3577 authored by Alex Newcomer's avatar Alex Newcomer Committed by Commit Bot

CrOS: Prevent blur from showing during hotseat animations

This disables blur during animations, which improves the performance
of hotseat animations.

Bug: 1031266
Change-Id: I6f0fc2dc4a5a8f552d244ac5bd877761261c6799
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2044766
Commit-Queue: Alex Newcomer <newcomer@chromium.org>
Reviewed-by: default avatarAlex Newcomer <newcomer@chromium.org>
Reviewed-by: default avatarManu Cornet <manucornet@chromium.org>
Cr-Commit-Position: refs/heads/master@{#740382}
parent 67a0f6c3
......@@ -12,6 +12,7 @@
#include "ash/public/cpp/shelf_config.h"
#include "ash/public/cpp/shelf_model.h"
#include "ash/public/cpp/wallpaper_controller_observer.h"
#include "ash/shelf/hotseat_transition_animator.h"
#include "ash/shelf/scrollable_shelf_view.h"
#include "ash/shelf/shelf_layout_manager.h"
#include "ash/shelf/shelf_navigation_widget.h"
......@@ -83,7 +84,8 @@ class HotseatWindowTargeter : public aura::WindowTargeter {
} // namespace
class HotseatWidget::DelegateView : public views::WidgetDelegateView,
class HotseatWidget::DelegateView : public HotseatTransitionAnimator::Observer,
public views::WidgetDelegateView,
public WallpaperControllerObserver {
public:
explicit DelegateView(WallpaperControllerImpl* wallpaper_controller)
......@@ -102,9 +104,19 @@ class HotseatWidget::DelegateView : public views::WidgetDelegateView,
void SetTranslucentBackground(const gfx::Rect& translucent_background_bounds);
// Sets whether the background should be blurred as requested by the argument,
// unless the feature flag is disabled or |disable_blur_for_animations_| is
// true, in which case this disables background blur.
void SetBackgroundBlur(bool enable_blur);
// Updates the hotseat background when tablet mode changes.
void OnTabletModeChanged();
// HotseatTransitionAnimator::Observer:
void OnHotseatTransitionAnimationStarted(HotseatState from_state,
HotseatState to_state) override;
void OnHotseatTransitionAnimationEnded(HotseatState from_state,
HotseatState to_state) override;
// views::WidgetDelegateView:
bool CanActivate() const override;
void ReorderChildLayers(ui::Layer* parent_layer) override;
......@@ -116,6 +128,10 @@ class HotseatWidget::DelegateView : public views::WidgetDelegateView,
focus_cycler_ = focus_cycler;
}
int background_blur() const {
return translucent_background_.background_blur();
}
private:
void SetParentLayer(ui::Layer* layer);
......@@ -125,6 +141,8 @@ class HotseatWidget::DelegateView : public views::WidgetDelegateView,
ScrollableShelfView* scrollable_shelf_view_ = nullptr; // unowned.
// The WallpaperController, responsible for providing proper colors.
WallpaperControllerImpl* wallpaper_controller_;
// Blur is disabled during animations to improve performance.
bool blur_lock_ = false;
// The most recent color that the |translucent_background_| has been animated
// to.
......@@ -158,8 +176,7 @@ void HotseatWidget::DelegateView::Init(
void HotseatWidget::DelegateView::UpdateTranslucentBackground() {
if (!HotseatWidget::ShouldShowHotseatBackground()) {
translucent_background_.SetVisible(false);
if (features::IsBackgroundBlurEnabled())
translucent_background_.SetBackgroundBlur(0);
SetBackgroundBlur(false);
return;
}
......@@ -172,6 +189,7 @@ void HotseatWidget::DelegateView::SetTranslucentBackground(
DCHECK(HotseatWidget::ShouldShowHotseatBackground());
translucent_background_.SetVisible(true);
SetBackgroundBlur(/*enable_blur=*/true);
// Animate the bounds change if we're changing the background, or if there's
// a change of width (for instance when dragging an app into, or out of,
......@@ -200,17 +218,36 @@ void HotseatWidget::DelegateView::SetTranslucentBackground(
if (translucent_background_.bounds() != background_bounds)
translucent_background_.SetBounds(background_bounds);
}
if (features::IsBackgroundBlurEnabled()) {
translucent_background_.SetBackgroundBlur(
ShelfConfig::Get()->shelf_blur_radius());
}
void HotseatWidget::DelegateView::SetBackgroundBlur(bool enable_blur) {
if (!features::IsBackgroundBlurEnabled() || blur_lock_)
return;
const int blur_radius =
enable_blur ? ShelfConfig::Get()->shelf_blur_radius() : 0;
if (translucent_background_.background_blur() != blur_radius)
translucent_background_.SetBackgroundBlur(blur_radius);
}
void HotseatWidget::DelegateView::OnTabletModeChanged() {
UpdateTranslucentBackground();
}
void HotseatWidget::DelegateView::OnHotseatTransitionAnimationStarted(
HotseatState from_state,
HotseatState to_state) {
SetBackgroundBlur(false);
blur_lock_ = true;
}
void HotseatWidget::DelegateView::OnHotseatTransitionAnimationEnded(
HotseatState from_state,
HotseatState to_state) {
blur_lock_ = false;
SetBackgroundBlur(true);
}
bool HotseatWidget::DelegateView::CanActivate() const {
// We don't want mouse clicks to activate us, but we need to allow
// activation when the user is using the keyboard (FocusCycler).
......@@ -241,6 +278,8 @@ HotseatWidget::HotseatWidget()
HotseatWidget::~HotseatWidget() {
ShelfConfig::Get()->RemoveObserver(this);
shelf_->shelf_widget()->hotseat_transition_animator()->RemoveObserver(
delegate_view_);
}
bool HotseatWidget::ShouldShowHotseatBackground() {
......@@ -279,6 +318,12 @@ void HotseatWidget::Initialize(aura::Window* container, Shelf* shelf) {
delegate_view_->Init(scrollable_shelf_view(), GetLayer());
}
void HotseatWidget::OnHotseatTransitionAnimatorCreated(
HotseatTransitionAnimator* animator) {
shelf_->shelf_widget()->hotseat_transition_animator()->AddObserver(
delegate_view_);
}
void HotseatWidget::OnMouseEvent(ui::MouseEvent* event) {
if (event->type() == ui::ET_MOUSE_PRESSED)
keyboard::KeyboardUIController::Get()->HideKeyboardImplicitlyByUser();
......@@ -408,6 +453,10 @@ ShelfView* HotseatWidget::GetShelfView() {
return shelf_view_;
}
int HotseatWidget::GetHotseatBackgroundBlurForTest() const {
return delegate_view_->background_blur();
}
bool HotseatWidget::IsShowingShelfMenu() const {
return GetShelfView()->IsShowingMenu();
}
......
......@@ -21,6 +21,7 @@ class FocusCycler;
class ScrollableShelfView;
class Shelf;
class ShelfView;
class HotseatTransitionAnimator;
// The hotseat widget is part of the shelf and hosts app shortcuts.
class ASH_EXPORT HotseatWidget : public ShelfComponent,
......@@ -36,6 +37,11 @@ class ASH_EXPORT HotseatWidget : public ShelfComponent,
// Initializes the widget, sets its contents view and basic properties.
void Initialize(aura::Window* container, Shelf* shelf);
// Initializes the animation metrics reporter responsible for recording
// animation performance during hotseat state changes, and attaches
// |delegate_view_| as an observer.
void OnHotseatTransitionAnimatorCreated(HotseatTransitionAnimator* animator);
// views::Widget:
void OnMouseEvent(ui::MouseEvent* event) override;
void OnGestureEvent(ui::GestureEvent* event) override;
......@@ -82,6 +88,9 @@ class ASH_EXPORT HotseatWidget : public ShelfComponent,
ShelfView* GetShelfView();
const ShelfView* GetShelfView() const;
// Returns the background blur of the |translucent_background_| for test.
int GetHotseatBackgroundBlurForTest() const;
void SetState(HotseatState state);
HotseatState state() const { return state_; }
......
......@@ -1846,4 +1846,27 @@ TEST_P(HotseatWidgetTest, HotseatRemainsHiddenIfPopupLaunched) {
EXPECT_EQ(HotseatState::kHidden, GetShelfLayoutManager()->hotseat_state());
}
// Tests that blur is not showing during animations.
TEST_P(HotseatWidgetTest, NoBlurDuringAnimations) {
TabletModeControllerTestApi().EnterTabletMode();
ASSERT_EQ(
ShelfConfig::Get()->shelf_blur_radius(),
GetShelfWidget()->hotseat_widget()->GetHotseatBackgroundBlurForTest());
ui::ScopedAnimationDurationScaleMode regular_animations(
ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION);
// Open a window, as the hotseat animates to kHidden, it should lose its blur.
std::unique_ptr<aura::Window> window =
AshTestBase::CreateTestWindow(gfx::Rect(0, 0, 400, 400));
wm::ActivateWindow(window.get());
EXPECT_EQ(
0, GetShelfWidget()->hotseat_widget()->GetHotseatBackgroundBlurForTest());
// Wait for the animation to finish, hotseat blur should return.
ShellTestApi().WaitForWindowFinishAnimating(window.get());
EXPECT_EQ(
ShelfConfig::Get()->shelf_blur_radius(),
GetShelfWidget()->hotseat_widget()->GetHotseatBackgroundBlurForTest());
}
} // namespace ash
......@@ -504,8 +504,8 @@ ScrollableShelfView::~ScrollableShelfView() {
void ScrollableShelfView::Init() {
// Although there is no animation for ScrollableShelfView, a layer is still
// needed. Otherwise, the child view without its own layer will be painted on
// RootView and RootView is beneath |opaque_background_| in ShelfWidget. As a
// result, the child view will not show.
// RootView which is beneath |translucent_background_| in ShelfWidget.
// As a result, the child view will not show.
SetPaintToLayer();
layer()->SetFillsBoundsOpaquely(false);
......
......@@ -582,6 +582,8 @@ void ShelfWidget::RegisterHotseatWidget(HotseatWidget* hotseat_widget) {
delegate_view_->set_context_menu_controller(hotseat_widget->GetShelfView());
hotseat_transition_animator_.reset(new HotseatTransitionAnimator(this));
hotseat_transition_animator_->AddObserver(delegate_view_);
shelf_->hotseat_widget()->OnHotseatTransitionAnimatorCreated(
hotseat_transition_animator());
}
void ShelfWidget::OnTabletModeChanged() {
......
......@@ -158,7 +158,7 @@ class ASH_EXPORT ShelfWidget : public AccessibilityObserver,
return &background_animator_;
}
HotseatTransitionAnimator* hotseat_transition_animator_for_testing() {
HotseatTransitionAnimator* hotseat_transition_animator() {
return hotseat_transition_animator_.get();
}
......
......@@ -417,7 +417,7 @@ TEST_F(ShelfWidgetTest, OpaqueBackgroundAndDragHandleTransition) {
{
TransitionAnimationWaiter waiter(
GetShelfWidget()->hotseat_transition_animator_for_testing());
GetShelfWidget()->hotseat_transition_animator());
waiter.Wait();
}
......
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