Upstream version 9.38.198.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   virtual ~NoEventWindowDelegate() {}
76
77  private:
78   // Overridden from aura::WindowDelegate:
79   virtual 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   virtual ~WindowSliderDelegateTest() {
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   virtual ui::Layer* CreateBackLayer() OVERRIDE {
131     if (!can_create_layer_)
132       return NULL;
133     created_back_layer_ = true;
134     return CreateLayerForTest();
135   }
136
137   virtual ui::Layer* CreateFrontLayer() OVERRIDE {
138     if (!can_create_layer_)
139       return NULL;
140     created_front_layer_ = true;
141     return CreateLayerForTest();
142   }
143
144   virtual void OnWindowSlideCompleted(scoped_ptr<ui::Layer> layer) OVERRIDE {
145     slide_completed_ = true;
146   }
147
148   virtual void OnWindowSlideCompleting() OVERRIDE {
149     slide_completing_ = true;
150   }
151
152   virtual void OnWindowSlideAborted() OVERRIDE {
153     slide_aborted_ = true;
154   }
155
156   virtual void OnWindowSliderDestroyed() OVERRIDE {
157     slider_destroyed_ = true;
158   }
159
160  private:
161   bool can_create_layer_;
162   bool created_back_layer_;
163   bool created_front_layer_;
164   bool slide_completing_;
165   bool slide_completed_;
166   bool slide_aborted_;
167   bool slider_destroyed_;
168
169   DISALLOW_COPY_AND_ASSIGN(WindowSliderDelegateTest);
170 };
171
172 // This delegate destroys the owner window when the slider is destroyed.
173 class WindowSliderDeleteOwnerOnDestroy : public WindowSliderDelegateTest {
174  public:
175   explicit WindowSliderDeleteOwnerOnDestroy(aura::Window* owner)
176       : owner_(owner) {
177   }
178   virtual ~WindowSliderDeleteOwnerOnDestroy() {}
179
180  private:
181   // Overridden from WindowSlider::Delegate:
182   virtual void OnWindowSliderDestroyed() OVERRIDE {
183     WindowSliderDelegateTest::OnWindowSliderDestroyed();
184     delete owner_;
185   }
186
187   aura::Window* owner_;
188   DISALLOW_COPY_AND_ASSIGN(WindowSliderDeleteOwnerOnDestroy);
189 };
190
191 // This delegate destroyes the owner window when a slide is completed.
192 class WindowSliderDeleteOwnerOnComplete : public WindowSliderDelegateTest {
193  public:
194   explicit WindowSliderDeleteOwnerOnComplete(aura::Window* owner)
195       : owner_(owner) {
196   }
197   virtual ~WindowSliderDeleteOwnerOnComplete() {}
198
199  private:
200   // Overridden from WindowSlider::Delegate:
201   virtual void OnWindowSlideCompleted(scoped_ptr<ui::Layer> layer) OVERRIDE {
202     WindowSliderDelegateTest::OnWindowSlideCompleted(layer.Pass());
203     delete owner_;
204   }
205
206   aura::Window* owner_;
207   DISALLOW_COPY_AND_ASSIGN(WindowSliderDeleteOwnerOnComplete);
208 };
209
210 typedef aura::test::AuraTestBase WindowSliderTest;
211
212 TEST_F(WindowSliderTest, WindowSlideUsingGesture) {
213   scoped_ptr<aura::Window> window(CreateNormalWindow(0, root_window(), NULL));
214   window->SetBounds(gfx::Rect(0, 0, 400, 400));
215   WindowSliderDelegateTest slider_delegate;
216
217   ui::test::EventGenerator generator(root_window());
218
219   // Generate a horizontal overscroll.
220   WindowSlider* slider =
221       new WindowSlider(&slider_delegate, root_window(), window.get());
222   generator.GestureScrollSequenceWithCallback(
223       gfx::Point(10, 10),
224       gfx::Point(180, 10),
225       base::TimeDelta::FromMilliseconds(10),
226       10,
227       base::Bind(&ConfirmSlideDuringScrollCallback, slider));
228   EXPECT_TRUE(slider_delegate.created_back_layer());
229   EXPECT_TRUE(slider_delegate.slide_completing());
230   EXPECT_TRUE(slider_delegate.slide_completed());
231   EXPECT_FALSE(slider_delegate.created_front_layer());
232   EXPECT_FALSE(slider_delegate.slide_aborted());
233   EXPECT_FALSE(slider_delegate.slider_destroyed());
234   EXPECT_FALSE(slider->IsSlideInProgress());
235   slider_delegate.Reset();
236   window->SetTransform(gfx::Transform());
237
238   // Generate a horizontal overscroll in the reverse direction.
239   generator.GestureScrollSequenceWithCallback(
240       gfx::Point(180, 10),
241       gfx::Point(10, 10),
242       base::TimeDelta::FromMilliseconds(10),
243       10,
244       base::Bind(&ConfirmSlideDuringScrollCallback, slider));
245   EXPECT_TRUE(slider_delegate.created_front_layer());
246   EXPECT_TRUE(slider_delegate.slide_completing());
247   EXPECT_TRUE(slider_delegate.slide_completed());
248   EXPECT_FALSE(slider_delegate.created_back_layer());
249   EXPECT_FALSE(slider_delegate.slide_aborted());
250   EXPECT_FALSE(slider_delegate.slider_destroyed());
251   EXPECT_FALSE(slider->IsSlideInProgress());
252   slider_delegate.Reset();
253
254   // Generate a vertical overscroll.
255   generator.GestureScrollSequenceWithCallback(
256       gfx::Point(10, 10),
257       gfx::Point(10, 80),
258       base::TimeDelta::FromMilliseconds(10),
259       10,
260       base::Bind(&ConfirmNoSlideDuringScrollCallback, slider));
261   EXPECT_FALSE(slider_delegate.created_back_layer());
262   EXPECT_FALSE(slider_delegate.slide_completing());
263   EXPECT_FALSE(slider_delegate.slide_completed());
264   EXPECT_FALSE(slider_delegate.created_front_layer());
265   EXPECT_FALSE(slider_delegate.slide_aborted());
266   EXPECT_FALSE(slider->IsSlideInProgress());
267   slider_delegate.Reset();
268
269   // Generate a horizontal scroll that starts overscroll, but doesn't scroll
270   // enough to complete it.
271   generator.GestureScrollSequenceWithCallback(
272       gfx::Point(10, 10),
273       gfx::Point(80, 10),
274       base::TimeDelta::FromMilliseconds(10),
275       10,
276       base::Bind(&ConfirmSlideDuringScrollCallback, slider));
277   EXPECT_TRUE(slider_delegate.created_back_layer());
278   EXPECT_TRUE(slider_delegate.slide_aborted());
279   EXPECT_FALSE(slider_delegate.created_front_layer());
280   EXPECT_FALSE(slider_delegate.slide_completing());
281   EXPECT_FALSE(slider_delegate.slide_completed());
282   EXPECT_FALSE(slider_delegate.slider_destroyed());
283   EXPECT_FALSE(slider->IsSlideInProgress());
284   slider_delegate.Reset();
285
286   // Destroy the window. This should destroy the slider.
287   window.reset();
288   EXPECT_TRUE(slider_delegate.slider_destroyed());
289 }
290
291 // Tests that the window slide is interrupted when a different type of event
292 // happens.
293 TEST_F(WindowSliderTest, WindowSlideIsCancelledOnEvent) {
294   scoped_ptr<aura::Window> window(CreateNormalWindow(0, root_window(), NULL));
295   window->SetBounds(gfx::Rect(0, 0, 400, 400));
296   WindowSliderDelegateTest slider_delegate;
297
298   ui::Event* events[] = {
299     new ui::MouseEvent(ui::ET_MOUSE_MOVED,
300                        gfx::Point(55, 10),
301                        gfx::Point(55, 10),
302                        0, 0),
303     new ui::KeyEvent('a', ui::VKEY_A, ui::EF_NONE),
304     NULL
305   };
306
307   new WindowSlider(&slider_delegate, root_window(), window.get());
308   for (int i = 0; events[i]; ++i) {
309     // Generate a horizontal overscroll.
310     ui::test::EventGenerator generator(root_window());
311     generator.GestureScrollSequenceWithCallback(
312         gfx::Point(10, 10),
313         gfx::Point(80, 10),
314         base::TimeDelta::FromMilliseconds(10),
315         1,
316         base::Bind(&DispatchEventDuringScrollCallback,
317                    root_window()->GetHost()->event_processor(),
318                    base::Owned(events[i])));
319     EXPECT_TRUE(slider_delegate.created_back_layer());
320     EXPECT_TRUE(slider_delegate.slide_aborted());
321     EXPECT_FALSE(slider_delegate.created_front_layer());
322     EXPECT_FALSE(slider_delegate.slide_completing());
323     EXPECT_FALSE(slider_delegate.slide_completed());
324     EXPECT_FALSE(slider_delegate.slider_destroyed());
325     slider_delegate.Reset();
326   }
327   window.reset();
328   EXPECT_TRUE(slider_delegate.slider_destroyed());
329 }
330
331 // Tests that the window slide can continue after it is interrupted by another
332 // event if the user continues scrolling.
333 TEST_F(WindowSliderTest, WindowSlideInterruptedThenContinues) {
334   scoped_ptr<aura::Window> window(CreateNormalWindow(0, root_window(), NULL));
335   window->SetBounds(gfx::Rect(0, 0, 400, 400));
336   WindowSliderDelegateTest slider_delegate;
337
338   ui::ScopedAnimationDurationScaleMode normal_duration_(
339       ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION);
340   ui::LayerAnimator* animator = window->layer()->GetAnimator();
341   animator->set_disable_timer_for_test(true);
342   ui::LayerAnimatorTestController test_controller(animator);
343
344   WindowSlider* slider =
345       new WindowSlider(&slider_delegate, root_window(), window.get());
346
347   ui::MouseEvent interrupt_event(ui::ET_MOUSE_MOVED,
348                                  gfx::Point(55, 10),
349                                  gfx::Point(55, 10),
350                                  0, 0);
351
352   ui::test::EventGenerator generator(root_window());
353
354   // Start the scroll sequence. Scroll forward so that |window|'s layer is the
355   // one animating.
356   const int kTouchId = 5;
357   ui::TouchEvent press(ui::ET_TOUCH_PRESSED,
358                        gfx::Point(10, 10),
359                        kTouchId,
360                        ui::EventTimeForNow());
361   generator.Dispatch(&press);
362
363   // First scroll event of the sequence.
364   ui::TouchEvent move1(ui::ET_TOUCH_MOVED,
365                        gfx::Point(100, 10),
366                        kTouchId,
367                        ui::EventTimeForNow());
368   generator.Dispatch(&move1);
369   EXPECT_TRUE(slider->IsSlideInProgress());
370   EXPECT_FALSE(animator->is_animating());
371   // Dispatch the event after the first scroll and confirm it interrupts the
372   // scroll and starts  the "reset slide" animation.
373   generator.Dispatch(&interrupt_event);
374   EXPECT_TRUE(slider->IsSlideInProgress());
375   EXPECT_TRUE(animator->is_animating());
376   EXPECT_TRUE(slider_delegate.created_back_layer());
377   // slide_aborted() should be false because the 'reset slide' animation
378   // hasn't completed yet.
379   EXPECT_FALSE(slider_delegate.slide_aborted());
380   EXPECT_FALSE(slider_delegate.created_front_layer());
381   EXPECT_FALSE(slider_delegate.slide_completing());
382   EXPECT_FALSE(slider_delegate.slide_completed());
383   EXPECT_FALSE(slider_delegate.slider_destroyed());
384   slider_delegate.Reset();
385
386   // Second scroll event of the sequence.
387   ui::TouchEvent move2(ui::ET_TOUCH_MOVED,
388                        gfx::Point(200, 10),
389                        kTouchId,
390                        ui::EventTimeForNow());
391   generator.Dispatch(&move2);
392   // The second scroll should instantly cause the animation to complete.
393   EXPECT_FALSE(animator->is_animating());
394   EXPECT_FALSE(slider_delegate.created_back_layer());
395   // The ResetScroll() animation was completed, so now slide_aborted()
396   // should be true.
397   EXPECT_TRUE(slider_delegate.slide_aborted());
398
399   // Third scroll event of the sequence.
400   ui::TouchEvent move3(ui::ET_TOUCH_MOVED,
401                        gfx::Point(300, 10),
402                        kTouchId,
403                        ui::EventTimeForNow());
404   generator.Dispatch(&move3);
405   // The third scroll should re-start the sliding.
406   EXPECT_TRUE(slider->IsSlideInProgress());
407   EXPECT_TRUE(slider_delegate.created_back_layer());
408
409   // Generate the release event, finishing the scroll sequence.
410   ui::TouchEvent release(ui::ET_TOUCH_RELEASED,
411                          gfx::Point(300, 10),
412                          kTouchId,
413                          ui::EventTimeForNow());
414   generator.Dispatch(&release);
415   // When the scroll gesture ends, the slide animation should start.
416   EXPECT_TRUE(slider->IsSlideInProgress());
417   EXPECT_TRUE(animator->is_animating());
418   EXPECT_TRUE(slider_delegate.slide_completing());
419   EXPECT_FALSE(slider_delegate.created_front_layer());
420   EXPECT_FALSE(slider_delegate.slide_completed());
421   EXPECT_FALSE(slider_delegate.slider_destroyed());
422
423   // Progress the animator to complete the slide animation.
424   ui::ScopedLayerAnimationSettings settings(animator);
425   base::TimeDelta duration = settings.GetTransitionDuration();
426   test_controller.StartThreadedAnimationsIfNeeded();
427   animator->Step(gfx::FrameTime::Now() + duration);
428
429   EXPECT_TRUE(slider_delegate.slide_completed());
430   EXPECT_FALSE(slider_delegate.slider_destroyed());
431
432   window.reset();
433   EXPECT_TRUE(slider_delegate.slider_destroyed());
434 }
435
436 // Tests that the slide works correctly when the owner of the window changes
437 // during the duration of the slide.
438 TEST_F(WindowSliderTest, OwnerWindowChangesDuringWindowSlide) {
439   scoped_ptr<aura::Window> parent(CreateNormalWindow(0, root_window(), NULL));
440
441   NoEventWindowDelegate window_delegate;
442   window_delegate.set_window_component(HTNOWHERE);
443   scoped_ptr<aura::Window> window(CreateNormalWindow(1, parent.get(),
444                                                      &window_delegate));
445
446   WindowSliderDelegateTest slider_delegate;
447   scoped_ptr<WindowSlider> slider(
448       new WindowSlider(&slider_delegate, parent.get(), window.get()));
449
450   // Generate a horizontal scroll, and change the owner in the middle of the
451   // scroll.
452   ui::test::EventGenerator generator(root_window());
453   aura::Window* old_window = window.get();
454   generator.GestureScrollSequenceWithCallback(
455       gfx::Point(10, 10),
456       gfx::Point(80, 10),
457       base::TimeDelta::FromMilliseconds(10),
458       1,
459       base::Bind(&ChangeSliderOwnerDuringScrollCallback,
460                  base::Unretained(&window),
461                  slider.get()));
462   aura::Window* new_window = window.get();
463   EXPECT_NE(old_window, new_window);
464
465   EXPECT_TRUE(slider_delegate.created_back_layer());
466   EXPECT_TRUE(slider_delegate.slide_completing());
467   EXPECT_TRUE(slider_delegate.slide_completed());
468   EXPECT_FALSE(slider_delegate.created_front_layer());
469   EXPECT_FALSE(slider_delegate.slide_aborted());
470   EXPECT_FALSE(slider_delegate.slider_destroyed());
471 }
472
473 // If the delegate doesn't create the layer to show while sliding, WindowSlider
474 // shouldn't start the slide or change delegate's state in any way in response
475 // to user input.
476 TEST_F(WindowSliderTest, NoSlideWhenLayerCantBeCreated) {
477   scoped_ptr<aura::Window> window(CreateNormalWindow(0, root_window(), NULL));
478   window->SetBounds(gfx::Rect(0, 0, 400, 400));
479   WindowSliderDelegateTest slider_delegate;
480   slider_delegate.SetCanCreateLayer(false);
481   WindowSlider* slider =
482       new WindowSlider(&slider_delegate, root_window(), window.get());
483
484   ui::test::EventGenerator generator(root_window());
485
486   // No slide in progress should be reported during scroll since the layer
487   // wasn't created.
488   generator.GestureScrollSequenceWithCallback(
489       gfx::Point(10, 10),
490       gfx::Point(180, 10),
491       base::TimeDelta::FromMilliseconds(10),
492       1,
493       base::Bind(&ConfirmNoSlideDuringScrollCallback, slider));
494
495   EXPECT_FALSE(slider_delegate.created_back_layer());
496   EXPECT_FALSE(slider_delegate.slide_completing());
497   EXPECT_FALSE(slider_delegate.slide_completed());
498   EXPECT_FALSE(slider_delegate.created_front_layer());
499   EXPECT_FALSE(slider_delegate.slide_aborted());
500   EXPECT_FALSE(slider_delegate.slider_destroyed());
501   window->SetTransform(gfx::Transform());
502
503   slider_delegate.SetCanCreateLayer(true);
504   generator.GestureScrollSequenceWithCallback(
505       gfx::Point(10, 10),
506       gfx::Point(180, 10),
507       base::TimeDelta::FromMilliseconds(10),
508       10,
509       base::Bind(&ConfirmSlideDuringScrollCallback, slider));
510   EXPECT_TRUE(slider_delegate.created_back_layer());
511   EXPECT_TRUE(slider_delegate.slide_completing());
512   EXPECT_TRUE(slider_delegate.slide_completed());
513   EXPECT_FALSE(slider_delegate.created_front_layer());
514   EXPECT_FALSE(slider_delegate.slide_aborted());
515   EXPECT_FALSE(slider_delegate.slider_destroyed());
516
517   window.reset();
518   EXPECT_TRUE(slider_delegate.slider_destroyed());
519 }
520
521 // Tests that the owner window can be destroyed from |OnWindowSliderDestroyed()|
522 // delegate callback without causing a crash.
523 TEST_F(WindowSliderTest, OwnerIsDestroyedOnSliderDestroy) {
524   size_t child_windows = root_window()->children().size();
525   aura::Window* window = CreateNormalWindow(0, root_window(), NULL);
526   window->SetBounds(gfx::Rect(0, 0, 400, 400));
527   EXPECT_EQ(child_windows + 1, root_window()->children().size());
528
529   WindowSliderDeleteOwnerOnDestroy slider_delegate(window);
530   ui::test::EventGenerator generator(root_window());
531
532   // Generate a horizontal overscroll.
533   scoped_ptr<WindowSlider> slider(
534       new WindowSlider(&slider_delegate, root_window(), window));
535   generator.GestureScrollSequence(gfx::Point(10, 10),
536                                   gfx::Point(180, 10),
537                                   base::TimeDelta::FromMilliseconds(10),
538                                   10);
539   EXPECT_TRUE(slider_delegate.created_back_layer());
540   EXPECT_TRUE(slider_delegate.slide_completing());
541   EXPECT_TRUE(slider_delegate.slide_completed());
542   EXPECT_FALSE(slider_delegate.created_front_layer());
543   EXPECT_FALSE(slider_delegate.slide_aborted());
544   EXPECT_FALSE(slider_delegate.slider_destroyed());
545
546   slider.reset();
547   // Destroying the slider would have destroyed |window| too. So |window| should
548   // not need to be destroyed here.
549   EXPECT_EQ(child_windows, root_window()->children().size());
550 }
551
552 // Tests that the owner window can be destroyed from |OnWindowSlideComplete()|
553 // delegate callback without causing a crash.
554 TEST_F(WindowSliderTest, OwnerIsDestroyedOnSlideComplete) {
555   size_t child_windows = root_window()->children().size();
556   aura::Window* window = CreateNormalWindow(0, root_window(), NULL);
557   window->SetBounds(gfx::Rect(0, 0, 400, 400));
558   EXPECT_EQ(child_windows + 1, root_window()->children().size());
559
560   WindowSliderDeleteOwnerOnComplete slider_delegate(window);
561   ui::test::EventGenerator generator(root_window());
562
563   // Generate a horizontal overscroll.
564   new WindowSlider(&slider_delegate, root_window(), window);
565   generator.GestureScrollSequence(gfx::Point(10, 10),
566                                   gfx::Point(180, 10),
567                                   base::TimeDelta::FromMilliseconds(10),
568                                   10);
569   EXPECT_TRUE(slider_delegate.created_back_layer());
570   EXPECT_TRUE(slider_delegate.slide_completing());
571   EXPECT_TRUE(slider_delegate.slide_completed());
572   EXPECT_FALSE(slider_delegate.created_front_layer());
573   EXPECT_FALSE(slider_delegate.slide_aborted());
574   EXPECT_TRUE(slider_delegate.slider_destroyed());
575
576   // Destroying the slider would have destroyed |window| too. So |window| should
577   // not need to be destroyed here.
578   EXPECT_EQ(child_windows, root_window()->children().size());
579 }
580
581 // Test the scenario when two swipe gesture occur quickly one after another so
582 // that the second swipe occurs while the transition animation triggered by the
583 // first swipe is in progress.
584 // The second swipe is supposed to instantly complete the animation caused by
585 // the first swipe, ask the delegate to create a new layer, and animate it.
586 TEST_F(WindowSliderTest, SwipeDuringSwipeAnimation) {
587   scoped_ptr<aura::Window> window(CreateNormalWindow(0, root_window(), NULL));
588   window->SetBounds(gfx::Rect(0, 0, 400, 400));
589   WindowSliderDelegateTest slider_delegate;
590   new WindowSlider(&slider_delegate, root_window(), window.get());
591
592   // This test uses explicit durations so needs a normal duration.
593   ui::ScopedAnimationDurationScaleMode normal_duration(
594       ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION);
595   ui::LayerAnimator* animator = window->layer()->GetAnimator();
596   animator->set_disable_timer_for_test(true);
597   ui::LayerAnimatorTestController test_controller(animator);
598
599   ui::test::EventGenerator generator(root_window());
600
601   // Swipe forward so that |window|'s layer is the one animating.
602   generator.GestureScrollSequence(
603       gfx::Point(10, 10),
604       gfx::Point(180, 10),
605       base::TimeDelta::FromMilliseconds(10),
606       2);
607   EXPECT_TRUE(slider_delegate.created_back_layer());
608   EXPECT_FALSE(slider_delegate.slide_aborted());
609   EXPECT_FALSE(slider_delegate.created_front_layer());
610   EXPECT_TRUE(slider_delegate.slide_completing());
611   EXPECT_FALSE(slider_delegate.slide_completed());
612   EXPECT_FALSE(slider_delegate.slider_destroyed());
613   ui::ScopedLayerAnimationSettings settings(animator);
614   base::TimeDelta duration = settings.GetTransitionDuration();
615   test_controller.StartThreadedAnimationsIfNeeded();
616   base::TimeTicks start_time1 =  gfx::FrameTime::Now();
617
618   animator->Step(start_time1 + duration / 2);
619   EXPECT_FALSE(slider_delegate.slide_completed());
620   slider_delegate.Reset();
621   // Generate another horizontal swipe while the animation from the previous
622   // swipe is in progress.
623   generator.GestureScrollSequence(
624       gfx::Point(10, 10),
625       gfx::Point(180, 10),
626       base::TimeDelta::FromMilliseconds(10),
627       2);
628   // Performing the second swipe should instantly complete the slide started
629   // by the first swipe and create a new layer.
630   EXPECT_TRUE(slider_delegate.created_back_layer());
631   EXPECT_FALSE(slider_delegate.slide_aborted());
632   EXPECT_FALSE(slider_delegate.created_front_layer());
633   EXPECT_TRUE(slider_delegate.slide_completing());
634   EXPECT_TRUE(slider_delegate.slide_completed());
635   EXPECT_FALSE(slider_delegate.slider_destroyed());
636   test_controller.StartThreadedAnimationsIfNeeded();
637   base::TimeTicks start_time2 =  gfx::FrameTime::Now();
638   slider_delegate.Reset();
639   animator->Step(start_time2 + duration);
640   // The animation for the second slide should now be completed.
641   EXPECT_TRUE(slider_delegate.slide_completed());
642   slider_delegate.Reset();
643
644   window.reset();
645   EXPECT_TRUE(slider_delegate.slider_destroyed());
646 }
647
648 }  // namespace content