diff options
author | jonross <jonross@chromium.org> | 2015-04-21 16:22:53 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-04-21 23:23:02 +0000 |
commit | 2de2331c7193aa7777b753c9253c86103e55cc91 (patch) | |
tree | b2cd41af870c531b5b0ad375b13ef9dd19f2cd9a /ash | |
parent | 130bc21cf23c049c0b567a456145376ecd7b8444 (diff) | |
download | chromium_src-2de2331c7193aa7777b753c9253c86103e55cc91.zip chromium_src-2de2331c7193aa7777b753c9253c86103e55cc91.tar.gz chromium_src-2de2331c7193aa7777b753c9253c86103e55cc91.tar.bz2 |
Prevent incorrect OverviewButton hiding states.
When exiting Maximize Mode the OverviewButton animates itself hiding. However
now any screen rotations occurring during this mode switch are also animated.
ScreenRotationAnimator copies the old layers, and deletes them upon the
completion of its animation. This can lead to layers being deleted while still
animating, without notifying their observers.
Update TrayBackgroundView to be notified when observed layers are deleted while
animating.
TEST=OverviewButtonTrayTest.HideAnimationAlwaysCompletes
BUG=476667
Review URL: https://codereview.chromium.org/1080633007
Cr-Commit-Position: refs/heads/master@{#326167}
Diffstat (limited to 'ash')
-rw-r--r-- | ash/system/overview/overview_button_tray_unittest.cc | 39 | ||||
-rw-r--r-- | ash/system/tray/tray_background_view.cc | 10 | ||||
-rw-r--r-- | ash/system/tray/tray_background_view.h | 1 |
3 files changed, 50 insertions, 0 deletions
diff --git a/ash/system/overview/overview_button_tray_unittest.cc b/ash/system/overview/overview_button_tray_unittest.cc index 8a6fc5e..516a5ba 100644 --- a/ash/system/overview/overview_button_tray_unittest.cc +++ b/ash/system/overview/overview_button_tray_unittest.cc @@ -4,8 +4,10 @@ #include "ash/system/overview/overview_button_tray.h" +#include "ash/ash_switches.h" #include "ash/display/display_manager.h" #include "ash/root_window_controller.h" +#include "ash/rotator/screen_rotation_animator.h" #include "ash/shelf/shelf_types.h" #include "ash/shelf/shelf_widget.h" #include "ash/shell.h" @@ -15,7 +17,9 @@ #include "ash/test/status_area_widget_test_helper.h" #include "ash/wm/maximize_mode/maximize_mode_controller.h" #include "ash/wm/overview/window_selector_controller.h" +#include "base/command_line.h" #include "base/time/time.h" +#include "ui/compositor/scoped_animation_duration_scale_mode.h" #include "ui/events/event.h" #include "ui/events/event_constants.h" #include "ui/events/gestures/gesture_types.h" @@ -42,6 +46,8 @@ class OverviewButtonTrayTest : public test::AshTestBase { OverviewButtonTrayTest() {} ~OverviewButtonTrayTest() override {} + void SetUp() override; + protected: views::ImageView* GetImageView(OverviewButtonTray* tray) { return tray->icon_; @@ -51,6 +57,14 @@ class OverviewButtonTrayTest : public test::AshTestBase { DISALLOW_COPY_AND_ASSIGN(OverviewButtonTrayTest); }; +void OverviewButtonTrayTest::SetUp() { + base::CommandLine::ForCurrentProcess()->AppendSwitch( + switches::kAshUseFirstDisplayAsInternal); + base::CommandLine::ForCurrentProcess()->AppendSwitch( + switches::kAshEnableScreenRotationAnimation); + AshTestBase::SetUp(); +} + // Ensures that creation doesn't cause any crashes and adds the image icon. TEST_F(OverviewButtonTrayTest, BasicConstruction) { EXPECT_TRUE(GetImageView(GetTray()) != NULL); @@ -156,4 +170,29 @@ TEST_F(OverviewButtonTrayTest, ActiveStateOnlyDuringOverviewMode) { EXPECT_FALSE(GetTray()->draw_background_as_active()); } +// Test that when a hide animation is aborted via deletion, that the +// OverviewButton is still hidden. +TEST_F(OverviewButtonTrayTest, HideAnimationAlwaysCompletes) { + Shell::GetInstance() + ->maximize_mode_controller() + ->EnableMaximizeModeWindowManager(true); + + // Long duration for hide animation, to allow it to be interrupted. + scoped_ptr<ui::ScopedAnimationDurationScaleMode> hide_duration( + new ui::ScopedAnimationDurationScaleMode( + ui::ScopedAnimationDurationScaleMode::SLOW_DURATION)); + GetTray()->SetVisible(false); + + // ScreenRotationAnimator copies the current layers, and deletes them upon + // completion. Allow its animation to complete first. + scoped_ptr<ui::ScopedAnimationDurationScaleMode> rotate_duration( + new ui::ScopedAnimationDurationScaleMode( + ui::ScopedAnimationDurationScaleMode::ZERO_DURATION)); + ash::ScreenRotationAnimator(gfx::Display::InternalDisplayId()) + .Rotate(gfx::Display::ROTATE_270); + + RunAllPendingInMessageLoop(); + EXPECT_FALSE(GetTray()->visible()); +} + } // namespace ash diff --git a/ash/system/tray/tray_background_view.cc b/ash/system/tray/tray_background_view.cc index 9b4afd3..53e116f 100644 --- a/ash/system/tray/tray_background_view.cc +++ b/ash/system/tray/tray_background_view.cc @@ -256,6 +256,7 @@ TrayBackgroundView::TrayBackgroundView(StatusAreaWidget* status_area_widget) TrayBackgroundView::~TrayBackgroundView() { if (GetWidget()) GetWidget()->RemoveObserver(widget_observer_.get()); + StopObservingImplicitAnimations(); } void TrayBackgroundView::Initialize() { @@ -439,6 +440,15 @@ void TrayBackgroundView::OnImplicitAnimationsCompleted() { views::View::SetVisible(false); } +bool TrayBackgroundView::RequiresNotificationWhenAnimatorDestroyed() const { + // This is needed so that OnImplicitAnimationsCompleted() is called even upon + // destruction of the animator. This can occure when parallel animations + // caused by ScreenRotationAnimator end before the animations of + // TrayBackgroundView. This allows for a proper update to the visual state of + // the view. (crbug.com/476667) + return true; +} + void TrayBackgroundView::HideTransformation() { gfx::Transform transform; if (shelf_alignment_ == SHELF_ALIGNMENT_BOTTOM || diff --git a/ash/system/tray/tray_background_view.h b/ash/system/tray/tray_background_view.h index b424cfc..f1562b7 100644 --- a/ash/system/tray/tray_background_view.h +++ b/ash/system/tray/tray_background_view.h @@ -158,6 +158,7 @@ class ASH_EXPORT TrayBackgroundView : public ActionableView, // ui::ImplicitAnimationObserver: void OnImplicitAnimationsCompleted() override; + bool RequiresNotificationWhenAnimatorDestroyed() const override; // Applies transformations to the |layer()| to animate the view when // SetVisible(false) is called. |