// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ui/events/blink/input_scroll_elasticity_controller.h"

#include "cc/input/input_handler.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/WebKit/public/web/WebInputEvent.h"

namespace ui {
namespace {

enum Phase {
  PhaseNone = blink::WebMouseWheelEvent::PhaseNone,
  PhaseBegan = blink::WebMouseWheelEvent::PhaseBegan,
  PhaseStationary = blink::WebMouseWheelEvent::PhaseStationary,
  PhaseChanged = blink::WebMouseWheelEvent::PhaseChanged,
  PhaseEnded = blink::WebMouseWheelEvent::PhaseEnded,
  PhaseCancelled = blink::WebMouseWheelEvent::PhaseCancelled,
  PhaseMayBegin = blink::WebMouseWheelEvent::PhaseMayBegin,
};

class MockScrollElasticityHelper : public cc::ScrollElasticityHelper {
 public:
  MockScrollElasticityHelper()
      : is_user_scrollable_(true),
        set_stretch_amount_count_(0),
        request_begin_frame_count_(0) {}
  ~MockScrollElasticityHelper() override {}

  // cc::ScrollElasticityHelper implementation:
  bool IsUserScrollable() const override { return is_user_scrollable_; }
  gfx::Vector2dF StretchAmount() const override { return stretch_amount_; }
  void SetStretchAmount(const gfx::Vector2dF& stretch_amount) override {
    set_stretch_amount_count_ += 1;
    stretch_amount_ = stretch_amount;
  }
  gfx::ScrollOffset ScrollOffset() const override { return scroll_offset_; }
  gfx::ScrollOffset MaxScrollOffset() const override {
    return max_scroll_offset_;
  }
  void ScrollBy(const gfx::Vector2dF& delta) override {
    scroll_offset_ += gfx::ScrollOffset(delta);
  }
  void RequestOneBeginFrame() override { request_begin_frame_count_ += 1; }

  // Counters for number of times functions were called.
  int request_begin_frame_count() const { return request_begin_frame_count_; }
  int set_stretch_amount_count() const { return set_stretch_amount_count_; }

  void SetScrollOffsetAndMaxScrollOffset(
      const gfx::ScrollOffset& scroll_offset,
      const gfx::ScrollOffset& max_scroll_offset) {
    scroll_offset_ = scroll_offset;
    max_scroll_offset_ = max_scroll_offset;
  }
  void SetUserScrollable(bool is_user_scrollable) {
    is_user_scrollable_ = is_user_scrollable;
  }

 private:
  bool is_user_scrollable_;
  gfx::Vector2dF stretch_amount_;
  int set_stretch_amount_count_;
  int request_begin_frame_count_;

  gfx::ScrollOffset scroll_offset_;
  gfx::ScrollOffset max_scroll_offset_;
};

class ScrollElasticityControllerTest : public testing::Test {
 public:
  ScrollElasticityControllerTest()
      : controller_(&helper_),
        input_event_count_(0),
        current_time_(base::TimeTicks::FromInternalValue(100000000ull)) {}
  ~ScrollElasticityControllerTest() override {}

  void SendMouseWheelEvent(
      Phase phase,
      Phase momentum_phase,
      const gfx::Vector2dF& event_delta = gfx::Vector2dF(),
      const gfx::Vector2dF& overscroll_delta = gfx::Vector2dF()) {
    blink::WebMouseWheelEvent event;
    event.phase = static_cast<blink::WebMouseWheelEvent::Phase>(phase);
    event.momentumPhase =
        static_cast<blink::WebMouseWheelEvent::Phase>(momentum_phase);
    event.deltaX = -event_delta.x();
    event.deltaY = -event_delta.y();
    TickCurrentTime();
    event.timeStampSeconds = (current_time_ - base::TimeTicks()).InSecondsF();

    cc::InputHandlerScrollResult scroll_result;
    scroll_result.did_overscroll_root = !overscroll_delta.IsZero();
    scroll_result.unused_scroll_delta = overscroll_delta;

    controller_.ObserveWheelEventAndResult(event, scroll_result);
    input_event_count_ += 1;
  }

  void SendGestureScrollBegin(bool inertial) {
    blink::WebGestureEvent event;
    event.sourceDevice = blink::WebGestureDeviceTouchpad;
    event.type = blink::WebInputEvent::GestureScrollBegin;
    event.data.scrollBegin.inertial = inertial;
    TickCurrentTime();
    event.timeStampSeconds = (current_time_ - base::TimeTicks()).InSecondsF();

    controller_.ObserveGestureEventAndResult(event,
                                             cc::InputHandlerScrollResult());
    input_event_count_ += 1;
  }

