Re-subimission of https://codereview.chromium.org/1041213003/
[chromium-blink-merge.git] / content / browser / web_contents / aura / window_slider_unittest.cc
bloba029dd8feb2fc2fbfdfa0a4cfe27cd050a7caadc
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"
7 #include "base/bind.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"
22 namespace content {
24 void DispatchEventDuringScrollCallback(ui::EventProcessor* dispatcher,
25 ui::Event* event,
26 ui::EventType type,
27 const gfx::Vector2dF& delta) {
28 if (type != ui::ET_GESTURE_SCROLL_UPDATE)
29 return;
30 ui::EventDispatchDetails details = dispatcher->OnEventFromSource(event);
31 CHECK(!details.dispatcher_destroyed);
34 void ChangeSliderOwnerDuringScrollCallback(scoped_ptr<aura::Window>* window,
35 WindowSlider* slider,
36 ui::EventType type,
37 const gfx::Vector2dF& delta) {
38 if (type != ui::ET_GESTURE_SCROLL_UPDATE)
39 return;
40 aura::Window* new_window = new aura::Window(NULL);
41 new_window->Init(ui::LAYER_TEXTURED);
42 new_window->Show();
43 slider->ChangeOwner(new_window);
44 (*window)->parent()->AddChild(new_window);
45 window->reset(new_window);
48 void ConfirmSlideDuringScrollCallback(WindowSlider* slider,
49 ui::EventType type,
50 const gfx::Vector2dF& delta) {
51 static float total_delta_x = 0;
52 if (type == ui::ET_GESTURE_SCROLL_BEGIN)
53 total_delta_x = 0;
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());
59 } else {
60 EXPECT_FALSE(slider->IsSlideInProgress());
64 void ConfirmNoSlideDuringScrollCallback(WindowSlider* slider,
65 ui::EventType type,
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 {
72 public:
73 NoEventWindowDelegate() {
75 ~NoEventWindowDelegate() override {}
77 private:
78 // Overridden from aura::WindowDelegate:
79 bool HasHitTestMask() const override { return true; }
81 DISALLOW_COPY_AND_ASSIGN(NoEventWindowDelegate);
84 class WindowSliderDelegateTest : public WindowSlider::Delegate {
85 public:
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_);
100 void Reset() {
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_; }
121 protected:
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);
126 return layer;
129 // Overridden from WindowSlider::Delegate:
130 ui::Layer* CreateBackLayer() override {
131 if (!can_create_layer_)
132 return NULL;
133 created_back_layer_ = true;
134 return CreateLayerForTest();
137 ui::Layer* CreateFrontLayer() override {
138 if (!can_create_layer_)
139 return NULL;
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; }
154 private:
155 bool can_create_layer_;
156 bool created_back_layer_;
157 bool created_front_layer_;
158 bool slide_completing_;
159 bool slide_completed_;
160 bool slide_aborted_;
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 {
168 public:
169 explicit WindowSliderDeleteOwnerOnDestroy(aura::Window* owner)
170 : owner_(owner) {
172 ~WindowSliderDeleteOwnerOnDestroy() override {}
174 private:
175 // Overridden from WindowSlider::Delegate:
176 void OnWindowSliderDestroyed() override {
177 WindowSliderDelegateTest::OnWindowSliderDestroyed();
178 delete owner_;
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 {
187 public:
188 explicit WindowSliderDeleteOwnerOnComplete(aura::Window* owner)
189 : owner_(owner) {
191 ~WindowSliderDeleteOwnerOnComplete() override {}
193 private:
194 // Overridden from WindowSlider::Delegate:
195 void OnWindowSlideCompleted(scoped_ptr<ui::Layer> layer) override {
196 WindowSliderDelegateTest::OnWindowSlideCompleted(layer.Pass());
197 delete owner_;
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(
217 gfx::Point(10, 10),
218 gfx::Point(180, 10),
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(
234 gfx::Point(180, 10),
235 gfx::Point(10, 10),
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(
250 gfx::Point(10, 10),
251 gfx::Point(10, 80),
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(
266 gfx::Point(10, 10),
267 gfx::Point(80, 10),
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.
281 window.reset();
282 EXPECT_TRUE(slider_delegate.slider_destroyed());
285 // Tests that the window slide is interrupted when a different type of event
286 // happens.
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),
296 nullptr
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(
304 gfx::Point(10, 10),
305 gfx::Point(80, 10),
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();
319 window.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
346 // one animating.
347 const int kTouchId = 5;
348 ui::TouchEvent press(ui::ET_TOUCH_PRESSED,
349 gfx::Point(10, 10),
350 kTouchId,
351 ui::EventTimeForNow());
352 generator.Dispatch(&press);
354 // First scroll event of the sequence.
355 ui::TouchEvent move1(ui::ET_TOUCH_MOVED,
356 gfx::Point(100, 10),
357 kTouchId,
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,
379 gfx::Point(200, 10),
380 kTouchId,
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()
387 // should be true.
388 EXPECT_TRUE(slider_delegate.slide_aborted());
390 // Third scroll event of the sequence.
391 ui::TouchEvent move3(ui::ET_TOUCH_MOVED,
392 gfx::Point(300, 10),
393 kTouchId,
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,
402 gfx::Point(300, 10),
403 kTouchId,
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());
423 window.reset();
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(),
435 &window_delegate));
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
442 // scroll.
443 ui::test::EventGenerator generator(root_window());
444 aura::Window* old_window = window.get();
445 generator.GestureScrollSequenceWithCallback(
446 gfx::Point(10, 10),
447 gfx::Point(80, 10),
448 base::TimeDelta::FromMilliseconds(10),
450 base::Bind(&ChangeSliderOwnerDuringScrollCallback,
451 base::Unretained(&window),
452 slider.get()));
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
466 // to user input.
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
478 // wasn't created.
479 generator.GestureScrollSequenceWithCallback(
480 gfx::Point(10, 10),
481 gfx::Point(180, 10),
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(
496 gfx::Point(10, 10),
497 gfx::Point(180, 10),
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());
508 window.reset();
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),
527 gfx::Point(180, 10),
528 base::TimeDelta::FromMilliseconds(10),
529 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());
537 slider.reset();
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),
557 gfx::Point(180, 10),
558 base::TimeDelta::FromMilliseconds(10),
559 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(
594 gfx::Point(10, 10),
595 gfx::Point(180, 10),
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(
615 gfx::Point(10, 10),
616 gfx::Point(180, 10),
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();
635 window.reset();
636 EXPECT_TRUE(slider_delegate.slider_destroyed());
639 } // namespace content