Index: content/browser/web_contents/web_contents_view_aura_browsertest.cc |
diff --git a/content/browser/web_contents/web_contents_view_aura_browsertest.cc b/content/browser/web_contents/web_contents_view_aura_browsertest.cc |
index 0ac5a3c2a659ecd30c96c283742ae9b7a32e704c..7b3ca6bc30ad9cbf76ab215f627328de95a1fc4c 100644 |
--- a/content/browser/web_contents/web_contents_view_aura_browsertest.cc |
+++ b/content/browser/web_contents/web_contents_view_aura_browsertest.cc |
@@ -23,6 +23,7 @@ |
#include "content/common/view_messages.h" |
#include "content/public/browser/browser_message_filter.h" |
#include "content/public/browser/render_frame_host.h" |
+#include "content/public/browser/web_contents_delegate.h" |
#include "content/public/browser/web_contents_observer.h" |
#include "content/public/common/content_switches.h" |
#include "content/public/test/browser_test_utils.h" |
@@ -52,6 +53,44 @@ void GiveItSomeTime() { |
run_loop.Run(); |
} |
+// WebContentsDelegate which tracks vertical overscroll updates. |
+class VerticalOverscrollTracker : public content::WebContentsDelegate { |
+ public: |
+ VerticalOverscrollTracker() : count_(0), completed_(false) {} |
+ virtual ~VerticalOverscrollTracker() {} |
+ |
+ int num_overscroll_updates() const { |
+ return count_; |
+ } |
+ |
+ bool overscroll_completed() const { |
+ return completed_; |
+ } |
+ |
+ void Reset() { |
+ count_ = 0; |
+ completed_ = false; |
+ } |
+ |
+ private: |
+ virtual bool CanOverscrollContent() const OVERRIDE { |
+ return true; |
+ } |
+ |
+ virtual void OverscrollUpdate(int delta_y) OVERRIDE { |
+ ++count_; |
+ } |
+ |
+ virtual void OverscrollComplete() OVERRIDE { |
+ completed_ = true; |
+ } |
+ |
+ int count_; |
+ bool completed_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(VerticalOverscrollTracker); |
+}; |
+ |
} //namespace |
@@ -969,4 +1008,149 @@ IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest, |
} |
} |
+// Test that vertical overscroll updates are sent only when a user overscrolls |
+// vertically. |
+#if defined(OS_WIN) |
+#define MAYBE_VerticalOverscroll DISABLED_VerticalOverscroll |
+#else |
+#define MAYBE_VerticalOverscroll VerticalOverscroll |
+#endif |
+ |
+IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest, MAYBE_VerticalOverscroll) { |
+ base::CommandLine::ForCurrentProcess()->AppendSwitchASCII( |
+ switches::kScrollEndEffect, "1"); |
+ |
+ ASSERT_NO_FATAL_FAILURE(StartTestWithPage("about:blank")); |
+ WebContentsImpl* web_contents = |
+ static_cast<WebContentsImpl*>(shell()->web_contents()); |
+ VerticalOverscrollTracker tracker; |
+ web_contents->SetDelegate(&tracker); |
+ |
+ // This test triggers a large number of animations. Speed them up to ensure |
+ // the test completes within its time limit. |
+ ui::ScopedAnimationDurationScaleMode fast_duration_mode( |
+ ui::ScopedAnimationDurationScaleMode::FAST_DURATION); |
+ |
+ aura::Window* content = web_contents->GetContentNativeView(); |
+ ui::EventProcessor* dispatcher = content->GetHost()->event_processor(); |
+ gfx::Rect bounds = content->GetBoundsInRootWindow(); |
+ |
+ // Overscroll horizontally. |
+ { |
+ int kXStep = bounds.width() / 10; |
+ gfx::Point location(bounds.right() - kXStep, bounds.y() + 5); |
+ base::TimeDelta timestamp = ui::EventTimeForNow(); |
+ ui::TouchEvent press( |
+ ui::ET_TOUCH_PRESSED, |
+ location, |
+ 0, |
+ timestamp); |
+ ui::EventDispatchDetails details = dispatcher->OnEventFromSource(&press); |
+ ASSERT_FALSE(details.dispatcher_destroyed); |
+ WaitAFrame(); |
+ location -= gfx::Vector2d(kXStep, 0); |
+ timestamp += base::TimeDelta::FromMilliseconds(10); |
+ |
+ while (location.x() > bounds.x() + kXStep) { |
+ ui::TouchEvent inc(ui::ET_TOUCH_MOVED, location, 0, timestamp); |
+ details = dispatcher->OnEventFromSource(&inc); |
+ ASSERT_FALSE(details.dispatcher_destroyed); |
+ WaitAFrame(); |
+ location -= gfx::Vector2d(10, 0); |
+ timestamp += base::TimeDelta::FromMilliseconds(10); |
+ } |
+ |
+ ui::TouchEvent release(ui::ET_TOUCH_RELEASED, location, 0, timestamp); |
+ details = dispatcher->OnEventFromSource(&press); |
+ ASSERT_FALSE(details.dispatcher_destroyed); |
+ WaitAFrame(); |
+ |
+ EXPECT_EQ(0, tracker.num_overscroll_updates()); |
+ EXPECT_FALSE(tracker.overscroll_completed()); |
+ } |
+ |
+ // Overscroll vertically. |
+ { |
+ tracker.Reset(); |
+ |
+ int kYStep = bounds.height() / 10; |
+ gfx::Point location(bounds.x() + 10, bounds.y() + kYStep); |
+ base::TimeDelta timestamp = ui::EventTimeForNow(); |
+ ui::TouchEvent press( |
+ ui::ET_TOUCH_PRESSED, |
+ location, |
+ 0, |
+ timestamp); |
+ ui::EventDispatchDetails details = dispatcher->OnEventFromSource(&press); |
+ ASSERT_FALSE(details.dispatcher_destroyed); |
+ WaitAFrame(); |
+ location += gfx::Vector2d(0, kYStep); |
+ timestamp += base::TimeDelta::FromMilliseconds(10); |
+ |
+ while (location.y() < bounds.bottom() - kYStep) { |
+ ui::TouchEvent inc(ui::ET_TOUCH_MOVED, location, 0, timestamp); |
+ details = dispatcher->OnEventFromSource(&inc); |
+ ASSERT_FALSE(details.dispatcher_destroyed); |
+ WaitAFrame(); |
+ location += gfx::Vector2d(0, kYStep); |
+ timestamp += base::TimeDelta::FromMilliseconds(10); |
+ } |
+ |
+ ui::TouchEvent release(ui::ET_TOUCH_RELEASED, location, 0, timestamp); |
+ details = dispatcher->OnEventFromSource(&release); |
+ ASSERT_FALSE(details.dispatcher_destroyed); |
+ WaitAFrame(); |
+ |
+ EXPECT_LT(0, tracker.num_overscroll_updates()); |
+ EXPECT_TRUE(tracker.overscroll_completed()); |
+ } |
+ |
+ // Start out overscrolling vertically, then switch directions and finish |
+ // overscrolling horizontally. |
+ { |
+ tracker.Reset(); |
+ |
+ int kXStep = bounds.width() / 10; |
+ int kYStep = bounds.height() / 10; |
+ gfx::Point location = bounds.origin() + gfx::Vector2d(0, kYStep); |
+ base::TimeDelta timestamp = ui::EventTimeForNow(); |
+ ui::TouchEvent press( |
+ ui::ET_TOUCH_PRESSED, |
+ location, |
+ 0, |
+ timestamp); |
+ ui::EventDispatchDetails details = dispatcher->OnEventFromSource(&press); |
+ ASSERT_FALSE(details.dispatcher_destroyed); |
+ WaitAFrame(); |
+ location += gfx::Vector2d(0, kYStep); |
+ timestamp += base::TimeDelta::FromMilliseconds(10); |
+ |
+ for (size_t i = 0; i < 3; ++i) { |
+ ui::TouchEvent inc(ui::ET_TOUCH_MOVED, location, 0, timestamp); |
+ details = dispatcher->OnEventFromSource(&inc); |
+ ASSERT_FALSE(details.dispatcher_destroyed); |
+ WaitAFrame(); |
+ location += gfx::Vector2d(0, kYStep); |
+ timestamp += base::TimeDelta::FromMilliseconds(10); |
+ } |
+ |
+ while (location.x() < bounds.right() - kXStep) { |
+ ui::TouchEvent inc(ui::ET_TOUCH_MOVED, location, 0, timestamp); |
+ details = dispatcher->OnEventFromSource(&inc); |
+ ASSERT_FALSE(details.dispatcher_destroyed); |
+ WaitAFrame(); |
+ location += gfx::Vector2d(kXStep, 0); |
+ timestamp += base::TimeDelta::FromMilliseconds(10); |
+ } |
+ |
+ ui::TouchEvent release(ui::ET_TOUCH_RELEASED, location, 0, timestamp); |
+ details = dispatcher->OnEventFromSource(&release); |
+ ASSERT_FALSE(details.dispatcher_destroyed); |
+ WaitAFrame(); |
+ |
+ EXPECT_LT(0, tracker.num_overscroll_updates()); |
+ EXPECT_FALSE(tracker.overscroll_completed()); |
+ } |
+} |
+ |
} // namespace content |