  void SendGestureScrollUpdate(
      bool inertial,
      const gfx::Vector2dF& event_delta = gfx::Vector2dF(),
      const gfx::Vector2dF& overscroll_delta = gfx::Vector2dF()) {
    blink::WebGestureEvent event;
    event.sourceDevice = blink::WebGestureDeviceTouchpad;
    event.type = blink::WebInputEvent::GestureScrollUpdate;
    event.data.scrollUpdate.inertial = inertial;
    event.data.scrollUpdate.deltaX = -event_delta.x();
    event.data.scrollUpdate.deltaY = -event_delta.y();
    TickCurrentTime();
    event.timeStampSeconds = (current_time_ - base::TimeTicks()).InSecondsF();

    cc::InputHandlerScrollResult scroll_result;
    scroll_result.did_overscroll_root = !overscroll_delta.IsZero();
    scroll_result.unused_scroll_delta = overscroll_delta;

    controller_.ObserveGestureEventAndResult(event, scroll_result);
    input_event_count_ += 1;
  }

  void SendGestureScrollEnd() {
    blink::WebGestureEvent event;
    event.sourceDevice = blink::WebGestureDeviceTouchpad;
    event.type = blink::WebInputEvent::GestureScrollEnd;

    TickCurrentTime();
    event.timeStampSeconds = (current_time_ - base::TimeTicks()).InSecondsF();

    controller_.ObserveGestureEventAndResult(event,
                                             cc::InputHandlerScrollResult());
    input_event_count_ += 1;
  }

  const base::TimeTicks& TickCurrentTime() {
    current_time_ += base::TimeDelta::FromSecondsD(1 / 60.f);
    return current_time_;
  }
  void TickCurrentTimeAndAnimate() {
    TickCurrentTime();
    controller_.Animate(current_time_);
  }

