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(aura::WINDOW_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,
297 new ui::KeyEvent('a', ui::VKEY_A, ui::EF_NONE),
301 new WindowSlider(&slider_delegate, root_window(), window.get());
302 for (int i = 0; events[i]; ++i) {
303 // Generate a horizontal overscroll.
304 ui::test::EventGenerator generator(root_window());
305 generator.GestureScrollSequenceWithCallback(
308 base::TimeDelta::FromMilliseconds(10),
310 base::Bind(&DispatchEventDuringScrollCallback,
311 root_window()->GetHost()->event_processor(),
312 base::Owned(events[i])));
313 EXPECT_TRUE(slider_delegate.created_back_layer());
314 EXPECT_TRUE(slider_delegate.slide_aborted());
315 EXPECT_FALSE(slider_delegate.created_front_layer());
316 EXPECT_FALSE(slider_delegate.slide_completing());
317 EXPECT_FALSE(slider_delegate.slide_completed());
318 EXPECT_FALSE(slider_delegate.slider_destroyed());
319 slider_delegate.Reset();
322 EXPECT_TRUE(slider_delegate.slider_destroyed());
325 // Tests that the window slide can continue after it is interrupted by another
326 // event if the user continues scrolling.
327 TEST_F(WindowSliderTest, WindowSlideInterruptedThenContinues) {
328 scoped_ptr<aura::Window> window(CreateNormalWindow(0, root_window(), NULL));
329 window->SetBounds(gfx::Rect(0, 0, 400, 400));
330 WindowSliderDelegateTest slider_delegate;
332 ui::ScopedAnimationDurationScaleMode normal_duration_(
333 ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION);
334 ui::LayerAnimator* animator = window->layer()->GetAnimator();
335 animator->set_disable_timer_for_test(true);
336 ui::LayerAnimatorTestController test_controller(animator);
338 WindowSlider* slider =
339 new WindowSlider(&slider_delegate, root_window(), window.get());
341 ui::MouseEvent interrupt_event(ui::ET_MOUSE_MOVED,
346 ui::test::EventGenerator generator(root_window());
348 // Start the scroll sequence. Scroll forward so that |window|'s layer is the
350 const int kTouchId = 5;
351 ui::TouchEvent press(ui::ET_TOUCH_PRESSED,
354 ui::EventTimeForNow());
355 generator.Dispatch(&press);
357 // First scroll event of the sequence.
358 ui::TouchEvent move1(ui::ET_TOUCH_MOVED,
361 ui::EventTimeForNow());
362 generator.Dispatch(&move1);
363 EXPECT_TRUE(slider->IsSlideInProgress());
364 EXPECT_FALSE(animator->is_animating());
365 // Dispatch the event after the first scroll and confirm it interrupts the
366 // scroll and starts the "reset slide" animation.
367 generator.Dispatch(&interrupt_event);
368 EXPECT_TRUE(slider->IsSlideInProgress());
369 EXPECT_TRUE(animator->is_animating());
370 EXPECT_TRUE(slider_delegate.created_back_layer());
371 // slide_aborted() should be false because the 'reset slide' animation
372 // hasn't completed yet.
373 EXPECT_FALSE(slider_delegate.slide_aborted());
374 EXPECT_FALSE(slider_delegate.created_front_layer());
375 EXPECT_FALSE(slider_delegate.slide_completing());
376 EXPECT_FALSE(slider_delegate.slide_completed());
377 EXPECT_FALSE(slider_delegate.slider_destroyed());
378 slider_delegate.Reset();
380 // Second scroll event of the sequence.
381 ui::TouchEvent move2(ui::ET_TOUCH_MOVED,
384 ui::EventTimeForNow());
385 generator.Dispatch(&move2);
386 // The second scroll should instantly cause the animation to complete.
387 EXPECT_FALSE(animator->is_animating());
388 EXPECT_FALSE(slider_delegate.created_back_layer());
389 // The ResetScroll() animation was completed, so now slide_aborted()
391 EXPECT_TRUE(slider_delegate.slide_aborted());
393 // Third scroll event of the sequence.
394 ui::TouchEvent move3(ui::ET_TOUCH_MOVED,
397 ui::EventTimeForNow());
398 generator.Dispatch(&move3);
399 // The third scroll should re-start the sliding.
400 EXPECT_TRUE(slider->IsSlideInProgress());
401 EXPECT_TRUE(slider_delegate.created_back_layer());
403 // Generate the release event, finishing the scroll sequence.
404 ui::TouchEvent release(ui::ET_TOUCH_RELEASED,
407 ui::EventTimeForNow());
408 generator.Dispatch(&release);
409 // When the scroll gesture ends, the slide animation should start.
410 EXPECT_TRUE(slider->IsSlideInProgress());
411 EXPECT_TRUE(animator->is_animating());
412 EXPECT_TRUE(slider_delegate.slide_completing());
413 EXPECT_FALSE(slider_delegate.created_front_layer());
414 EXPECT_FALSE(slider_delegate.slide_completed());
415 EXPECT_FALSE(slider_delegate.slider_destroyed());
417 // Progress the animator to complete the slide animation.
418 ui::ScopedLayerAnimationSettings settings(animator);
419 base::TimeDelta duration = settings.GetTransitionDuration();
420 test_controller.StartThreadedAnimationsIfNeeded();
421 animator->Step(gfx::FrameTime::Now() + duration);
423 EXPECT_TRUE(slider_delegate.slide_completed());
424 EXPECT_FALSE(slider_delegate.slider_destroyed());
427 EXPECT_TRUE(slider_delegate.slider_destroyed());
430 // Tests that the slide works correctly when the owner of the window changes
431 // during the duration of the slide.
432 TEST_F(WindowSliderTest, OwnerWindowChangesDuringWindowSlide) {
433 scoped_ptr<aura::Window> parent(CreateNormalWindow(0, root_window(), NULL));
435 NoEventWindowDelegate window_delegate;
436 window_delegate.set_window_component(HTNOWHERE);
437 scoped_ptr<aura::Window> window(CreateNormalWindow(1, parent.get(),
440 WindowSliderDelegateTest slider_delegate;
441 scoped_ptr<WindowSlider> slider(
442 new WindowSlider(&slider_delegate, parent.get(), window.get()));
444 // Generate a horizontal scroll, and change the owner in the middle of the
446 ui::test::EventGenerator generator(root_window());
447 aura::Window* old_window = window.get();
448 generator.GestureScrollSequenceWithCallback(
451 base::TimeDelta::FromMilliseconds(10),
453 base::Bind(&ChangeSliderOwnerDuringScrollCallback,
454 base::Unretained(&window),
456 aura::Window* new_window = window.get();
457 EXPECT_NE(old_window, new_window);
459 EXPECT_TRUE(slider_delegate.created_back_layer());
460 EXPECT_TRUE(slider_delegate.slide_completing());
461 EXPECT_TRUE(slider_delegate.slide_completed());
462 EXPECT_FALSE(slider_delegate.created_front_layer());
463 EXPECT_FALSE(slider_delegate.slide_aborted());
464 EXPECT_FALSE(slider_delegate.slider_destroyed());
467 // If the delegate doesn't create the layer to show while sliding, WindowSlider
468 // shouldn't start the slide or change delegate's state in any way in response
470 TEST_F(WindowSliderTest, NoSlideWhenLayerCantBeCreated) {
471 scoped_ptr<aura::Window> window(CreateNormalWindow(0, root_window(), NULL));
472 window->SetBounds(gfx::Rect(0, 0, 400, 400));
473 WindowSliderDelegateTest slider_delegate;
474 slider_delegate.SetCanCreateLayer(false);
475 WindowSlider* slider =
476 new WindowSlider(&slider_delegate, root_window(), window.get());
478 ui::test::EventGenerator generator(root_window());
480 // No slide in progress should be reported during scroll since the layer
482 generator.GestureScrollSequenceWithCallback(
485 base::TimeDelta::FromMilliseconds(10),
487 base::Bind(&ConfirmNoSlideDuringScrollCallback, slider));
489 EXPECT_FALSE(slider_delegate.created_back_layer());
490 EXPECT_FALSE(slider_delegate.slide_completing());
491 EXPECT_FALSE(slider_delegate.slide_completed());
492 EXPECT_FALSE(slider_delegate.created_front_layer());
493 EXPECT_FALSE(slider_delegate.slide_aborted());
494 EXPECT_FALSE(slider_delegate.slider_destroyed());
495 window->SetTransform(gfx::Transform());
497 slider_delegate.SetCanCreateLayer(true);
498 generator.GestureScrollSequenceWithCallback(
501 base::TimeDelta::FromMilliseconds(10),
503 base::Bind(&ConfirmSlideDuringScrollCallback, slider));
504 EXPECT_TRUE(slider_delegate.created_back_layer());
505 EXPECT_TRUE(slider_delegate.slide_completing());
506 EXPECT_TRUE(slider_delegate.slide_completed());
507 EXPECT_FALSE(slider_delegate.created_front_layer());
508 EXPECT_FALSE(slider_delegate.slide_aborted());
509 EXPECT_FALSE(slider_delegate.slider_destroyed());
512 EXPECT_TRUE(slider_delegate.slider_destroyed());
515 // Tests that the owner window can be destroyed from |OnWindowSliderDestroyed()|
516 // delegate callback without causing a crash.
517 TEST_F(WindowSliderTest, OwnerIsDestroyedOnSliderDestroy) {
518 size_t child_windows = root_window()->children().size();
519 aura::Window* window = CreateNormalWindow(0, root_window(), NULL);
520 window->SetBounds(gfx::Rect(0, 0, 400, 400));
521 EXPECT_EQ(child_windows + 1, root_window()->children().size());
523 WindowSliderDeleteOwnerOnDestroy slider_delegate(window);
524 ui::test::EventGenerator generator(root_window());
526 // Generate a horizontal overscroll.
527 scoped_ptr<WindowSlider> slider(
528 new WindowSlider(&slider_delegate, root_window(), window));
529 generator.GestureScrollSequence(gfx::Point(10, 10),
531 base::TimeDelta::FromMilliseconds(10),
533 EXPECT_TRUE(slider_delegate.created_back_layer());
534 EXPECT_TRUE(slider_delegate.slide_completing());
535 EXPECT_TRUE(slider_delegate.slide_completed());
536 EXPECT_FALSE(slider_delegate.created_front_layer());
537 EXPECT_FALSE(slider_delegate.slide_aborted());
538 EXPECT_FALSE(slider_delegate.slider_destroyed());
541 // Destroying the slider would have destroyed |window| too. So |window| should
542 // not need to be destroyed here.
543 EXPECT_EQ(child_windows, root_window()->children().size());
546 // Tests that the owner window can be destroyed from |OnWindowSlideComplete()|
547 // delegate callback without causing a crash.
548 TEST_F(WindowSliderTest, OwnerIsDestroyedOnSlideComplete) {
549 size_t child_windows = root_window()->children().size();
550 aura::Window* window = CreateNormalWindow(0, root_window(), NULL);
551 window->SetBounds(gfx::Rect(0, 0, 400, 400));
552 EXPECT_EQ(child_windows + 1, root_window()->children().size());
554 WindowSliderDeleteOwnerOnComplete slider_delegate(window);
555 ui::test::EventGenerator generator(root_window());
557 // Generate a horizontal overscroll.
558 new WindowSlider(&slider_delegate, root_window(), window);
559 generator.GestureScrollSequence(gfx::Point(10, 10),
561 base::TimeDelta::FromMilliseconds(10),
563 EXPECT_TRUE(slider_delegate.created_back_layer());
564 EXPECT_TRUE(slider_delegate.slide_completing());
565 EXPECT_TRUE(slider_delegate.slide_completed());
566 EXPECT_FALSE(slider_delegate.created_front_layer());
567 EXPECT_FALSE(slider_delegate.slide_aborted());
568 EXPECT_TRUE(slider_delegate.slider_destroyed());
570 // Destroying the slider would have destroyed |window| too. So |window| should
571 // not need to be destroyed here.
572 EXPECT_EQ(child_windows, root_window()->children().size());
575 // Test the scenario when two swipe gesture occur quickly one after another so
576 // that the second swipe occurs while the transition animation triggered by the
577 // first swipe is in progress.
578 // The second swipe is supposed to instantly complete the animation caused by
579 // the first swipe, ask the delegate to create a new layer, and animate it.
580 TEST_F(WindowSliderTest, SwipeDuringSwipeAnimation) {
581 scoped_ptr<aura::Window> window(CreateNormalWindow(0, root_window(), NULL));
582 window->SetBounds(gfx::Rect(0, 0, 400, 400));
583 WindowSliderDelegateTest slider_delegate;
584 new WindowSlider(&slider_delegate, root_window(), window.get());
586 // This test uses explicit durations so needs a normal duration.
587 ui::ScopedAnimationDurationScaleMode normal_duration(
588 ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION);
589 ui::LayerAnimator* animator = window->layer()->GetAnimator();
590 animator->set_disable_timer_for_test(true);
591 ui::LayerAnimatorTestController test_controller(animator);
593 ui::test::EventGenerator generator(root_window());
595 // Swipe forward so that |window|'s layer is the one animating.
596 generator.GestureScrollSequence(
599 base::TimeDelta::FromMilliseconds(10),
601 EXPECT_TRUE(slider_delegate.created_back_layer());
602 EXPECT_FALSE(slider_delegate.slide_aborted());
603 EXPECT_FALSE(slider_delegate.created_front_layer());
604 EXPECT_TRUE(slider_delegate.slide_completing());
605 EXPECT_FALSE(slider_delegate.slide_completed());
606 EXPECT_FALSE(slider_delegate.slider_destroyed());
607 ui::ScopedLayerAnimationSettings settings(animator);
608 base::TimeDelta duration = settings.GetTransitionDuration();
609 test_controller.StartThreadedAnimationsIfNeeded();
610 base::TimeTicks start_time1 = gfx::FrameTime::Now();
612 animator->Step(start_time1 + duration / 2);
613 EXPECT_FALSE(slider_delegate.slide_completed());
614 slider_delegate.Reset();
615 // Generate another horizontal swipe while the animation from the previous
616 // swipe is in progress.
617 generator.GestureScrollSequence(
620 base::TimeDelta::FromMilliseconds(10),
622 // Performing the second swipe should instantly complete the slide started
623 // by the first swipe and create a new layer.
624 EXPECT_TRUE(slider_delegate.created_back_layer());
625 EXPECT_FALSE(slider_delegate.slide_aborted());
626 EXPECT_FALSE(slider_delegate.created_front_layer());
627 EXPECT_TRUE(slider_delegate.slide_completing());
628 EXPECT_TRUE(slider_delegate.slide_completed());
629 EXPECT_FALSE(slider_delegate.slider_destroyed());
630 test_controller.StartThreadedAnimationsIfNeeded();
631 base::TimeTicks start_time2 = gfx::FrameTime::Now();
632 slider_delegate.Reset();
633 animator->Step(start_time2 + duration);
634 // The animation for the second slide should now be completed.
635 EXPECT_TRUE(slider_delegate.slide_completed());
636 slider_delegate.Reset();
639 EXPECT_TRUE(slider_delegate.slider_destroyed());
642 } // namespace content