summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ash/app_list/app_list.cc20
-rw-r--r--ash/app_list/app_list.h11
-rw-r--r--ash/drag_drop/drag_drop_controller.cc22
-rw-r--r--ash/drag_drop/drag_drop_controller.h13
-rw-r--r--ash/test/aura_shell_test_base.cc6
-rw-r--r--ash/wm/compact_layout_manager.cc11
-rw-r--r--ash/wm/compact_layout_manager.h11
-rw-r--r--ash/wm/shelf_layout_manager.cc56
-rw-r--r--ash/wm/shelf_layout_manager.h21
-rw-r--r--ash/wm/system_modal_container_layout_manager.cc24
-rw-r--r--ash/wm/system_modal_container_layout_manager.h11
-rw-r--r--ash/wm/system_modal_container_layout_manager_unittest.cc6
-rw-r--r--ash/wm/visibility_controller_unittest.cc4
-rw-r--r--ash/wm/window_animations.cc3
-rw-r--r--ui/aura/root_window.cc6
-rw-r--r--ui/aura/root_window.h6
-rw-r--r--ui/aura/test/aura_test_base.cc4
-rw-r--r--ui/aura/window_unittest.cc5
-rw-r--r--ui/gfx/compositor/layer_animation_observer.cc53
-rw-r--r--ui/gfx/compositor/layer_animation_observer.h58
-rw-r--r--ui/gfx/compositor/layer_animator.cc18
-rw-r--r--ui/gfx/compositor/layer_animator.h22
-rw-r--r--ui/gfx/compositor/layer_animator_unittest.cc133
-rw-r--r--ui/gfx/compositor/scoped_layer_animation_settings.cc18
-rw-r--r--ui/gfx/compositor/scoped_layer_animation_settings.h6
-rw-r--r--ui/gfx/compositor/test/test_layer_animation_observer.cc6
-rw-r--r--ui/gfx/compositor/test/test_layer_animation_observer.h6
27 files changed, 303 insertions, 257 deletions
diff --git a/ash/app_list/app_list.cc b/ash/app_list/app_list.cc
index c439bbb..ad9fd01 100644
--- a/ash/app_list/app_list.cc
+++ b/ash/app_list/app_list.cc
@@ -87,7 +87,6 @@ void AppList::SetWidget(views::Widget* widget) {
if (is_visible_) {
widget_ = widget;
- widget_->AddObserver(this);
GetLayer(widget_)->GetAnimator()->AddObserver(this);
Shell::GetInstance()->AddRootWindowEventFilter(this);
@@ -119,13 +118,19 @@ void AppList::ScheduleAnimation() {
return;
ui::Layer* layer = GetLayer(widget_);
+
+ // Stop observing previous animation.
+ StopObservingImplicitAnimations();
+
ui::ScopedLayerAnimationSettings app_list_animation(layer->GetAnimator());
+ app_list_animation.AddObserver(this);
layer->SetBounds(GetPreferredBounds(is_visible_));
layer->SetOpacity(is_visible_ ? 1.0 : 0.0);
ui::Layer* default_container_layer = default_container->layer();
ui::ScopedLayerAnimationSettings default_container_animation(
default_container_layer->GetAnimator());
+ app_list_animation.AddObserver(this);
default_container_layer->SetOpacity(is_visible_ ? 0.0 : 1.0);
}
@@ -159,22 +164,13 @@ ui::GestureStatus AppList::PreHandleGestureEvent(
}
////////////////////////////////////////////////////////////////////////////////
-// AppList, ui::LayerAnimationObserver implementation:
+// AppList, ui::ImplicitAnimationObserver implementation:
-void AppList::OnLayerAnimationEnded(
- const ui::LayerAnimationSequence* sequence) {
+void AppList::OnImplicitAnimationsCompleted() {
if (!is_visible_ )
widget_->Close();
}
-void AppList::OnLayerAnimationAborted(
- const ui::LayerAnimationSequence* sequence) {
-}
-
-void AppList::OnLayerAnimationScheduled(
- const ui::LayerAnimationSequence* sequence) {
-}
-
////////////////////////////////////////////////////////////////////////////////
// AppList, views::Widget::Observer implementation:
diff --git a/ash/app_list/app_list.h b/ash/app_list/app_list.h
index 77b2ecd..b499498 100644
--- a/ash/app_list/app_list.h
+++ b/ash/app_list/app_list.h
@@ -20,7 +20,7 @@ namespace internal {
// While the UI is visible, it monitors things such as app list widget's
// activation state and desktop mouse click to auto dismiss the UI.
class AppList : public aura::EventFilter,
- public ui::LayerAnimationObserver,
+ public ui::ImplicitAnimationObserver,
public views::Widget::Observer {
public:
AppList();
@@ -54,13 +54,8 @@ class AppList : public aura::EventFilter,
aura::Window* target,
aura::GestureEvent* event) OVERRIDE;
- // ui::LayerAnimationObserver overrides:
- virtual void OnLayerAnimationEnded(
- const ui::LayerAnimationSequence* sequence) OVERRIDE;
- virtual void OnLayerAnimationAborted(
- const ui::LayerAnimationSequence* sequence) OVERRIDE;
- virtual void OnLayerAnimationScheduled(
- const ui::LayerAnimationSequence* sequence) OVERRIDE;
+ // ui::ImplicitAnimationObserver overrides:
+ virtual void OnImplicitAnimationsCompleted() OVERRIDE;
// views::Widget::Observer overrides:
virtual void OnWidgetClosing(views::Widget* widget) OVERRIDE;
diff --git a/ash/drag_drop/drag_drop_controller.cc b/ash/drag_drop/drag_drop_controller.cc
index 2e43ea3..255b0e2 100644
--- a/ash/drag_drop/drag_drop_controller.cc
+++ b/ash/drag_drop/drag_drop_controller.cc
@@ -28,7 +28,7 @@ namespace {
const gfx::Point kDragDropWidgetOffset(0, 0);
const base::TimeDelta kDragDropAnimationDuration =
base::TimeDelta::FromMilliseconds(250);
-}
+} // namespace
////////////////////////////////////////////////////////////////////////////////
// DragDropController, public:
@@ -47,11 +47,8 @@ DragDropController::DragDropController()
DragDropController::~DragDropController() {
Shell::GetInstance()->RemoveRootWindowEventFilter(this);
Cleanup();
- if (drag_image_.get()) {
- aura::Window* window = drag_image_->GetWidget()->GetNativeView();
- window->layer()->GetAnimator()->RemoveObserver(this);
+ if (drag_image_.get())
drag_image_.reset();
- }
}
int DragDropController::StartDragAndDrop(const ui::OSExchangeData& data,
@@ -206,14 +203,7 @@ ui::GestureStatus DragDropController::PreHandleGestureEvent(
////////////////////////////////////////////////////////////////////////////////
// DragDropController, private:
-void DragDropController::OnLayerAnimationEnded(
- const ui::LayerAnimationSequence* sequence) {
- DCHECK(drag_image_.get());
- drag_image_.reset();
-}
-
-void DragDropController::OnLayerAnimationAborted(
- const ui::LayerAnimationSequence* sequence) {
+void DragDropController::OnImplicitAnimationsCompleted() {
DCHECK(drag_image_.get());
drag_image_.reset();
}
@@ -223,9 +213,13 @@ void DragDropController::StartCanceledAnimation() {
ui::LayerAnimator* animator = window->layer()->GetAnimator();
animator->set_preemption_strategy(
ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
- animator->AddObserver(this);
+
+ // Stop waiting for any as yet unfinished implicit animations.
+ StopObservingImplicitAnimations();
+
ui::ScopedLayerAnimationSettings animation_setter(animator);
animation_setter.SetTransitionDuration(kDragDropAnimationDuration);
+ animation_setter.AddObserver(this);
window->SetBounds(gfx::Rect(drag_start_location_, window->bounds().size()));
}
diff --git a/ash/drag_drop/drag_drop_controller.h b/ash/drag_drop/drag_drop_controller.h
index 0f9b257..9272257 100644
--- a/ash/drag_drop/drag_drop_controller.h
+++ b/ash/drag_drop/drag_drop_controller.h
@@ -36,8 +36,8 @@ class DragImageView;
class ASH_EXPORT DragDropController
: public aura::client::DragDropClient,
public aura::EventFilter,
- public ui::LayerAnimationObserver {
- public:
+ public ui::ImplicitAnimationObserver {
+public:
DragDropController();
virtual ~DragDropController();
@@ -69,13 +69,8 @@ class ASH_EXPORT DragDropController
private:
friend class ash::test::DragDropControllerTest;
- // Overridden from ui::LayerAnimationObserver:
- virtual void OnLayerAnimationEnded(
- const ui::LayerAnimationSequence* sequence) OVERRIDE;
- virtual void OnLayerAnimationAborted(
- const ui::LayerAnimationSequence* sequence) OVERRIDE;
- virtual void OnLayerAnimationScheduled(
- const ui::LayerAnimationSequence* sequence) OVERRIDE {}
+ // Implementation of ImplicitAnimationObserver
+ virtual void OnImplicitAnimationsCompleted() OVERRIDE;
// Helper method to start drag widget flying back animation.
void StartCanceledAnimation();
diff --git a/ash/test/aura_shell_test_base.cc b/ash/test/aura_shell_test_base.cc
index b6011de..1486f1c 100644
--- a/ash/test/aura_shell_test_base.cc
+++ b/ash/test/aura_shell_test_base.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 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.
@@ -6,6 +6,7 @@
#include "ash/shell.h"
#include "ash/test/test_shell_delegate.h"
+#include "ui/gfx/compositor/layer_animator.h"
namespace ash {
namespace test {
@@ -21,6 +22,9 @@ void AuraShellTestBase::SetUp() {
// Creates Shell and hook with Desktop.
ash::Shell::CreateInstance(new TestShellDelegate);
+
+ // Disable animations during tests.
+ ui::LayerAnimator::set_disable_animations_for_test(true);
}
void AuraShellTestBase::TearDown() {
diff --git a/ash/wm/compact_layout_manager.cc b/ash/wm/compact_layout_manager.cc
index 105d04c..2be9525 100644
--- a/ash/wm/compact_layout_manager.cc
+++ b/ash/wm/compact_layout_manager.cc
@@ -140,20 +140,11 @@ void CompactLayoutManager::OnWindowStackingChanged(aura::Window* window) {
/////////////////////////////////////////////////////////////////////////////
// CompactLayoutManager, AnimationDelegate overrides:
-void CompactLayoutManager::OnLayerAnimationEnded(
- const ui::LayerAnimationSequence* animation) {
+void CompactLayoutManager::OnImplicitAnimationsCompleted() {
if (!GetDefaultContainerLayer()->GetAnimator()->is_animating())
HideWindows();
}
-void CompactLayoutManager::OnLayerAnimationScheduled(
- const ui::LayerAnimationSequence* animation) {
-}
-
-void CompactLayoutManager::OnLayerAnimationAborted(
- const ui::LayerAnimationSequence* animation) {
-}
-
//////////////////////////////////////////////////////////////////////////////
// CompactLayoutManager, private:
diff --git a/ash/wm/compact_layout_manager.h b/ash/wm/compact_layout_manager.h
index 8b4f241..9f9843a 100644
--- a/ash/wm/compact_layout_manager.h
+++ b/ash/wm/compact_layout_manager.h
@@ -25,7 +25,7 @@ namespace internal {
// maximized, fill the screen, and only one tabbed browser window is visible at
// a time. The status area appears in the top-right corner of the screen.
class ASH_EXPORT CompactLayoutManager : public BaseLayoutManager,
- public ui::LayerAnimationObserver {
+ public ui::ImplicitAnimationObserver {
public:
CompactLayoutManager();
virtual ~CompactLayoutManager();
@@ -48,13 +48,8 @@ class ASH_EXPORT CompactLayoutManager : public BaseLayoutManager,
void* old) OVERRIDE;
virtual void OnWindowStackingChanged(aura::Window* window) OVERRIDE;
- // ui::LayerAnimationObserver:
- virtual void OnLayerAnimationEnded(
- const ui::LayerAnimationSequence* animation) OVERRIDE;
- virtual void OnLayerAnimationScheduled(
- const ui::LayerAnimationSequence* animation) OVERRIDE;
- virtual void OnLayerAnimationAborted(
- const ui::LayerAnimationSequence* animation) OVERRIDE;
+ // ui::OnImplicitAnimationsCompleted:
+ virtual void OnImplicitAnimationsCompleted() OVERRIDE;
private:
FRIEND_TEST_ALL_PREFIXES(CompactLayoutManagerTransitionTest,
diff --git a/ash/wm/shelf_layout_manager.cc b/ash/wm/shelf_layout_manager.cc
index 1283fe5..c747c0f 100644
--- a/ash/wm/shelf_layout_manager.cc
+++ b/ash/wm/shelf_layout_manager.cc
@@ -10,6 +10,7 @@
#include "ui/aura/root_window.h"
#include "ui/aura/screen_aura.h"
#include "ui/gfx/compositor/layer.h"
+#include "ui/gfx/compositor/layer_animation_observer.h"
#include "ui/gfx/compositor/layer_animator.h"
#include "ui/gfx/compositor/scoped_layer_animation_settings.h"
#include "ui/views/widget/widget.h"
@@ -30,8 +31,7 @@ ui::Layer* GetLayer(views::Widget* widget) {
ShelfLayoutManager::ShelfLayoutManager(views::Widget* launcher,
views::Widget* status)
- : animating_(false),
- in_layout_(false),
+ : in_layout_(false),
visible_(true),
max_height_(-1),
launcher_(launcher),
@@ -39,11 +39,9 @@ ShelfLayoutManager::ShelfLayoutManager(views::Widget* launcher,
gfx::Rect launcher_bounds = launcher->GetWindowScreenBounds();
gfx::Rect status_bounds = status->GetWindowScreenBounds();
max_height_ = std::max(launcher_bounds.height(), status_bounds.height());
- GetLayer(launcher)->GetAnimator()->AddObserver(this);
}
ShelfLayoutManager::~ShelfLayoutManager() {
- GetLayer(launcher_)->GetAnimator()->RemoveObserver(this);
// Without a shelf we don't need special insets anymore.
aura::RootWindow::GetInstance()->
screen()->set_work_area_insets(gfx::Insets());
@@ -66,19 +64,36 @@ void ShelfLayoutManager::LayoutShelf() {
}
void ShelfLayoutManager::SetVisible(bool visible) {
- bool current_visibility = animating_ ? !visible_ : visible_;
+ ui::Layer* launcher_layer = GetLayer(launcher_);
+ ui::Layer* status_layer = GetLayer(status_);
+
+ // TODO(vollick): once visibility is animatable, use GetTargetVisibility.
+ bool current_visibility = visible_ &&
+ launcher_layer->GetTargetOpacity() > 0.0f &&
+ status_layer->GetTargetOpacity() > 0.0f;
+
if (visible == current_visibility)
return; // Nothing changed.
StopAnimating();
+ visible_ = visible;
TargetBounds target_bounds;
float target_opacity = visible ? 1.0f : 0.0f;
CalculateTargetBounds(visible, &target_bounds);
- AnimateWidgetTo(launcher_, target_bounds.launcher_bounds, target_opacity);
- AnimateWidgetTo(status_, target_bounds.status_bounds, target_opacity);
- animating_ = true;
- // |visible_| is updated once the animation completes.
+
+ ui::ScopedLayerAnimationSettings launcher_animation_setter(
+ launcher_layer->GetAnimator());
+ ui::ScopedLayerAnimationSettings status_animation_setter(
+ status_layer->GetAnimator());
+
+ launcher_animation_setter.AddObserver(this);
+ status_animation_setter.AddObserver(this);
+
+ launcher_layer->SetBounds(target_bounds.launcher_bounds);
+ launcher_layer->SetOpacity(target_opacity);
+ status_layer->SetBounds(target_bounds.status_bounds);
+ status_layer->SetOpacity(target_opacity);
}
////////////////////////////////////////////////////////////////////////////////
@@ -109,10 +124,7 @@ void ShelfLayoutManager::SetChildBounds(aura::Window* child,
// ShelfLayoutManager, private:
void ShelfLayoutManager::StopAnimating() {
- if (animating_) {
- animating_ = false;
- visible_ = !visible_;
- }
+ StopObservingImplicitAnimations();
GetLayer(launcher_)->GetAnimator()->StopAnimating();
GetLayer(status_)->GetAnimator()->StopAnimating();
}
@@ -135,23 +147,7 @@ void ShelfLayoutManager::CalculateTargetBounds(bool visible,
target_bounds->work_area_insets = gfx::Insets(0, 0, max_height_, 0);
}
-void ShelfLayoutManager::AnimateWidgetTo(views::Widget* widget,
- const gfx::Rect& target_bounds,
- float target_opacity) {
- ui::Layer* layer = GetLayer(widget);
- ui::ScopedLayerAnimationSettings animation_setter(layer->GetAnimator());
- // Don't go through the widget, otherwise we end up back in SetChildBounds and
- // cancel the animation/layout.
- layer->SetBounds(target_bounds);
- layer->SetOpacity(target_opacity);
-}
-
-void ShelfLayoutManager::OnLayerAnimationEnded(
- const ui::LayerAnimationSequence* sequence) {
- if (!animating_)
- return;
- animating_ = false;
- visible_ = !visible_;
+void ShelfLayoutManager::OnImplicitAnimationsCompleted() {
TargetBounds target_bounds;
CalculateTargetBounds(visible_, &target_bounds);
aura::RootWindow::GetInstance()->screen()->set_work_area_insets(
diff --git a/ash/wm/shelf_layout_manager.h b/ash/wm/shelf_layout_manager.h
index 3c35389..8d69cc6 100644
--- a/ash/wm/shelf_layout_manager.h
+++ b/ash/wm/shelf_layout_manager.h
@@ -28,7 +28,7 @@ namespace internal {
// To respond to bounds changes in the status area StatusAreaLayoutManager works
// closely with ShelfLayoutManager.
class ASH_EXPORT ShelfLayoutManager : public aura::LayoutManager,
- public ui::LayerAnimationObserver {
+ public ui::ImplicitAnimationObserver {
public:
ShelfLayoutManager(views::Widget* launcher, views::Widget* status);
virtual ~ShelfLayoutManager();
@@ -41,7 +41,7 @@ class ASH_EXPORT ShelfLayoutManager : public aura::LayoutManager,
// Sets the visibility of the shelf to |visible|.
void SetVisible(bool visible);
- bool visible() const { return animating_ ? !visible_ : visible_; }
+ bool visible() const { return visible_; }
views::Widget* launcher() { return launcher_; }
views::Widget* status() { return status_; }
@@ -72,21 +72,8 @@ class ASH_EXPORT ShelfLayoutManager : public aura::LayoutManager,
void CalculateTargetBounds(bool visible,
TargetBounds* target_bounds);
- // Animates |widget| to the specified bounds and opacity.
- void AnimateWidgetTo(views::Widget* widget,
- const gfx::Rect& target_bounds,
- float target_opacity);
-
- // LayerAnimationObserver overrides:
- virtual void OnLayerAnimationEnded(
- const ui::LayerAnimationSequence* sequence) OVERRIDE;
- virtual void OnLayerAnimationAborted(
- const ui::LayerAnimationSequence* sequence) OVERRIDE {}
- virtual void OnLayerAnimationScheduled(
- const ui::LayerAnimationSequence* sequence) OVERRIDE {}
-
- // Are we animating?
- bool animating_;
+ // Implementation of ImplicitAnimationObserver
+ virtual void OnImplicitAnimationsCompleted() OVERRIDE;
// True when inside LayoutShelf method. Used to prevent calling LayoutShelf
// again from SetChildBounds().
diff --git a/ash/wm/system_modal_container_layout_manager.cc b/ash/wm/system_modal_container_layout_manager.cc
index 6fdd910..e337a57 100644
--- a/ash/wm/system_modal_container_layout_manager.cc
+++ b/ash/wm/system_modal_container_layout_manager.cc
@@ -122,22 +122,14 @@ void SystemModalContainerLayoutManager::OnWindowPropertyChanged(
}
////////////////////////////////////////////////////////////////////////////////
-// SystemModalContainerLayoutManager, ui::LayerAnimationObserver implementation:
+// SystemModalContainerLayoutManager,
+// ui::ImplicitAnimationObserver implementation:
-void SystemModalContainerLayoutManager::OnLayerAnimationEnded(
- const ui::LayerAnimationSequence* sequence) {
+void SystemModalContainerLayoutManager::OnImplicitAnimationsCompleted() {
if (modal_screen_ && !modal_screen_->GetNativeView()->layer()->ShouldDraw())
DestroyModalScreen();
}
-void SystemModalContainerLayoutManager::OnLayerAnimationAborted(
- const ui::LayerAnimationSequence* sequence) {
-}
-
-void SystemModalContainerLayoutManager::OnLayerAnimationScheduled(
- const ui::LayerAnimationSequence* sequence) {
-}
-
////////////////////////////////////////////////////////////////////////////////
// SystemModalContainerLayoutManager,
// SystemModalContainerEventFilter::Delegate implementation:
@@ -186,27 +178,33 @@ void SystemModalContainerLayoutManager::CreateModalScreen() {
"SystemModalContainerLayoutManager.ModalScreen");
modal_screen_->SetContentsView(new ScreenView);
modal_screen_->GetNativeView()->layer()->SetOpacity(0.0f);
- modal_screen_->GetNativeView()->layer()->GetAnimator()->AddObserver(this);
Shell::GetInstance()->AddRootWindowEventFilter(modality_filter_.get());
+ StopObservingImplicitAnimations();
+
ui::ScopedLayerAnimationSettings settings(
modal_screen_->GetNativeView()->layer()->GetAnimator());
+ settings.AddObserver(this);
modal_screen_->Show();
modal_screen_->GetNativeView()->layer()->SetOpacity(0.5f);
container_->StackChildAtTop(modal_screen_->GetNativeView());
}
void SystemModalContainerLayoutManager::DestroyModalScreen() {
- modal_screen_->GetNativeView()->layer()->GetAnimator()->RemoveObserver(this);
+ // Stop observing the modal screen's animations.
+ StopObservingImplicitAnimations();
modal_screen_->Close();
modal_screen_ = NULL;
}
void SystemModalContainerLayoutManager::HideModalScreen() {
+ StopObservingImplicitAnimations();
+
Shell::GetInstance()->RemoveRootWindowEventFilter(modality_filter_.get());
ui::ScopedLayerAnimationSettings settings(
modal_screen_->GetNativeView()->layer()->GetAnimator());
+ settings.AddObserver(this);
modal_screen_->GetNativeView()->layer()->SetOpacity(0.0f);
}
diff --git a/ash/wm/system_modal_container_layout_manager.h b/ash/wm/system_modal_container_layout_manager.h
index c713500..309d0f07 100644
--- a/ash/wm/system_modal_container_layout_manager.h
+++ b/ash/wm/system_modal_container_layout_manager.h
@@ -35,7 +35,7 @@ namespace internal {
class ASH_EXPORT SystemModalContainerLayoutManager
: public aura::LayoutManager,
public aura::WindowObserver,
- public ui::LayerAnimationObserver,
+ public ui::ImplicitAnimationObserver,
public SystemModalContainerEventFilterDelegate {
public:
explicit SystemModalContainerLayoutManager(aura::Window* container);
@@ -55,13 +55,8 @@ class ASH_EXPORT SystemModalContainerLayoutManager
const char* key,
void* old) OVERRIDE;
- // Overridden from ui::LayerAnimationObserver:
- virtual void OnLayerAnimationEnded(
- const ui::LayerAnimationSequence* sequence) OVERRIDE;
- virtual void OnLayerAnimationAborted(
- const ui::LayerAnimationSequence* sequence) OVERRIDE;
- virtual void OnLayerAnimationScheduled(
- const ui::LayerAnimationSequence* sequence) OVERRIDE;
+ // Overridden from ui::ImplicitAnimationObserver:
+ virtual void OnImplicitAnimationsCompleted() OVERRIDE;
// Overridden from SystemModalContainerEventFilterDelegate:
virtual bool CanWindowReceiveEvents(aura::Window* window) OVERRIDE;
diff --git a/ash/wm/system_modal_container_layout_manager_unittest.cc b/ash/wm/system_modal_container_layout_manager_unittest.cc
index 04198ea..e3be65d 100644
--- a/ash/wm/system_modal_container_layout_manager_unittest.cc
+++ b/ash/wm/system_modal_container_layout_manager_unittest.cc
@@ -168,10 +168,8 @@ TEST_F(SystemModalContainerLayoutManagerTest, ModalTransient) {
// Tests that we can activate an unrelated window after a modal window is closed
// for a window.
-// TODO(beng): This test is disabled pending a solution re: visibility & target
-// visibility.
TEST_F(SystemModalContainerLayoutManagerTest,
- DISABLED_CanActivateAfterEndModalSession) {
+ CanActivateAfterEndModalSession) {
scoped_ptr<aura::Window> unrelated(TestWindow::OpenTestWindow(NULL, false));
unrelated->SetBounds(gfx::Rect(100, 100, 50, 50));
scoped_ptr<aura::Window> parent(TestWindow::OpenTestWindow(NULL, false));
@@ -191,6 +189,8 @@ TEST_F(SystemModalContainerLayoutManagerTest,
// Now close the transient.
transient.reset();
+ MessageLoopForUI::current()->RunAllPending();
+
// parent should now be active again.
EXPECT_TRUE(IsActiveWindow(parent.get()));
diff --git a/ash/wm/visibility_controller_unittest.cc b/ash/wm/visibility_controller_unittest.cc
index aaa15a5..9fb1024 100644
--- a/ash/wm/visibility_controller_unittest.cc
+++ b/ash/wm/visibility_controller_unittest.cc
@@ -8,6 +8,7 @@
#include "ui/aura/test/test_windows.h"
#include "ui/aura/test/test_window_delegate.h"
#include "ui/aura/window.h"
+#include "ui/gfx/compositor/layer_animator.h"
namespace ash {
namespace internal {
@@ -17,6 +18,9 @@ typedef test::AuraShellTestBase VisibilityControllerTest;
// Hiding a window in an animatable container should not hide the window's layer
// immediately.
TEST_F(VisibilityControllerTest, AnimateHideDoesntHideWindowLayer) {
+ // We cannot disable animations for this test.
+ ui::LayerAnimator::set_disable_animations_for_test(false);
+
scoped_ptr<aura::Window> container(
aura::test::CreateTestWindowWithId(-1, NULL));
SetChildWindowVisibilityChangesAnimated(container.get());
diff --git a/ash/wm/window_animations.cc b/ash/wm/window_animations.cc
index 8b8c0b1..5c4c3a4 100644
--- a/ash/wm/window_animations.cc
+++ b/ash/wm/window_animations.cc
@@ -171,7 +171,8 @@ void AnimateHideWindowCommon(aura::Window* window,
// Property sets within this scope will be implicitly animated.
ui::ScopedLayerAnimationSettings settings(window->layer()->GetAnimator());
- settings.AddImplicitObserver(new HidingWindowAnimationObserver(window));
+ settings.AddObserver(new HidingWindowAnimationObserver(window));
+
int duration =
window->GetIntProperty(internal::kWindowVisibilityAnimationDurationKey);
if (duration > 0) {
diff --git a/ui/aura/root_window.cc b/ui/aura/root_window.cc
index b2f380e..0b4baa3 100644
--- a/ui/aura/root_window.cc
+++ b/ui/aura/root_window.cc
@@ -676,16 +676,16 @@ internal::FocusManager* RootWindow::GetFocusManager() {
}
void RootWindow::OnLayerAnimationEnded(
- const ui::LayerAnimationSequence* animation) {
+ ui::LayerAnimationSequence* animation) {
OnHostResized(host_->GetSize());
}
void RootWindow::OnLayerAnimationScheduled(
- const ui::LayerAnimationSequence* animation) {
+ ui::LayerAnimationSequence* animation) {
}
void RootWindow::OnLayerAnimationAborted(
- const ui::LayerAnimationSequence* animation) {
+ ui::LayerAnimationSequence* animation) {
}
void RootWindow::SetFocusedWindow(Window* focused_window) {
diff --git a/ui/aura/root_window.h b/ui/aura/root_window.h
index ec0f09f..4f5bd4f 100644
--- a/ui/aura/root_window.h
+++ b/ui/aura/root_window.h
@@ -219,11 +219,11 @@ class AURA_EXPORT RootWindow : public ui::CompositorDelegate,
// Overridden from ui::LayerAnimationObserver:
virtual void OnLayerAnimationEnded(
- const ui::LayerAnimationSequence* animation) OVERRIDE;
+ ui::LayerAnimationSequence* animation) OVERRIDE;
virtual void OnLayerAnimationScheduled(
- const ui::LayerAnimationSequence* animation) OVERRIDE;
+ ui::LayerAnimationSequence* animation) OVERRIDE;
virtual void OnLayerAnimationAborted(
- const ui::LayerAnimationSequence* animation) OVERRIDE;
+ ui::LayerAnimationSequence* animation) OVERRIDE;
// Overridden from FocusManager:
virtual void SetFocusedWindow(Window* window) OVERRIDE;
diff --git a/ui/aura/test/aura_test_base.cc b/ui/aura/test/aura_test_base.cc
index 70d33f5..3e1e95f 100644
--- a/ui/aura/test/aura_test_base.cc
+++ b/ui/aura/test/aura_test_base.cc
@@ -9,6 +9,7 @@
#endif
#include "ui/aura/root_window.h"
+#include "ui/gfx/compositor/layer_animator.h"
namespace aura {
namespace test {
@@ -22,6 +23,9 @@ AuraTestBase::AuraTestBase()
RootWindow::GetInstance()->Show();
RootWindow::GetInstance()->SetHostSize(gfx::Size(600, 600));
+
+ // Disable animations during tests.
+ ui::LayerAnimator::set_disable_animations_for_test(true);
}
AuraTestBase::~AuraTestBase() {
diff --git a/ui/aura/window_unittest.cc b/ui/aura/window_unittest.cc
index 1e59c2d..78b9142 100644
--- a/ui/aura/window_unittest.cc
+++ b/ui/aura/window_unittest.cc
@@ -933,6 +933,9 @@ TEST_F(WindowTest, Property) {
}
TEST_F(WindowTest, SetBoundsInternalShouldCheckTargetBounds) {
+ // We cannot short-circuit animations in this test.
+ ui::LayerAnimator::set_disable_animations_for_test(false);
+
scoped_ptr<Window> w1(
CreateTestWindowWithBounds(gfx::Rect(0, 0, 100, 100), NULL));
@@ -966,7 +969,7 @@ TEST_F(WindowTest, SetBoundsInternalShouldCheckTargetBounds) {
// Confirm that the target bounds are reached.
base::TimeTicks start_time =
- w1->layer()->GetAnimator()->get_last_step_time_for_test();
+ w1->layer()->GetAnimator()->last_step_time();
element->Step(start_time + base::TimeDelta::FromMilliseconds(1000));
diff --git a/ui/gfx/compositor/layer_animation_observer.cc b/ui/gfx/compositor/layer_animation_observer.cc
index 23217a5..a477bde 100644
--- a/ui/gfx/compositor/layer_animation_observer.cc
+++ b/ui/gfx/compositor/layer_animation_observer.cc
@@ -11,14 +11,26 @@ namespace ui {
////////////////////////////////////////////////////////////////////////////////
// LayerAnimationObserver
+LayerAnimationObserver::LayerAnimationObserver() {
+}
+
+LayerAnimationObserver::~LayerAnimationObserver() {
+ StopObserving();
+}
+
bool LayerAnimationObserver::RequiresNotificationWhenAnimatorDestroyed() const {
return false;
}
-LayerAnimationObserver::LayerAnimationObserver() {
+void LayerAnimationObserver::OnAttachedToSequence(
+ LayerAnimationSequence* sequence) {
}
-LayerAnimationObserver::~LayerAnimationObserver() {
+void LayerAnimationObserver::OnDetachedFromSequence(
+ LayerAnimationSequence* sequence) {
+}
+
+void LayerAnimationObserver::StopObserving() {
while (!attached_sequences_.empty()) {
LayerAnimationSequence* sequence = *attached_sequences_.begin();
sequence->RemoveObserver(this);
@@ -29,20 +41,21 @@ void LayerAnimationObserver::AttachedToSequence(
LayerAnimationSequence* sequence) {
DCHECK(attached_sequences_.find(sequence) == attached_sequences_.end());
attached_sequences_.insert(sequence);
+ OnAttachedToSequence(sequence);
}
void LayerAnimationObserver::DetachedFromSequence(
LayerAnimationSequence* sequence) {
if (attached_sequences_.find(sequence) != attached_sequences_.end())
attached_sequences_.erase(sequence);
+ OnDetachedFromSequence(sequence);
}
////////////////////////////////////////////////////////////////////////////////
// ImplicitAnimationObserver
ImplicitAnimationObserver::ImplicitAnimationObserver()
- : active_(false),
- animation_count_(0) {
+ : active_(false) {
}
ImplicitAnimationObserver::~ImplicitAnimationObserver() {}
@@ -52,26 +65,44 @@ void ImplicitAnimationObserver::SetActive(bool active) {
CheckCompleted();
}
+void ImplicitAnimationObserver::StopObservingImplicitAnimations() {
+ SetActive(false);
+ StopObserving();
+}
+
void ImplicitAnimationObserver::OnLayerAnimationEnded(
- const LayerAnimationSequence* sequence) {
- animation_count_--;
+ LayerAnimationSequence* sequence) {
+ sequence->RemoveObserver(this);
+ DCHECK(attached_sequences().find(sequence) == attached_sequences().end());
CheckCompleted();
}
void ImplicitAnimationObserver::OnLayerAnimationAborted(
- const LayerAnimationSequence* sequence) {
- animation_count_--;
+ LayerAnimationSequence* sequence) {
+ sequence->RemoveObserver(this);
+ DCHECK(attached_sequences().find(sequence) == attached_sequences().end());
CheckCompleted();
}
void ImplicitAnimationObserver::OnLayerAnimationScheduled(
- const LayerAnimationSequence* sequence) {
- animation_count_++;
+ LayerAnimationSequence* sequence) {
+}
+
+void ImplicitAnimationObserver::OnAttachedToSequence(
+ LayerAnimationSequence* sequence) {
+}
+
+void ImplicitAnimationObserver::OnDetachedFromSequence(
+ LayerAnimationSequence* sequence) {
+ DCHECK(attached_sequences().find(sequence) == attached_sequences().end());
+ CheckCompleted();
}
void ImplicitAnimationObserver::CheckCompleted() {
- if (active_ && animation_count_ == 0)
+ if (active_ && attached_sequences().empty()) {
OnImplicitAnimationsCompleted();
+ active_ = false;
+ }
}
} // namespace ui
diff --git a/ui/gfx/compositor/layer_animation_observer.h b/ui/gfx/compositor/layer_animation_observer.h
index c35dc60..a2eb911 100644
--- a/ui/gfx/compositor/layer_animation_observer.h
+++ b/ui/gfx/compositor/layer_animation_observer.h
@@ -16,22 +16,29 @@ namespace ui {
class LayerAnimationSequence;
class ScopedLayerAnimationSettings;
+class ImplicitAnimationObserver;
// LayerAnimationObservers are notified when animations complete.
class COMPOSITOR_EXPORT LayerAnimationObserver {
public:
// Called when the |sequence| ends. Not called if |sequence| is aborted.
virtual void OnLayerAnimationEnded(
- const LayerAnimationSequence* sequence) = 0;
+ LayerAnimationSequence* sequence) = 0;
// Called if |sequence| is aborted for any reason. Should never do anything
// that may cause another animation to be started.
virtual void OnLayerAnimationAborted(
- const LayerAnimationSequence* sequence) = 0;
+ LayerAnimationSequence* sequence) = 0;
// Called when the animation is scheduled.
virtual void OnLayerAnimationScheduled(
- const LayerAnimationSequence* sequence) = 0;
+ LayerAnimationSequence* sequence) = 0;
+
+ protected:
+ typedef std::set<LayerAnimationSequence*> AttachedSequences;
+
+ LayerAnimationObserver();
+ virtual ~LayerAnimationObserver();
// If the animator is destroyed during an animation, the animations are
// aborted. The resulting NotifyAborted notifications will NOT be sent to
@@ -40,9 +47,18 @@ class COMPOSITOR_EXPORT LayerAnimationObserver {
// OBSERVER WHEN YOU ARE DESTROYED.
virtual bool RequiresNotificationWhenAnimatorDestroyed() const;
- protected:
- LayerAnimationObserver();
- virtual ~LayerAnimationObserver();
+ // Called when |this| is added to |sequence|'s observer list.
+ virtual void OnAttachedToSequence(LayerAnimationSequence* sequence);
+
+ // Called when |this| is removed to |sequence|'s observer list.
+ virtual void OnDetachedFromSequence(LayerAnimationSequence* sequence);
+
+ // Detaches this observer from all sequences it is currently observing.
+ void StopObserving();
+
+ const AttachedSequences& attached_sequences() const {
+ return attached_sequences_;
+ }
private:
friend class LayerAnimationSequence;
@@ -53,7 +69,7 @@ class COMPOSITOR_EXPORT LayerAnimationObserver {
// Called when |this| is removed to |sequence|'s observer list.
void DetachedFromSequence(LayerAnimationSequence* sequence);
- std::set<LayerAnimationSequence*> attached_sequences_;
+ AttachedSequences attached_sequences_;
};
// An implicit animation observer is intended to be used in conjunction with a
@@ -67,29 +83,33 @@ class COMPOSITOR_EXPORT ImplicitAnimationObserver
virtual void OnImplicitAnimationsCompleted() = 0;
+ protected:
+ // Deactivates the observer and clears the collection of animations it is
+ // waiting for.
+ void StopObservingImplicitAnimations();
+
private:
friend class ScopedLayerAnimationSettings;
- // OnImplicitAnimationsCompleted is not fired unless the observer is active.
- bool active() const { return active_; }
- void SetActive(bool active);
-
// LayerAnimationObserver implementation
virtual void OnLayerAnimationEnded(
- const LayerAnimationSequence* sequence) OVERRIDE;
+ LayerAnimationSequence* sequence) OVERRIDE;
virtual void OnLayerAnimationAborted(
- const LayerAnimationSequence* sequence) OVERRIDE;
+ LayerAnimationSequence* sequence) OVERRIDE;
virtual void OnLayerAnimationScheduled(
- const LayerAnimationSequence* sequence) OVERRIDE;
+ LayerAnimationSequence* sequence) OVERRIDE;
+ virtual void OnAttachedToSequence(
+ LayerAnimationSequence* sequence) OVERRIDE;
+ virtual void OnDetachedFromSequence(
+ LayerAnimationSequence* sequence) OVERRIDE;
+
+ // OnImplicitAnimationsCompleted is not fired unless the observer is active.
+ bool active() const { return active_; }
+ void SetActive(bool active);
void CheckCompleted();
bool active_;
-
- // This tracks the number of scheduled animations that have yet to complete.
- // If this value is zero, and the observer is active, then
- // OnImplicitAnimationsCompleted is fired.
- size_t animation_count_;
};
} // namespace ui
diff --git a/ui/gfx/compositor/layer_animator.cc b/ui/gfx/compositor/layer_animator.cc
index 82aa949..f98904c 100644
--- a/ui/gfx/compositor/layer_animator.cc
+++ b/ui/gfx/compositor/layer_animator.cc
@@ -45,6 +45,9 @@ LayerAnimator::~LayerAnimator() {
}
// static
+bool LayerAnimator::disable_animations_for_test_ = false;
+
+// static
LayerAnimator* LayerAnimator::CreateDefaultAnimator() {
return new LayerAnimator(base::TimeDelta::FromMilliseconds(0));
}
@@ -55,9 +58,12 @@ LayerAnimator* LayerAnimator::CreateImplicitAnimator() {
}
void LayerAnimator::SetTransform(const Transform& transform) {
+ base::TimeDelta duration = transition_duration_;
+ if (disable_animations_for_test_)
+ duration = base::TimeDelta();
StartAnimation(new LayerAnimationSequence(
LayerAnimationElement::CreateTransformElement(
- transform, transition_duration_)));
+ transform, duration)));
}
Transform LayerAnimator::GetTargetTransform() const {
@@ -67,9 +73,12 @@ Transform LayerAnimator::GetTargetTransform() const {
}
void LayerAnimator::SetBounds(const gfx::Rect& bounds) {
+ base::TimeDelta duration = transition_duration_;
+ if (disable_animations_for_test_)
+ duration = base::TimeDelta();
StartAnimation(new LayerAnimationSequence(
LayerAnimationElement::CreateBoundsElement(
- bounds, transition_duration_)));
+ bounds, duration)));
}
gfx::Rect LayerAnimator::GetTargetBounds() const {
@@ -79,9 +88,12 @@ gfx::Rect LayerAnimator::GetTargetBounds() const {
}
void LayerAnimator::SetOpacity(float opacity) {
+ base::TimeDelta duration = transition_duration_;
+ if (disable_animations_for_test_)
+ duration = base::TimeDelta();
StartAnimation(new LayerAnimationSequence(
LayerAnimationElement::CreateOpacityElement(
- opacity, transition_duration_)));
+ opacity, duration)));
}
float LayerAnimator::GetTargetOpacity() const {
diff --git a/ui/gfx/compositor/layer_animator.h b/ui/gfx/compositor/layer_animator.h
index 60ee25a..2231f57 100644
--- a/ui/gfx/compositor/layer_animator.h
+++ b/ui/gfx/compositor/layer_animator.h
@@ -33,6 +33,8 @@ class Transform;
// When a property of layer needs to be changed it is set by way of
// LayerAnimator. This enables LayerAnimator to animate property changes.
+// NB: during many tests, set_disable_animations_for_test is used and causes
+// all animations to complete immediately.
class COMPOSITOR_EXPORT LayerAnimator : public AnimationContainerElement {
public:
enum PreemptionStrategy {
@@ -108,17 +110,22 @@ class COMPOSITOR_EXPORT LayerAnimator : public AnimationContainerElement {
// Stops all animation and clears any queued animations.
void StopAnimating();
- // For testing purposes only.
- void set_disable_timer_for_test(bool enabled) {
- disable_timer_for_test_ = enabled;
- }
- base::TimeTicks get_last_step_time_for_test() { return last_step_time_; }
-
// These functions are used for adding or removing observers from the observer
// list. The observers are notified when animations end.
void AddObserver(LayerAnimationObserver* observer);
void RemoveObserver(LayerAnimationObserver* observer);
+ // For testing purposes only.
+ void set_disable_timer_for_test(bool disable_timer) {
+ disable_timer_for_test_ = disable_timer;
+ }
+ base::TimeTicks last_step_time() const { return last_step_time_; }
+
+ // When set to true, all animations complete immediately.
+ static void set_disable_animations_for_test(bool disable_animations) {
+ disable_animations_for_test_ = disable_animations;
+ }
+
protected:
LayerAnimationDelegate* delegate() { return delegate_; }
const LayerAnimationDelegate* delegate() const { return delegate_; }
@@ -233,6 +240,9 @@ class COMPOSITOR_EXPORT LayerAnimator : public AnimationContainerElement {
// and allows for manual stepping.
bool disable_timer_for_test_;
+ // This causes all animations to complete immediately.
+ static bool disable_animations_for_test_;
+
// Observers are notified when layer animations end, are scheduled or are
// aborted.
ObserverList<LayerAnimationObserver> observers_;
diff --git a/ui/gfx/compositor/layer_animator_unittest.cc b/ui/gfx/compositor/layer_animator_unittest.cc
index cad4a6b..09d1c66 100644
--- a/ui/gfx/compositor/layer_animator_unittest.cc
+++ b/ui/gfx/compositor/layer_animator_unittest.cc
@@ -133,7 +133,7 @@ TEST(LayerAnimatorTest, ScheduleAnimationThatCanRunImmediately) {
EXPECT_TRUE(animator->is_animating());
EXPECT_FLOAT_EQ(delegate.GetOpacityForAnimation(), start_opacity);
- base::TimeTicks start_time = animator->get_last_step_time_for_test();
+ base::TimeTicks start_time = animator->last_step_time();
element->Step(start_time + base::TimeDelta::FromMilliseconds(500));
@@ -181,7 +181,7 @@ TEST(LayerAnimatorTest, ScheduleTwoAnimationsThatCanRunImmediately) {
EXPECT_FLOAT_EQ(delegate.GetOpacityForAnimation(), start_opacity);
CheckApproximatelyEqual(delegate.GetBoundsForAnimation(), start_bounds);
- base::TimeTicks start_time = animator->get_last_step_time_for_test();
+ base::TimeTicks start_time = animator->last_step_time();
element->Step(start_time + base::TimeDelta::FromMilliseconds(500));
@@ -224,7 +224,7 @@ TEST(LayerAnimatorTest, ScheduleTwoAnimationsOnSameProperty) {
EXPECT_TRUE(animator->is_animating());
EXPECT_FLOAT_EQ(delegate.GetOpacityForAnimation(), start_opacity);
- base::TimeTicks start_time = animator->get_last_step_time_for_test();
+ base::TimeTicks start_time = animator->last_step_time();
element->Step(start_time + base::TimeDelta::FromMilliseconds(500));
@@ -292,7 +292,7 @@ TEST(LayerAnimatorTest, ScheduleBlockedAnimation) {
EXPECT_FLOAT_EQ(delegate.GetOpacityForAnimation(), start_opacity);
CheckApproximatelyEqual(delegate.GetBoundsForAnimation(), start_bounds);
- base::TimeTicks start_time = animator->get_last_step_time_for_test();
+ base::TimeTicks start_time = animator->last_step_time();
element->Step(start_time + base::TimeDelta::FromMilliseconds(500));
@@ -364,7 +364,7 @@ TEST(LayerAnimatorTest, ScheduleTogether) {
EXPECT_FLOAT_EQ(delegate.GetOpacityForAnimation(), start_opacity);
CheckApproximatelyEqual(delegate.GetBoundsForAnimation(), start_bounds);
- base::TimeTicks start_time = animator->get_last_step_time_for_test();
+ base::TimeTicks start_time = animator->last_step_time();
element->Step(start_time + base::TimeDelta::FromMilliseconds(1000));
@@ -403,7 +403,7 @@ TEST(LayerAnimatorTest, StartAnimationThatCanRunImmediately) {
EXPECT_TRUE(animator->is_animating());
EXPECT_FLOAT_EQ(delegate.GetOpacityForAnimation(), start_opacity);
- base::TimeTicks start_time = animator->get_last_step_time_for_test();
+ base::TimeTicks start_time = animator->last_step_time();
element->Step(start_time + base::TimeDelta::FromMilliseconds(500));
@@ -467,7 +467,7 @@ TEST(LayerAnimatorTest, PreemptByImmediatelyAnimatingToNewTarget) {
new LayerAnimationSequence(
LayerAnimationElement::CreateOpacityElement(target_opacity, delta)));
- base::TimeTicks start_time = animator->get_last_step_time_for_test();
+ base::TimeTicks start_time = animator->last_step_time();
element->Step(start_time + base::TimeDelta::FromMilliseconds(500));
@@ -518,7 +518,7 @@ TEST(LayerAnimatorTest, PreemptEnqueueNewAnimation) {
new LayerAnimationSequence(
LayerAnimationElement::CreateOpacityElement(target_opacity, delta)));
- base::TimeTicks start_time = animator->get_last_step_time_for_test();
+ base::TimeTicks start_time = animator->last_step_time();
element->Step(start_time + base::TimeDelta::FromMilliseconds(500));
@@ -571,7 +571,7 @@ TEST(LayerAnimatorTest, PreemptyByReplacingQueuedAnimations) {
new LayerAnimationSequence(
LayerAnimationElement::CreateOpacityElement(target_opacity, delta)));
- base::TimeTicks start_time = animator->get_last_step_time_for_test();
+ base::TimeTicks start_time = animator->last_step_time();
element->Step(start_time + base::TimeDelta::FromMilliseconds(500));
@@ -630,7 +630,7 @@ TEST(LayerAnimatorTest, CyclicSequences) {
animator->StartAnimation(sequence.release());
- base::TimeTicks start_time = animator->get_last_step_time_for_test();
+ base::TimeTicks start_time = animator->last_step_time();
element->Step(start_time + base::TimeDelta::FromMilliseconds(1000));
@@ -687,7 +687,7 @@ TEST(LayerAnimatorTest, AddObserverExplicit) {
EXPECT_EQ(observer.last_scheduled_sequence(), sequence);
- base::TimeTicks start_time = animator->get_last_step_time_for_test();
+ base::TimeTicks start_time = animator->last_step_time();
element->Step(start_time + base::TimeDelta::FromMilliseconds(1000));
@@ -704,45 +704,6 @@ TEST(LayerAnimatorTest, AddObserverExplicit) {
EXPECT_EQ(observer.last_aborted_sequence(), sequence);
}
-TEST(LayerAnimatorTest, AddObserverImplicit) {
- scoped_ptr<LayerAnimator> animator(LayerAnimator::CreateDefaultAnimator());
- AnimationContainerElement* element = animator.get();
- animator->set_disable_timer_for_test(true);
- TestLayerAnimationObserver observer;
- TestLayerAnimationDelegate delegate;
- animator->SetDelegate(&delegate);
- animator->AddObserver(&observer);
-
- // Should end a sequence with the default animator.
- EXPECT_TRUE(!observer.last_ended_sequence());
- animator->SetOpacity(1.0f);
- base::TimeTicks start_time = base::TimeTicks::Now();
- element->Step(start_time + base::TimeDelta::FromMilliseconds(1000));
- EXPECT_TRUE(observer.last_ended_sequence());
-
- TestLayerAnimationObserver scoped_observer;
- {
- ScopedLayerAnimationSettings settings(animator.get());
- settings.AddObserver(&scoped_observer);
- for (int i = 0; i < 2; ++i) {
- // reset the observer
- scoped_observer = TestLayerAnimationObserver();
- EXPECT_TRUE(!scoped_observer.last_ended_sequence());
- animator->SetOpacity(1.0f);
- start_time = animator->get_last_step_time_for_test();
- element->Step(start_time + base::TimeDelta::FromMilliseconds(1000));
- EXPECT_FALSE(!scoped_observer.last_ended_sequence());
- }
- }
-
- scoped_observer = TestLayerAnimationObserver();
- EXPECT_TRUE(!scoped_observer.last_ended_sequence());
- animator->SetOpacity(1.0f);
- start_time = base::TimeTicks::Now();
- element->Step(start_time + base::TimeDelta::FromMilliseconds(1000));
- EXPECT_TRUE(!scoped_observer.last_ended_sequence());
-}
-
// Tests that an observer added to a scoped settings object is still notified
// when the object goes out of scope.
TEST(LayerAnimatorTest, ImplicitAnimationObservers) {
@@ -758,12 +719,12 @@ TEST(LayerAnimatorTest, ImplicitAnimationObservers) {
{
ScopedLayerAnimationSettings settings(animator.get());
- settings.AddImplicitObserver(&observer);
+ settings.AddObserver(&observer);
animator->SetOpacity(0.0f);
}
EXPECT_FALSE(observer.animations_completed());
- base::TimeTicks start_time = animator->get_last_step_time_for_test();
+ base::TimeTicks start_time = animator->last_step_time();
element->Step(start_time + base::TimeDelta::FromMilliseconds(1000));
EXPECT_TRUE(observer.animations_completed());
EXPECT_FLOAT_EQ(0.0f, delegate.GetOpacityForAnimation());
@@ -783,7 +744,7 @@ TEST(LayerAnimatorTest, InterruptedImplicitAnimationObservers) {
{
ScopedLayerAnimationSettings settings(animator.get());
- settings.AddImplicitObserver(&observer);
+ settings.AddObserver(&observer);
animator->SetOpacity(0.0f);
}
@@ -822,7 +783,7 @@ TEST(LayerAnimatorTest, RemoveObserverShouldRemoveFromSequences) {
// This should stop the observer from observing sequence.
animator->RemoveObserver(&removed_observer);
- base::TimeTicks start_time = animator->get_last_step_time_for_test();
+ base::TimeTicks start_time = animator->last_step_time();
element->Step(start_time + base::TimeDelta::FromMilliseconds(1000));
@@ -858,6 +819,70 @@ TEST(LayerAnimatorTest, ObserverReleasedBeforeAnimationSequenceEnds) {
EXPECT_EQ(static_cast<size_t>(0), sequence->observers_.size());
}
+TEST(LayerAnimatorTest, ObserverAttachedAfterAnimationStarted) {
+ scoped_ptr<LayerAnimator> animator(LayerAnimator::CreateDefaultAnimator());
+ AnimationContainerElement* element = animator.get();
+ animator->set_disable_timer_for_test(true);
+
+ TestImplicitAnimationObserver observer;
+ TestLayerAnimationDelegate delegate;
+ animator->SetDelegate(&delegate);
+
+ delegate.SetOpacityFromAnimation(0.0f);
+
+ {
+ ScopedLayerAnimationSettings setter(animator.get());
+
+ base::TimeDelta delta = base::TimeDelta::FromSeconds(1);
+ LayerAnimationSequence* sequence = new LayerAnimationSequence(
+ LayerAnimationElement::CreateOpacityElement(1.0f, delta));
+
+ animator->StartAnimation(sequence);
+ base::TimeTicks start_time = animator->last_step_time();
+ element->Step(start_time + base::TimeDelta::FromMilliseconds(500));
+
+ setter.AddObserver(&observer);
+
+ // Start observing an in-flight animation.
+ sequence->AddObserver(&observer);
+
+ element->Step(start_time + base::TimeDelta::FromMilliseconds(1000));
+ }
+
+ EXPECT_TRUE(observer.animations_completed());
+}
+
+TEST(LayerAnimatorTest, ObserverDetachedBeforeAnimationFinished) {
+ scoped_ptr<LayerAnimator> animator(LayerAnimator::CreateDefaultAnimator());
+ AnimationContainerElement* element = animator.get();
+ animator->set_disable_timer_for_test(true);
+
+ TestImplicitAnimationObserver observer;
+ TestLayerAnimationDelegate delegate;
+ animator->SetDelegate(&delegate);
+
+ delegate.SetOpacityFromAnimation(0.0f);
+ base::TimeDelta delta = base::TimeDelta::FromSeconds(1);
+ LayerAnimationSequence* sequence = new LayerAnimationSequence(
+ LayerAnimationElement::CreateOpacityElement(1.0f, delta));
+
+ {
+ ScopedLayerAnimationSettings setter(animator.get());
+ setter.AddObserver(&observer);
+
+ animator->StartAnimation(sequence);
+ base::TimeTicks start_time = animator->last_step_time();
+ element->Step(start_time + base::TimeDelta::FromMilliseconds(500));
+ }
+
+ EXPECT_FALSE(observer.animations_completed());
+
+ // Stop observing an in-flight animation.
+ sequence->RemoveObserver(&observer);
+
+ EXPECT_TRUE(observer.animations_completed());
+}
+
// Check that setting a property during an animation with a default animator
// cancels the original animation.
TEST(LayerAnimatorTest, SettingPropertyDuringAnAnimation) {
diff --git a/ui/gfx/compositor/scoped_layer_animation_settings.cc b/ui/gfx/compositor/scoped_layer_animation_settings.cc
index 874b927..7a7dbc1 100644
--- a/ui/gfx/compositor/scoped_layer_animation_settings.cc
+++ b/ui/gfx/compositor/scoped_layer_animation_settings.cc
@@ -26,27 +26,19 @@ ScopedLayerAnimationSettings::ScopedLayerAnimationSettings(
ScopedLayerAnimationSettings::~ScopedLayerAnimationSettings() {
animator_->transition_duration_ = old_transition_duration_;
- for (std::set<LayerAnimationObserver*>::const_iterator i =
- observers_.begin(); i != observers_.end(); ++i)
- animator_->observers_.RemoveObserver(*i);
-
for (std::set<ImplicitAnimationObserver*>::const_iterator i =
- implicit_observers_.begin(); i != implicit_observers_.end(); ++i)
- (*i)->SetActive(true);
+ observers_.begin(); i != observers_.end(); ++i) {
+ animator_->observers_.RemoveObserver(*i);
+ (*i)->SetActive(true);
+ }
}
void ScopedLayerAnimationSettings::AddObserver(
- LayerAnimationObserver* observer) {
+ ImplicitAnimationObserver* observer) {
observers_.insert(observer);
animator_->AddObserver(observer);
}
-void ScopedLayerAnimationSettings::AddImplicitObserver(
- ImplicitAnimationObserver* observer) {
- implicit_observers_.insert(observer);
- AddObserver(observer);
-}
-
void ScopedLayerAnimationSettings::SetTransitionDuration(
base::TimeDelta duration) {
animator_->transition_duration_ = duration;
diff --git a/ui/gfx/compositor/scoped_layer_animation_settings.h b/ui/gfx/compositor/scoped_layer_animation_settings.h
index 2f90055..dce64ef 100644
--- a/ui/gfx/compositor/scoped_layer_animation_settings.h
+++ b/ui/gfx/compositor/scoped_layer_animation_settings.h
@@ -27,15 +27,13 @@ class COMPOSITOR_EXPORT ScopedLayerAnimationSettings {
explicit ScopedLayerAnimationSettings(LayerAnimator* animator);
virtual ~ScopedLayerAnimationSettings();
- void AddObserver(LayerAnimationObserver* observer);
- void AddImplicitObserver(ImplicitAnimationObserver* observer);
+ void AddObserver(ImplicitAnimationObserver* observer);
void SetTransitionDuration(base::TimeDelta duration);
private:
LayerAnimator* animator_;
base::TimeDelta old_transition_duration_;
- std::set<LayerAnimationObserver*> observers_;
- std::set<ImplicitAnimationObserver*> implicit_observers_;
+ std::set<ImplicitAnimationObserver*> observers_;
DISALLOW_COPY_AND_ASSIGN(ScopedLayerAnimationSettings);
};
diff --git a/ui/gfx/compositor/test/test_layer_animation_observer.cc b/ui/gfx/compositor/test/test_layer_animation_observer.cc
index fe515d3..2afcb1b 100644
--- a/ui/gfx/compositor/test/test_layer_animation_observer.cc
+++ b/ui/gfx/compositor/test/test_layer_animation_observer.cc
@@ -19,17 +19,17 @@ TestLayerAnimationObserver::~TestLayerAnimationObserver() {
}
void TestLayerAnimationObserver::OnLayerAnimationEnded(
- const LayerAnimationSequence* sequence) {
+ LayerAnimationSequence* sequence) {
last_ended_sequence_ = sequence;
}
void TestLayerAnimationObserver::OnLayerAnimationAborted(
- const LayerAnimationSequence* sequence) {
+ LayerAnimationSequence* sequence) {
last_aborted_sequence_ = sequence;
}
void TestLayerAnimationObserver::OnLayerAnimationScheduled(
- const LayerAnimationSequence* sequence) {
+ LayerAnimationSequence* sequence) {
last_scheduled_sequence_ = sequence;
}
diff --git a/ui/gfx/compositor/test/test_layer_animation_observer.h b/ui/gfx/compositor/test/test_layer_animation_observer.h
index b90a9dc..44a7119 100644
--- a/ui/gfx/compositor/test/test_layer_animation_observer.h
+++ b/ui/gfx/compositor/test/test_layer_animation_observer.h
@@ -21,13 +21,13 @@ class TestLayerAnimationObserver : public LayerAnimationObserver {
virtual ~TestLayerAnimationObserver();
virtual void OnLayerAnimationEnded(
- const LayerAnimationSequence* sequence) OVERRIDE;
+ LayerAnimationSequence* sequence) OVERRIDE;
virtual void OnLayerAnimationAborted(
- const LayerAnimationSequence* sequence) OVERRIDE;
+ LayerAnimationSequence* sequence) OVERRIDE;
virtual void OnLayerAnimationScheduled(
- const LayerAnimationSequence* sequence) OVERRIDE;
+ LayerAnimationSequence* sequence) OVERRIDE;
virtual bool RequiresNotificationWhenAnimatorDestroyed() const OVERRIDE;