  MockScrollElasticityHelper helper_;
  InputScrollElasticityController controller_;
  int input_event_count_;
  base::TimeTicks current_time_;
};

// Verify that stretching only occurs in one axis at a time, and that it
// is biased to the Y axis.
TEST_F(ScrollElasticityControllerTest, Axis) {
  helper_.SetScrollOffsetAndMaxScrollOffset(gfx::ScrollOffset(0, 0),
                                            gfx::ScrollOffset(0, 0));

  // If we push equally in the X and Y directions, we should see a stretch only
  // in the Y direction.
  SendMouseWheelEvent(PhaseBegan, PhaseNone);
  SendMouseWheelEvent(PhaseChanged, PhaseNone, gfx::Vector2dF(10, 10),
                      gfx::Vector2dF(10, 10));
  EXPECT_EQ(1, helper_.set_stretch_amount_count());
  EXPECT_EQ(0.f, helper_.StretchAmount().x());
  EXPECT_LT(0.f, helper_.StretchAmount().y());
  helper_.SetStretchAmount(gfx::Vector2dF());
  EXPECT_EQ(2, helper_.set_stretch_amount_count());
  SendMouseWheelEvent(PhaseEnded, PhaseNone);
  EXPECT_EQ(0, helper_.request_begin_frame_count());

  // If we push more in the X direction than the Y direction, we should see a
  // stretch only in the X direction. This decision should be based on the
  // input delta, not the actual overscroll delta.
  SendMouseWheelEvent(PhaseBegan, PhaseNone);
  SendMouseWheelEvent(PhaseChanged, PhaseNone, gfx::Vector2dF(-25, 10),
                      gfx::Vector2dF(-25, 40));
  EXPECT_EQ(3, helper_.set_stretch_amount_count());
  EXPECT_GT(0.f, helper_.StretchAmount().x());
  EXPECT_EQ(0.f, helper_.StretchAmount().y());
  helper_.SetStretchAmount(gfx::Vector2dF());
  EXPECT_EQ(4, helper_.set_stretch_amount_count());
  SendMouseWheelEvent(PhaseEnded, PhaseNone);
  EXPECT_EQ(0, helper_.request_begin_frame_count());
}

// Verify that stretching only occurs in one axis at a time, and that it
// is biased to the Y axis.
TEST_F(ScrollElasticityControllerTest, GestureBased_Axis) {
  helper_.SetScrollOffsetAndMaxScrollOffset(gfx::ScrollOffset(0, 0),
                                            gfx::ScrollOffset(0, 0));

  // If we push equally in the X and Y directions, we should see a stretch only
  // in the Y direction.
  SendGestureScrollBegin(false);
  SendGestureScrollUpdate(false, gfx::Vector2dF(10, 10),
                          gfx::Vector2dF(10, 10));
  EXPECT_EQ(1, helper_.set_stretch_amount_count());
  EXPECT_EQ(0.f, helper_.StretchAmount().x());
  EXPECT_LT(0.f, helper_.StretchAmount().y());
  helper_.SetStretchAmount(gfx::Vector2dF());
  EXPECT_EQ(2, helper_.set_stretch_amount_count());
  SendGestureScrollEnd();
  EXPECT_EQ(0, helper_.request_begin_frame_count());

  // If we push more in the X direction than the Y direction, we should see a
  // stretch only in the X direction. This decision should be based on the
  // input delta, not the actual overscroll delta.
  SendGestureScrollBegin(false);
  SendGestureScrollUpdate(false, gfx::Vector2dF(-25, 10),
                          gfx::Vector2dF(-25, 40));
  EXPECT_EQ(3, helper_.set_stretch_amount_count());
  EXPECT_GT(0.f, helper_.StretchAmount().x());
  EXPECT_EQ(0.f, helper_.StretchAmount().y());
  helper_.SetStretchAmount(gfx::Vector2dF());
  EXPECT_EQ(4, helper_.set_stretch_amount_count());
  SendGestureScrollEnd();
  EXPECT_EQ(0, helper_.request_begin_frame_count());
}

// Verify that we need a total overscroll delta of at least 10 in a pinned
// direction before we start stretching.
TEST_F(ScrollElasticityControllerTest, MinimumDeltaBeforeStretch) {
  // We should not start stretching while we are not pinned in the direction
  // of the scroll (even if there is an overscroll delta). We have to wait for
  // the regular scroll to eat all of the events.
  helper_.SetScrollOffsetAndMaxScrollOffset(gfx::ScrollOffset(5, 5),
                                            gfx::ScrollOffset(10, 10));
  SendMouseWheelEvent(PhaseMayBegin, PhaseNone);
  SendMouseWheelEvent(PhaseBegan, PhaseNone);
  SendMouseWheelEvent(PhaseChanged, PhaseNone, gfx::Vector2dF(0, 10),
                      gfx::Vector2dF(0, 10));
  SendMouseWheelEvent(PhaseChanged, PhaseNone, gfx::Vector2dF(0, 10),
                      gfx::Vector2dF(0, 10));
  EXPECT_EQ(0, helper_.set_stretch_amount_count());

  // Now pin the -X and +Y direction. The first event will not generate a
  // stretch
  // because it is below the delta threshold of 10.
  helper_.SetScrollOffsetAndMaxScrollOffset(gfx::ScrollOffset(0, 10),
                                            gfx::ScrollOffset(10, 10));
  SendMouseWheelEvent(PhaseChanged, PhaseNone, gfx::Vector2dF(0, 10),
                      gfx::Vector2dF(0, 8));
  EXPECT_EQ(0, helper_.set_stretch_amount_count());

  // Make the next scroll be in the -X direction more than the +Y direction,
  // which will erase the memory of the previous unused delta of 8.
  SendMouseWheelEvent(PhaseChanged, PhaseNone, gfx::Vector2dF(-10, 5),
                      gfx::Vector2dF(-8, 10));
  EXPECT_EQ(0, helper_.set_stretch_amount_count());

  // Now push against the pinned +Y direction again by 8. We reset the
  // previous delta, so this will not generate a stretch.
  SendMouseWheelEvent(PhaseChanged, PhaseNone, gfx::Vector2dF(0, 10),
                      gfx::Vector2dF(0, 8));
  EXPECT_EQ(0, helper_.set_stretch_amount_count());

  // Push against +Y by another 8. This gets us above the delta threshold of
  // 10, so we should now have had the stretch set, and it should be in the
  // +Y direction. The scroll in the -X direction should have been forgotten.
  SendMouseWheelEvent(PhaseChanged, PhaseNone, gfx::Vector2dF(0, 10),
                      gfx::Vector2dF(0, 8));
  EXPECT_EQ(1, helper_.set_stretch_amount_count());
  EXPECT_EQ(0.f, helper_.StretchAmount().x());
  EXPECT_LT(0.f, helper_.StretchAmount().y());

  // End the gesture. Because there is a non-zero stretch, we should be in the
  // animated state, and should have had a frame requested.
  EXPECT_EQ(0, helper_.request_begin_frame_count());
  SendMouseWheelEvent(PhaseEnded, PhaseNone);
  EXPECT_EQ(1, helper_.request_begin_frame_count());
}

// Verify that we need a total overscroll delta of at least 10 in a pinned
// direction before we start stretching.
TEST_F(ScrollElasticityControllerTest, GestureBased_MinimumDeltaBeforeStretch) {
  // We should not start stretching while we are not pinned in the direction
  // of the scroll (even if there is an overscroll delta). We have to wait for
  // the regular scroll to eat all of the events.
  helper_.SetScrollOffsetAndMaxScrollOffset(gfx::ScrollOffset(5, 5),
                                            gfx::ScrollOffset(10, 10));
  SendGestureScrollBegin(false);
  SendGestureScrollUpdate(false, gfx::Vector2dF(0, 10), gfx::Vector2dF(0, 10));
  SendGestureScrollUpdate(false, gfx::Vector2dF(0, 10), gfx::Vector2dF(0, 10));
  EXPECT_EQ(0, helper_.set_stretch_amount_count());

  // Now pin the -X and +Y direction. The first event will not generate a
  // stretch
  // because it is below the delta threshold of 10.
  helper_.SetScrollOffsetAndMaxScrollOffset(gfx::ScrollOffset(0, 10),
                                            gfx::ScrollOffset(10, 10));
  SendGestureScrollUpdate(false, gfx::Vector2dF(0, 10), gfx::Vector2dF(0, 8));
  EXPECT_EQ(0, helper_.set_stretch_amount_count());

  // Make the next scroll be in the -X direction more than the +Y direction,
  // which will erase the memory of the previous unused delta of 8.
  SendGestureScrollUpdate(false, gfx::Vector2dF(-10, 5),
                          gfx::Vector2dF(-8, 10));
  EXPECT_EQ(0, helper_.set_stretch_amount_count());

  // Now push against the pinned +Y direction again by 8. We reset the
  // previous delta, so this will not generate a stretch.
  SendGestureScrollUpdate(false, gfx::Vector2dF(0, 10), gfx::Vector2dF(0, 8));
  EXPECT_EQ(0, helper_.set_stretch_amount_count());

  // Push against +Y by another 8. This gets us above the delta threshold of
  // 10, so we should now have had the stretch set, and it should be in the
  // +Y direction. The scroll in the -X direction should have been forgotten.
  SendGestureScrollUpdate(false, gfx::Vector2dF(0, 10), gfx::Vector2dF(0, 8));
  EXPECT_EQ(1, helper_.set_stretch_amount_count());
  EXPECT_EQ(0.f, helper_.StretchAmount().x());
  EXPECT_LT(0.f, helper_.StretchAmount().y());

  // End the gesture. Because there is a non-zero stretch, we should be in the
  // animated state, and should have had a frame requested.
  EXPECT_EQ(0, helper_.request_begin_frame_count());
  SendGestureScrollEnd();
  EXPECT_EQ(1, helper_.request_begin_frame_count());
}

// Verify that a stretch caused by a momentum scroll will switch to the
// animating mode, where input events are ignored, and the stretch is updated
// while animating.
TEST_F(ScrollElasticityControllerTest, MomentumAnimate) {
  // Do an active scroll, then switch to the momentum phase and scroll for a
  // bit.
  helper_.SetScrollOffsetAndMaxScrollOffset(gfx::ScrollOffset(5, 5),
                                            gfx::ScrollOffset(10, 10));
  SendMouseWheelEvent(PhaseBegan, PhaseNone);
  SendMouseWheelEvent(PhaseChanged, PhaseNone, gfx::Vector2dF(0, -80),
                      gfx::Vector2dF(0, 0));
  SendMouseWheelEvent(PhaseChanged, PhaseNone, gfx::Vector2dF(0, -80),
                      gfx::Vector2dF(0, 0));
  SendMouseWheelEvent(PhaseChanged, PhaseNone, gfx::Vector2dF(0, -80),
                      gfx::Vector2dF(0, 0));
  SendMouseWheelEvent(PhaseEnded, PhaseNone);
  SendMouseWheelEvent(PhaseNone, PhaseBegan);
  SendMouseWheelEvent(PhaseNone, PhaseChanged, gfx::Vector2dF(0, -80),
                      gfx::Vector2dF(0, 0));
  SendMouseWheelEvent(PhaseNone, PhaseChanged, gfx::Vector2dF(0, -80),
                      gfx::Vector2dF(0, 0));
  SendMouseWheelEvent(PhaseNone, PhaseChanged, gfx::Vector2dF(0, -80),
                      gfx::Vector2dF(0, 0));
  EXPECT_EQ(0, helper_.set_stretch_amount_count());

  // Hit the -Y edge and overscroll slightly, but not enough to go over the
  // threshold to cause a stretch.
  helper_.SetScrollOffsetAndMaxScrollOffset(gfx::ScrollOffset(5, 0),
                                            gfx::ScrollOffset(10, 10));
  SendMouseWheelEvent(PhaseNone, PhaseChanged, gfx::Vector2dF(0, -80),
                      gfx::Vector2dF(0, -8));
  EXPECT_EQ(0, helper_.set_stretch_amount_count());
  EXPECT_EQ(0, helper_.request_begin_frame_count());

  // Take another step, this time going over the threshold. This should update
  // the stretch amount, and then switch to the animating mode.
  SendMouseWheelEvent(PhaseNone, PhaseChanged, gfx::Vector2dF(0, -80),
                      gfx::Vector2dF(0, -80));
  EXPECT_EQ(1, helper_.set_stretch_amount_count());
  EXPECT_EQ(1, helper_.request_begin_frame_count());
  EXPECT_GT(-1.f, helper_.StretchAmount().y());

  // Subsequent momentum events should do nothing.
  SendMouseWheelEvent(PhaseNone, PhaseChanged, gfx::Vector2dF(0, -80),
                      gfx::Vector2dF(0, -80));
  SendMouseWheelEvent(PhaseNone, PhaseChanged, gfx::Vector2dF(0, -80),
                      gfx::Vector2dF(0, -80));
  SendMouseWheelEvent(PhaseNone, PhaseEnded, gfx::Vector2dF(0, -80),
                      gfx::Vector2dF(0, -80));
  EXPECT_EQ(1, helper_.set_stretch_amount_count());
  EXPECT_EQ(1, helper_.request_begin_frame_count());

  // Subsequent animate events should update the stretch amount and request
  // another frame.
  TickCurrentTimeAndAnimate();
  EXPECT_EQ(2, helper_.set_stretch_amount_count());
  EXPECT_EQ(2, helper_.request_begin_frame_count());
  EXPECT_GT(-1.f, helper_.StretchAmount().y());

  // Touching the trackpad (a PhaseMayBegin event) should disable animation.
  SendMouseWheelEvent(PhaseMayBegin, PhaseNone);
  TickCurrentTimeAndAnimate();
  EXPECT_EQ(2, helper_.set_stretch_amount_count());
  EXPECT_EQ(2, helper_.request_begin_frame_count());

  // Releasing the trackpad should re-enable animation.
  SendMouseWheelEvent(PhaseCancelled, PhaseNone);
  EXPECT_EQ(2, helper_.set_stretch_amount_count());
  EXPECT_EQ(3, helper_.request_begin_frame_count());
  TickCurrentTimeAndAnimate();
  EXPECT_EQ(3, helper_.set_stretch_amount_count());
  EXPECT_EQ(4, helper_.request_begin_frame_count());

  // Keep animating frames until the stretch returns to rest.
  int stretch_count = 3;
  int begin_frame_count = 4;
  while (1) {
    TickCurrentTimeAndAnimate();
    if (helper_.StretchAmount().IsZero()) {
      stretch_count += 1;
      EXPECT_EQ(stretch_count, helper_.set_stretch_amount_count());
      EXPECT_EQ(begin_frame_count, helper_.request_begin_frame_count());
      break;
    }
    stretch_count += 1;
    begin_frame_count += 1;
    EXPECT_EQ(stretch_count, helper_.set_stretch_amount_count());
    EXPECT_EQ(begin_frame_count, helper_.request_begin_frame_count());
  }

  // After coming to rest, no subsequent animate calls change anything.
  TickCurrentTimeAndAnimate();
  EXPECT_EQ(stretch_count, helper_.set_stretch_amount_count());
  EXPECT_EQ(begin_frame_count, helper_.request_begin_frame_count());
}

// Verify that a stretch caused by a momentum scroll will switch to the
// animating mode, where input events are ignored, and the stretch is updated
// while animating.
TEST_F(ScrollElasticityControllerTest, GestureBased_MomentumAnimate) {
  // Do an active scroll, then switch to the momentum phase and scroll for a
  // bit.
  helper_.SetScrollOffsetAndMaxScrollOffset(gfx::ScrollOffset(5, 5),
                                            gfx::ScrollOffset(10, 10));
  SendGestureScrollBegin(false);
  SendGestureScrollUpdate(false, gfx::Vector2dF(0, -80), gfx::Vector2dF(0, 0));
  SendGestureScrollUpdate(false, gfx::Vector2dF(0, -80), gfx::Vector2dF(0, 0));
  SendGestureScrollUpdate(false, gfx::Vector2dF(0, -80), gfx::Vector2dF(0, 0));
  SendGestureScrollEnd();
  SendGestureScrollBegin(true);
  SendGestureScrollUpdate(true, gfx::Vector2dF(0, -80), gfx::Vector2dF(0, 0));
  SendGestureScrollUpdate(true, gfx::Vector2dF(0, -80), gfx::Vector2dF(0, 0));
  SendGestureScrollUpdate(true, gfx::Vector2dF(0, -80), gfx::Vector2dF(0, 0));
  EXPECT_EQ(0, helper_.set_stretch_amount_count());

  // Hit the -Y edge and overscroll slightly, but not enough to go over the
  // threshold to cause a stretch.
  helper_.SetScrollOffsetAndMaxScrollOffset(gfx::ScrollOffset(5, 0),
                                            gfx::ScrollOffset(10, 10));
  SendGestureScrollUpdate(true, gfx::Vector2dF(0, -80), gfx::Vector2dF(0, -8));
  EXPECT_EQ(0, helper_.set_stretch_amount_count());
  EXPECT_EQ(0, helper_.request_begin_frame_count());

  // Take another step, this time going over the threshold. This should update
  // the stretch amount, and then switch to the animating mode.
  SendGestureScrollUpdate(true, gfx::Vector2dF(0, -80), gfx::Vector2dF(0, -80));
  EXPECT_EQ(1, helper_.set_stretch_amount_count());
  EXPECT_EQ(1, helper_.request_begin_frame_count());
  EXPECT_GT(-1.f, helper_.StretchAmount().y());

  // Subsequent momentum events should do nothing.
  SendGestureScrollUpdate(true, gfx::Vector2dF(0, -80), gfx::Vector2dF(0, -80));
  SendGestureScrollUpdate(true, gfx::Vector2dF(0, -80), gfx::Vector2dF(0, -80));
  SendGestureScrollUpdate(true, gfx::Vector2dF(0, -80), gfx::Vector2dF(0, -80));
  SendGestureScrollEnd();
  EXPECT_EQ(1, helper_.set_stretch_amount_count());
  EXPECT_EQ(1, helper_.request_begin_frame_count());

  // Subsequent animate events should update the stretch amount and request
  // another frame.
  TickCurrentTimeAndAnimate();
  EXPECT_EQ(2, helper_.set_stretch_amount_count());
  EXPECT_EQ(2, helper_.request_begin_frame_count());
  EXPECT_GT(-1.f, helper_.StretchAmount().y());

  // Touching the trackpad (a PhaseMayBegin event) should disable animation.
  SendGestureScrollBegin(false);
  TickCurrentTimeAndAnimate();
  EXPECT_EQ(2, helper_.set_stretch_amount_count());
  EXPECT_EQ(2, helper_.request_begin_frame_count());

  // Releasing the trackpad should re-enable animation.
  SendGestureScrollEnd();
  EXPECT_EQ(2, helper_.set_stretch_amount_count());
  EXPECT_EQ(3, helper_.request_begin_frame_count());
  TickCurrentTimeAndAnimate();
  EXPECT_EQ(3, helper_.set_stretch_amount_count());
  EXPECT_EQ(4, helper_.request_begin_frame_count());

  // Keep animating frames until the stretch returns to rest.
  int stretch_count = 3;
  int begin_frame_count = 4;
  while (1) {
    TickCurrentTimeAndAnimate();
    if (helper_.StretchAmount().IsZero()) {
      stretch_count += 1;
      EXPECT_EQ(stretch_count, helper_.set_stretch_amount_count());
      EXPECT_EQ(begin_frame_count, helper_.request_begin_frame_count());
      break;
    }
    stretch_count += 1;
    begin_frame_count += 1;
    EXPECT_EQ(stretch_count, helper_.set_stretch_amount_count());
    EXPECT_EQ(begin_frame_count, helper_.request_begin_frame_count());
  }

  // After coming to rest, no subsequent animate calls change anything.
  TickCurrentTimeAndAnimate();
  EXPECT_EQ(stretch_count, helper_.set_stretch_amount_count());
  EXPECT_EQ(begin_frame_count, helper_.request_begin_frame_count());
}

// Verify that a stretch opposing a scroll is correctly resolved.
TEST_F(ScrollElasticityControllerTest, ReconcileStretchAndScroll) {
  SendMouseWheelEvent(PhaseBegan, PhaseNone);

  // Verify completely knocking out the scroll in the -Y direction.
  helper_.SetScrollOffsetAndMaxScrollOffset(gfx::ScrollOffset(5, 5),
                                            gfx::ScrollOffset(10, 10));
  helper_.SetStretchAmount(gfx::Vector2dF(0, -10));
  controller_.ReconcileStretchAndScroll();
  EXPECT_EQ(helper_.StretchAmount(), gfx::Vector2dF(0, -5));
  EXPECT_EQ(helper_.ScrollOffset(), gfx::ScrollOffset(5, 0));

  // Verify partially knocking out the scroll in the -Y direction.
  helper_.SetScrollOffsetAndMaxScrollOffset(gfx::ScrollOffset(5, 8),
                                            gfx::ScrollOffset(10, 10));
  helper_.SetStretchAmount(gfx::Vector2dF(0, -5));
  controller_.ReconcileStretchAndScroll();
  EXPECT_EQ(helper_.StretchAmount(), gfx::Vector2dF(0, 0));
  EXPECT_EQ(helper_.ScrollOffset(), gfx::ScrollOffset(5, 3));

  // Verify completely knocking out the scroll in the +X direction.
  helper_.SetScrollOffsetAndMaxScrollOffset(gfx::ScrollOffset(5, 5),
                                            gfx::ScrollOffset(10, 10));
  helper_.SetStretchAmount(gfx::Vector2dF(10, 0));
  controller_.ReconcileStretchAndScroll();
  EXPECT_EQ(helper_.StretchAmount(), gfx::Vector2dF(5, 0));
  EXPECT_EQ(helper_.ScrollOffset(), gfx::ScrollOffset(10, 5));

  // Verify partially knocking out the scroll in the +X and +Y directions.
  helper_.SetScrollOffsetAndMaxScrollOffset(gfx::ScrollOffset(2, 3),
                                            gfx::ScrollOffset(10, 10));
  helper_.SetStretchAmount(gfx::Vector2dF(5, 5));
  controller_.ReconcileStretchAndScroll();
  EXPECT_EQ(helper_.StretchAmount(), gfx::Vector2dF(0, 0));
  EXPECT_EQ(helper_.ScrollOffset(), gfx::ScrollOffset(7, 8));
}

// Verify that a stretch opposing a scroll is correctly resolved.
TEST_F(ScrollElasticityControllerTest, GestureBased_ReconcileStretchAndScroll) {
  SendGestureScrollBegin(false);

  // Verify completely knocking out the scroll in the -Y direction.
  helper_.SetScrollOffsetAndMaxScrollOffset(gfx::ScrollOffset(5, 5),
                                            gfx::ScrollOffset(10, 10));
  helper_.SetStretchAmount(gfx::Vector2dF(0, -10));
  controller_.ReconcileStretchAndScroll();
  EXPECT_EQ(helper_.StretchAmount(), gfx::Vector2dF(0, -5));
  EXPECT_EQ(helper_.ScrollOffset(), gfx::ScrollOffset(5, 0));

  // Verify partially knocking out the scroll in the -Y direction.
  helper_.SetScrollOffsetAndMaxScrollOffset(gfx::ScrollOffset(5, 8),
                                            gfx::ScrollOffset(10, 10));
  helper_.SetStretchAmount(gfx::Vector2dF(0, -5));
  controller_.ReconcileStretchAndScroll();
  EXPECT_EQ(helper_.StretchAmount(), gfx::Vector2dF(0, 0));
  EXPECT_EQ(helper_.ScrollOffset(), gfx::ScrollOffset(5, 3));

  // Verify completely knocking out the scroll in the +X direction.
  helper_.SetScrollOffsetAndMaxScrollOffset(gfx::ScrollOffset(5, 5),
                                            gfx::ScrollOffset(10, 10));
  helper_.SetStretchAmount(gfx::Vector2dF(10, 0));
  controller_.ReconcileStretchAndScroll();
  EXPECT_EQ(helper_.StretchAmount(), gfx::Vector2dF(5, 0));
  EXPECT_EQ(helper_.ScrollOffset(), gfx::ScrollOffset(10, 5));

  // Verify partially knocking out the scroll in the +X and +Y directions.
  helper_.SetScrollOffsetAndMaxScrollOffset(gfx::ScrollOffset(2, 3),
                                            gfx::ScrollOffset(10, 10));
  helper_.SetStretchAmount(gfx::Vector2dF(5, 5));
  controller_.ReconcileStretchAndScroll();
  EXPECT_EQ(helper_.StretchAmount(), gfx::Vector2dF(0, 0));
  EXPECT_EQ(helper_.ScrollOffset(), gfx::ScrollOffset(7, 8));
}

// Verify that stretching only happens when the area is user scrollable.
TEST_F(ScrollElasticityControllerTest, UserScrollableRequiredForStretch) {
  helper_.SetScrollOffsetAndMaxScrollOffset(gfx::ScrollOffset(0, 0),
                                            gfx::ScrollOffset(10, 10));
  gfx::Vector2dF delta(0, -15);

  // Do an active scroll, and ensure that the stretch amount doesn't change.
  helper_.SetUserScrollable(false);
  SendMouseWheelEvent(PhaseBegan, PhaseNone);
  SendMouseWheelEvent(PhaseChanged, PhaseNone, delta, delta);
  SendMouseWheelEvent(PhaseChanged, PhaseNone, delta, delta);
  SendMouseWheelEvent(PhaseEnded, PhaseNone);
  EXPECT_EQ(helper_.StretchAmount(), gfx::Vector2dF(0, 0));
  EXPECT_EQ(0, helper_.set_stretch_amount_count());
  SendMouseWheelEvent(PhaseNone, PhaseBegan);
  SendMouseWheelEvent(PhaseNone, PhaseChanged, delta, delta);
  SendMouseWheelEvent(PhaseNone, PhaseChanged, delta, delta);
  SendMouseWheelEvent(PhaseNone, PhaseEnded);
  EXPECT_EQ(helper_.StretchAmount(), gfx::Vector2dF(0, 0));
  EXPECT_EQ(0, helper_.set_stretch_amount_count());

  // Re-enable user scrolling and ensure that stretching is re-enabled.
  helper_.SetUserScrollable(true);
  SendMouseWheelEvent(PhaseBegan, PhaseNone);
  SendMouseWheelEvent(PhaseChanged, PhaseNone, delta, delta);
  SendMouseWheelEvent(PhaseChanged, PhaseNone, delta, delta);
  SendMouseWheelEvent(PhaseEnded, PhaseNone);
  EXPECT_NE(helper_.StretchAmount(), gfx::Vector2dF(0, 0));
  EXPECT_GT(helper_.set_stretch_amount_count(), 0);
  SendMouseWheelEvent(PhaseNone, PhaseBegan);
  SendMouseWheelEvent(PhaseNone, PhaseChanged, delta, delta);
  SendMouseWheelEvent(PhaseNone, PhaseChanged, delta, delta);
  SendMouseWheelEvent(PhaseNone, PhaseEnded);
  EXPECT_NE(helper_.StretchAmount(), gfx::Vector2dF(0, 0));
  EXPECT_GT(helper_.set_stretch_amount_count(), 0);

  // Disable user scrolling and tick the timer until the stretch goes back
  // to zero. Ensure that the return to zero doesn't happen immediately.
  helper_.SetUserScrollable(false);
  int ticks_to_zero = 0;
  while (1) {
    TickCurrentTimeAndAnimate();
    if (helper_.StretchAmount().IsZero())
      break;
    ticks_to_zero += 1;
  }
  EXPECT_GT(ticks_to_zero, 3);
}

// Verify that stretching only happens when the area is user scrollable.
TEST_F(ScrollElasticityControllerTest,
       GestureBased_UserScrollableRequiredForStretch) {
  helper_.SetScrollOffsetAndMaxScrollOffset(gfx::ScrollOffset(0, 0),
                                            gfx::ScrollOffset(10, 10));
  gfx::Vector2dF delta(0, -15);

  // Do an active scroll, and ensure that the stretch amount doesn't change.
  helper_.SetUserScrollable(false);
  SendGestureScrollBegin(false);
  SendGestureScrollUpdate(false, delta, delta);
  SendGestureScrollUpdate(false, delta, delta);
  SendGestureScrollEnd();
  EXPECT_EQ(helper_.StretchAmount(), gfx::Vector2dF(0, 0));
  EXPECT_EQ(0, helper_.set_stretch_amount_count());
  SendGestureScrollBegin(true);
  SendGestureScrollUpdate(true, delta, delta);
  SendGestureScrollUpdate(true, delta, delta);
  SendGestureScrollEnd();
  EXPECT_EQ(helper_.StretchAmount(), gfx::Vector2dF(0, 0));
  EXPECT_EQ(0, helper_.set_stretch_amount_count());

  // Re-enable user scrolling and ensure that stretching is re-enabled.
  helper_.SetUserScrollable(true);
  SendGestureScrollBegin(false);
  SendGestureScrollUpdate(false, delta, delta);
  SendGestureScrollUpdate(false, delta, delta);
  SendGestureScrollEnd();
  EXPECT_NE(helper_.StretchAmount(), gfx::Vector2dF(0, 0));
  EXPECT_GT(helper_.set_stretch_amount_count(), 0);
  SendGestureScrollBegin(true);
  SendGestureScrollUpdate(true, delta, delta);
  SendGestureScrollUpdate(true, delta, delta);
  SendGestureScrollEnd();
  EXPECT_NE(helper_.StretchAmount(), gfx::Vector2dF(0, 0));
  EXPECT_GT(helper_.set_stretch_amount_count(), 0);

  // Disable user scrolling and tick the timer until the stretch goes back
  // to zero. Ensure that the return to zero doesn't happen immediately.
  helper_.SetUserScrollable(false);
  int ticks_to_zero = 0;
  while (1) {
    TickCurrentTimeAndAnimate();
    if (helper_.StretchAmount().IsZero())
      break;
    ticks_to_zero += 1;
  }
  EXPECT_GT(ticks_to_zero, 3);
}

}  // namespace
}  // namespace ui
