1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/browser/web_contents/aura/window_slider.h"
8 #include "base/time/time.h"
9 #include "testing/gtest/include/gtest/gtest.h"
10 #include "ui/aura/test/aura_test_base.h"
11 #include "ui/aura/test/test_window_delegate.h"
12 #include "ui/aura/window.h"
13 #include "ui/base/hit_test.h"
14 #include "ui/compositor/scoped_animation_duration_scale_mode.h"
15 #include "ui/compositor/scoped_layer_animation_settings.h"
16 #include "ui/compositor/test/layer_animator_test_controller.h"
17 #include "ui/events/event_processor.h"
18 #include "ui/events/event_utils.h"
19 #include "ui/events/test/event_generator.h"
20 #include "ui/gfx/frame_time.h"
24 void DispatchEventDuringScrollCallback(ui::EventProcessor
* dispatcher
,
27 const gfx::Vector2dF
& delta
) {
28 if (type
!= ui::ET_GESTURE_SCROLL_UPDATE
)
30 ui::EventDispatchDetails details
= dispatcher
->OnEventFromSource(event
);
31 CHECK(!details
.dispatcher_destroyed
);
34 void ChangeSliderOwnerDuringScrollCallback(scoped_ptr
<aura::Window
>* window
,
37 const gfx::Vector2dF
& delta
) {
38 if (type
!= ui::ET_GESTURE_SCROLL_UPDATE
)
40 aura::Window
* new_window
= new aura::Window(NULL
);
41 new_window
->Init(ui::LAYER_TEXTURED
);
43 slider
->ChangeOwner(new_window
);
44 (*window
)->parent()->AddChild(new_window
);
45 window
->reset(new_window
);
48 void ConfirmSlideDuringScrollCallback(WindowSlider
* slider
,
50 const gfx::Vector2dF
& delta
) {
51 static float total_delta_x
= 0;
52 if (type
== ui::ET_GESTURE_SCROLL_BEGIN
)
55 if (type
== ui::ET_GESTURE_SCROLL_UPDATE
) {
56 total_delta_x
+= delta
.x();
57 if (total_delta_x
>= 70)
58 EXPECT_TRUE(slider
->IsSlideInProgress());
60 EXPECT_FALSE(slider
->IsSlideInProgress());
64 void ConfirmNoSlideDuringScrollCallback(WindowSlider
* slider
,
66 const gfx::Vector2dF
& delta
) {
67 EXPECT_FALSE(slider
->IsSlideInProgress());
70 // The window delegate does not receive any events.
71 class NoEventWindowDelegate
: public aura::test::TestWindowDelegate
{
73 NoEventWindowDelegate() {
75 ~NoEventWindowDelegate() override
{}
78 // Overridden from aura::WindowDelegate:
79 bool HasHitTestMask() const override
{ return true; }
81 DISALLOW_COPY_AND_ASSIGN(NoEventWindowDelegate
);
84 class WindowSliderDelegateTest
: public WindowSlider::Delegate
{
86 WindowSliderDelegateTest()
87 : can_create_layer_(true),
88 created_back_layer_(false),
89 created_front_layer_(false),
90 slide_completing_(false),
91 slide_completed_(false),
92 slide_aborted_(false),
93 slider_destroyed_(false) {
95 ~WindowSliderDelegateTest() override
{
96 // Make sure slide_completed() gets called if slide_completing() was called.
97 CHECK(!slide_completing_
|| slide_completed_
);
101 can_create_layer_
= true;
102 created_back_layer_
= false;
103 created_front_layer_
= false;
104 slide_completing_
= false;
105 slide_completed_
= false;
106 slide_aborted_
= false;
107 slider_destroyed_
= false;
110 void SetCanCreateLayer(bool can_create_layer
) {
111 can_create_layer_
= can_create_layer
;
114 bool created_back_layer() const { return created_back_layer_
; }
115 bool created_front_layer() const { return created_front_layer_
; }
116 bool slide_completing() const { return slide_completing_
; }
117 bool slide_completed() const { return slide_completed_
; }
118 bool slide_aborted() const { return slide_aborted_
; }
119 bool slider_destroyed() const { return slider_destroyed_
; }
122 ui::Layer
* CreateLayerForTest() {
123 CHECK(can_create_layer_
);
124 ui::Layer
* layer
= new ui::Layer(ui::LAYER_SOLID_COLOR
);
125 layer
->SetColor(SK_ColorRED
);
129 // Overridden from WindowSlider::Delegate:
130 ui::Layer
* CreateBackLayer() override
{
131 if (!can_create_layer_
)
133 created_back_layer_
= true;
134 return CreateLayerForTest();
137 ui::Layer
* CreateFrontLayer() override
{
138 if (!can_create_layer_
)
140 created_front_layer_
= true;
141 return CreateLayerForTest();
144 void OnWindowSlideCompleted(scoped_ptr
<ui::Layer
> layer
) override
{
145 slide_completed_
= true;
148 void OnWindowSlideCompleting() override
{ slide_completing_
= true; }
150 void OnWindowSlideAborted() override
{ slide_aborted_
= true; }
152 void OnWindowSliderDestroyed() override
{ slider_destroyed_
= true; }
155 bool can_create_layer_
;
156 bool created_back_layer_
;
157 bool created_front_layer_
;
158 bool slide_completing_
;
159 bool slide_completed_
;
161 bool slider_destroyed_
;
163 DISALLOW_COPY_AND_ASSIGN(WindowSliderDelegateTest
);
166 // This delegate destroys the owner window when the slider is destroyed.
167 class WindowSliderDeleteOwnerOnDestroy
: public WindowSliderDelegateTest
{
169 explicit WindowSliderDeleteOwnerOnDestroy(aura::Window
* owner
)
172 ~WindowSliderDeleteOwnerOnDestroy() override
{}
175 // Overridden from WindowSlider::Delegate:
176 void OnWindowSliderDestroyed() override
{
177 WindowSliderDelegateTest::OnWindowSliderDestroyed();
181 aura::Window
* owner_
;
182 DISALLOW_COPY_AND_ASSIGN(WindowSliderDeleteOwnerOnDestroy
);
185 // This delegate destroyes the owner window when a slide is completed.
186 class WindowSliderDeleteOwnerOnComplete
: public WindowSliderDelegateTest
{
188 explicit WindowSliderDeleteOwnerOnComplete(aura::Window
* owner
)
191 ~WindowSliderDeleteOwnerOnComplete() override
{}
194 // Overridden from WindowSlider::Delegate:
195 void OnWindowSlideCompleted(scoped_ptr
<ui::Layer
> layer
) override
{
196 WindowSliderDelegateTest::OnWindowSlideCompleted(layer
.Pass());
200 aura::Window
* owner_
;
201 DISALLOW_COPY_AND_ASSIGN(WindowSliderDeleteOwnerOnComplete
);
204 typedef aura::test::AuraTestBase WindowSliderTest
;
206 TEST_F(WindowSliderTest
, WindowSlideUsingGesture
) {
207 scoped_ptr
<aura::Window
> window(CreateNormalWindow(0, root_window(), NULL
));
208 window
->SetBounds(gfx::Rect(0, 0, 400, 400));
209 WindowSliderDelegateTest slider_delegate
;
211 ui::test::EventGenerator
generator(root_window());
213 // Generate a horizontal overscroll.
214 WindowSlider
* slider
=
215 new WindowSlider(&slider_delegate
, root_window(), window
.get());
216 generator
.GestureScrollSequenceWithCallback(
219 base::TimeDelta::FromMilliseconds(10),
221 base::Bind(&ConfirmSlideDuringScrollCallback
, slider
));
222 EXPECT_TRUE(slider_delegate
.created_back_layer());
223 EXPECT_TRUE(slider_delegate
.slide_completing());
224 EXPECT_TRUE(slider_delegate
.slide_completed());
225 EXPECT_FALSE(slider_delegate
.created_front_layer());
226 EXPECT_FALSE(slider_delegate
.slide_aborted());
227 EXPECT_FALSE(slider_delegate
.slider_destroyed());
228 EXPECT_FALSE(slider
->IsSlideInProgress());
229 slider_delegate
.Reset();
230 window
->SetTransform(gfx::Transform());
232 // Generate a horizontal overscroll in the reverse direction.
233 generator
.GestureScrollSequenceWithCallback(
236 base::TimeDelta::FromMilliseconds(10),
238 base::Bind(&ConfirmSlideDuringScrollCallback
, slider
));
239 EXPECT_TRUE(slider_delegate
.created_front_layer());
240 EXPECT_TRUE(slider_delegate
.slide_completing());
241 EXPECT_TRUE(slider_delegate
.slide_completed());
242 EXPECT_FALSE(slider_delegate
.created_back_layer());
243 EXPECT_FALSE(slider_delegate
.slide_aborted());
244 EXPECT_FALSE(slider_delegate
.slider_destroyed());
245 EXPECT_FALSE(slider
->IsSlideInProgress());
246 slider_delegate
.Reset();
248 // Generate a vertical overscroll.
249 generator
.GestureScrollSequenceWithCallback(
252 base::TimeDelta::FromMilliseconds(10),
254 base::Bind(&ConfirmNoSlideDuringScrollCallback
, slider
));
255 EXPECT_FALSE(slider_delegate
.created_back_layer());
256 EXPECT_FALSE(slider_delegate
.slide_completing());
257 EXPECT_FALSE(slider_delegate
.slide_completed());
258 EXPECT_FALSE(slider_delegate
.created_front_layer());
259 EXPECT_FALSE(slider_delegate
.slide_aborted());
260 EXPECT_FALSE(slider
->IsSlideInProgress());
261 slider_delegate
.Reset();
263 // Generate a horizontal scroll that starts overscroll, but doesn't scroll
264 // enough to complete it.
265 generator
.GestureScrollSequenceWithCallback(
268 base::TimeDelta::FromMilliseconds(10),
270 base::Bind(&ConfirmSlideDuringScrollCallback
, slider
));
271 EXPECT_TRUE(slider_delegate
.created_back_layer());
272 EXPECT_TRUE(slider_delegate
.slide_aborted());
273 EXPECT_FALSE(slider_delegate
.created_front_layer());
274 EXPECT_FALSE(slider_delegate
.slide_completing());
275 EXPECT_FALSE(slider_delegate
.slide_completed());
276 EXPECT_FALSE(slider_delegate
.slider_destroyed());
277 EXPECT_FALSE(slider
->IsSlideInProgress());
278 slider_delegate
.Reset();
280 // Destroy the window. This should destroy the slider.
282 EXPECT_TRUE(slider_delegate
.slider_destroyed());
285 // Tests that the window slide is interrupted when a different type of event
287 TEST_F(WindowSliderTest
, WindowSlideIsCancelledOnEvent
) {
288 scoped_ptr
<aura::Window
> window(CreateNormalWindow(0, root_window(), NULL
));
289 window
->SetBounds(gfx::Rect(0, 0, 400, 400));
290 WindowSliderDelegateTest slider_delegate
;
292 ui::Event
* events
[] = {
293 new ui::MouseEvent(ui::ET_MOUSE_MOVED
, gfx::Point(55, 10),
294 gfx::Point(55, 10), ui::EventTimeForNow(), 0, 0),
295 new ui::KeyEvent('a', ui::VKEY_A
, ui::EF_NONE
),
299 new WindowSlider(&slider_delegate
, root_window(), window
.get());
300 for (int i
= 0; events
[i
]; ++i
) {
301 // Generate a horizontal overscroll.
302 ui::test::EventGenerator
generator(root_window());
303 generator
.GestureScrollSequenceWithCallback(
306 base::TimeDelta::FromMilliseconds(10),
308 base::Bind(&DispatchEventDuringScrollCallback
,
309 root_window()->GetHost()->event_processor(),
310 base::Owned(events
[i
])));
311 EXPECT_TRUE(slider_delegate
.created_back_layer());
312 EXPECT_TRUE(slider_delegate
.slide_aborted());
313 EXPECT_FALSE(slider_delegate
.created_front_layer());
314 EXPECT_FALSE(slider_delegate
.slide_completing());
315 EXPECT_FALSE(slider_delegate
.slide_completed());
316 EXPECT_FALSE(slider_delegate
.slider_destroyed());
317 slider_delegate
.Reset();
320 EXPECT_TRUE(slider_delegate
.slider_destroyed());
323 // Tests that the window slide can continue after it is interrupted by another
324 // event if the user continues scrolling.
325 TEST_F(WindowSliderTest
, WindowSlideInterruptedThenContinues
) {
326 scoped_ptr
<aura::Window
> window(CreateNormalWindow(0, root_window(), NULL
));
327 window
->SetBounds(gfx::Rect(0, 0, 400, 400));
328 WindowSliderDelegateTest slider_delegate
;
330 ui::ScopedAnimationDurationScaleMode
normal_duration_(
331 ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION
);
332 ui::LayerAnimator
* animator
= window
->layer()->GetAnimator();
333 animator
->set_disable_timer_for_test(true);
334 ui::LayerAnimatorTestController
test_controller(animator
);
336 WindowSlider
* slider
=
337 new WindowSlider(&slider_delegate
, root_window(), window
.get());
339 ui::MouseEvent
interrupt_event(ui::ET_MOUSE_MOVED
, gfx::Point(55, 10),
340 gfx::Point(55, 10), ui::EventTimeForNow(), 0,
343 ui::test::EventGenerator
generator(root_window());
345 // Start the scroll sequence. Scroll forward so that |window|'s layer is the
347 const int kTouchId
= 5;
348 ui::TouchEvent
press(ui::ET_TOUCH_PRESSED
,
351 ui::EventTimeForNow());
352 generator
.Dispatch(&press
);
354 // First scroll event of the sequence.
355 ui::TouchEvent
move1(ui::ET_TOUCH_MOVED
,
358 ui::EventTimeForNow());
359 generator
.Dispatch(&move1
);
360 EXPECT_TRUE(slider
->IsSlideInProgress());
361 EXPECT_FALSE(animator
->is_animating());
362 // Dispatch the event after the first scroll and confirm it interrupts the
363 // scroll and starts the "reset slide" animation.
364 generator
.Dispatch(&interrupt_event
);
365 EXPECT_TRUE(slider
->IsSlideInProgress());
366 EXPECT_TRUE(animator
->is_animating());
367 EXPECT_TRUE(slider_delegate
.created_back_layer());
368 // slide_aborted() should be false because the 'reset slide' animation
369 // hasn't completed yet.
370 EXPECT_FALSE(slider_delegate
.slide_aborted());
371 EXPECT_FALSE(slider_delegate
.created_front_layer());
372 EXPECT_FALSE(slider_delegate
.slide_completing());
373 EXPECT_FALSE(slider_delegate
.slide_completed());
374 EXPECT_FALSE(slider_delegate
.slider_destroyed());
375 slider_delegate
.Reset();
377 // Second scroll event of the sequence.
378 ui::TouchEvent
move2(ui::ET_TOUCH_MOVED
,
381 ui::EventTimeForNow());
382 generator
.Dispatch(&move2
);
383 // The second scroll should instantly cause the animation to complete.
384 EXPECT_FALSE(animator
->is_animating());
385 EXPECT_FALSE(slider_delegate
.created_back_layer());
386 // The ResetScroll() animation was completed, so now slide_aborted()
388 EXPECT_TRUE(slider_delegate
.slide_aborted());
390 // Third scroll event of the sequence.
391 ui::TouchEvent
move3(ui::ET_TOUCH_MOVED
,
394 ui::EventTimeForNow());
395 generator
.Dispatch(&move3
);
396 // The third scroll should re-start the sliding.
397 EXPECT_TRUE(slider
->IsSlideInProgress());
398 EXPECT_TRUE(slider_delegate
.created_back_layer());
400 // Generate the release event, finishing the scroll sequence.
401 ui::TouchEvent
release(ui::ET_TOUCH_RELEASED
,
404 ui::EventTimeForNow());
405 generator
.Dispatch(&release
);
406 // When the scroll gesture ends, the slide animation should start.
407 EXPECT_TRUE(slider
->IsSlideInProgress());
408 EXPECT_TRUE(animator
->is_animating());
409 EXPECT_TRUE(slider_delegate
.slide_completing());
410 EXPECT_FALSE(slider_delegate
.created_front_layer());
411 EXPECT_FALSE(slider_delegate
.slide_completed());
412 EXPECT_FALSE(slider_delegate
.slider_destroyed());
414 // Progress the animator to complete the slide animation.
415 ui::ScopedLayerAnimationSettings
settings(animator
);
416 base::TimeDelta duration
= settings
.GetTransitionDuration();
417 test_controller
.StartThreadedAnimationsIfNeeded();
418 animator
->Step(gfx::FrameTime::Now() + duration
);
420 EXPECT_TRUE(slider_delegate
.slide_completed());
421 EXPECT_FALSE(slider_delegate
.slider_destroyed());
424 EXPECT_TRUE(slider_delegate
.slider_destroyed());
427 // Tests that the slide works correctly when the owner of the window changes
428 // during the duration of the slide.
429 TEST_F(WindowSliderTest
, OwnerWindowChangesDuringWindowSlide
) {
430 scoped_ptr
<aura::Window
> parent(CreateNormalWindow(0, root_window(), NULL
));
432 NoEventWindowDelegate window_delegate
;
433 window_delegate
.set_window_component(HTNOWHERE
);
434 scoped_ptr
<aura::Window
> window(CreateNormalWindow(1, parent
.get(),
437 WindowSliderDelegateTest slider_delegate
;
438 scoped_ptr
<WindowSlider
> slider(
439 new WindowSlider(&slider_delegate
, parent
.get(), window
.get()));
441 // Generate a horizontal scroll, and change the owner in the middle of the
443 ui::test::EventGenerator
generator(root_window());
444 aura::Window
* old_window
= window
.get();
445 generator
.GestureScrollSequenceWithCallback(
448 base::TimeDelta::FromMilliseconds(10),
450 base::Bind(&ChangeSliderOwnerDuringScrollCallback
,
451 base::Unretained(&window
),
453 aura::Window
* new_window
= window
.get();
454 EXPECT_NE(old_window
, new_window
);
456 EXPECT_TRUE(slider_delegate
.created_back_layer());
457 EXPECT_TRUE(slider_delegate
.slide_completing());
458 EXPECT_TRUE(slider_delegate
.slide_completed());
459 EXPECT_FALSE(slider_delegate
.created_front_layer());
460 EXPECT_FALSE(slider_delegate
.slide_aborted());
461 EXPECT_FALSE(slider_delegate
.slider_destroyed());
464 // If the delegate doesn't create the layer to show while sliding, WindowSlider
465 // shouldn't start the slide or change delegate's state in any way in response
467 TEST_F(WindowSliderTest
, NoSlideWhenLayerCantBeCreated
) {
468 scoped_ptr
<aura::Window
> window(CreateNormalWindow(0, root_window(), NULL
));
469 window
->SetBounds(gfx::Rect(0, 0, 400, 400));
470 WindowSliderDelegateTest slider_delegate
;
471 slider_delegate
.SetCanCreateLayer(false);
472 WindowSlider
* slider
=
473 new WindowSlider(&slider_delegate
, root_window(), window
.get());
475 ui::test::EventGenerator
generator(root_window());
477 // No slide in progress should be reported during scroll since the layer
479 generator
.GestureScrollSequenceWithCallback(
482 base::TimeDelta::FromMilliseconds(10),
484 base::Bind(&ConfirmNoSlideDuringScrollCallback
, slider
));
486 EXPECT_FALSE(slider_delegate
.created_back_layer());
487 EXPECT_FALSE(slider_delegate
.slide_completing());
488 EXPECT_FALSE(slider_delegate
.slide_completed());
489 EXPECT_FALSE(slider_delegate
.created_front_layer());
490 EXPECT_FALSE(slider_delegate
.slide_aborted());
491 EXPECT_FALSE(slider_delegate
.slider_destroyed());
492 window
->SetTransform(gfx::Transform());
494 slider_delegate
.SetCanCreateLayer(true);
495 generator
.GestureScrollSequenceWithCallback(
498 base::TimeDelta::FromMilliseconds(10),
500 base::Bind(&ConfirmSlideDuringScrollCallback
, slider
));
501 EXPECT_TRUE(slider_delegate
.created_back_layer());
502 EXPECT_TRUE(slider_delegate
.slide_completing());
503 EXPECT_TRUE(slider_delegate
.slide_completed());
504 EXPECT_FALSE(slider_delegate
.created_front_layer());
505 EXPECT_FALSE(slider_delegate
.slide_aborted());
506 EXPECT_FALSE(slider_delegate
.slider_destroyed());
509 EXPECT_TRUE(slider_delegate
.slider_destroyed());
512 // Tests that the owner window can be destroyed from |OnWindowSliderDestroyed()|
513 // delegate callback without causing a crash.
514 TEST_F(WindowSliderTest
, OwnerIsDestroyedOnSliderDestroy
) {
515 size_t child_windows
= root_window()->children().size();
516 aura::Window
* window
= CreateNormalWindow(0, root_window(), NULL
);
517 window
->SetBounds(gfx::Rect(0, 0, 400, 400));
518 EXPECT_EQ(child_windows
+ 1, root_window()->children().size());
520 WindowSliderDeleteOwnerOnDestroy
slider_delegate(window
);
521 ui::test::EventGenerator
generator(root_window());
523 // Generate a horizontal overscroll.
524 scoped_ptr
<WindowSlider
> slider(
525 new WindowSlider(&slider_delegate
, root_window(), window
));
526 generator
.GestureScrollSequence(gfx::Point(10, 10),
528 base::TimeDelta::FromMilliseconds(10),
530 EXPECT_TRUE(slider_delegate
.created_back_layer());
531 EXPECT_TRUE(slider_delegate
.slide_completing());
532 EXPECT_TRUE(slider_delegate
.slide_completed());
533 EXPECT_FALSE(slider_delegate
.created_front_layer());
534 EXPECT_FALSE(slider_delegate
.slide_aborted());
535 EXPECT_FALSE(slider_delegate
.slider_destroyed());
538 // Destroying the slider would have destroyed |window| too. So |window| should
539 // not need to be destroyed here.
540 EXPECT_EQ(child_windows
, root_window()->children().size());
543 // Tests that the owner window can be destroyed from |OnWindowSlideComplete()|
544 // delegate callback without causing a crash.
545 TEST_F(WindowSliderTest
, OwnerIsDestroyedOnSlideComplete
) {
546 size_t child_windows
= root_window()->children().size();
547 aura::Window
* window
= CreateNormalWindow(0, root_window(), NULL
);
548 window
->SetBounds(gfx::Rect(0, 0, 400, 400));
549 EXPECT_EQ(child_windows
+ 1, root_window()->children().size());
551 WindowSliderDeleteOwnerOnComplete
slider_delegate(window
);
552 ui::test::EventGenerator
generator(root_window());
554 // Generate a horizontal overscroll.
555 new WindowSlider(&slider_delegate
, root_window(), window
);
556 generator
.GestureScrollSequence(gfx::Point(10, 10),
558 base::TimeDelta::FromMilliseconds(10),
560 EXPECT_TRUE(slider_delegate
.created_back_layer());
561 EXPECT_TRUE(slider_delegate
.slide_completing());
562 EXPECT_TRUE(slider_delegate
.slide_completed());
563 EXPECT_FALSE(slider_delegate
.created_front_layer());
564 EXPECT_FALSE(slider_delegate
.slide_aborted());
565 EXPECT_TRUE(slider_delegate
.slider_destroyed());
567 // Destroying the slider would have destroyed |window| too. So |window| should
568 // not need to be destroyed here.
569 EXPECT_EQ(child_windows
, root_window()->children().size());
572 // Test the scenario when two swipe gesture occur quickly one after another so
573 // that the second swipe occurs while the transition animation triggered by the
574 // first swipe is in progress.
575 // The second swipe is supposed to instantly complete the animation caused by
576 // the first swipe, ask the delegate to create a new layer, and animate it.
577 TEST_F(WindowSliderTest
, SwipeDuringSwipeAnimation
) {
578 scoped_ptr
<aura::Window
> window(CreateNormalWindow(0, root_window(), NULL
));
579 window
->SetBounds(gfx::Rect(0, 0, 400, 400));
580 WindowSliderDelegateTest slider_delegate
;
581 new WindowSlider(&slider_delegate
, root_window(), window
.get());
583 // This test uses explicit durations so needs a normal duration.
584 ui::ScopedAnimationDurationScaleMode
normal_duration(
585 ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION
);
586 ui::LayerAnimator
* animator
= window
->layer()->GetAnimator();
587 animator
->set_disable_timer_for_test(true);
588 ui::LayerAnimatorTestController
test_controller(animator
);
590 ui::test::EventGenerator
generator(root_window());
592 // Swipe forward so that |window|'s layer is the one animating.
593 generator
.GestureScrollSequence(
596 base::TimeDelta::FromMilliseconds(10),
598 EXPECT_TRUE(slider_delegate
.created_back_layer());
599 EXPECT_FALSE(slider_delegate
.slide_aborted());
600 EXPECT_FALSE(slider_delegate
.created_front_layer());
601 EXPECT_TRUE(slider_delegate
.slide_completing());
602 EXPECT_FALSE(slider_delegate
.slide_completed());
603 EXPECT_FALSE(slider_delegate
.slider_destroyed());
604 ui::ScopedLayerAnimationSettings
settings(animator
);
605 base::TimeDelta duration
= settings
.GetTransitionDuration();
606 test_controller
.StartThreadedAnimationsIfNeeded();
607 base::TimeTicks start_time1
= gfx::FrameTime::Now();
609 animator
->Step(start_time1
+ duration
/ 2);
610 EXPECT_FALSE(slider_delegate
.slide_completed());
611 slider_delegate
.Reset();
612 // Generate another horizontal swipe while the animation from the previous
613 // swipe is in progress.
614 generator
.GestureScrollSequence(
617 base::TimeDelta::FromMilliseconds(10),
619 // Performing the second swipe should instantly complete the slide started
620 // by the first swipe and create a new layer.
621 EXPECT_TRUE(slider_delegate
.created_back_layer());
622 EXPECT_FALSE(slider_delegate
.slide_aborted());
623 EXPECT_FALSE(slider_delegate
.created_front_layer());
624 EXPECT_TRUE(slider_delegate
.slide_completing());
625 EXPECT_TRUE(slider_delegate
.slide_completed());
626 EXPECT_FALSE(slider_delegate
.slider_destroyed());
627 test_controller
.StartThreadedAnimationsIfNeeded();
628 base::TimeTicks start_time2
= gfx::FrameTime::Now();
629 slider_delegate
.Reset();
630 animator
->Step(start_time2
+ duration
);
631 // The animation for the second slide should now be completed.
632 EXPECT_TRUE(slider_delegate
.slide_completed());
633 slider_delegate
.Reset();
636 EXPECT_TRUE(slider_delegate
.slider_destroyed());
639 } // namespace content