summaryrefslogtreecommitdiffstats
path: root/ash
diff options
context:
space:
mode:
authorjonross <jonross@chromium.org>2015-04-21 16:22:53 -0700
committerCommit bot <commit-bot@chromium.org>2015-04-21 23:23:02 +0000
commit2de2331c7193aa7777b753c9253c86103e55cc91 (patch)
treeb2cd41af870c531b5b0ad375b13ef9dd19f2cd9a /ash
parent130bc21cf23c049c0b567a456145376ecd7b8444 (diff)
downloadchromium_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.cc39
-rw-r--r--ash/system/tray/tray_background_view.cc10
-rw-r--r--ash/system/tray/tray_background_view.h1
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.