Home | History | Annotate | Download | only in aura
      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
    649