Chromium Code Reviews| Index: content/browser/web_contents/aura/window_slider_unittest.cc |
| diff --git a/content/browser/web_contents/aura/window_slider_unittest.cc b/content/browser/web_contents/aura/window_slider_unittest.cc |
| index ed41347ee4d659bdbb81ef0c3a1a4a79b0d786fb..6582186ad9edaad6a62120bf57f5deb83aff1c47 100644 |
| --- a/content/browser/web_contents/aura/window_slider_unittest.cc |
| +++ b/content/browser/web_contents/aura/window_slider_unittest.cc |
| @@ -5,13 +5,21 @@ |
| #include "content/browser/web_contents/aura/window_slider.h" |
| #include "base/bind.h" |
| +#include "base/time/time.h" |
| +#include "cc/animation/animation.h" |
| +#include "cc/animation/animation_events.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| #include "ui/aura/test/aura_test_base.h" |
| #include "ui/aura/test/event_generator.h" |
| #include "ui/aura/test/test_window_delegate.h" |
| #include "ui/aura/window.h" |
| #include "ui/base/hit_test.h" |
| +#include "ui/compositor/layer_animation_sequence.h" |
| +#include "ui/compositor/scoped_animation_duration_scale_mode.h" |
| +#include "ui/compositor/scoped_layer_animation_settings.h" |
| +#include "ui/compositor/test/layer_animator_test_controller.h" |
| #include "ui/events/event_processor.h" |
| +#include "ui/events/event_utils.h" |
| namespace content { |
| @@ -39,6 +47,28 @@ void ChangeSliderOwnerDuringScrollCallback(scoped_ptr<aura::Window>* window, |
| window->reset(new_window); |
| } |
| +void ConfirmSlideDuringScrollCallback(WindowSlider* slider, |
| + ui::EventType type, |
| + const gfx::Vector2dF& delta) { |
| + static float total_delta_x = 0; |
| + if (type == ui::ET_GESTURE_SCROLL_BEGIN) |
| + total_delta_x = 0; |
| + |
| + if (type == ui::ET_GESTURE_SCROLL_UPDATE) { |
| + total_delta_x += delta.x(); |
| + if (total_delta_x >= 70) |
| + EXPECT_TRUE(slider->IsSlideInProgress()); |
| + } else { |
| + EXPECT_FALSE(slider->IsSlideInProgress()); |
| + } |
| +} |
| + |
| +void ConfirmNoSlideDuringScrollCallback(WindowSlider* slider, |
| + ui::EventType type, |
| + const gfx::Vector2dF& delta) { |
| + EXPECT_FALSE(slider->IsSlideInProgress()); |
| +} |
| + |
| // The window delegate does not receive any events. |
| class NoEventWindowDelegate : public aura::test::TestWindowDelegate { |
| public: |
| @@ -59,7 +89,8 @@ class WindowSliderDelegateTest : public WindowSlider::Delegate { |
| : can_create_layer_(true), |
| created_back_layer_(false), |
| created_front_layer_(false), |
| - slide_completed_(false), |
| + fling_started_(false), |
| + fling_completed_(false), |
| slide_aborted_(false), |
| slider_destroyed_(false) { |
| } |
| @@ -69,7 +100,8 @@ class WindowSliderDelegateTest : public WindowSlider::Delegate { |
| can_create_layer_ = true; |
| created_back_layer_ = false; |
| created_front_layer_ = false; |
| - slide_completed_ = false; |
| + fling_started_ = false; |
| + fling_completed_ = false; |
| slide_aborted_ = false; |
| slider_destroyed_ = false; |
| } |
| @@ -80,7 +112,8 @@ class WindowSliderDelegateTest : public WindowSlider::Delegate { |
| bool created_back_layer() const { return created_back_layer_; } |
| bool created_front_layer() const { return created_front_layer_; } |
| - bool slide_completed() const { return slide_completed_; } |
| + bool fling_started() const { return fling_started_; } |
| + bool fling_completed() const { return fling_completed_; } |
| bool slide_aborted() const { return slide_aborted_; } |
| bool slider_destroyed() const { return slider_destroyed_; } |
| @@ -93,22 +126,26 @@ class WindowSliderDelegateTest : public WindowSlider::Delegate { |
| } |
| // Overridden from WindowSlider::Delegate: |
| - virtual ui::Layer* CreateBackLayer() OVERRIDE { |
| + virtual ui::Layer* OnSlideBackStartedCreateLayer() OVERRIDE { |
| if (!can_create_layer_) |
| return NULL; |
| created_back_layer_ = true; |
| return CreateLayerForTest(); |
| } |
| - virtual ui::Layer* CreateFrontLayer() OVERRIDE { |
| + virtual ui::Layer* OnSlideForwardStartedCreateLayer() OVERRIDE { |
| if (!can_create_layer_) |
| return NULL; |
| created_front_layer_ = true; |
| return CreateLayerForTest(); |
| } |
| - virtual void OnWindowSlideComplete() OVERRIDE { |
| - slide_completed_ = true; |
| + virtual void OnWindowFlingCompleted() OVERRIDE { |
| + fling_completed_ = true; |
| + } |
| + |
| + virtual void OnWindowFlingStarted() OVERRIDE { |
| + fling_started_ = true; |
| } |
| virtual void OnWindowSlideAborted() OVERRIDE { |
| @@ -123,7 +160,8 @@ class WindowSliderDelegateTest : public WindowSlider::Delegate { |
| bool can_create_layer_; |
| bool created_back_layer_; |
| bool created_front_layer_; |
| - bool slide_completed_; |
| + bool fling_started_; |
| + bool fling_completed_; |
| bool slide_aborted_; |
| bool slider_destroyed_; |
| @@ -159,8 +197,8 @@ class WindowSliderDeleteOwnerOnComplete : public WindowSliderDelegateTest { |
| private: |
| // Overridden from WindowSlider::Delegate: |
| - virtual void OnWindowSlideComplete() OVERRIDE { |
| - WindowSliderDelegateTest::OnWindowSlideComplete(); |
| + virtual void OnWindowFlingCompleted() OVERRIDE { |
| + WindowSliderDelegateTest::OnWindowFlingCompleted(); |
| delete owner_; |
| } |
| @@ -180,12 +218,15 @@ TEST_F(WindowSliderTest, WindowSlideUsingGesture) { |
| // Generate a horizontal overscroll. |
| WindowSlider* slider = |
| new WindowSlider(&slider_delegate, root_window(), window.get()); |
| - generator.GestureScrollSequence(gfx::Point(10, 10), |
| - gfx::Point(180, 10), |
| - base::TimeDelta::FromMilliseconds(10), |
| - 10); |
| + generator.GestureScrollSequenceWithCallback( |
| + gfx::Point(10, 10), |
| + gfx::Point(180, 10), |
| + base::TimeDelta::FromMilliseconds(10), |
| + 10, |
| + base::Bind(&ConfirmSlideDuringScrollCallback, slider)); |
| EXPECT_TRUE(slider_delegate.created_back_layer()); |
| - EXPECT_TRUE(slider_delegate.slide_completed()); |
| + EXPECT_TRUE(slider_delegate.fling_started()); |
| + EXPECT_TRUE(slider_delegate.fling_completed()); |
| EXPECT_FALSE(slider_delegate.created_front_layer()); |
| EXPECT_FALSE(slider_delegate.slide_aborted()); |
| EXPECT_FALSE(slider_delegate.slider_destroyed()); |
| @@ -193,13 +234,16 @@ TEST_F(WindowSliderTest, WindowSlideUsingGesture) { |
| slider_delegate.Reset(); |
| window->SetTransform(gfx::Transform()); |
| - // Generat a horizontal overscroll in the reverse direction. |
| - generator.GestureScrollSequence(gfx::Point(180, 10), |
| - gfx::Point(10, 10), |
| - base::TimeDelta::FromMilliseconds(10), |
| - 10); |
| + // Generate a horizontal overscroll in the reverse direction. |
| + generator.GestureScrollSequenceWithCallback( |
| + gfx::Point(180, 10), |
| + gfx::Point(10, 10), |
| + base::TimeDelta::FromMilliseconds(10), |
| + 10, |
| + base::Bind(&ConfirmSlideDuringScrollCallback, slider)); |
| EXPECT_TRUE(slider_delegate.created_front_layer()); |
| - EXPECT_TRUE(slider_delegate.slide_completed()); |
| + EXPECT_TRUE(slider_delegate.fling_started()); |
| + EXPECT_TRUE(slider_delegate.fling_completed()); |
| EXPECT_FALSE(slider_delegate.created_back_layer()); |
| EXPECT_FALSE(slider_delegate.slide_aborted()); |
| EXPECT_FALSE(slider_delegate.slider_destroyed()); |
| @@ -207,12 +251,15 @@ TEST_F(WindowSliderTest, WindowSlideUsingGesture) { |
| slider_delegate.Reset(); |
| // Generate a vertical overscroll. |
| - generator.GestureScrollSequence(gfx::Point(10, 10), |
| - gfx::Point(10, 80), |
| - base::TimeDelta::FromMilliseconds(10), |
| - 10); |
| + generator.GestureScrollSequenceWithCallback( |
| + gfx::Point(10, 10), |
| + gfx::Point(10, 80), |
| + base::TimeDelta::FromMilliseconds(10), |
| + 10, |
| + base::Bind(&ConfirmNoSlideDuringScrollCallback, slider)); |
| EXPECT_FALSE(slider_delegate.created_back_layer()); |
| - EXPECT_FALSE(slider_delegate.slide_completed()); |
| + EXPECT_FALSE(slider_delegate.fling_started()); |
| + EXPECT_FALSE(slider_delegate.fling_completed()); |
| EXPECT_FALSE(slider_delegate.created_front_layer()); |
| EXPECT_FALSE(slider_delegate.slide_aborted()); |
| EXPECT_FALSE(slider->IsSlideInProgress()); |
| @@ -220,14 +267,17 @@ TEST_F(WindowSliderTest, WindowSlideUsingGesture) { |
| // Generate a horizontal scroll that starts overscroll, but doesn't scroll |
| // enough to complete it. |
| - generator.GestureScrollSequence(gfx::Point(10, 10), |
| - gfx::Point(80, 10), |
| - base::TimeDelta::FromMilliseconds(10), |
| - 10); |
| + generator.GestureScrollSequenceWithCallback( |
| + gfx::Point(10, 10), |
| + gfx::Point(80, 10), |
| + base::TimeDelta::FromMilliseconds(10), |
| + 10, |
| + base::Bind(&ConfirmSlideDuringScrollCallback, slider)); |
| EXPECT_TRUE(slider_delegate.created_back_layer()); |
| EXPECT_TRUE(slider_delegate.slide_aborted()); |
| EXPECT_FALSE(slider_delegate.created_front_layer()); |
| - EXPECT_FALSE(slider_delegate.slide_completed()); |
| + EXPECT_FALSE(slider_delegate.fling_started()); |
| + EXPECT_FALSE(slider_delegate.fling_completed()); |
| EXPECT_FALSE(slider_delegate.slider_destroyed()); |
| EXPECT_FALSE(slider->IsSlideInProgress()); |
| slider_delegate.Reset(); |
| @@ -237,10 +287,11 @@ TEST_F(WindowSliderTest, WindowSlideUsingGesture) { |
| EXPECT_TRUE(slider_delegate.slider_destroyed()); |
| } |
| -// Tests that the window slide is cancelled when a different type of event |
| +// Tests that the window slide is interrupted when a different type of event |
| // happens. |
| TEST_F(WindowSliderTest, WindowSlideIsCancelledOnEvent) { |
| scoped_ptr<aura::Window> window(CreateNormalWindow(0, root_window(), NULL)); |
| + window->SetBounds(gfx::Rect(0, 0, 400, 400)); |
| WindowSliderDelegateTest slider_delegate; |
| ui::Event* events[] = { |
| @@ -270,7 +321,8 @@ TEST_F(WindowSliderTest, WindowSlideIsCancelledOnEvent) { |
| EXPECT_TRUE(slider_delegate.created_back_layer()); |
| EXPECT_TRUE(slider_delegate.slide_aborted()); |
| EXPECT_FALSE(slider_delegate.created_front_layer()); |
| - EXPECT_FALSE(slider_delegate.slide_completed()); |
| + EXPECT_FALSE(slider_delegate.fling_started()); |
| + EXPECT_FALSE(slider_delegate.fling_completed()); |
| EXPECT_FALSE(slider_delegate.slider_destroyed()); |
| slider_delegate.Reset(); |
| } |
| @@ -278,6 +330,118 @@ TEST_F(WindowSliderTest, WindowSlideIsCancelledOnEvent) { |
| EXPECT_TRUE(slider_delegate.slider_destroyed()); |
| } |
| +// Tests that the window slide can continue after it is interrupted by another |
| +// event if the user continues scrolling. |
| +TEST_F(WindowSliderTest, WindowSlideInterruptedThenContinues) { |
| + scoped_ptr<aura::Window> window(CreateNormalWindow(0, root_window(), NULL)); |
| + window->SetBounds(gfx::Rect(0, 0, 400, 400)); |
| + WindowSliderDelegateTest slider_delegate; |
| + |
| + ui::ScopedAnimationDurationScaleMode normal_duration_( |
| + ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION); |
| + ui::LayerAnimator* animator = window->layer()->GetAnimator(); |
| + gfx::AnimationContainerElement* element = animator; |
| + animator->set_disable_timer_for_test(true); |
| + ui::LayerAnimatorTestController test_controller(animator); |
| + |
| + WindowSlider* slider = |
| + new WindowSlider(&slider_delegate, root_window(), window.get()); |
| + |
| + ui::MouseEvent interrupt_event(ui::ET_MOUSE_MOVED, |
| + gfx::Point(55, 10), |
| + gfx::Point(55, 10), |
| + 0, 0); |
| + |
| + aura::test::EventGenerator generator(root_window()); |
| + |
| + // Start the scroll sequence. Scroll forward so that |window|'s layer is the |
| + // one animating. |
| + const int kTouchId = 5; |
| + ui::TouchEvent press(ui::ET_TOUCH_PRESSED, |
| + gfx::Point(10, 10), |
| + kTouchId, |
| + ui::EventTimeForNow()); |
| + generator.Dispatch(&press); |
| + |
| + // First scroll event of the sequence. |
| + ui::TouchEvent move1(ui::ET_TOUCH_MOVED, |
| + gfx::Point(100, 10), |
| + kTouchId, |
| + ui::EventTimeForNow()); |
| + generator.Dispatch(&move1); |
| + EXPECT_TRUE(slider->IsSlideInProgress()); |
| + EXPECT_FALSE(animator->is_animating()); |
| + // Dispatch the event after the first scroll and confirm it interrupts the |
| + // scroll and starts the "reset slide" animation. |
| + generator.Dispatch(&interrupt_event); |
| + EXPECT_TRUE(slider->IsSlideInProgress()); |
| + EXPECT_TRUE(animator->is_animating()); |
| + EXPECT_TRUE(slider_delegate.created_back_layer()); |
| + // slide_aborted() should be false because the 'reset slide' animation |
| + // hasn't completed yet. |
| + EXPECT_FALSE(slider_delegate.slide_aborted()); |
| + EXPECT_FALSE(slider_delegate.created_front_layer()); |
| + EXPECT_FALSE(slider_delegate.fling_started()); |
| + EXPECT_FALSE(slider_delegate.fling_completed()); |
| + EXPECT_FALSE(slider_delegate.slider_destroyed()); |
| + slider_delegate.Reset(); |
| + |
| + // Second scroll event of the sequence. |
| + ui::TouchEvent move2(ui::ET_TOUCH_MOVED, |
| + gfx::Point(200, 10), |
| + kTouchId, |
| + ui::EventTimeForNow()); |
| + generator.Dispatch(&move2); |
| + // The second scroll should instantly cause the animation to complete. |
| + EXPECT_FALSE(animator->is_animating()); |
| + EXPECT_FALSE(slider_delegate.created_back_layer()); |
| + // The ResetScroll() animation was completed, so now slide_aborted() |
| + // should be true. |
| + EXPECT_TRUE(slider_delegate.slide_aborted()); |
| + |
| + // Third scroll event of the sequence. |
| + ui::TouchEvent move3(ui::ET_TOUCH_MOVED, |
| + gfx::Point(300, 10), |
| + kTouchId, |
| + ui::EventTimeForNow()); |
| + generator.Dispatch(&move3); |
| + // The third scroll should re-start the sliding. |
| + EXPECT_TRUE(slider->IsSlideInProgress()); |
| + EXPECT_TRUE(slider_delegate.created_back_layer()); |
| + |
| + // Generate the release event, finishing the scroll sequence. |
| + ui::TouchEvent release(ui::ET_TOUCH_RELEASED, |
| + gfx::Point(300, 10), |
| + kTouchId, |
| + ui::EventTimeForNow()); |
| + generator.Dispatch(&release); |
| + // When the scroll gesture ends, the "fling" animation should start. |
| + EXPECT_TRUE(slider->IsSlideInProgress()); |
| + EXPECT_TRUE(animator->is_animating()); |
| + EXPECT_TRUE(slider_delegate.fling_started()); |
| + EXPECT_FALSE(slider_delegate.created_front_layer()); |
| + EXPECT_FALSE(slider_delegate.fling_completed()); |
| + EXPECT_FALSE(slider_delegate.slider_destroyed()); |
| + |
| + // Progress the animator to complete the 'fling' animation. |
| + base::TimeTicks start_time = animator->last_step_time(); |
| + animator->OnThreadedAnimationStarted(cc::AnimationEvent( |
|
sadrul
2014/03/19 20:21:18
I don't think we are supposed to use cc::Animation
mfomitchev
2014/03/20 15:10:06
Done.
|
| + cc::AnimationEvent::Started, |
| + 0, |
| + test_controller.GetRunningSequence( |
| + ui::LayerAnimationElement::TRANSFORM)->animation_group_id(), |
| + cc::Animation::Transform, |
| + (start_time - base::TimeTicks()).InSecondsF())); |
| + ui::ScopedLayerAnimationSettings settings(animator); |
| + base::TimeDelta duration = settings.GetTransitionDuration(); |
| + element->Step(start_time + duration); |
| + EXPECT_TRUE(slider_delegate.fling_completed()); |
| + EXPECT_FALSE(slider_delegate.slider_destroyed()); |
| + |
| + window.reset(); |
| + EXPECT_TRUE(slider_delegate.slider_destroyed()); |
| +} |
| + |
| // Tests that the slide works correctly when the owner of the window changes |
| // during the duration of the slide. |
| TEST_F(WindowSliderTest, OwnerWindowChangesDuringWindowSlide) { |
| @@ -308,44 +472,59 @@ TEST_F(WindowSliderTest, OwnerWindowChangesDuringWindowSlide) { |
| EXPECT_NE(old_window, new_window); |
| EXPECT_TRUE(slider_delegate.created_back_layer()); |
| - EXPECT_TRUE(slider_delegate.slide_completed()); |
| + EXPECT_TRUE(slider_delegate.fling_started()); |
| + EXPECT_TRUE(slider_delegate.fling_completed()); |
| EXPECT_FALSE(slider_delegate.created_front_layer()); |
| EXPECT_FALSE(slider_delegate.slide_aborted()); |
| EXPECT_FALSE(slider_delegate.slider_destroyed()); |
| } |
| +// If the delegate doesn't create the layer to show while sliding, WindowSlider |
| +// shouldn't start the slide or change delegate's state in any way in response |
| +// to user input. |
| TEST_F(WindowSliderTest, NoSlideWhenLayerCantBeCreated) { |
| scoped_ptr<aura::Window> window(CreateNormalWindow(0, root_window(), NULL)); |
| window->SetBounds(gfx::Rect(0, 0, 400, 400)); |
| WindowSliderDelegateTest slider_delegate; |
| slider_delegate.SetCanCreateLayer(false); |
| + WindowSlider* slider = |
| + new WindowSlider(&slider_delegate, root_window(), window.get()); |
| aura::test::EventGenerator generator(root_window()); |
| - // Generate a horizontal overscroll. |
| - scoped_ptr<WindowSlider> slider( |
| - new WindowSlider(&slider_delegate, root_window(), window.get())); |
| - generator.GestureScrollSequence(gfx::Point(10, 10), |
| - gfx::Point(160, 10), |
| - base::TimeDelta::FromMilliseconds(10), |
| - 10); |
| + // No slide in progress should be reported during scroll since the layer |
| + // wasn't created. |
| + generator.GestureScrollSequenceWithCallback( |
| + gfx::Point(10, 10), |
| + gfx::Point(180, 10), |
| + base::TimeDelta::FromMilliseconds(10), |
| + 1, |
| + base::Bind(&ConfirmNoSlideDuringScrollCallback, slider)); |
| + |
| EXPECT_FALSE(slider_delegate.created_back_layer()); |
| - EXPECT_FALSE(slider_delegate.slide_completed()); |
| + EXPECT_FALSE(slider_delegate.fling_started()); |
| + EXPECT_FALSE(slider_delegate.fling_completed()); |
| EXPECT_FALSE(slider_delegate.created_front_layer()); |
| EXPECT_FALSE(slider_delegate.slide_aborted()); |
| EXPECT_FALSE(slider_delegate.slider_destroyed()); |
| window->SetTransform(gfx::Transform()); |
| slider_delegate.SetCanCreateLayer(true); |
| - generator.GestureScrollSequence(gfx::Point(10, 10), |
| - gfx::Point(160, 10), |
| - base::TimeDelta::FromMilliseconds(10), |
| - 10); |
| + generator.GestureScrollSequenceWithCallback( |
| + gfx::Point(10, 10), |
| + gfx::Point(180, 10), |
| + base::TimeDelta::FromMilliseconds(10), |
| + 10, |
| + base::Bind(&ConfirmSlideDuringScrollCallback, slider)); |
| EXPECT_TRUE(slider_delegate.created_back_layer()); |
| - EXPECT_TRUE(slider_delegate.slide_completed()); |
| + EXPECT_TRUE(slider_delegate.fling_started()); |
| + EXPECT_TRUE(slider_delegate.fling_completed()); |
| EXPECT_FALSE(slider_delegate.created_front_layer()); |
| EXPECT_FALSE(slider_delegate.slide_aborted()); |
| EXPECT_FALSE(slider_delegate.slider_destroyed()); |
| + |
| + window.reset(); |
| + EXPECT_TRUE(slider_delegate.slider_destroyed()); |
| } |
| // Tests that the owner window can be destroyed from |OnWindowSliderDestroyed()| |
| @@ -367,7 +546,8 @@ TEST_F(WindowSliderTest, OwnerIsDestroyedOnSliderDestroy) { |
| base::TimeDelta::FromMilliseconds(10), |
| 10); |
| EXPECT_TRUE(slider_delegate.created_back_layer()); |
| - EXPECT_TRUE(slider_delegate.slide_completed()); |
| + EXPECT_TRUE(slider_delegate.fling_started()); |
| + EXPECT_TRUE(slider_delegate.fling_completed()); |
| EXPECT_FALSE(slider_delegate.created_front_layer()); |
| EXPECT_FALSE(slider_delegate.slide_aborted()); |
| EXPECT_FALSE(slider_delegate.slider_destroyed()); |
| @@ -396,7 +576,8 @@ TEST_F(WindowSliderTest, OwnerIsDestroyedOnSlideComplete) { |
| base::TimeDelta::FromMilliseconds(10), |
| 10); |
| EXPECT_TRUE(slider_delegate.created_back_layer()); |
| - EXPECT_TRUE(slider_delegate.slide_completed()); |
| + EXPECT_TRUE(slider_delegate.fling_started()); |
| + EXPECT_TRUE(slider_delegate.fling_completed()); |
| EXPECT_FALSE(slider_delegate.created_front_layer()); |
| EXPECT_FALSE(slider_delegate.slide_aborted()); |
| EXPECT_TRUE(slider_delegate.slider_destroyed()); |
| @@ -406,4 +587,85 @@ TEST_F(WindowSliderTest, OwnerIsDestroyedOnSlideComplete) { |
| EXPECT_EQ(child_windows, root_window()->children().size()); |
| } |
| +// Test the scenario when two swipe gesture occur quickly one after another so |
| +// that the second swipe occurs while the transition animation triggered by the |
| +// first swipe is in progress. |
| +// The second swipe is supposed to instantly complete the animation caused by |
| +// the first swipe, ask the delegate to create a new layer, and animate it. |
| +TEST_F(WindowSliderTest, SwipeDuringSwipeAnimation) { |
| + scoped_ptr<aura::Window> window(CreateNormalWindow(0, root_window(), NULL)); |
| + window->SetBounds(gfx::Rect(0, 0, 400, 400)); |
| + WindowSliderDelegateTest slider_delegate; |
| + new WindowSlider(&slider_delegate, root_window(), window.get()); |
| + |
| + ui::ScopedAnimationDurationScaleMode normal_duration_( |
| + ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION); |
| + ui::LayerAnimator* animator = window->layer()->GetAnimator(); |
| + gfx::AnimationContainerElement* element = animator; |
| + animator->set_disable_timer_for_test(true); |
| + ui::LayerAnimatorTestController test_controller(animator); |
| + |
| + aura::test::EventGenerator generator(root_window()); |
| + |
| + // Swipe forward so that |window|'s layer is the one animating. |
| + generator.GestureScrollSequence( |
| + gfx::Point(10, 10), |
| + gfx::Point(180, 10), |
| + base::TimeDelta::FromMilliseconds(10), |
| + 2); |
| + ui::ScopedLayerAnimationSettings settings(animator); |
| + base::TimeDelta duration = settings.GetTransitionDuration(); |
| + base::TimeTicks start_time1 = animator->last_step_time(); |
| + EXPECT_TRUE(slider_delegate.created_back_layer()); |
| + EXPECT_FALSE(slider_delegate.slide_aborted()); |
| + EXPECT_FALSE(slider_delegate.created_front_layer()); |
| + EXPECT_TRUE(slider_delegate.fling_started()); |
| + EXPECT_FALSE(slider_delegate.fling_completed()); |
| + EXPECT_FALSE(slider_delegate.slider_destroyed()); |
| + // Transform animation is a threaded animation, so it needs an extra kick to |
| + // emulate the start. |
| + animator->OnThreadedAnimationStarted(cc::AnimationEvent( |
| + cc::AnimationEvent::Started, |
| + 0, |
| + test_controller.GetRunningSequence(ui::LayerAnimationElement::TRANSFORM)-> |
| + animation_group_id(), |
| + cc::Animation::Transform, |
| + (start_time1 - base::TimeTicks()).InSecondsF())); |
| + |
| + base::TimeTicks start_time2 = start_time1 + duration/2; |
| + element->Step(start_time2); |
| + EXPECT_FALSE(slider_delegate.fling_completed()); |
| + slider_delegate.Reset(); |
| + // Generate another horizontal swipe while the animation from the previous |
| + // swipe is in progress. |
| + generator.GestureScrollSequence( |
| + gfx::Point(10, 10), |
| + gfx::Point(180, 10), |
| + base::TimeDelta::FromMilliseconds(10), |
| + 2); |
| + // Performing the second swipe should instantly complete the slide started |
| + // by the first swipe and create a new layer. |
| + EXPECT_TRUE(slider_delegate.created_back_layer()); |
| + EXPECT_FALSE(slider_delegate.slide_aborted()); |
| + EXPECT_FALSE(slider_delegate.created_front_layer()); |
| + EXPECT_TRUE(slider_delegate.fling_started()); |
| + EXPECT_TRUE(slider_delegate.fling_completed()); |
| + EXPECT_FALSE(slider_delegate.slider_destroyed()); |
| + animator->OnThreadedAnimationStarted(cc::AnimationEvent( |
| + cc::AnimationEvent::Started, |
| + 0, |
| + test_controller.GetRunningSequence(ui::LayerAnimationElement::TRANSFORM)-> |
| + animation_group_id(), |
| + cc::Animation::Transform, |
| + (start_time2 - base::TimeTicks()).InSecondsF())); |
| + slider_delegate.Reset(); |
| + element->Step(start_time2 + duration); |
| + // The animation for the second slide should now be completed. |
| + EXPECT_TRUE(slider_delegate.fling_completed()); |
| + slider_delegate.Reset(); |
| + |
| + window.reset(); |
| + EXPECT_TRUE(slider_delegate.slider_destroyed()); |
| +} |
| + |
| } // namespace content |