Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / content / browser / web_contents / aura / window_slider_unittest.cc
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.
4
5 #include "content/browser/web_contents/aura/window_slider.h"
6
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"
21
22 namespace content {
23
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);
32 }
33
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(aura::WINDOW_LAYER_TEXTURED);
42   new_window->Show();
43   slider->ChangeOwner(new_window);
44   (*window)->parent()->AddChild(new_window);
45   window->reset(new_window);
46 }
47
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;
54
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());
61   }
62 }
63
64 void ConfirmNoSlideDuringScrollCallback(WindowSlider* slider,
65                                         ui::EventType type,
66                                         const gfx::Vector2dF& delta) {
67   EXPECT_FALSE(slider->IsSlideInProgress());
68 }
69
70 // The window delegate does not receive any events.
71 class NoEventWindowDelegate : public aura::test::TestWindowDelegate {
72  public:
73   NoEventWindowDelegate() {
74   }
75   ~NoEventWindowDelegate() override {}
76
77  private:
78   // Overridden from aura::WindowDelegate:
79   bool HasHitTestMask() const override { return true; }
80
81   DISALLOW_COPY_AND_ASSIGN(NoEventWindowDelegate);
82 };
83
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) {
94   }
95   ~WindowSliderDelegateTest() override {
96     // Make sure slide_completed() gets called if slide_completing() was called.
97     CHECK(!slide_completing_ || slide_completed_);
98   }
99
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;
108   }
109
110   void SetCanCreateLayer(bool can_create_layer) {
111     can_create_layer_ = can_create_layer;
112   }
113
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_; }
120
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;
127   }
128
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();
135   }
136
137   ui::Layer* CreateFrontLayer() override {
138     if (!can_create_layer_)
139       return NULL;
140     created_front_layer_ = true;
141     return CreateLayerForTest();
142   }
143
144   void OnWindowSlideCompleted(scoped_ptr<ui::Layer> layer) override {
145     slide_completed_ = true;
146   }
147
148   void OnWindowSlideCompleting() override { slide_completing_ = true; }
149
150   void OnWindowSlideAborted() override { slide_aborted_ = true; }
151
152   void OnWindowSliderDestroyed() override { slider_destroyed_ = true; }
153
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_;
162
163   DISALLOW_COPY_AND_ASSIGN(WindowSliderDelegateTest);
164 };
165
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) {
171   }
172   ~WindowSliderDeleteOwnerOnDestroy() override {}
173
174  private:
175   // Overridden from WindowSlider::Delegate:
176   void OnWindowSliderDestroyed() override {
177     WindowSliderDelegateTest::OnWindowSliderDestroyed();
178     delete owner_;
179   }
180
181   aura::Window* owner_;
182   DISALLOW_COPY_AND_ASSIGN(WindowSliderDeleteOwnerOnDestroy);
183 };
184
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) {
190   }
191   ~WindowSliderDeleteOwnerOnComplete() override {}
192
193  private:
194   // Overridden from WindowSlider::Delegate:
195   void OnWindowSlideCompleted(scoped_ptr<ui::Layer> layer) override {
196     WindowSliderDelegateTest::OnWindowSlideCompleted(layer.Pass());
197     delete owner_;
198   }
199
200   aura::Window* owner_;
201   DISALLOW_COPY_AND_ASSIGN(WindowSliderDeleteOwnerOnComplete);
202 };
203
204 typedef aura::test::AuraTestBase WindowSliderTest;
205
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;
210
211   ui::test::EventGenerator generator(root_window());
212
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),
220       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());
231
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),
237       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();
247
248   // Generate a vertical overscroll.
249   generator.GestureScrollSequenceWithCallback(
250       gfx::Point(10, 10),
251       gfx::Point(10, 80),
252       base::TimeDelta::FromMilliseconds(10),
253       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();
262
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),
269       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();
279
280   // Destroy the window. This should destroy the slider.
281   window.reset();
282   EXPECT_TRUE(slider_delegate.slider_destroyed());
283 }
284
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;
291
292   ui::Event* events[] = {
293     new ui::MouseEvent(ui::ET_MOUSE_MOVED,
294                        gfx::Point(55, 10),
295                        gfx::Point(55, 10),
296                        0, 0),
297     new ui::KeyEvent('a', ui::VKEY_A, ui::EF_NONE),
298     NULL
299   };
300
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(
306         gfx::Point(10, 10),
307         gfx::Point(80, 10),
308         base::TimeDelta::FromMilliseconds(10),
309         1,
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();
320   }
321   window.reset();
322   EXPECT_TRUE(slider_delegate.slider_destroyed());
323 }
324
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;
331
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);
337
338   WindowSlider* slider =
339       new WindowSlider(&slider_delegate, root_window(), window.get());
340
341   ui::MouseEvent interrupt_event(ui::ET_MOUSE_MOVED,
342                                  gfx::Point(55, 10),
343                                  gfx::Point(55, 10),
344                                  0, 0);
345
346   ui::test::EventGenerator generator(root_window());
347
348   // Start the scroll sequence. Scroll forward so that |window|'s layer is the
349   // one animating.
350   const int kTouchId = 5;
351   ui::TouchEvent press(ui::ET_TOUCH_PRESSED,
352                        gfx::Point(10, 10),
353                        kTouchId,
354                        ui::EventTimeForNow());
355   generator.Dispatch(&press);
356
357   // First scroll event of the sequence.
358   ui::TouchEvent move1(ui::ET_TOUCH_MOVED,
359                        gfx::Point(100, 10),
360                        kTouchId,
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();
379
380   // Second scroll event of the sequence.
381   ui::TouchEvent move2(ui::ET_TOUCH_MOVED,
382                        gfx::Point(200, 10),
383                        kTouchId,
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()
390   // should be true.
391   EXPECT_TRUE(slider_delegate.slide_aborted());
392
393   // Third scroll event of the sequence.
394   ui::TouchEvent move3(ui::ET_TOUCH_MOVED,
395                        gfx::Point(300, 10),
396                        kTouchId,
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());
402
403   // Generate the release event, finishing the scroll sequence.
404   ui::TouchEvent release(ui::ET_TOUCH_RELEASED,
405                          gfx::Point(300, 10),
406                          kTouchId,
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());
416
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);
422
423   EXPECT_TRUE(slider_delegate.slide_completed());
424   EXPECT_FALSE(slider_delegate.slider_destroyed());
425
426   window.reset();
427   EXPECT_TRUE(slider_delegate.slider_destroyed());
428 }
429
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));
434
435   NoEventWindowDelegate window_delegate;
436   window_delegate.set_window_component(HTNOWHERE);
437   scoped_ptr<aura::Window> window(CreateNormalWindow(1, parent.get(),
438                                                      &window_delegate));
439
440   WindowSliderDelegateTest slider_delegate;
441   scoped_ptr<WindowSlider> slider(
442       new WindowSlider(&slider_delegate, parent.get(), window.get()));
443
444   // Generate a horizontal scroll, and change the owner in the middle of the
445   // scroll.
446   ui::test::EventGenerator generator(root_window());
447   aura::Window* old_window = window.get();
448   generator.GestureScrollSequenceWithCallback(
449       gfx::Point(10, 10),
450       gfx::Point(80, 10),
451       base::TimeDelta::FromMilliseconds(10),
452       1,
453       base::Bind(&ChangeSliderOwnerDuringScrollCallback,
454                  base::Unretained(&window),
455                  slider.get()));
456   aura::Window* new_window = window.get();
457   EXPECT_NE(old_window, new_window);
458
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());
465 }
466
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
469 // to user input.
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());
477
478   ui::test::EventGenerator generator(root_window());
479
480   // No slide in progress should be reported during scroll since the layer
481   // wasn't created.
482   generator.GestureScrollSequenceWithCallback(
483       gfx::Point(10, 10),
484       gfx::Point(180, 10),
485       base::TimeDelta::FromMilliseconds(10),
486       1,
487       base::Bind(&ConfirmNoSlideDuringScrollCallback, slider));
488
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());
496
497   slider_delegate.SetCanCreateLayer(true);
498   generator.GestureScrollSequenceWithCallback(
499       gfx::Point(10, 10),
500       gfx::Point(180, 10),
501       base::TimeDelta::FromMilliseconds(10),
502       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());
510
511   window.reset();
512   EXPECT_TRUE(slider_delegate.slider_destroyed());
513 }
514
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());
522
523   WindowSliderDeleteOwnerOnDestroy slider_delegate(window);
524   ui::test::EventGenerator generator(root_window());
525
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),
530                                   gfx::Point(180, 10),
531                                   base::TimeDelta::FromMilliseconds(10),
532                                   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());
539
540   slider.reset();
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());
544 }
545
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());
553
554   WindowSliderDeleteOwnerOnComplete slider_delegate(window);
555   ui::test::EventGenerator generator(root_window());
556
557   // Generate a horizontal overscroll.
558   new WindowSlider(&slider_delegate, root_window(), window);
559   generator.GestureScrollSequence(gfx::Point(10, 10),
560                                   gfx::Point(180, 10),
561                                   base::TimeDelta::FromMilliseconds(10),
562                                   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());
569
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());
573 }
574
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());
585
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);
592
593   ui::test::EventGenerator generator(root_window());
594
595   // Swipe forward so that |window|'s layer is the one animating.
596   generator.GestureScrollSequence(
597       gfx::Point(10, 10),
598       gfx::Point(180, 10),
599       base::TimeDelta::FromMilliseconds(10),
600       2);
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();
611
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(
618       gfx::Point(10, 10),
619       gfx::Point(180, 10),
620       base::TimeDelta::FromMilliseconds(10),
621       2);
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();
637
638   window.reset();
639   EXPECT_TRUE(slider_delegate.slider_destroyed());
640 }
641
642 }  // namespace content