diff options
Diffstat (limited to 'chromium/ui/aura/gestures/gesture_recognizer_unittest.cc')
-rw-r--r-- | chromium/ui/aura/gestures/gesture_recognizer_unittest.cc | 1584 |
1 files changed, 1138 insertions, 446 deletions
diff --git a/chromium/ui/aura/gestures/gesture_recognizer_unittest.cc b/chromium/ui/aura/gestures/gesture_recognizer_unittest.cc index 3a18d1fffc4..596cb1f40cb 100644 --- a/chromium/ui/aura/gestures/gesture_recognizer_unittest.cc +++ b/chromium/ui/aura/gestures/gesture_recognizer_unittest.cc @@ -9,12 +9,12 @@ #include "base/timer/timer.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/aura/env.h" -#include "ui/aura/root_window.h" #include "ui/aura/test/aura_test_base.h" #include "ui/aura/test/event_generator.h" #include "ui/aura/test/test_window_delegate.h" #include "ui/aura/test/test_windows.h" #include "ui/aura/window.h" +#include "ui/aura/window_event_dispatcher.h" #include "ui/base/hit_test.h" #include "ui/base/ui_base_switches.h" #include "ui/events/event.h" @@ -93,15 +93,11 @@ class GestureEventConsumeDelegate : public TestWindowDelegate { scroll_velocity_y_(0), velocity_x_(0), velocity_y_(0), - scroll_x_ordinal_(0), - scroll_y_ordinal_(0), - scroll_velocity_x_ordinal_(0), - scroll_velocity_y_ordinal_(0), - velocity_x_ordinal_(0), - velocity_y_ordinal_(0), + scroll_x_hint_(0), + scroll_y_hint_(0), tap_count_(0), - wait_until_event_(ui::ET_UNKNOWN) { - } + flags_(0), + wait_until_event_(ui::ET_UNKNOWN) {} virtual ~GestureEventConsumeDelegate() {} @@ -129,6 +125,7 @@ class GestureEventConsumeDelegate : public TestWindowDelegate { scroll_begin_position_.SetPoint(0, 0); tap_location_.SetPoint(0, 0); + gesture_end_location_.SetPoint(0, 0); scroll_x_ = 0; scroll_y_ = 0; @@ -136,13 +133,12 @@ class GestureEventConsumeDelegate : public TestWindowDelegate { scroll_velocity_y_ = 0; velocity_x_ = 0; velocity_y_ = 0; - scroll_x_ordinal_ = 0; - scroll_y_ordinal_ = 0; - scroll_velocity_x_ordinal_ = 0; - scroll_velocity_y_ordinal_ = 0; - velocity_x_ordinal_ = 0; - velocity_y_ordinal_ = 0; + scroll_x_hint_ = 0; + scroll_y_hint_ = 0; tap_count_ = 0; + scale_ = 0; + flags_ = 0; + latency_info_.Clear(); } const std::vector<ui::EventType>& events() const { return events_; }; @@ -168,40 +164,43 @@ class GestureEventConsumeDelegate : public TestWindowDelegate { bool swipe_up() const { return swipe_up_; } bool swipe_down() const { return swipe_down_; } - const gfx::Point scroll_begin_position() const { + const gfx::Point& scroll_begin_position() const { return scroll_begin_position_; } - const gfx::Point tap_location() const { + const gfx::Point& tap_location() const { return tap_location_; } + const gfx::Point& gesture_end_location() const { + return gesture_end_location_; + } + float scroll_x() const { return scroll_x_; } float scroll_y() const { return scroll_y_; } float scroll_velocity_x() const { return scroll_velocity_x_; } float scroll_velocity_y() const { return scroll_velocity_y_; } float velocity_x() const { return velocity_x_; } float velocity_y() const { return velocity_y_; } - float scroll_x_ordinal() const { return scroll_x_ordinal_; } - float scroll_y_ordinal() const { return scroll_y_ordinal_; } - float scroll_velocity_x_ordinal() const { return scroll_velocity_x_ordinal_; } - float scroll_velocity_y_ordinal() const { return scroll_velocity_y_ordinal_; } - float velocity_x_ordinal() const { return velocity_x_ordinal_; } - float velocity_y_ordinal() const { return velocity_y_ordinal_; } - int touch_id() const { return touch_id_; } + float scroll_x_hint() const { return scroll_x_hint_; } + float scroll_y_hint() const { return scroll_y_hint_; } + float scale() const { return scale_; } const gfx::Rect& bounding_box() const { return bounding_box_; } int tap_count() const { return tap_count_; } + int flags() const { return flags_; } + const ui::LatencyInfo& latency_info() const { return latency_info_; } void WaitUntilReceivedGesture(ui::EventType type) { wait_until_event_ = type; - run_loop_.reset(new base::RunLoop( - Env::GetInstance()->GetDispatcher())); + run_loop_.reset(new base::RunLoop()); run_loop_->Run(); } virtual void OnGestureEvent(ui::GestureEvent* gesture) OVERRIDE { events_.push_back(gesture->type()); bounding_box_ = gesture->details().bounding_box(); + flags_ = gesture->flags(); + latency_info_ = *gesture->latency(); switch (gesture->type()) { case ui::ET_GESTURE_TAP: tap_location_ = gesture->location(); @@ -219,21 +218,18 @@ class GestureEventConsumeDelegate : public TestWindowDelegate { break; case ui::ET_GESTURE_END: end_ = true; + gesture_end_location_ = gesture->location(); break; case ui::ET_GESTURE_SCROLL_BEGIN: scroll_begin_ = true; scroll_begin_position_ = gesture->location(); + scroll_x_hint_ = gesture->details().scroll_x_hint(); + scroll_y_hint_ = gesture->details().scroll_y_hint(); break; case ui::ET_GESTURE_SCROLL_UPDATE: scroll_update_ = true; scroll_x_ += gesture->details().scroll_x(); scroll_y_ += gesture->details().scroll_y(); - scroll_velocity_x_ = gesture->details().velocity_x(); - scroll_velocity_y_ = gesture->details().velocity_y(); - scroll_x_ordinal_ += gesture->details().scroll_x_ordinal(); - scroll_y_ordinal_ += gesture->details().scroll_y_ordinal(); - scroll_velocity_x_ordinal_ = gesture->details().velocity_x_ordinal(); - scroll_velocity_y_ordinal_ = gesture->details().velocity_y_ordinal(); break; case ui::ET_GESTURE_SCROLL_END: EXPECT_TRUE(velocity_x_ == 0 && velocity_y_ == 0); @@ -244,13 +240,13 @@ class GestureEventConsumeDelegate : public TestWindowDelegate { break; case ui::ET_GESTURE_PINCH_UPDATE: pinch_update_ = true; + scale_ = gesture->details().scale(); break; case ui::ET_GESTURE_PINCH_END: pinch_end_ = true; break; case ui::ET_GESTURE_LONG_PRESS: long_press_ = true; - touch_id_ = gesture->details().touch_id(); break; case ui::ET_GESTURE_LONG_TAP: long_tap_ = true; @@ -262,8 +258,6 @@ class GestureEventConsumeDelegate : public TestWindowDelegate { fling_ = true; velocity_x_ = gesture->details().velocity_x(); velocity_y_ = gesture->details().velocity_y(); - velocity_x_ordinal_ = gesture->details().velocity_x_ordinal(); - velocity_y_ordinal_ = gesture->details().velocity_y_ordinal(); break; case ui::ET_GESTURE_TWO_FINGER_TAP: two_finger_tap_ = true; @@ -271,12 +265,15 @@ class GestureEventConsumeDelegate : public TestWindowDelegate { case ui::ET_GESTURE_SHOW_PRESS: show_press_ = true; break; - case ui::ET_GESTURE_MULTIFINGER_SWIPE: + case ui::ET_GESTURE_SWIPE: swipe_left_ = gesture->details().swipe_left(); swipe_right_ = gesture->details().swipe_right(); swipe_up_ = gesture->details().swipe_up(); swipe_down_ = gesture->details().swipe_down(); break; + case ui::ET_SCROLL_FLING_CANCEL: + // Only used in unified gesture detection. + break; default: NOTREACHED(); } @@ -314,6 +311,7 @@ class GestureEventConsumeDelegate : public TestWindowDelegate { gfx::Point scroll_begin_position_; gfx::Point tap_location_; + gfx::Point gesture_end_location_; float scroll_x_; float scroll_y_; @@ -321,15 +319,13 @@ class GestureEventConsumeDelegate : public TestWindowDelegate { float scroll_velocity_y_; float velocity_x_; float velocity_y_; - float scroll_x_ordinal_; - float scroll_y_ordinal_; - float scroll_velocity_x_ordinal_; - float scroll_velocity_y_ordinal_; - float velocity_x_ordinal_; - float velocity_y_ordinal_; - int touch_id_; + float scroll_x_hint_; + float scroll_y_hint_; + float scale_; gfx::Rect bounding_box_; int tap_count_; + int flags_; + ui::LatencyInfo latency_info_; ui::EventType wait_until_event_; @@ -338,9 +334,9 @@ class GestureEventConsumeDelegate : public TestWindowDelegate { class QueueTouchEventDelegate : public GestureEventConsumeDelegate { public: - explicit QueueTouchEventDelegate(RootWindow* root_window) + explicit QueueTouchEventDelegate(WindowEventDispatcher* dispatcher) : window_(NULL), - root_window_(root_window), + dispatcher_(dispatcher), queue_events_(true) { } virtual ~QueueTouchEventDelegate() { @@ -371,14 +367,14 @@ class QueueTouchEventDelegate : public GestureEventConsumeDelegate { private: void ReceivedAckImpl(bool prevent_defaulted) { scoped_ptr<ui::TouchEvent> event(queue_.front()); - root_window_->ProcessedTouchEvent(event.get(), window_, + dispatcher_->ProcessedTouchEvent(event.get(), window_, prevent_defaulted ? ui::ER_HANDLED : ui::ER_UNHANDLED); queue_.pop(); } std::queue<ui::TouchEvent*> queue_; Window* window_; - RootWindow* root_window_; + WindowEventDispatcher* dispatcher_; bool queue_events_; DISALLOW_COPY_AND_ASSIGN(QueueTouchEventDelegate); @@ -543,7 +539,9 @@ class TimedEvents { int simulated_now_; public: - TimedEvents() : simulated_now_(0) { + // Use a non-zero start time to pass DCHECKs which ensure events have had a + // time assigned. + TimedEvents() : simulated_now_(1) { } base::TimeDelta Now() { @@ -561,9 +559,9 @@ class TimedEvents { return base::TimeDelta::FromMilliseconds(simulated_now_ + time_in_millis); } - void SendScrollEvents(RootWindow* root_window, - int x_start, - int y_start, + void SendScrollEvents(ui::EventProcessor* dispatcher, + float x_start, + float y_start, int dx, int dy, int touch_id, @@ -576,24 +574,26 @@ class TimedEvents { for (int i = 0; i < num_steps; i++) { x += dx; y += dy; - ui::TouchEvent move(ui::ET_TOUCH_MOVED, gfx::Point(x, y), + ui::TouchEvent move(ui::ET_TOUCH_MOVED, gfx::PointF(x, y), touch_id, base::TimeDelta::FromMilliseconds(simulated_now_)); - root_window->AsRootWindowHostDelegate()->OnHostTouchEvent(&move); + ui::EventDispatchDetails details = dispatcher->OnEventFromSource(&move); + ASSERT_FALSE(details.dispatcher_destroyed); simulated_now_ += time_step; } } - void SendScrollEvent(RootWindow* root_window, - int x, - int y, + void SendScrollEvent(ui::EventProcessor* dispatcher, + float x, + float y, int touch_id, GestureEventConsumeDelegate* delegate) { delegate->Reset(); - ui::TouchEvent move(ui::ET_TOUCH_MOVED, gfx::Point(x, y), + ui::TouchEvent move(ui::ET_TOUCH_MOVED, gfx::PointF(x, y), touch_id, base::TimeDelta::FromMilliseconds(simulated_now_)); - root_window->AsRootWindowHostDelegate()->OnHostTouchEvent(&move); + ui::EventDispatchDetails details = dispatcher->OnEventFromSource(&move); + ASSERT_FALSE(details.dispatcher_destroyed); simulated_now_++; } }; @@ -601,8 +601,9 @@ class TimedEvents { // An event handler to keep track of events. class TestEventHandler : public ui::EventHandler { public: - TestEventHandler() : touch_released_count_(0), touch_pressed_count_(0), - touch_moved_count_(0), touch_stationary_count_(0), + TestEventHandler() : touch_released_count_(0), + touch_pressed_count_(0), + touch_moved_count_(0), touch_cancelled_count_(0) { } @@ -619,9 +620,6 @@ class TestEventHandler : public ui::EventHandler { case ui::ET_TOUCH_MOVED: touch_moved_count_++; break; - case ui::ET_TOUCH_STATIONARY: - touch_stationary_count_++; - break; case ui::ET_TOUCH_CANCELLED: touch_cancelled_count_++; break; @@ -634,21 +632,18 @@ class TestEventHandler : public ui::EventHandler { touch_released_count_ = 0; touch_pressed_count_ = 0; touch_moved_count_ = 0; - touch_stationary_count_ = 0; touch_cancelled_count_ = 0; } int touch_released_count() const { return touch_released_count_; } int touch_pressed_count() const { return touch_pressed_count_; } int touch_moved_count() const { return touch_moved_count_; } - int touch_stationary_count() const { return touch_stationary_count_; } int touch_cancelled_count() const { return touch_cancelled_count_; } private: int touch_released_count_; int touch_pressed_count_; int touch_moved_count_; - int touch_stationary_count_; int touch_cancelled_count_; DISALLOW_COPY_AND_ASSIGN(TestEventHandler); @@ -679,21 +674,34 @@ class RemoveOnTouchCancelHandler : public TestEventHandler { } // namespace -class GestureRecognizerTest : public AuraTestBase { +class GestureRecognizerTest : public AuraTestBase, + public ::testing::WithParamInterface<bool> { public: GestureRecognizerTest() {} + bool UsingUnifiedGR() { + return GetParam(); + } + virtual void SetUp() OVERRIDE { - CommandLine::ForCurrentProcess()->AppendSwitch( - switches::kEnableScrollPrediction); + // TODO(tdresser): Once unified GR has landed, only run these tests once. + CommandLine::ForCurrentProcess()->AppendSwitchASCII( + switches::kUnifiedGestureDetector, + UsingUnifiedGR() ? switches::kUnifiedGestureDetectorEnabled + : switches::kUnifiedGestureDetectorDisabled); + AuraTestBase::SetUp(); + ui::GestureConfiguration::set_min_touch_down_duration_in_seconds_for_click( + 0.001); + ui::GestureConfiguration::set_show_press_delay_in_ms(2); + ui::GestureConfiguration::set_long_press_time_in_seconds(0.003); } DISALLOW_COPY_AND_ASSIGN(GestureRecognizerTest); }; // Check that appropriate touch events generate tap gesture events. -TEST_F(GestureRecognizerTest, GestureEventTap) { +TEST_P(GestureRecognizerTest, GestureEventTap) { scoped_ptr<GestureEventConsumeDelegate> delegate( new GestureEventConsumeDelegate()); TimedEvents tes; @@ -707,7 +715,7 @@ TEST_F(GestureRecognizerTest, GestureEventTap) { delegate->Reset(); ui::TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), kTouchId, tes.Now()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press); + DispatchEventUsingWindowDispatcher(&press); EXPECT_FALSE(delegate->tap()); EXPECT_FALSE(delegate->show_press()); EXPECT_TRUE(delegate->tap_down()); @@ -729,7 +737,7 @@ TEST_F(GestureRecognizerTest, GestureEventTap) { ui::TouchEvent release(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), kTouchId, tes.LeapForward(50)); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&release); + DispatchEventUsingWindowDispatcher(&release); EXPECT_TRUE(delegate->tap()); EXPECT_FALSE(delegate->tap_down()); EXPECT_FALSE(delegate->tap_cancel()); @@ -744,7 +752,12 @@ TEST_F(GestureRecognizerTest, GestureEventTap) { // Check that appropriate touch events generate tap gesture events // when information about the touch radii are provided. -TEST_F(GestureRecognizerTest, GestureEventTapRegion) { +TEST_P(GestureRecognizerTest, GestureEventTapRegion) { + // TODO(tdresser): enable this test with unified GR once we resolve the + // bounding box differences. See crbug.com/366641. + if (UsingUnifiedGR()) + return; + scoped_ptr<GestureEventConsumeDelegate> delegate( new GestureEventConsumeDelegate()); TimedEvents tes; @@ -762,7 +775,7 @@ TEST_F(GestureRecognizerTest, GestureEventTapRegion) { kTouchId, tes.Now()); press.set_radius_x(5); press.set_radius_y(12); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press); + DispatchEventUsingWindowDispatcher(&press); EXPECT_FALSE(delegate->tap()); EXPECT_TRUE(delegate->tap_down()); EXPECT_FALSE(delegate->tap_cancel()); @@ -780,7 +793,7 @@ TEST_F(GestureRecognizerTest, GestureEventTapRegion) { release.set_radius_x(5); release.set_radius_y(12); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&release); + DispatchEventUsingWindowDispatcher(&release); EXPECT_TRUE(delegate->tap()); EXPECT_FALSE(delegate->tap_down()); EXPECT_FALSE(delegate->tap_cancel()); @@ -805,7 +818,7 @@ TEST_F(GestureRecognizerTest, GestureEventTapRegion) { kTouchId, tes.Now()); press.set_radius_x(8); press.set_radius_y(14); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press); + DispatchEventUsingWindowDispatcher(&press); EXPECT_FALSE(delegate->tap()); EXPECT_TRUE(delegate->tap_down()); EXPECT_FALSE(delegate->tap_cancel()); @@ -821,7 +834,7 @@ TEST_F(GestureRecognizerTest, GestureEventTapRegion) { release.set_radius_x(20); release.set_radius_y(13); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&release); + DispatchEventUsingWindowDispatcher(&release); EXPECT_TRUE(delegate->tap()); EXPECT_FALSE(delegate->tap_down()); EXPECT_FALSE(delegate->tap_cancel()); @@ -846,7 +859,7 @@ TEST_F(GestureRecognizerTest, GestureEventTapRegion) { kTouchId, tes.Now()); press.set_radius_x(6); press.set_radius_y(10); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press); + DispatchEventUsingWindowDispatcher(&press); EXPECT_FALSE(delegate->tap()); EXPECT_TRUE(delegate->tap_down()); EXPECT_FALSE(delegate->tap_cancel()); @@ -862,7 +875,7 @@ TEST_F(GestureRecognizerTest, GestureEventTapRegion) { kTouchId, tes.LeapForward(50)); move.set_radius_x(8); move.set_radius_y(12); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&move); + DispatchEventUsingWindowDispatcher(&move); EXPECT_FALSE(delegate->tap()); EXPECT_FALSE(delegate->tap_down()); EXPECT_FALSE(delegate->tap_cancel()); @@ -878,7 +891,7 @@ TEST_F(GestureRecognizerTest, GestureEventTapRegion) { release.set_radius_x(4); release.set_radius_y(8); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&release); + DispatchEventUsingWindowDispatcher(&release); EXPECT_TRUE(delegate->tap()); EXPECT_FALSE(delegate->tap_down()); EXPECT_FALSE(delegate->tap_cancel()); @@ -903,7 +916,7 @@ TEST_F(GestureRecognizerTest, GestureEventTapRegion) { kTouchId, tes.Now()); press.set_radius_x(7); press.set_radius_y(10); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press); + DispatchEventUsingWindowDispatcher(&press); EXPECT_FALSE(delegate->tap()); EXPECT_TRUE(delegate->tap_down()); EXPECT_FALSE(delegate->tap_cancel()); @@ -918,7 +931,7 @@ TEST_F(GestureRecognizerTest, GestureEventTapRegion) { kTouchId, tes.LeapForward(50)); move.set_radius_x(13); move.set_radius_y(12); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&move); + DispatchEventUsingWindowDispatcher(&move); EXPECT_FALSE(delegate->tap()); EXPECT_FALSE(delegate->tap_down()); EXPECT_FALSE(delegate->tap_cancel()); @@ -933,7 +946,7 @@ TEST_F(GestureRecognizerTest, GestureEventTapRegion) { kTouchId, tes.LeapForward(50)); move1.set_radius_x(16); move1.set_radius_y(16); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&move1); + DispatchEventUsingWindowDispatcher(&move1); EXPECT_FALSE(delegate->tap()); EXPECT_FALSE(delegate->tap_down()); EXPECT_FALSE(delegate->tap_cancel()); @@ -948,7 +961,7 @@ TEST_F(GestureRecognizerTest, GestureEventTapRegion) { kTouchId, tes.LeapForward(50)); move2.set_radius_x(14); move2.set_radius_y(10); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&move2); + DispatchEventUsingWindowDispatcher(&move2); EXPECT_FALSE(delegate->tap()); EXPECT_FALSE(delegate->tap_down()); EXPECT_FALSE(delegate->tap_cancel()); @@ -964,7 +977,7 @@ TEST_F(GestureRecognizerTest, GestureEventTapRegion) { release.set_radius_x(8); release.set_radius_y(9); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&release); + DispatchEventUsingWindowDispatcher(&release); EXPECT_TRUE(delegate->tap()); EXPECT_FALSE(delegate->tap_down()); EXPECT_FALSE(delegate->tap_cancel()); @@ -984,7 +997,12 @@ TEST_F(GestureRecognizerTest, GestureEventTapRegion) { } // Check that appropriate touch events generate scroll gesture events. -TEST_F(GestureRecognizerTest, GestureEventScroll) { +TEST_P(GestureRecognizerTest, GestureEventScroll) { + // We'll start by moving the touch point by (10.5, 10.5). We want 5 dips of + // that distance to be consumed by the slop, so we set the slop radius to + // sqrt(5 * 5 + 5 * 5). + ui::GestureConfiguration::set_max_touch_move_in_pixels_for_click( + sqrt(static_cast<double>(5 * 5 + 5 * 5))); scoped_ptr<GestureEventConsumeDelegate> delegate( new GestureEventConsumeDelegate()); TimedEvents tes; @@ -998,7 +1016,7 @@ TEST_F(GestureRecognizerTest, GestureEventScroll) { delegate->Reset(); ui::TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), kTouchId, tes.Now()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press); + DispatchEventUsingWindowDispatcher(&press); EXPECT_2_EVENTS(delegate->events(), ui::ET_GESTURE_BEGIN, ui::ET_GESTURE_TAP_DOWN); @@ -1007,13 +1025,15 @@ TEST_F(GestureRecognizerTest, GestureEventScroll) { // should generate both SCROLL_BEGIN and SCROLL_UPDATE gestures. // The first movement is diagonal, to ensure that we have a free scroll, // and not a rail scroll. - tes.SendScrollEvent(dispatcher(), 130, 230, kTouchId, delegate.get()); + tes.SendScrollEvent(event_processor(), 111.5, 211.5, kTouchId, + delegate.get()); EXPECT_3_EVENTS(delegate->events(), ui::ET_GESTURE_TAP_CANCEL, ui::ET_GESTURE_SCROLL_BEGIN, ui::ET_GESTURE_SCROLL_UPDATE); - EXPECT_EQ(29, delegate->scroll_x()); - EXPECT_EQ(29, delegate->scroll_y()); + // The slop consumed 5 dips + EXPECT_FLOAT_EQ(5.5, delegate->scroll_x()); + EXPECT_FLOAT_EQ(5.5, delegate->scroll_y()); EXPECT_EQ(gfx::Point(1, 1).ToString(), delegate->scroll_begin_position().ToString()); @@ -1021,14 +1041,15 @@ TEST_F(GestureRecognizerTest, GestureEventScroll) { // be empty, since it's a single point and the radius for testing is zero. EXPECT_TRUE(delegate->bounding_box().IsEmpty()); - // Move some more to generate a few more scroll updates. - tes.SendScrollEvent(dispatcher(), 110, 211, kTouchId, delegate.get()); + // Move some more to generate a few more scroll updates. Make sure that we get + // out of the snap channel for the unified GR. + tes.SendScrollEvent(event_processor(), 20, 120, kTouchId, delegate.get()); EXPECT_1_EVENT(delegate->events(), ui::ET_GESTURE_SCROLL_UPDATE); - EXPECT_EQ(-20, delegate->scroll_x()); - EXPECT_EQ(-19, delegate->scroll_y()); + EXPECT_FLOAT_EQ(-91.5, delegate->scroll_x()); + EXPECT_FLOAT_EQ(-91.5, delegate->scroll_y()); EXPECT_TRUE(delegate->bounding_box().IsEmpty()); - tes.SendScrollEvent(dispatcher(), 140, 215, kTouchId, delegate.get()); + tes.SendScrollEvent(event_processor(), 50, 124, kTouchId, delegate.get()); EXPECT_1_EVENT(delegate->events(), ui::ET_GESTURE_SCROLL_UPDATE); EXPECT_EQ(30, delegate->scroll_x()); EXPECT_EQ(4, delegate->scroll_y()); @@ -1039,7 +1060,7 @@ TEST_F(GestureRecognizerTest, GestureEventScroll) { ui::TouchEvent release(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), kTouchId, tes.LeapForward(50)); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&release); + DispatchEventUsingWindowDispatcher(&release); EXPECT_2_EVENTS(delegate->events(), ui::ET_SCROLL_FLING_START, ui::ET_GESTURE_END); @@ -1047,16 +1068,22 @@ TEST_F(GestureRecognizerTest, GestureEventScroll) { } // Check that predicted scroll update positions are correct. -TEST_F(GestureRecognizerTest, GestureEventScrollPrediction) { +TEST_P(GestureRecognizerTest, GestureEventScrollPrediction) { const double prediction_interval = 0.03; ui::GestureConfiguration::set_scroll_prediction_seconds(prediction_interval); + // We'll start by moving the touch point by (5, 5). We want all of that + // distance to be consumed by the slop, so we set the slop radius to + // sqrt(5 * 5 + 5 * 5). + ui::GestureConfiguration::set_max_touch_move_in_pixels_for_click( + sqrt(static_cast<double>(5 * 5 + 5 * 5))); + scoped_ptr<GestureEventConsumeDelegate> delegate( new GestureEventConsumeDelegate()); TimedEvents tes; const int kWindowWidth = 123; const int kWindowHeight = 45; const int kTouchId = 5; - gfx::Rect bounds(100, 200, kWindowWidth, kWindowHeight); + gfx::Rect bounds(95, 195, kWindowWidth, kWindowHeight); scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( delegate.get(), -1234, bounds, root_window())); @@ -1064,63 +1091,59 @@ TEST_F(GestureRecognizerTest, GestureEventScrollPrediction) { // Tracks the total scroll since we want to verify that the correct position // will be scrolled to throughout the prediction. gfx::Vector2dF total_scroll; - ui::TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), + ui::TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(96, 196), kTouchId, tes.Now()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press); + DispatchEventUsingWindowDispatcher(&press); EXPECT_2_EVENTS(delegate->events(), ui::ET_GESTURE_BEGIN, ui::ET_GESTURE_TAP_DOWN); + delegate->Reset(); + + // Get rid of touch slop. + ui::TouchEvent move(ui::ET_TOUCH_MOVED, gfx::Point(111, 211), + kTouchId, tes.Now()); + DispatchEventUsingWindowDispatcher(&move); + EXPECT_3_EVENTS(delegate->events(), + ui::ET_GESTURE_TAP_CANCEL, + ui::ET_GESTURE_SCROLL_BEGIN, + ui::ET_GESTURE_SCROLL_UPDATE); + total_scroll.set_x(total_scroll.x() + delegate->scroll_x()); + total_scroll.set_y(total_scroll.y() + delegate->scroll_y()); // Move the touch-point enough so that it is considered as a scroll. This // should generate both SCROLL_BEGIN and SCROLL_UPDATE gestures. // The first movement is diagonal, to ensure that we have a free scroll, // and not a rail scroll. tes.LeapForward(30); - tes.SendScrollEvent(dispatcher(), 130, 230, kTouchId, delegate.get()); - EXPECT_3_EVENTS(delegate->events(), - ui::ET_GESTURE_TAP_CANCEL, - ui::ET_GESTURE_SCROLL_BEGIN, - ui::ET_GESTURE_SCROLL_UPDATE); - EXPECT_GT(delegate->scroll_velocity_x(), 0); - EXPECT_GT(delegate->scroll_velocity_y(), 0); + tes.SendScrollEvent(event_processor(), 130, 230, kTouchId, delegate.get()); + EXPECT_1_EVENT(delegate->events(), + ui::ET_GESTURE_SCROLL_UPDATE); total_scroll.set_x(total_scroll.x() + delegate->scroll_x()); total_scroll.set_y(total_scroll.y() + delegate->scroll_y()); - EXPECT_EQ((int)(29 + delegate->scroll_velocity_x() * prediction_interval), - (int)(total_scroll.x())); - EXPECT_EQ((int)(29 + delegate->scroll_velocity_y() * prediction_interval), - (int)(total_scroll.y())); // Move some more to generate a few more scroll updates. tes.LeapForward(30); - tes.SendScrollEvent(dispatcher(), 110, 211, kTouchId, delegate.get()); + tes.SendScrollEvent(event_processor(), 110, 211, kTouchId, delegate.get()); EXPECT_1_EVENT(delegate->events(), ui::ET_GESTURE_SCROLL_UPDATE); total_scroll.set_x(total_scroll.x() + delegate->scroll_x()); total_scroll.set_y(total_scroll.y() + delegate->scroll_y()); - EXPECT_EQ((int)(9 + delegate->scroll_velocity_x() * prediction_interval), - (int)(total_scroll.x())); - EXPECT_EQ((int)(10 + delegate->scroll_velocity_y() * prediction_interval), - (int)(total_scroll.y())); tes.LeapForward(30); - tes.SendScrollEvent(dispatcher(), 140, 215, kTouchId, delegate.get()); + tes.SendScrollEvent(event_processor(), 140, 215, kTouchId, delegate.get()); EXPECT_1_EVENT(delegate->events(), ui::ET_GESTURE_SCROLL_UPDATE); total_scroll.set_x(total_scroll.x() + delegate->scroll_x()); total_scroll.set_y(total_scroll.y() + delegate->scroll_y()); - EXPECT_EQ((int)(39 + delegate->scroll_velocity_x() * prediction_interval), - (int)(total_scroll.x())); - EXPECT_EQ((int)(14 + delegate->scroll_velocity_y() * prediction_interval), - (int)(total_scroll.y())); // Release the touch. This should end the scroll. delegate->Reset(); ui::TouchEvent release(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), kTouchId, tes.LeapForward(50)); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&release); + DispatchEventUsingWindowDispatcher(&release); } // Check that the bounding box during a scroll event is correct. -TEST_F(GestureRecognizerTest, GestureEventScrollBoundingBox) { +TEST_P(GestureRecognizerTest, GestureEventScrollBoundingBox) { TimedEvents tes; for (int radius = 1; radius <= 10; ++radius) { ui::GestureConfiguration::set_default_radius(radius); @@ -1140,7 +1163,7 @@ TEST_F(GestureRecognizerTest, GestureEventScrollBoundingBox) { gfx::Point(kPositionX, kPositionY), kTouchId, tes.Now()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press); + DispatchEventUsingWindowDispatcher(&press); EXPECT_EQ(gfx::Rect(kPositionX - radius, kPositionY - radius, radius * 2, @@ -1148,7 +1171,7 @@ TEST_F(GestureRecognizerTest, GestureEventScrollBoundingBox) { delegate->bounding_box().ToString()); const int kScrollAmount = 50; - tes.SendScrollEvents(dispatcher(), kPositionX, kPositionY, + tes.SendScrollEvents(event_processor(), kPositionX, kPositionY, 1, 1, kTouchId, 1, kScrollAmount, delegate.get()); EXPECT_EQ(gfx::Point(1, 1).ToString(), delegate->scroll_begin_position().ToString()); @@ -1165,7 +1188,7 @@ TEST_F(GestureRecognizerTest, GestureEventScrollBoundingBox) { kPositionY + kScrollAmount), kTouchId, press.time_stamp() + base::TimeDelta::FromMilliseconds(50)); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&release); + DispatchEventUsingWindowDispatcher(&release); EXPECT_EQ(gfx::Rect(kPositionX + kScrollAmount - radius, kPositionY + kScrollAmount - radius, radius * 2, @@ -1177,7 +1200,7 @@ TEST_F(GestureRecognizerTest, GestureEventScrollBoundingBox) { // Check Scroll End Events report correct velocities // if the user was on a horizontal rail -TEST_F(GestureRecognizerTest, GestureEventHorizontalRailFling) { +TEST_P(GestureRecognizerTest, GestureEventHorizontalRailFling) { scoped_ptr<GestureEventConsumeDelegate> delegate( new GestureEventConsumeDelegate()); TimedEvents tes; @@ -1188,30 +1211,31 @@ TEST_F(GestureRecognizerTest, GestureEventHorizontalRailFling) { ui::TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(0, 0), kTouchId, tes.Now()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press); + DispatchEventUsingWindowDispatcher(&press); + + // Get rid of touch slop. + ui::TouchEvent move(ui::ET_TOUCH_MOVED, gfx::Point(10, 0), + kTouchId, tes.Now()); + DispatchEventUsingWindowDispatcher(&move); + delegate->Reset(); + // Move the touch-point horizontally enough that it is considered a // horizontal scroll. - tes.SendScrollEvent(dispatcher(), 20, 1, kTouchId, delegate.get()); - EXPECT_EQ(0, delegate->scroll_y()); - EXPECT_EQ(1, delegate->scroll_y_ordinal()); - EXPECT_EQ(20, delegate->scroll_x()); - EXPECT_EQ(20, delegate->scroll_x_ordinal()); + tes.SendScrollEvent(event_processor(), 30, 1, kTouchId, delegate.get()); + EXPECT_FLOAT_EQ(0, delegate->scroll_y()); + EXPECT_FLOAT_EQ(20, delegate->scroll_x()); // Get a high x velocity, while still staying on the rail - tes.SendScrollEvents(dispatcher(), 1, 1, + tes.SendScrollEvents(event_processor(), 1, 1, 100, 10, kTouchId, 1, ui::GestureConfiguration::points_buffered_for_velocity(), delegate.get()); - // The y-velocity during the scroll should be 0 since this is in a horizontal - // rail scroll. - EXPECT_GT(delegate->scroll_velocity_x(), 0); - EXPECT_EQ(0, delegate->scroll_velocity_y()); delegate->Reset(); ui::TouchEvent release(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), kTouchId, tes.Now()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&release); + DispatchEventUsingWindowDispatcher(&release); EXPECT_TRUE(delegate->fling()); EXPECT_FALSE(delegate->scroll_end()); @@ -1221,7 +1245,7 @@ TEST_F(GestureRecognizerTest, GestureEventHorizontalRailFling) { // Check Scroll End Events report correct velocities // if the user was on a vertical rail -TEST_F(GestureRecognizerTest, GestureEventVerticalRailFling) { +TEST_P(GestureRecognizerTest, GestureEventVerticalRailFling) { scoped_ptr<GestureEventConsumeDelegate> delegate( new GestureEventConsumeDelegate()); TimedEvents tes; @@ -1232,30 +1256,32 @@ TEST_F(GestureRecognizerTest, GestureEventVerticalRailFling) { ui::TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(0, 0), kTouchId, tes.Now()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press); + DispatchEventUsingWindowDispatcher(&press); + + // Get rid of touch slop. + ui::TouchEvent move(ui::ET_TOUCH_MOVED, gfx::Point(0, 10), + kTouchId, tes.Now()); + DispatchEventUsingWindowDispatcher(&move); + delegate->Reset(); // Move the touch-point vertically enough that it is considered a // vertical scroll. - tes.SendScrollEvent(dispatcher(), 1, 20, kTouchId, delegate.get()); + tes.SendScrollEvent(event_processor(), 1, 30, kTouchId, delegate.get()); EXPECT_EQ(20, delegate->scroll_y()); - EXPECT_EQ(20, delegate->scroll_y_ordinal()); EXPECT_EQ(0, delegate->scroll_x()); - EXPECT_EQ(1, delegate->scroll_x_ordinal()); EXPECT_EQ(0, delegate->scroll_velocity_x()); - EXPECT_GT(delegate->scroll_velocity_x_ordinal(), 0); // Get a high y velocity, while still staying on the rail - tes.SendScrollEvents(dispatcher(), 1, 1, + tes.SendScrollEvents(event_processor(), 1, 6, 10, 100, kTouchId, 1, ui::GestureConfiguration::points_buffered_for_velocity(), delegate.get()); EXPECT_EQ(0, delegate->scroll_velocity_x()); - EXPECT_GT(delegate->scroll_velocity_y(), 0); delegate->Reset(); - ui::TouchEvent release(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), + ui::TouchEvent release(ui::ET_TOUCH_RELEASED, gfx::Point(101, 206), kTouchId, tes.Now()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&release); + DispatchEventUsingWindowDispatcher(&release); EXPECT_TRUE(delegate->fling()); EXPECT_FALSE(delegate->scroll_end()); @@ -1263,9 +1289,10 @@ TEST_F(GestureRecognizerTest, GestureEventVerticalRailFling) { EXPECT_GT(delegate->velocity_y(), 0); } -// Check Scroll End Events reports zero velocities -// if the user is not on a rail -TEST_F(GestureRecognizerTest, GestureEventNonRailFling) { +// Check Scroll End Events report non-zero velocities if the user is not on a +// rail +TEST_P(GestureRecognizerTest, GestureEventNonRailFling) { + ui::GestureConfiguration::set_max_touch_move_in_pixels_for_click(0); scoped_ptr<GestureEventConsumeDelegate> delegate( new GestureEventConsumeDelegate()); TimedEvents tes; @@ -1276,14 +1303,15 @@ TEST_F(GestureRecognizerTest, GestureEventNonRailFling) { ui::TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(0, 0), kTouchId, tes.Now()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press); + DispatchEventUsingWindowDispatcher(&press); - // Move the touch-point such that a non-rail scroll begins - tes.SendScrollEvent(dispatcher(), 20, 20, kTouchId, delegate.get()); - EXPECT_EQ(20, delegate->scroll_y()); - EXPECT_EQ(20, delegate->scroll_x()); + // Move the touch-point such that a non-rail scroll begins, and we're outside + // the snap channel for the unified GR. + tes.SendScrollEvent(event_processor(), 50, 50, kTouchId, delegate.get()); + EXPECT_EQ(50, delegate->scroll_y()); + EXPECT_EQ(50, delegate->scroll_x()); - tes.SendScrollEvents(dispatcher(), 1, 1, + tes.SendScrollEvents(event_processor(), 1, 1, 10, 100, kTouchId, 1, ui::GestureConfiguration::points_buffered_for_velocity(), delegate.get()); @@ -1291,7 +1319,7 @@ TEST_F(GestureRecognizerTest, GestureEventNonRailFling) { delegate->Reset(); ui::TouchEvent release(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), kTouchId, tes.Now()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&release); + DispatchEventUsingWindowDispatcher(&release); EXPECT_TRUE(delegate->fling()); EXPECT_FALSE(delegate->scroll_end()); @@ -1300,10 +1328,12 @@ TEST_F(GestureRecognizerTest, GestureEventNonRailFling) { } // Check that appropriate touch events generate long press events -TEST_F(GestureRecognizerTest, GestureEventLongPress) { +TEST_P(GestureRecognizerTest, GestureEventLongPress) { + ui::GestureConfiguration::set_max_touch_down_duration_in_seconds_for_click( + 0.0025); + scoped_ptr<GestureEventConsumeDelegate> delegate( new GestureEventConsumeDelegate()); - TimedEvents tes; const int kWindowWidth = 123; const int kWindowHeight = 45; const int kTouchId = 2; @@ -1318,9 +1348,11 @@ TEST_F(GestureRecognizerTest, GestureEventLongPress) { ScopedGestureRecognizerSetter gr_setter(gesture_recognizer); - ui::TouchEvent press1(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), - kTouchId, tes.Now()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press1); + ui::TouchEvent press1(ui::ET_TOUCH_PRESSED, + gfx::Point(101, 201), + kTouchId, + ui::EventTimeForNow()); + DispatchEventUsingWindowDispatcher(&press1); EXPECT_TRUE(delegate->tap_down()); EXPECT_TRUE(delegate->begin()); EXPECT_FALSE(delegate->tap_cancel()); @@ -1331,25 +1363,26 @@ TEST_F(GestureRecognizerTest, GestureEventLongPress) { // Wait until the timer runs out delegate->WaitUntilReceivedGesture(ui::ET_GESTURE_LONG_PRESS); EXPECT_TRUE(delegate->long_press()); - EXPECT_EQ(0, delegate->touch_id()); EXPECT_FALSE(delegate->tap_cancel()); delegate->Reset(); - ui::TouchEvent release1(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), - kTouchId, tes.Now()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&release1); + ui::TouchEvent release1(ui::ET_TOUCH_RELEASED, + gfx::Point(101, 201), + kTouchId, + ui::EventTimeForNow()); + DispatchEventUsingWindowDispatcher(&release1); EXPECT_FALSE(delegate->long_press()); - // Note the tap down isn't cancelled until the release + // Note the tap cancel isn't dispatched until the release EXPECT_TRUE(delegate->tap_cancel()); + EXPECT_FALSE(delegate->tap()); } // Check that scrolling cancels a long press -TEST_F(GestureRecognizerTest, GestureEventLongPressCancelledByScroll) { +TEST_P(GestureRecognizerTest, GestureEventLongPressCancelledByScroll) { scoped_ptr<GestureEventConsumeDelegate> delegate( new GestureEventConsumeDelegate()); TimedEvents tes; - ui::GestureConfiguration::set_long_press_time_in_seconds(.01); const int kWindowWidth = 123; const int kWindowHeight = 45; const int kTouchId = 6; @@ -1369,7 +1402,7 @@ TEST_F(GestureRecognizerTest, GestureEventLongPressCancelledByScroll) { ui::TouchEvent press1(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), kTouchId, tes.Now()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press1); + DispatchEventUsingWindowDispatcher(&press1); EXPECT_TRUE(delegate->tap_down()); // We haven't pressed long enough for a long press to occur @@ -1377,7 +1410,7 @@ TEST_F(GestureRecognizerTest, GestureEventLongPressCancelledByScroll) { EXPECT_FALSE(delegate->tap_cancel()); // Scroll around, to cancel the long press - tes.SendScrollEvent(dispatcher(), 130, 230, kTouchId, delegate.get()); + tes.SendScrollEvent(event_processor(), 130, 230, kTouchId, delegate.get()); // Wait until the timer runs out gesture_sequence->ForceTimeout(); EXPECT_FALSE(delegate->long_press()); @@ -1386,16 +1419,17 @@ TEST_F(GestureRecognizerTest, GestureEventLongPressCancelledByScroll) { delegate->Reset(); ui::TouchEvent release1(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), kTouchId, tes.LeapForward(10)); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&release1); + DispatchEventUsingWindowDispatcher(&release1); EXPECT_FALSE(delegate->long_press()); EXPECT_FALSE(delegate->tap_cancel()); } // Check that appropriate touch events generate long tap events -TEST_F(GestureRecognizerTest, GestureEventLongTap) { +TEST_P(GestureRecognizerTest, GestureEventLongTap) { + ui::GestureConfiguration::set_max_touch_down_duration_in_seconds_for_click( + 0.0025); scoped_ptr<GestureEventConsumeDelegate> delegate( new GestureEventConsumeDelegate()); - TimedEvents tes; const int kWindowWidth = 123; const int kWindowHeight = 45; const int kTouchId = 2; @@ -1410,9 +1444,11 @@ TEST_F(GestureRecognizerTest, GestureEventLongTap) { ScopedGestureRecognizerSetter gr_setter(gesture_recognizer); - ui::TouchEvent press1(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), - kTouchId, tes.Now()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press1); + ui::TouchEvent press1(ui::ET_TOUCH_PRESSED, + gfx::Point(101, 201), + kTouchId, + ui::EventTimeForNow()); + DispatchEventUsingWindowDispatcher(&press1); EXPECT_TRUE(delegate->tap_down()); EXPECT_TRUE(delegate->begin()); EXPECT_FALSE(delegate->tap_cancel()); @@ -1423,26 +1459,27 @@ TEST_F(GestureRecognizerTest, GestureEventLongTap) { // Wait until the timer runs out delegate->WaitUntilReceivedGesture(ui::ET_GESTURE_LONG_PRESS); EXPECT_TRUE(delegate->long_press()); - EXPECT_EQ(0, delegate->touch_id()); EXPECT_FALSE(delegate->tap_cancel()); delegate->Reset(); - ui::TouchEvent release1(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), - kTouchId, tes.Now()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&release1); + ui::TouchEvent release1(ui::ET_TOUCH_RELEASED, + gfx::Point(101, 201), + kTouchId, + ui::EventTimeForNow()); + DispatchEventUsingWindowDispatcher(&release1); EXPECT_FALSE(delegate->long_press()); EXPECT_TRUE(delegate->long_tap()); - // Note the tap down isn't cancelled until the release + // Note the tap cancel isn't dispatched until the release EXPECT_TRUE(delegate->tap_cancel()); + EXPECT_FALSE(delegate->tap()); } // Check that second tap cancels a long press -TEST_F(GestureRecognizerTest, GestureEventLongPressCancelledBySecondTap) { +TEST_P(GestureRecognizerTest, GestureEventLongPressCancelledBySecondTap) { scoped_ptr<GestureEventConsumeDelegate> delegate( new GestureEventConsumeDelegate()); TimedEvents tes; - ui::GestureConfiguration::set_long_press_time_in_seconds(.01); const int kWindowWidth = 300; const int kWindowHeight = 400; const int kTouchId1 = 8; @@ -1462,7 +1499,7 @@ TEST_F(GestureRecognizerTest, GestureEventLongPressCancelledBySecondTap) { delegate->Reset(); ui::TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), kTouchId1, tes.Now()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press); + DispatchEventUsingWindowDispatcher(&press); EXPECT_TRUE(delegate->tap_down()); EXPECT_TRUE(delegate->begin()); @@ -1473,7 +1510,7 @@ TEST_F(GestureRecognizerTest, GestureEventLongPressCancelledBySecondTap) { delegate->Reset(); ui::TouchEvent press2(ui::ET_TOUCH_PRESSED, gfx::Point(10, 10), kTouchId2, tes.Now()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press2); + DispatchEventUsingWindowDispatcher(&press2); EXPECT_FALSE(delegate->tap_down()); // no touch down for second tap. EXPECT_TRUE(delegate->tap_cancel()); EXPECT_TRUE(delegate->begin()); @@ -1487,7 +1524,7 @@ TEST_F(GestureRecognizerTest, GestureEventLongPressCancelledBySecondTap) { delegate->Reset(); ui::TouchEvent release1(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), kTouchId1, tes.Now()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&release1); + DispatchEventUsingWindowDispatcher(&release1); EXPECT_FALSE(delegate->long_press()); EXPECT_TRUE(delegate->two_finger_tap()); EXPECT_FALSE(delegate->tap_cancel()); @@ -1495,7 +1532,7 @@ TEST_F(GestureRecognizerTest, GestureEventLongPressCancelledBySecondTap) { // Check that horizontal scroll gestures cause scrolls on horizontal rails. // Also tests that horizontal rails can be broken. -TEST_F(GestureRecognizerTest, GestureEventHorizontalRailScroll) { +TEST_P(GestureRecognizerTest, GestureEventHorizontalRailScroll) { scoped_ptr<GestureEventConsumeDelegate> delegate( new GestureEventConsumeDelegate()); TimedEvents tes; @@ -1506,15 +1543,22 @@ TEST_F(GestureRecognizerTest, GestureEventHorizontalRailScroll) { ui::TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(0, 0), kTouchId, tes.Now()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press); + DispatchEventUsingWindowDispatcher(&press); + + // Get rid of touch slop. + ui::TouchEvent move(ui::ET_TOUCH_MOVED, gfx::Point(5, 0), + kTouchId, tes.Now()); + + DispatchEventUsingWindowDispatcher(&move); + delegate->Reset(); // Move the touch-point horizontally enough that it is considered a // horizontal scroll. - tes.SendScrollEvent(dispatcher(), 20, 1, kTouchId, delegate.get()); + tes.SendScrollEvent(event_processor(), 25, 0, kTouchId, delegate.get()); EXPECT_EQ(0, delegate->scroll_y()); EXPECT_EQ(20, delegate->scroll_x()); - tes.SendScrollEvent(dispatcher(), 25, 6, kTouchId, delegate.get()); + tes.SendScrollEvent(event_processor(), 30, 6, kTouchId, delegate.get()); EXPECT_TRUE(delegate->scroll_update()); EXPECT_EQ(5, delegate->scroll_x()); // y shouldn't change, as we're on a horizontal rail. @@ -1522,17 +1566,13 @@ TEST_F(GestureRecognizerTest, GestureEventHorizontalRailScroll) { // Send enough information that a velocity can be calculated for the gesture, // and we can break the rail - tes.SendScrollEvents(dispatcher(), 1, 1, - 1, 100, kTouchId, 1, + tes.SendScrollEvents(event_processor(), 1, 1, + 6, 100, kTouchId, 1, ui::GestureConfiguration::points_buffered_for_velocity(), delegate.get()); - // Since the scroll is not longer railing, the velocity should be set for both - // axis. - EXPECT_GT(delegate->scroll_velocity_x(), 0); - EXPECT_GT(delegate->scroll_velocity_y(), 0); - tes.SendScrollEvent(dispatcher(), 0, 0, kTouchId, delegate.get()); - tes.SendScrollEvent(dispatcher(), 5, 5, kTouchId, delegate.get()); + tes.SendScrollEvent(event_processor(), 5, 0, kTouchId, delegate.get()); + tes.SendScrollEvent(event_processor(), 10, 5, kTouchId, delegate.get()); // The rail should be broken EXPECT_TRUE(delegate->scroll_update()); @@ -1542,7 +1582,7 @@ TEST_F(GestureRecognizerTest, GestureEventHorizontalRailScroll) { // Check that vertical scroll gestures cause scrolls on vertical rails. // Also tests that vertical rails can be broken. -TEST_F(GestureRecognizerTest, GestureEventVerticalRailScroll) { +TEST_P(GestureRecognizerTest, GestureEventVerticalRailScroll) { scoped_ptr<GestureEventConsumeDelegate> delegate( new GestureEventConsumeDelegate()); TimedEvents tes; @@ -1553,15 +1593,21 @@ TEST_F(GestureRecognizerTest, GestureEventVerticalRailScroll) { ui::TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(0, 0), kTouchId, tes.Now()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press); + DispatchEventUsingWindowDispatcher(&press); + + // Get rid of touch slop. + ui::TouchEvent move(ui::ET_TOUCH_MOVED, gfx::Point(0, 5), + kTouchId, tes.Now()); + DispatchEventUsingWindowDispatcher(&move); + delegate->Reset(); // Move the touch-point vertically enough that it is considered a // vertical scroll. - tes.SendScrollEvent(dispatcher(), 1, 20, kTouchId, delegate.get()); + tes.SendScrollEvent(event_processor(), 0, 25, kTouchId, delegate.get()); EXPECT_EQ(0, delegate->scroll_x()); EXPECT_EQ(20, delegate->scroll_y()); - tes.SendScrollEvent(dispatcher(), 6, 25, kTouchId, delegate.get()); + tes.SendScrollEvent(event_processor(), 6, 30, kTouchId, delegate.get()); EXPECT_TRUE(delegate->scroll_update()); EXPECT_EQ(5, delegate->scroll_y()); // x shouldn't change, as we're on a vertical rail. @@ -1570,15 +1616,13 @@ TEST_F(GestureRecognizerTest, GestureEventVerticalRailScroll) { // Send enough information that a velocity can be calculated for the gesture, // and we can break the rail - tes.SendScrollEvents(dispatcher(), 1, 1, + tes.SendScrollEvents(event_processor(), 1, 6, 100, 1, kTouchId, 1, ui::GestureConfiguration::points_buffered_for_velocity(), delegate.get()); - EXPECT_GT(delegate->scroll_velocity_x(), 0); - EXPECT_GT(delegate->scroll_velocity_y(), 0); - tes.SendScrollEvent(dispatcher(), 0, 0, kTouchId, delegate.get()); - tes.SendScrollEvent(dispatcher(), 5, 5, kTouchId, delegate.get()); + tes.SendScrollEvent(event_processor(), 0, 5, kTouchId, delegate.get()); + tes.SendScrollEvent(event_processor(), 5, 10, kTouchId, delegate.get()); // The rail should be broken EXPECT_TRUE(delegate->scroll_update()); @@ -1586,7 +1630,13 @@ TEST_F(GestureRecognizerTest, GestureEventVerticalRailScroll) { EXPECT_EQ(5, delegate->scroll_y()); } -TEST_F(GestureRecognizerTest, GestureTapFollowedByScroll) { +TEST_P(GestureRecognizerTest, GestureTapFollowedByScroll) { + // We'll start by moving the touch point by (5, 5). We want all of that + // distance to be consumed by the slop, so we set the slop radius to + // sqrt(5 * 5 + 5 * 5). + ui::GestureConfiguration::set_max_touch_move_in_pixels_for_click( + sqrt(static_cast<double>(5 * 5 + 5 * 5))); + // First, tap. Then, do a scroll using the same touch-id. scoped_ptr<GestureEventConsumeDelegate> delegate( new GestureEventConsumeDelegate()); @@ -1601,7 +1651,7 @@ TEST_F(GestureRecognizerTest, GestureTapFollowedByScroll) { delegate->Reset(); ui::TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), kTouchId, tes.Now()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press); + DispatchEventUsingWindowDispatcher(&press); EXPECT_FALSE(delegate->tap()); EXPECT_TRUE(delegate->tap_down()); EXPECT_FALSE(delegate->tap_cancel()); @@ -1614,7 +1664,7 @@ TEST_F(GestureRecognizerTest, GestureTapFollowedByScroll) { delegate->Reset(); ui::TouchEvent release(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), kTouchId, tes.LeapForward(50)); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&release); + DispatchEventUsingWindowDispatcher(&release); EXPECT_TRUE(delegate->tap()); EXPECT_FALSE(delegate->tap_down()); EXPECT_FALSE(delegate->tap_cancel()); @@ -1627,7 +1677,7 @@ TEST_F(GestureRecognizerTest, GestureTapFollowedByScroll) { delegate->Reset(); ui::TouchEvent press1(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), kTouchId, tes.LeapForward(1000)); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press1); + DispatchEventUsingWindowDispatcher(&press1); EXPECT_FALSE(delegate->tap()); EXPECT_TRUE(delegate->tap_down()); EXPECT_FALSE(delegate->tap_cancel()); @@ -1635,28 +1685,40 @@ TEST_F(GestureRecognizerTest, GestureTapFollowedByScroll) { EXPECT_FALSE(delegate->scroll_update()); EXPECT_FALSE(delegate->scroll_end()); + // Get rid of touch slop. + ui::TouchEvent move_remove_slop(ui::ET_TOUCH_MOVED, gfx::Point(116, 216), + kTouchId, tes.Now()); + DispatchEventUsingWindowDispatcher(&move_remove_slop); + EXPECT_TRUE(delegate->tap_cancel()); + EXPECT_TRUE(delegate->scroll_begin()); + EXPECT_TRUE(delegate->scroll_update()); + EXPECT_EQ(15, delegate->scroll_x_hint()); + EXPECT_EQ(15, delegate->scroll_y_hint()); + + delegate->Reset(); + // Move the touch-point enough so that it is considered as a scroll. This // should generate both SCROLL_BEGIN and SCROLL_UPDATE gestures. // The first movement is diagonal, to ensure that we have a free scroll, // and not a rail scroll. delegate->Reset(); - ui::TouchEvent move(ui::ET_TOUCH_MOVED, gfx::Point(130, 230), + ui::TouchEvent move(ui::ET_TOUCH_MOVED, gfx::Point(135, 235), kTouchId, tes.Now()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&move); + DispatchEventUsingWindowDispatcher(&move); EXPECT_FALSE(delegate->tap()); EXPECT_FALSE(delegate->tap_down()); - EXPECT_TRUE(delegate->tap_cancel()); - EXPECT_TRUE(delegate->scroll_begin()); + EXPECT_FALSE(delegate->tap_cancel()); + EXPECT_FALSE(delegate->scroll_begin()); EXPECT_TRUE(delegate->scroll_update()); EXPECT_FALSE(delegate->scroll_end()); - EXPECT_EQ(29, delegate->scroll_x()); - EXPECT_EQ(29, delegate->scroll_y()); + EXPECT_EQ(19, delegate->scroll_x()); + EXPECT_EQ(19, delegate->scroll_y()); // Move some more to generate a few more scroll updates. delegate->Reset(); - ui::TouchEvent move1(ui::ET_TOUCH_MOVED, gfx::Point(110, 211), + ui::TouchEvent move1(ui::ET_TOUCH_MOVED, gfx::Point(115, 216), kTouchId, tes.Now()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&move1); + DispatchEventUsingWindowDispatcher(&move1); EXPECT_FALSE(delegate->tap()); EXPECT_FALSE(delegate->tap_down()); EXPECT_FALSE(delegate->tap_cancel()); @@ -1665,11 +1727,13 @@ TEST_F(GestureRecognizerTest, GestureTapFollowedByScroll) { EXPECT_FALSE(delegate->scroll_end()); EXPECT_EQ(-20, delegate->scroll_x()); EXPECT_EQ(-19, delegate->scroll_y()); + EXPECT_EQ(0, delegate->scroll_x_hint()); + EXPECT_EQ(0, delegate->scroll_y_hint()); delegate->Reset(); - ui::TouchEvent move2(ui::ET_TOUCH_MOVED, gfx::Point(140, 215), + ui::TouchEvent move2(ui::ET_TOUCH_MOVED, gfx::Point(145, 220), kTouchId, tes.Now()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&move2); + DispatchEventUsingWindowDispatcher(&move2); EXPECT_FALSE(delegate->tap()); EXPECT_FALSE(delegate->tap_down()); EXPECT_FALSE(delegate->tap_cancel()); @@ -1683,7 +1747,7 @@ TEST_F(GestureRecognizerTest, GestureTapFollowedByScroll) { delegate->Reset(); ui::TouchEvent release1(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), kTouchId, tes.Now()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&release1); + DispatchEventUsingWindowDispatcher(&release1); EXPECT_FALSE(delegate->tap()); EXPECT_FALSE(delegate->tap_down()); EXPECT_FALSE(delegate->tap_cancel()); @@ -1693,9 +1757,9 @@ TEST_F(GestureRecognizerTest, GestureTapFollowedByScroll) { EXPECT_TRUE(delegate->fling()); } -TEST_F(GestureRecognizerTest, AsynchronousGestureRecognition) { +TEST_P(GestureRecognizerTest, AsynchronousGestureRecognition) { scoped_ptr<QueueTouchEventDelegate> queued_delegate( - new QueueTouchEventDelegate(dispatcher())); + new QueueTouchEventDelegate(host()->dispatcher())); const int kWindowWidth = 123; const int kWindowHeight = 45; const int kTouchId1 = 6; @@ -1710,7 +1774,7 @@ TEST_F(GestureRecognizerTest, AsynchronousGestureRecognition) { queued_delegate->Reset(); ui::TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), kTouchId1, GetTime()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press); + DispatchEventUsingWindowDispatcher(&press); EXPECT_FALSE(queued_delegate->tap()); EXPECT_FALSE(queued_delegate->tap_down()); EXPECT_FALSE(queued_delegate->tap_cancel()); @@ -1725,7 +1789,7 @@ TEST_F(GestureRecognizerTest, AsynchronousGestureRecognition) { ui::TouchEvent release(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), kTouchId1, press.time_stamp() + base::TimeDelta::FromMilliseconds(50)); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&release); + DispatchEventUsingWindowDispatcher(&release); EXPECT_FALSE(queued_delegate->tap()); EXPECT_FALSE(queued_delegate->tap_down()); EXPECT_FALSE(queued_delegate->tap_cancel()); @@ -1744,7 +1808,7 @@ TEST_F(GestureRecognizerTest, AsynchronousGestureRecognition) { delegate->Reset(); ui::TouchEvent press2(ui::ET_TOUCH_PRESSED, gfx::Point(10, 20), kTouchId2, GetTime()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press2); + DispatchEventUsingWindowDispatcher(&press2); EXPECT_FALSE(delegate->tap()); EXPECT_TRUE(delegate->tap_down()); EXPECT_FALSE(delegate->tap_cancel()); @@ -1756,7 +1820,7 @@ TEST_F(GestureRecognizerTest, AsynchronousGestureRecognition) { ui::TouchEvent release2(ui::ET_TOUCH_RELEASED, gfx::Point(10, 20), kTouchId2, GetTime()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&release2); + DispatchEventUsingWindowDispatcher(&release2); // Process the first queued event. queued_delegate->Reset(); @@ -1787,7 +1851,7 @@ TEST_F(GestureRecognizerTest, AsynchronousGestureRecognition) { queued_delegate->Reset(); ui::TouchEvent press3(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), kTouchId1, GetTime()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press3); + DispatchEventUsingWindowDispatcher(&press3); EXPECT_FALSE(queued_delegate->tap()); EXPECT_FALSE(queued_delegate->tap_down()); EXPECT_FALSE(queued_delegate->tap_cancel()); @@ -1803,7 +1867,7 @@ TEST_F(GestureRecognizerTest, AsynchronousGestureRecognition) { delegate->Reset(); ui::TouchEvent press4(ui::ET_TOUCH_PRESSED, gfx::Point(103, 203), kTouchId2, GetTime()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press4); + DispatchEventUsingWindowDispatcher(&press4); EXPECT_FALSE(delegate->tap()); EXPECT_FALSE(delegate->tap_down()); EXPECT_FALSE(delegate->tap_cancel()); @@ -1826,9 +1890,9 @@ TEST_F(GestureRecognizerTest, AsynchronousGestureRecognition) { queued_delegate->Reset(); delegate->Reset(); int x_move = ui::GestureConfiguration::max_touch_move_in_pixels_for_click(); - ui::TouchEvent move(ui::ET_TOUCH_MOVED, gfx::Point(103 + x_move, 203), + ui::TouchEvent move(ui::ET_TOUCH_MOVED, gfx::Point(203 + x_move, 303), kTouchId2, GetTime()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&move); + DispatchEventUsingWindowDispatcher(&move); EXPECT_FALSE(delegate->tap()); EXPECT_FALSE(delegate->tap_down()); EXPECT_FALSE(delegate->tap_cancel()); @@ -1877,7 +1941,8 @@ TEST_F(GestureRecognizerTest, AsynchronousGestureRecognition) { EXPECT_FALSE(queued_delegate->begin()); EXPECT_FALSE(queued_delegate->end()); EXPECT_TRUE(queued_delegate->scroll_begin()); - EXPECT_FALSE(queued_delegate->scroll_update()); + // TODO(tdresser): uncomment once we've switched to the unified GR. + // EXPECT_TRUE(queued_delegate->scroll_update()); EXPECT_FALSE(queued_delegate->scroll_end()); EXPECT_TRUE(queued_delegate->pinch_begin()); EXPECT_FALSE(queued_delegate->pinch_update()); @@ -1885,7 +1950,12 @@ TEST_F(GestureRecognizerTest, AsynchronousGestureRecognition) { } // Check that appropriate touch events generate pinch gesture events. -TEST_F(GestureRecognizerTest, GestureEventPinchFromScroll) { +TEST_P(GestureRecognizerTest, GestureEventPinchFromScroll) { + // Disabled for unified GR due to differences in when pinch begin is sent. The + // Aura GR sends it earlier than is necessary. + if (UsingUnifiedGR()) + return; + scoped_ptr<GestureEventConsumeDelegate> delegate( new GestureEventConsumeDelegate()); TimedEvents tes; @@ -1897,12 +1967,10 @@ TEST_F(GestureRecognizerTest, GestureEventPinchFromScroll) { scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( delegate.get(), -1234, bounds, root_window())); - aura::RootWindow* root = dispatcher(); - delegate->Reset(); ui::TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), kTouchId1, tes.Now()); - root->AsRootWindowHostDelegate()->OnHostTouchEvent(&press); + DispatchEventUsingWindowDispatcher(&press); EXPECT_2_EVENTS(delegate->events(), ui::ET_GESTURE_BEGIN, ui::ET_GESTURE_TAP_DOWN); @@ -1912,7 +1980,7 @@ TEST_F(GestureRecognizerTest, GestureEventPinchFromScroll) { delegate->Reset(); ui::TouchEvent move(ui::ET_TOUCH_MOVED, gfx::Point(130, 301), kTouchId1, tes.Now()); - root->AsRootWindowHostDelegate()->OnHostTouchEvent(&move); + DispatchEventUsingWindowDispatcher(&move); EXPECT_3_EVENTS(delegate->events(), ui::ET_GESTURE_TAP_CANCEL, ui::ET_GESTURE_SCROLL_BEGIN, @@ -1923,7 +1991,7 @@ TEST_F(GestureRecognizerTest, GestureEventPinchFromScroll) { delegate->Reset(); ui::TouchEvent press2(ui::ET_TOUCH_PRESSED, gfx::Point(10, 10), kTouchId2, tes.Now()); - root->AsRootWindowHostDelegate()->OnHostTouchEvent(&press2); + DispatchEventUsingWindowDispatcher(&press2); EXPECT_2_EVENTS(delegate->events(), ui::ET_GESTURE_BEGIN, ui::ET_GESTURE_PINCH_BEGIN); @@ -1934,7 +2002,7 @@ TEST_F(GestureRecognizerTest, GestureEventPinchFromScroll) { delegate->Reset(); ui::TouchEvent move3(ui::ET_TOUCH_MOVED, gfx::Point(95, 201), kTouchId1, tes.Now()); - root->AsRootWindowHostDelegate()->OnHostTouchEvent(&move3); + DispatchEventUsingWindowDispatcher(&move3); EXPECT_2_EVENTS(delegate->events(), ui::ET_GESTURE_PINCH_UPDATE, ui::ET_GESTURE_SCROLL_UPDATE); @@ -1945,7 +2013,7 @@ TEST_F(GestureRecognizerTest, GestureEventPinchFromScroll) { delegate->Reset(); ui::TouchEvent move4(ui::ET_TOUCH_MOVED, gfx::Point(55, 15), kTouchId2, tes.Now()); - root->AsRootWindowHostDelegate()->OnHostTouchEvent(&move4); + DispatchEventUsingWindowDispatcher(&move4); EXPECT_2_EVENTS(delegate->events(), ui::ET_GESTURE_PINCH_UPDATE, ui::ET_GESTURE_SCROLL_UPDATE); @@ -1956,7 +2024,7 @@ TEST_F(GestureRecognizerTest, GestureEventPinchFromScroll) { delegate->Reset(); ui::TouchEvent release(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), kTouchId1, tes.Now()); - root->AsRootWindowHostDelegate()->OnHostTouchEvent(&release); + DispatchEventUsingWindowDispatcher(&release); EXPECT_2_EVENTS(delegate->events(), ui::ET_GESTURE_PINCH_END, ui::ET_GESTURE_END); @@ -1967,12 +2035,12 @@ TEST_F(GestureRecognizerTest, GestureEventPinchFromScroll) { delegate->Reset(); ui::TouchEvent move5(ui::ET_TOUCH_MOVED, gfx::Point(25, 10), kTouchId2, tes.Now()); - root->AsRootWindowHostDelegate()->OnHostTouchEvent(&move5); + DispatchEventUsingWindowDispatcher(&move5); EXPECT_1_EVENT(delegate->events(), ui::ET_GESTURE_SCROLL_UPDATE); EXPECT_TRUE(delegate->bounding_box().IsEmpty()); } -TEST_F(GestureRecognizerTest, GestureEventPinchFromScrollFromPinch) { +TEST_P(GestureRecognizerTest, GestureEventPinchFromScrollFromPinch) { scoped_ptr<GestureEventConsumeDelegate> delegate( new GestureEventConsumeDelegate()); TimedEvents tes; @@ -1986,20 +2054,20 @@ scoped_ptr<GestureEventConsumeDelegate> delegate( ui::TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(101, 301), kTouchId1, tes.Now()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press); + DispatchEventUsingWindowDispatcher(&press); delegate->Reset(); ui::TouchEvent press2(ui::ET_TOUCH_PRESSED, gfx::Point(10, 10), kTouchId2, tes.Now()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press2); + DispatchEventUsingWindowDispatcher(&press2); EXPECT_FALSE(delegate->pinch_begin()); // Touch move triggers pinch begin. - tes.SendScrollEvent(dispatcher(), 130, 230, kTouchId1, delegate.get()); + tes.SendScrollEvent(event_processor(), 130, 230, kTouchId1, delegate.get()); EXPECT_TRUE(delegate->pinch_begin()); EXPECT_FALSE(delegate->pinch_update()); // Touch move triggers pinch update. - tes.SendScrollEvent(dispatcher(), 160, 200, kTouchId1, delegate.get()); + tes.SendScrollEvent(event_processor(), 160, 200, kTouchId1, delegate.get()); EXPECT_FALSE(delegate->pinch_begin()); EXPECT_TRUE(delegate->pinch_update()); @@ -2007,29 +2075,33 @@ scoped_ptr<GestureEventConsumeDelegate> delegate( delegate->Reset(); ui::TouchEvent release(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), kTouchId1, tes.Now()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&release); + DispatchEventUsingWindowDispatcher(&release); EXPECT_TRUE(delegate->pinch_end()); - tes.SendScrollEvent(dispatcher(), 130, 230, kTouchId2, delegate.get()); + tes.SendScrollEvent(event_processor(), 130, 230, kTouchId2, delegate.get()); EXPECT_TRUE(delegate->scroll_update()); // Pinch again delegate->Reset(); ui::TouchEvent press3(ui::ET_TOUCH_PRESSED, gfx::Point(10, 10), kTouchId1, tes.Now()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press3); + DispatchEventUsingWindowDispatcher(&press3); // Now the touch points are close. So we will go into two finger tap. // Move the touch-point enough to break two-finger-tap and enter pinch. - ui::TouchEvent move2(ui::ET_TOUCH_MOVED, gfx::Point(101, 202), + ui::TouchEvent move2(ui::ET_TOUCH_MOVED, gfx::Point(101, 50), kTouchId1, tes.Now()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&move2); + DispatchEventUsingWindowDispatcher(&move2); EXPECT_TRUE(delegate->pinch_begin()); - tes.SendScrollEvent(dispatcher(), 130, 230, kTouchId1, delegate.get()); + tes.SendScrollEvent(event_processor(), 350, 350, kTouchId1, delegate.get()); EXPECT_TRUE(delegate->pinch_update()); } -TEST_F(GestureRecognizerTest, GestureEventPinchFromTap) { +TEST_P(GestureRecognizerTest, GestureEventPinchFromTap) { + // TODO(tdresser): enable this test with unified GR once two finger tap. + if (UsingUnifiedGR()) + return; + scoped_ptr<GestureEventConsumeDelegate> delegate( new GestureEventConsumeDelegate()); TimedEvents tes; @@ -2041,12 +2113,10 @@ TEST_F(GestureRecognizerTest, GestureEventPinchFromTap) { scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( delegate.get(), -1234, bounds, root_window())); - aura::RootWindow* root = dispatcher(); - delegate->Reset(); ui::TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(101, 301), kTouchId1, tes.Now()); - root->AsRootWindowHostDelegate()->OnHostTouchEvent(&press); + DispatchEventUsingWindowDispatcher(&press); EXPECT_2_EVENTS(delegate->events(), ui::ET_GESTURE_BEGIN, ui::ET_GESTURE_TAP_DOWN); @@ -2056,7 +2126,7 @@ TEST_F(GestureRecognizerTest, GestureEventPinchFromTap) { delegate->Reset(); ui::TouchEvent press2(ui::ET_TOUCH_PRESSED, gfx::Point(10, 10), kTouchId2, tes.Now()); - root->AsRootWindowHostDelegate()->OnHostTouchEvent(&press2); + DispatchEventUsingWindowDispatcher(&press2); EXPECT_2_EVENTS(delegate->events(), ui::ET_GESTURE_TAP_CANCEL, ui::ET_GESTURE_BEGIN); @@ -2067,10 +2137,10 @@ TEST_F(GestureRecognizerTest, GestureEventPinchFromTap) { delegate->Reset(); ui::TouchEvent move3(ui::ET_TOUCH_MOVED, gfx::Point(65, 201), kTouchId1, tes.Now()); - root->AsRootWindowHostDelegate()->OnHostTouchEvent(&move3); + DispatchEventUsingWindowDispatcher(&move3); EXPECT_2_EVENTS(delegate->events(), - ui::ET_GESTURE_PINCH_BEGIN, - ui::ET_GESTURE_SCROLL_BEGIN); + ui::ET_GESTURE_SCROLL_BEGIN, + ui::ET_GESTURE_PINCH_BEGIN); EXPECT_EQ(gfx::Rect(10, 10, 55, 191).ToString(), delegate->bounding_box().ToString()); @@ -2078,7 +2148,7 @@ TEST_F(GestureRecognizerTest, GestureEventPinchFromTap) { delegate->Reset(); ui::TouchEvent move4(ui::ET_TOUCH_MOVED, gfx::Point(55, 15), kTouchId2, tes.Now()); - root->AsRootWindowHostDelegate()->OnHostTouchEvent(&move4); + DispatchEventUsingWindowDispatcher(&move4); EXPECT_2_EVENTS(delegate->events(), ui::ET_GESTURE_PINCH_UPDATE, ui::ET_GESTURE_SCROLL_UPDATE); @@ -2089,7 +2159,7 @@ TEST_F(GestureRecognizerTest, GestureEventPinchFromTap) { delegate->Reset(); ui::TouchEvent release(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), kTouchId1, tes.LeapForward(10)); - root->AsRootWindowHostDelegate()->OnHostTouchEvent(&release); + DispatchEventUsingWindowDispatcher(&release); EXPECT_2_EVENTS(delegate->events(), ui::ET_GESTURE_PINCH_END, ui::ET_GESTURE_END); @@ -2100,26 +2170,26 @@ TEST_F(GestureRecognizerTest, GestureEventPinchFromTap) { delegate->Reset(); ui::TouchEvent move5(ui::ET_TOUCH_MOVED, gfx::Point(25, 10), kTouchId2, tes.Now()); - root->AsRootWindowHostDelegate()->OnHostTouchEvent(&move5); + DispatchEventUsingWindowDispatcher(&move5); EXPECT_1_EVENT(delegate->events(), ui::ET_GESTURE_SCROLL_UPDATE); EXPECT_TRUE(delegate->bounding_box().IsEmpty()); } -TEST_F(GestureRecognizerTest, GestureEventIgnoresDisconnectedEvents) { +TEST_P(GestureRecognizerTest, GestureEventIgnoresDisconnectedEvents) { scoped_ptr<GestureEventConsumeDelegate> delegate( new GestureEventConsumeDelegate()); TimedEvents tes; ui::TouchEvent release1(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), 6, tes.Now()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&release1); + DispatchEventUsingWindowDispatcher(&release1); EXPECT_FALSE(delegate->tap()); EXPECT_FALSE(delegate->tap_down()); } // Check that a touch is locked to the window of the closest current touch // within max_separation_for_gesture_touches_in_pixels -TEST_F(GestureRecognizerTest, GestureEventTouchLockSelectsCorrectWindow) { +TEST_P(GestureRecognizerTest, GestureEventTouchLockSelectsCorrectWindow) { ui::GestureRecognizer* gesture_recognizer = new ui::GestureRecognizerImpl(); TimedEvents tes; ScopedGestureRecognizerSetter gr_setter(gesture_recognizer); @@ -2150,50 +2220,50 @@ TEST_F(GestureRecognizerTest, GestureEventTouchLockSelectsCorrectWindow) { windows[i]->set_id(i); ui::TouchEvent press(ui::ET_TOUCH_PRESSED, window_bounds[i].origin(), i, tes.Now()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press); + DispatchEventUsingWindowDispatcher(&press); } // Touches should now be associated with the closest touch within // ui::GestureConfiguration::max_separation_for_gesture_touches_in_pixels - target = gesture_recognizer->GetTargetForLocation(gfx::Point(11, 11)); + target = gesture_recognizer->GetTargetForLocation(gfx::Point(11, 11), -1); EXPECT_EQ("0", WindowIDAsString(target)); - target = gesture_recognizer->GetTargetForLocation(gfx::Point(511, 11)); + target = gesture_recognizer->GetTargetForLocation(gfx::Point(511, 11), -1); EXPECT_EQ("1", WindowIDAsString(target)); - target = gesture_recognizer->GetTargetForLocation(gfx::Point(11, 511)); + target = gesture_recognizer->GetTargetForLocation(gfx::Point(11, 511), -1); EXPECT_EQ("2", WindowIDAsString(target)); - target = gesture_recognizer->GetTargetForLocation(gfx::Point(511, 511)); + target = gesture_recognizer->GetTargetForLocation(gfx::Point(511, 511), -1); EXPECT_EQ("3", WindowIDAsString(target)); // Add a touch in the middle associated with windows[2] ui::TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(0, 500), kNumWindows, tes.Now()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press); + DispatchEventUsingWindowDispatcher(&press); ui::TouchEvent move(ui::ET_TOUCH_MOVED, gfx::Point(250, 250), kNumWindows, tes.Now()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&move); + DispatchEventUsingWindowDispatcher(&move); - target = gesture_recognizer->GetTargetForLocation(gfx::Point(250, 250)); + target = gesture_recognizer->GetTargetForLocation(gfx::Point(250, 250), -1); EXPECT_EQ("2", WindowIDAsString(target)); // Make sure that ties are broken by distance to a current touch // Closer to the point in the bottom right. - target = gesture_recognizer->GetTargetForLocation(gfx::Point(380, 380)); + target = gesture_recognizer->GetTargetForLocation(gfx::Point(380, 380), -1); EXPECT_EQ("3", WindowIDAsString(target)); // This touch is closer to the point in the middle - target = gesture_recognizer->GetTargetForLocation(gfx::Point(300, 300)); + target = gesture_recognizer->GetTargetForLocation(gfx::Point(300, 300), -1); EXPECT_EQ("2", WindowIDAsString(target)); // A touch too far from other touches won't be locked to anything - target = gesture_recognizer->GetTargetForLocation(gfx::Point(1000, 1000)); + target = gesture_recognizer->GetTargetForLocation(gfx::Point(1000, 1000), -1); EXPECT_TRUE(target == NULL); // Move a touch associated with windows[2] to 1000, 1000 ui::TouchEvent move2(ui::ET_TOUCH_MOVED, gfx::Point(1000, 1000), kNumWindows, tes.Now()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&move2); + DispatchEventUsingWindowDispatcher(&move2); - target = gesture_recognizer->GetTargetForLocation(gfx::Point(1000, 1000)); + target = gesture_recognizer->GetTargetForLocation(gfx::Point(1000, 1000), -1); EXPECT_EQ("2", WindowIDAsString(target)); for (int i = 0; i < kNumWindows; ++i) { @@ -2203,9 +2273,43 @@ TEST_F(GestureRecognizerTest, GestureEventTouchLockSelectsCorrectWindow) { } } +// Check that a touch's target will not be effected by a touch on a different +// screen. +TEST_P(GestureRecognizerTest, GestureEventTouchLockIgnoresOtherScreens) { + scoped_ptr<GestureEventConsumeDelegate> delegate( + new GestureEventConsumeDelegate()); + gfx::Rect bounds(0, 0, 10, 10); + scoped_ptr<aura::Window> window( + CreateTestWindowWithDelegate(delegate.get(), 0, bounds, root_window())); + + const int kTouchId1 = 8; + const int kTouchId2 = 2; + TimedEvents tes; + + ui::TouchEvent press1(ui::ET_TOUCH_PRESSED, gfx::Point(5, 5), + kTouchId1, tes.Now()); + press1.set_source_device_id(1); + DispatchEventUsingWindowDispatcher(&press1); + + ui::TouchEvent press2(ui::ET_TOUCH_PRESSED, gfx::Point(20, 20), + kTouchId2, tes.Now()); + press2.set_source_device_id(2); + DispatchEventUsingWindowDispatcher(&press2); + + // The second press should not have been locked to the same target as the + // first, as they occured on different displays. + EXPECT_NE( + ui::GestureRecognizer::Get()->GetTouchLockedTarget(press1), + ui::GestureRecognizer::Get()->GetTouchLockedTarget(press2)); +} + // Check that touch events outside the root window are still handled // by the root window's gesture sequence. -TEST_F(GestureRecognizerTest, GestureEventOutsideRootWindowTap) { +TEST_P(GestureRecognizerTest, GestureEventOutsideRootWindowTap) { + // TODO(tdresser): write a version of this test for the unified GR. + if (UsingUnifiedGR()) + return; + TestGestureRecognizer* gesture_recognizer = new TestGestureRecognizer(); TimedEvents tes; @@ -2222,11 +2326,11 @@ TEST_F(GestureRecognizerTest, GestureEventOutsideRootWindowTap) { gfx::Point pos1(-10, -10); ui::TouchEvent press1(ui::ET_TOUCH_PRESSED, pos1, 0, tes.Now()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press1); + DispatchEventUsingWindowDispatcher(&press1); gfx::Point pos2(1000, 1000); ui::TouchEvent press2(ui::ET_TOUCH_PRESSED, pos2, 1, tes.Now()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press2); + DispatchEventUsingWindowDispatcher(&press2); // As these presses were outside the root window, they should be // associated with the root window. @@ -2234,9 +2338,9 @@ TEST_F(GestureRecognizerTest, GestureEventOutsideRootWindowTap) { EXPECT_EQ(2, root_window_gesture_sequence->point_count()); } -TEST_F(GestureRecognizerTest, NoTapWithPreventDefaultedRelease) { +TEST_P(GestureRecognizerTest, NoTapWithPreventDefaultedRelease) { scoped_ptr<QueueTouchEventDelegate> delegate( - new QueueTouchEventDelegate(dispatcher())); + new QueueTouchEventDelegate(host()->dispatcher())); TimedEvents tes; const int kTouchId = 2; gfx::Rect bounds(100, 200, 100, 100); @@ -2247,10 +2351,10 @@ TEST_F(GestureRecognizerTest, NoTapWithPreventDefaultedRelease) { delegate->Reset(); ui::TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), kTouchId, tes.Now()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press); + DispatchEventUsingWindowDispatcher(&press); ui::TouchEvent release(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), kTouchId, tes.LeapForward(50)); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&release); + DispatchEventUsingWindowDispatcher(&release); delegate->Reset(); delegate->ReceivedAck(); @@ -2261,9 +2365,14 @@ TEST_F(GestureRecognizerTest, NoTapWithPreventDefaultedRelease) { EXPECT_TRUE(delegate->tap_cancel()); } -TEST_F(GestureRecognizerTest, PinchScrollWithPreventDefaultedRelease) { +TEST_P(GestureRecognizerTest, PinchScrollWithPreventDefaultedRelease) { + // Disabled for unified GR due to differences in when pinch begin is sent. The + // Aura GR sends it earlier than is necessary. + if (UsingUnifiedGR()) + return; + scoped_ptr<QueueTouchEventDelegate> delegate( - new QueueTouchEventDelegate(dispatcher())); + new QueueTouchEventDelegate(host()->dispatcher())); TimedEvents tes; const int kTouchId1 = 7; const int kTouchId2 = 5; @@ -2280,9 +2389,9 @@ TEST_F(GestureRecognizerTest, PinchScrollWithPreventDefaultedRelease) { tes.LeapForward(200)); ui::TouchEvent release(ui::ET_TOUCH_RELEASED, gfx::Point(15, 25), kTouchId1, tes.LeapForward(50)); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&move); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&release); + DispatchEventUsingWindowDispatcher(&press); + DispatchEventUsingWindowDispatcher(&move); + DispatchEventUsingWindowDispatcher(&release); delegate->Reset(); // Ack the press event. @@ -2316,12 +2425,12 @@ TEST_F(GestureRecognizerTest, PinchScrollWithPreventDefaultedRelease) { tes.LeapForward(14)); // Do a pinch. - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&move); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press2); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&move2); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&release); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&release2); + DispatchEventUsingWindowDispatcher(&press); + DispatchEventUsingWindowDispatcher(&move); + DispatchEventUsingWindowDispatcher(&press2); + DispatchEventUsingWindowDispatcher(&move2); + DispatchEventUsingWindowDispatcher(&release); + DispatchEventUsingWindowDispatcher(&release2); // Ack the press and move events. delegate->Reset(); @@ -2355,7 +2464,25 @@ TEST_F(GestureRecognizerTest, PinchScrollWithPreventDefaultedRelease) { EXPECT_TRUE(delegate->end()); } -TEST_F(GestureRecognizerTest, CaptureSendsGestureEnd) { +TEST_P(GestureRecognizerTest, GestureEndLocation) { + GestureEventConsumeDelegate delegate; + scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( + &delegate, -1234, gfx::Rect(10, 10, 300, 300), root_window())); + EventGenerator generator(root_window(), window.get()); + const gfx::Point begin(20, 20); + const gfx::Point end(150, 150); + const gfx::Vector2d window_offset = + window->bounds().origin().OffsetFromOrigin(); + generator.GestureScrollSequence(begin, end, + base::TimeDelta::FromMilliseconds(20), + 10); + EXPECT_EQ((begin - window_offset).ToString(), + delegate.scroll_begin_position().ToString()); + EXPECT_EQ((end - window_offset).ToString(), + delegate.gesture_end_location().ToString()); +} + +TEST_P(GestureRecognizerTest, CaptureSendsGestureEnd) { scoped_ptr<GestureEventConsumeDelegate> delegate( new GestureEventConsumeDelegate()); TestGestureRecognizer* gesture_recognizer = @@ -2384,7 +2511,7 @@ TEST_F(GestureRecognizerTest, CaptureSendsGestureEnd) { // Check that previous touch actions that are completely finished (either // released or cancelled), do not receive extra synthetic cancels upon change of // capture. -TEST_F(GestureRecognizerTest, CaptureDoesNotCancelFinishedTouches) { +TEST_P(GestureRecognizerTest, CaptureDoesNotCancelFinishedTouches) { scoped_ptr<GestureEventConsumeDelegate> delegate( new GestureEventConsumeDelegate()); scoped_ptr<TestEventHandler> handler(new TestEventHandler); @@ -2437,7 +2564,8 @@ TEST_F(GestureRecognizerTest, CaptureDoesNotCancelFinishedTouches) { root_window()->RemovePreTargetHandler(handler.get()); } -TEST_F(GestureRecognizerTest, PressDoesNotCrash) { +// Tests that a press with the same touch id as an existing touch is ignored. +TEST_P(GestureRecognizerTest, PressDoesNotCrash) { scoped_ptr<GestureEventConsumeDelegate> delegate( new GestureEventConsumeDelegate()); TestGestureRecognizer* gesture_recognizer = @@ -2450,14 +2578,14 @@ TEST_F(GestureRecognizerTest, PressDoesNotCrash) { ui::TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(45, 45), 7, tes.Now()); press.set_radius_x(40); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press); + DispatchEventUsingWindowDispatcher(&press); EXPECT_TRUE(delegate->tap_down()); EXPECT_EQ(gfx::Rect(5, 5, 80, 80).ToString(), delegate->bounding_box().ToString()); delegate->Reset(); ui::TouchEvent press2(ui::ET_TOUCH_PRESSED, gfx::Point(55, 45), 7, tes.Now()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press2); + DispatchEventUsingWindowDispatcher(&press2); // This new press should not generate a tap-down. EXPECT_FALSE(delegate->begin()); @@ -2466,7 +2594,12 @@ TEST_F(GestureRecognizerTest, PressDoesNotCrash) { EXPECT_FALSE(delegate->scroll_begin()); } -TEST_F(GestureRecognizerTest, TwoFingerTap) { +TEST_P(GestureRecognizerTest, TwoFingerTap) { + // TODO(tdresser): enable this test with unified GR once two finger tap is + // supported. See crbug.com/354396. + if (UsingUnifiedGR()) + return; + scoped_ptr<GestureEventConsumeDelegate> delegate( new GestureEventConsumeDelegate()); const int kWindowWidth = 123; @@ -2481,7 +2614,7 @@ TEST_F(GestureRecognizerTest, TwoFingerTap) { delegate->Reset(); ui::TouchEvent press1(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), kTouchId1, tes.Now()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press1); + DispatchEventUsingWindowDispatcher(&press1); EXPECT_FALSE(delegate->tap()); EXPECT_TRUE(delegate->tap_down()); EXPECT_FALSE(delegate->tap_cancel()); @@ -2494,7 +2627,7 @@ TEST_F(GestureRecognizerTest, TwoFingerTap) { delegate->Reset(); ui::TouchEvent press2(ui::ET_TOUCH_PRESSED, gfx::Point(130, 201), kTouchId2, tes.Now()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press2); + DispatchEventUsingWindowDispatcher(&press2); EXPECT_FALSE(delegate->tap()); EXPECT_FALSE(delegate->tap_down()); // no touch down for second tap. EXPECT_TRUE(delegate->tap_cancel()); @@ -2508,10 +2641,10 @@ TEST_F(GestureRecognizerTest, TwoFingerTap) { delegate->Reset(); ui::TouchEvent move1(ui::ET_TOUCH_MOVED, gfx::Point(102, 202), kTouchId1, tes.Now()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&move1); + DispatchEventUsingWindowDispatcher(&move1); ui::TouchEvent move2(ui::ET_TOUCH_MOVED, gfx::Point(131, 202), kTouchId2, tes.Now()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&move2); + DispatchEventUsingWindowDispatcher(&move2); EXPECT_FALSE(delegate->tap()); EXPECT_FALSE(delegate->tap_down()); EXPECT_FALSE(delegate->tap_cancel()); @@ -2527,11 +2660,11 @@ TEST_F(GestureRecognizerTest, TwoFingerTap) { ui::TouchEvent release1(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), kTouchId1, tes.LeapForward(50)); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&release1); + DispatchEventUsingWindowDispatcher(&release1); EXPECT_FALSE(delegate->tap()); EXPECT_FALSE(delegate->tap_down()); EXPECT_FALSE(delegate->tap_cancel()); - EXPECT_FALSE(delegate->scroll_begin()); + EXPECT_TRUE(delegate->scroll_begin()); EXPECT_FALSE(delegate->scroll_update()); EXPECT_FALSE(delegate->scroll_end()); EXPECT_TRUE(delegate->two_finger_tap()); @@ -2543,7 +2676,7 @@ TEST_F(GestureRecognizerTest, TwoFingerTap) { ui::TouchEvent release2(ui::ET_TOUCH_RELEASED, gfx::Point(130, 201), kTouchId2, tes.LeapForward(50)); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&release2); + DispatchEventUsingWindowDispatcher(&release2); EXPECT_FALSE(delegate->tap()); EXPECT_FALSE(delegate->tap_down()); EXPECT_FALSE(delegate->tap_cancel()); @@ -2554,7 +2687,7 @@ TEST_F(GestureRecognizerTest, TwoFingerTap) { EXPECT_FALSE(delegate->two_finger_tap()); } -TEST_F(GestureRecognizerTest, TwoFingerTapExpired) { +TEST_P(GestureRecognizerTest, TwoFingerTapExpired) { scoped_ptr<GestureEventConsumeDelegate> delegate( new GestureEventConsumeDelegate()); const int kWindowWidth = 123; @@ -2569,19 +2702,19 @@ TEST_F(GestureRecognizerTest, TwoFingerTapExpired) { delegate->Reset(); ui::TouchEvent press1(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), kTouchId1, tes.Now()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press1); + DispatchEventUsingWindowDispatcher(&press1); delegate->Reset(); ui::TouchEvent press2(ui::ET_TOUCH_PRESSED, gfx::Point(130, 201), kTouchId2, tes.Now()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press2); + DispatchEventUsingWindowDispatcher(&press2); // Send release event after sufficient delay so that two finger time expires. delegate->Reset(); ui::TouchEvent release1(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), kTouchId1, tes.LeapForward(1000)); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&release1); + DispatchEventUsingWindowDispatcher(&release1); EXPECT_FALSE(delegate->two_finger_tap()); // Lift second finger. @@ -2591,11 +2724,11 @@ TEST_F(GestureRecognizerTest, TwoFingerTapExpired) { ui::TouchEvent release2(ui::ET_TOUCH_RELEASED, gfx::Point(130, 201), kTouchId2, tes.LeapForward(50)); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&release2); + DispatchEventUsingWindowDispatcher(&release2); EXPECT_FALSE(delegate->two_finger_tap()); } -TEST_F(GestureRecognizerTest, TwoFingerTapChangesToPinch) { +TEST_P(GestureRecognizerTest, TwoFingerTapChangesToPinch) { scoped_ptr<GestureEventConsumeDelegate> delegate( new GestureEventConsumeDelegate()); const int kWindowWidth = 123; @@ -2613,14 +2746,14 @@ TEST_F(GestureRecognizerTest, TwoFingerTapChangesToPinch) { delegate->Reset(); ui::TouchEvent press1(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), kTouchId1, tes.Now()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press1); + DispatchEventUsingWindowDispatcher(&press1); delegate->Reset(); ui::TouchEvent press2(ui::ET_TOUCH_PRESSED, gfx::Point(130, 201), kTouchId2, tes.Now()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press2); + DispatchEventUsingWindowDispatcher(&press2); - tes.SendScrollEvent(dispatcher(), 130, 230, kTouchId1, delegate.get()); + tes.SendScrollEvent(event_processor(), 230, 330, kTouchId1, delegate.get()); EXPECT_FALSE(delegate->two_finger_tap()); EXPECT_TRUE(delegate->pinch_begin()); @@ -2630,7 +2763,7 @@ TEST_F(GestureRecognizerTest, TwoFingerTapChangesToPinch) { ui::TouchEvent release(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), kTouchId2, tes.LeapForward(50)); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&release); + DispatchEventUsingWindowDispatcher(&release); EXPECT_FALSE(delegate->two_finger_tap()); EXPECT_TRUE(delegate->pinch_end()); } @@ -2644,14 +2777,14 @@ TEST_F(GestureRecognizerTest, TwoFingerTapChangesToPinch) { delegate->Reset(); ui::TouchEvent press1(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), kTouchId1, tes.Now()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press1); + DispatchEventUsingWindowDispatcher(&press1); delegate->Reset(); ui::TouchEvent press2(ui::ET_TOUCH_PRESSED, gfx::Point(130, 201), kTouchId2, tes.Now()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press2); + DispatchEventUsingWindowDispatcher(&press2); - tes.SendScrollEvent(dispatcher(), 101, 230, kTouchId2, delegate.get()); + tes.SendScrollEvent(event_processor(), 301, 230, kTouchId2, delegate.get()); EXPECT_FALSE(delegate->two_finger_tap()); EXPECT_TRUE(delegate->pinch_begin()); @@ -2661,13 +2794,18 @@ TEST_F(GestureRecognizerTest, TwoFingerTapChangesToPinch) { ui::TouchEvent release(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), kTouchId1, tes.LeapForward(50)); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&release); + DispatchEventUsingWindowDispatcher(&release); EXPECT_FALSE(delegate->two_finger_tap()); EXPECT_TRUE(delegate->pinch_end()); } } -TEST_F(GestureRecognizerTest, NoTwoFingerTapWhenFirstFingerHasScrolled) { +TEST_P(GestureRecognizerTest, NoTwoFingerTapWhenFirstFingerHasScrolled) { + // Disabled for unified GR due to differences in when pinch begin is sent. The + // Aura GR sends it earlier than is necessary. + if (UsingUnifiedGR()) + return; + scoped_ptr<GestureEventConsumeDelegate> delegate( new GestureEventConsumeDelegate()); const int kWindowWidth = 123; @@ -2683,13 +2821,13 @@ TEST_F(GestureRecognizerTest, NoTwoFingerTapWhenFirstFingerHasScrolled) { delegate->Reset(); ui::TouchEvent press1(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), kTouchId1, tes.Now()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press1); - tes.SendScrollEvent(dispatcher(), 130, 230, kTouchId1, delegate.get()); + DispatchEventUsingWindowDispatcher(&press1); + tes.SendScrollEvent(event_processor(), 130, 230, kTouchId1, delegate.get()); delegate->Reset(); ui::TouchEvent press2(ui::ET_TOUCH_PRESSED, gfx::Point(130, 201), kTouchId2, tes.Now()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press2); + DispatchEventUsingWindowDispatcher(&press2); EXPECT_TRUE(delegate->pinch_begin()); @@ -2699,12 +2837,12 @@ TEST_F(GestureRecognizerTest, NoTwoFingerTapWhenFirstFingerHasScrolled) { ui::TouchEvent release(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), kTouchId2, tes.LeapForward(50)); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&release); + DispatchEventUsingWindowDispatcher(&release); EXPECT_FALSE(delegate->two_finger_tap()); EXPECT_TRUE(delegate->pinch_end()); } -TEST_F(GestureRecognizerTest, MultiFingerSwipe) { +TEST_P(GestureRecognizerTest, MultiFingerSwipe) { scoped_ptr<GestureEventConsumeDelegate> delegate( new GestureEventConsumeDelegate()); const int kWindowWidth = 123; @@ -2725,26 +2863,33 @@ TEST_F(GestureRecognizerTest, MultiFingerSwipe) { aura::test::EventGenerator generator(root_window(), window.get()); + // The unified gesture recognizer assumes a finger has stopped if it hasn't + // moved for too long. See ui/events/gesture_detection/velocity_tracker.cc's + // kAssumePointerStoppedTimeMs. for (int count = 2; count <= kTouchPoints; ++count) { - generator.GestureMultiFingerScroll(count, points, 15, kSteps, 0, -150); + generator.GestureMultiFingerScroll( + count, points, 10, kSteps, 0, -11 * kSteps); EXPECT_TRUE(delegate->swipe_up()); delegate->Reset(); - generator.GestureMultiFingerScroll(count, points, 15, kSteps, 0, 150); + generator.GestureMultiFingerScroll( + count, points, 10, kSteps, 0, 11 * kSteps); EXPECT_TRUE(delegate->swipe_down()); delegate->Reset(); - generator.GestureMultiFingerScroll(count, points, 15, kSteps, -150, 0); + generator.GestureMultiFingerScroll( + count, points, 10, kSteps, -11 * kSteps, 0); EXPECT_TRUE(delegate->swipe_left()); delegate->Reset(); - generator.GestureMultiFingerScroll(count, points, 15, kSteps, 150, 0); + generator.GestureMultiFingerScroll( + count, points, 10, kSteps, 11 * kSteps, 0); EXPECT_TRUE(delegate->swipe_right()); delegate->Reset(); } } -TEST_F(GestureRecognizerTest, TwoFingerTapCancelled) { +TEST_P(GestureRecognizerTest, TwoFingerTapCancelled) { scoped_ptr<GestureEventConsumeDelegate> delegate( new GestureEventConsumeDelegate()); const int kWindowWidth = 123; @@ -2762,17 +2907,17 @@ TEST_F(GestureRecognizerTest, TwoFingerTapCancelled) { delegate->Reset(); ui::TouchEvent press1(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), kTouchId1, tes.Now()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press1); + DispatchEventUsingWindowDispatcher(&press1); delegate->Reset(); ui::TouchEvent press2(ui::ET_TOUCH_PRESSED, gfx::Point(130, 201), kTouchId2, tes.Now()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press2); + DispatchEventUsingWindowDispatcher(&press2); delegate->Reset(); ui::TouchEvent cancel(ui::ET_TOUCH_CANCELLED, gfx::Point(130, 201), kTouchId1, tes.Now()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&cancel); + DispatchEventUsingWindowDispatcher(&cancel); EXPECT_FALSE(delegate->two_finger_tap()); // Make sure there is enough delay before the touch is released so that it @@ -2781,7 +2926,7 @@ TEST_F(GestureRecognizerTest, TwoFingerTapCancelled) { ui::TouchEvent release(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), kTouchId2, tes.LeapForward(50)); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&release); + DispatchEventUsingWindowDispatcher(&release); EXPECT_FALSE(delegate->two_finger_tap()); } @@ -2794,17 +2939,17 @@ TEST_F(GestureRecognizerTest, TwoFingerTapCancelled) { delegate->Reset(); ui::TouchEvent press1(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), kTouchId1, tes.Now()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press1); + DispatchEventUsingWindowDispatcher(&press1); delegate->Reset(); ui::TouchEvent press2(ui::ET_TOUCH_PRESSED, gfx::Point(130, 201), kTouchId2, tes.Now()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press2); + DispatchEventUsingWindowDispatcher(&press2); delegate->Reset(); ui::TouchEvent cancel(ui::ET_TOUCH_CANCELLED, gfx::Point(130, 201), kTouchId2, tes.Now()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&cancel); + DispatchEventUsingWindowDispatcher(&cancel); EXPECT_FALSE(delegate->two_finger_tap()); // Make sure there is enough delay before the touch is released so that it @@ -2813,12 +2958,18 @@ TEST_F(GestureRecognizerTest, TwoFingerTapCancelled) { ui::TouchEvent release(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), kTouchId1, tes.LeapForward(50)); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&release); + DispatchEventUsingWindowDispatcher(&release); EXPECT_FALSE(delegate->two_finger_tap()); } } -TEST_F(GestureRecognizerTest, VeryWideTwoFingerTouchDownShouldBeAPinch) { +TEST_P(GestureRecognizerTest, VeryWideTwoFingerTouchDownShouldBeAPinch) { + // Disabled for unified GR due to differences in when scroll update is + // sent. The Aura GR will never send a ScrollUpdate with a ScrollBegin, but + // the unified GR will. + if (UsingUnifiedGR()) + return; + scoped_ptr<GestureEventConsumeDelegate> delegate( new GestureEventConsumeDelegate()); const int kWindowWidth = 523; @@ -2833,7 +2984,7 @@ TEST_F(GestureRecognizerTest, VeryWideTwoFingerTouchDownShouldBeAPinch) { delegate->Reset(); ui::TouchEvent press1(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), kTouchId1, tes.Now()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press1); + DispatchEventUsingWindowDispatcher(&press1); EXPECT_FALSE(delegate->tap()); EXPECT_TRUE(delegate->tap_down()); EXPECT_FALSE(delegate->tap_cancel()); @@ -2846,7 +2997,7 @@ TEST_F(GestureRecognizerTest, VeryWideTwoFingerTouchDownShouldBeAPinch) { delegate->Reset(); ui::TouchEvent press2(ui::ET_TOUCH_PRESSED, gfx::Point(430, 201), kTouchId2, tes.Now()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press2); + DispatchEventUsingWindowDispatcher(&press2); EXPECT_FALSE(delegate->tap()); EXPECT_FALSE(delegate->tap_down()); // no touch down for second tap. EXPECT_TRUE(delegate->tap_cancel()); @@ -2860,7 +3011,7 @@ TEST_F(GestureRecognizerTest, VeryWideTwoFingerTouchDownShouldBeAPinch) { delegate->Reset(); ui::TouchEvent move2(ui::ET_TOUCH_MOVED, gfx::Point(530, 301), kTouchId2, tes.Now()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&move2); + DispatchEventUsingWindowDispatcher(&move2); EXPECT_FALSE(delegate->tap()); EXPECT_FALSE(delegate->tap_down()); EXPECT_FALSE(delegate->tap_cancel()); @@ -2875,7 +3026,7 @@ TEST_F(GestureRecognizerTest, VeryWideTwoFingerTouchDownShouldBeAPinch) { // Verifies if a window is the target of multiple touch-ids and we hide the // window everything is cleaned up correctly. -TEST_F(GestureRecognizerTest, FlushAllOnHide) { +TEST_P(GestureRecognizerTest, FlushAllOnHide) { scoped_ptr<GestureEventConsumeDelegate> delegate( new GestureEventConsumeDelegate()); gfx::Rect bounds(0, 0, 200, 200); @@ -2887,10 +3038,10 @@ TEST_F(GestureRecognizerTest, FlushAllOnHide) { ui::TouchEvent press1(ui::ET_TOUCH_PRESSED, gfx::Point(10, 10), kTouchId1, tes.Now()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press1); + DispatchEventUsingWindowDispatcher(&press1); ui::TouchEvent press2(ui::ET_TOUCH_PRESSED, gfx::Point(20, 20), kTouchId2, tes.Now()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press2); + DispatchEventUsingWindowDispatcher(&press2); window->Hide(); EXPECT_EQ(NULL, ui::GestureRecognizer::Get()->GetTouchLockedTarget(press1)); @@ -2898,9 +3049,13 @@ TEST_F(GestureRecognizerTest, FlushAllOnHide) { ui::GestureRecognizer::Get()->GetTouchLockedTarget(press2)); } -TEST_F(GestureRecognizerTest, LongPressTimerStopsOnPreventDefaultedTouchMoves) { +TEST_P(GestureRecognizerTest, LongPressTimerStopsOnPreventDefaultedTouchMoves) { + // TODO(tdresser): write a version of this test for the unified GR. + if (UsingUnifiedGR()) + return; + scoped_ptr<QueueTouchEventDelegate> delegate( - new QueueTouchEventDelegate(dispatcher())); + new QueueTouchEventDelegate(host()->dispatcher())); const int kTouchId = 2; gfx::Rect bounds(100, 200, 100, 100); scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( @@ -2919,9 +3074,9 @@ TEST_F(GestureRecognizerTest, LongPressTimerStopsOnPreventDefaultedTouchMoves) { delegate->Reset(); ui::TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), kTouchId, tes.Now()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press); + DispatchEventUsingWindowDispatcher(&press); // Scroll around, to cancel the long press - tes.SendScrollEvent(dispatcher(), 130, 230, kTouchId, delegate.get()); + tes.SendScrollEvent(event_processor(), 130, 230, kTouchId, delegate.get()); delegate->Reset(); delegate->ReceivedAck(); @@ -2958,7 +3113,7 @@ class ConsumesTouchMovesDelegate : public GestureEventConsumeDelegate { // Same as GestureEventScroll, but tests that the behavior is the same // even if all the touch-move events are consumed. -TEST_F(GestureRecognizerTest, GestureEventScrollTouchMoveConsumed) { +TEST_P(GestureRecognizerTest, GestureEventScrollTouchMoveConsumed) { scoped_ptr<ConsumesTouchMovesDelegate> delegate( new ConsumesTouchMovesDelegate()); const int kWindowWidth = 123; @@ -2972,7 +3127,7 @@ TEST_F(GestureRecognizerTest, GestureEventScrollTouchMoveConsumed) { delegate->Reset(); ui::TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), kTouchId, tes.Now()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press); + DispatchEventUsingWindowDispatcher(&press); EXPECT_FALSE(delegate->tap()); EXPECT_TRUE(delegate->tap_down()); EXPECT_FALSE(delegate->tap_cancel()); @@ -2984,7 +3139,7 @@ TEST_F(GestureRecognizerTest, GestureEventScrollTouchMoveConsumed) { // Move the touch-point enough so that it would normally be considered a // scroll. But since the touch-moves will be consumed, the scroll should not // start. - tes.SendScrollEvent(dispatcher(), 130, 230, kTouchId, delegate.get()); + tes.SendScrollEvent(event_processor(), 130, 230, kTouchId, delegate.get()); EXPECT_FALSE(delegate->tap()); EXPECT_FALSE(delegate->tap_down()); EXPECT_TRUE(delegate->tap_cancel()); @@ -2998,7 +3153,7 @@ TEST_F(GestureRecognizerTest, GestureEventScrollTouchMoveConsumed) { delegate->Reset(); ui::TouchEvent release(ui::ET_TOUCH_RELEASED, gfx::Point(130, 230), kTouchId, tes.LeapForward(50)); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&release); + DispatchEventUsingWindowDispatcher(&release); EXPECT_FALSE(delegate->tap()); EXPECT_FALSE(delegate->tap_down()); EXPECT_FALSE(delegate->tap_cancel()); @@ -3010,7 +3165,12 @@ TEST_F(GestureRecognizerTest, GestureEventScrollTouchMoveConsumed) { } // Tests the behavior of 2F scroll when all the touch-move events are consumed. -TEST_F(GestureRecognizerTest, GestureEventScrollTwoFingerTouchMoveConsumed) { +TEST_P(GestureRecognizerTest, GestureEventScrollTwoFingerTouchMoveConsumed) { + // TODO(tdresser): enable this test with unified GR once two finger tap is + // supported. See crbug.com/354396. + if (UsingUnifiedGR()) + return; + scoped_ptr<ConsumesTouchMovesDelegate> delegate( new ConsumesTouchMovesDelegate()); const int kWindowWidth = 123; @@ -3026,8 +3186,8 @@ TEST_F(GestureRecognizerTest, GestureEventScrollTwoFingerTouchMoveConsumed) { delegate->Reset(); ui::TouchEvent press1(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), kTouchId1, tes.Now()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press1); - tes.SendScrollEvent(dispatcher(), 131, 231, kTouchId1, delegate.get()); + DispatchEventUsingWindowDispatcher(&press1); + tes.SendScrollEvent(event_processor(), 131, 231, kTouchId1, delegate.get()); // First finger touches down and moves. EXPECT_FALSE(delegate->tap()); @@ -3039,8 +3199,8 @@ TEST_F(GestureRecognizerTest, GestureEventScrollTwoFingerTouchMoveConsumed) { // Second finger touches down and moves. ui::TouchEvent press2(ui::ET_TOUCH_PRESSED, gfx::Point(130, 201), kTouchId2, tes.LeapForward(50)); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press2); - tes.SendScrollEvent(dispatcher(), 161, 231, kTouchId2, delegate.get()); + DispatchEventUsingWindowDispatcher(&press2); + tes.SendScrollEvent(event_processor(), 161, 231, kTouchId2, delegate.get()); // PinchBegin & ScrollBegin were not sent if the touch-move events were // consumed. @@ -3058,7 +3218,7 @@ TEST_F(GestureRecognizerTest, GestureEventScrollTwoFingerTouchMoveConsumed) { delegate->Reset(); // Moves First finger again, no PinchUpdate & ScrollUpdate. - tes.SendScrollEvent(dispatcher(), 161, 261, kTouchId1, delegate.get()); + tes.SendScrollEvent(event_processor(), 161, 261, kTouchId1, delegate.get()); EXPECT_FALSE(delegate->pinch_update()); EXPECT_FALSE(delegate->pinch_end()); @@ -3070,7 +3230,7 @@ TEST_F(GestureRecognizerTest, GestureEventScrollTwoFingerTouchMoveConsumed) { delegate->Reset(); // Making a pinch gesture. - tes.SendScrollEvent(dispatcher(), 161, 251, kTouchId1, delegate.get()); + tes.SendScrollEvent(event_processor(), 161, 251, kTouchId1, delegate.get()); // If touch moves are ever consumed, we should not see PinchBegin/Update // even touch moves become not consumed. EXPECT_FALSE(delegate->scroll_begin()); @@ -3082,7 +3242,7 @@ TEST_F(GestureRecognizerTest, GestureEventScrollTwoFingerTouchMoveConsumed) { EXPECT_FALSE(delegate->pinch_end()); delegate->Reset(); - tes.SendScrollEvent(dispatcher(), 161, 241, kTouchId2, delegate.get()); + tes.SendScrollEvent(event_processor(), 161, 241, kTouchId2, delegate.get()); EXPECT_FALSE(delegate->scroll_begin()); EXPECT_FALSE(delegate->scroll_update()); EXPECT_FALSE(delegate->scroll_end()); @@ -3096,17 +3256,18 @@ TEST_F(GestureRecognizerTest, GestureEventScrollTwoFingerTouchMoveConsumed) { kTouchId1, tes.Now()); ui::TouchEvent release2(ui::ET_TOUCH_RELEASED, gfx::Point(130, 201), kTouchId2, tes.Now()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&release1); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&release2); + DispatchEventUsingWindowDispatcher(&release1); + DispatchEventUsingWindowDispatcher(&release2); EXPECT_FALSE(delegate->tap()); // Touch release is not consumed, so we still see two finger tap. EXPECT_TRUE(delegate->two_finger_tap()); - // Should not see PinchEnd & ScrollEnd. - EXPECT_FALSE(delegate->scroll_begin()); + // Should not see PinchEnd. + EXPECT_TRUE(delegate->scroll_begin()); EXPECT_FALSE(delegate->scroll_update()); EXPECT_FALSE(delegate->scroll_end()); + EXPECT_TRUE(delegate->fling()); EXPECT_FALSE(delegate->pinch_begin()); EXPECT_FALSE(delegate->pinch_update()); @@ -3116,7 +3277,7 @@ TEST_F(GestureRecognizerTest, GestureEventScrollTwoFingerTouchMoveConsumed) { // Like as GestureEventTouchMoveConsumed but tests the different behavior // depending on whether the events were consumed before or after the scroll // started. -TEST_F(GestureRecognizerTest, GestureEventScrollTouchMovePartialConsumed) { +TEST_P(GestureRecognizerTest, GestureEventScrollTouchMovePartialConsumed) { scoped_ptr<ConsumesTouchMovesDelegate> delegate( new ConsumesTouchMovesDelegate()); const int kWindowWidth = 123; @@ -3130,7 +3291,7 @@ TEST_F(GestureRecognizerTest, GestureEventScrollTouchMovePartialConsumed) { delegate->Reset(); ui::TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), kTouchId, tes.Now()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press); + DispatchEventUsingWindowDispatcher(&press); EXPECT_FALSE(delegate->tap()); EXPECT_TRUE(delegate->tap_down()); EXPECT_FALSE(delegate->tap_cancel()); @@ -3142,7 +3303,7 @@ TEST_F(GestureRecognizerTest, GestureEventScrollTouchMovePartialConsumed) { // Move the touch-point enough so that it would normally be considered a // scroll. But since the touch-moves will be consumed, the scroll should not // start. - tes.SendScrollEvent(dispatcher(), 130, 230, kTouchId, delegate.get()); + tes.SendScrollEvent(event_processor(), 130, 230, kTouchId, delegate.get()); EXPECT_FALSE(delegate->tap()); EXPECT_FALSE(delegate->tap_down()); EXPECT_TRUE(delegate->tap_cancel()); @@ -3153,7 +3314,7 @@ TEST_F(GestureRecognizerTest, GestureEventScrollTouchMovePartialConsumed) { // Now, stop consuming touch-move events, and move the touch-point again. delegate->set_consume_touch_move(false); - tes.SendScrollEvent(dispatcher(), 159, 259, kTouchId, delegate.get()); + tes.SendScrollEvent(event_processor(), 159, 259, kTouchId, delegate.get()); EXPECT_FALSE(delegate->tap()); EXPECT_FALSE(delegate->tap_down()); EXPECT_FALSE(delegate->tap_cancel()); @@ -3171,7 +3332,7 @@ TEST_F(GestureRecognizerTest, GestureEventScrollTouchMovePartialConsumed) { delegate->set_consume_touch_move(true); // Move some more to generate a few more scroll updates. - tes.SendScrollEvent(dispatcher(), 110, 211, kTouchId, delegate.get()); + tes.SendScrollEvent(event_processor(), 110, 211, kTouchId, delegate.get()); EXPECT_FALSE(delegate->tap()); EXPECT_FALSE(delegate->tap_down()); EXPECT_FALSE(delegate->tap_cancel()); @@ -3182,7 +3343,7 @@ TEST_F(GestureRecognizerTest, GestureEventScrollTouchMovePartialConsumed) { EXPECT_EQ(0, delegate->scroll_x()); EXPECT_EQ(0, delegate->scroll_y()); - tes.SendScrollEvent(dispatcher(), 140, 215, kTouchId, delegate.get()); + tes.SendScrollEvent(event_processor(), 140, 215, kTouchId, delegate.get()); EXPECT_FALSE(delegate->tap()); EXPECT_FALSE(delegate->tap_down()); EXPECT_FALSE(delegate->tap_cancel()); @@ -3197,7 +3358,7 @@ TEST_F(GestureRecognizerTest, GestureEventScrollTouchMovePartialConsumed) { delegate->Reset(); ui::TouchEvent release(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), kTouchId, tes.LeapForward(50)); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&release); + DispatchEventUsingWindowDispatcher(&release); EXPECT_FALSE(delegate->tap()); EXPECT_FALSE(delegate->tap_down()); EXPECT_FALSE(delegate->tap_cancel()); @@ -3210,7 +3371,7 @@ TEST_F(GestureRecognizerTest, GestureEventScrollTouchMovePartialConsumed) { } // Check that appropriate touch events generate double tap gesture events. -TEST_F(GestureRecognizerTest, GestureEventDoubleTap) { +TEST_P(GestureRecognizerTest, GestureEventDoubleTap) { scoped_ptr<GestureEventConsumeDelegate> delegate( new GestureEventConsumeDelegate()); const int kWindowWidth = 123; @@ -3224,19 +3385,19 @@ TEST_F(GestureRecognizerTest, GestureEventDoubleTap) { // First tap (tested in GestureEventTap) ui::TouchEvent press1(ui::ET_TOUCH_PRESSED, gfx::Point(104, 201), kTouchId, tes.Now()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press1); + DispatchEventUsingWindowDispatcher(&press1); ui::TouchEvent release1(ui::ET_TOUCH_RELEASED, gfx::Point(104, 201), kTouchId, tes.LeapForward(50)); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&release1); + DispatchEventUsingWindowDispatcher(&release1); delegate->Reset(); // Second tap ui::TouchEvent press2(ui::ET_TOUCH_PRESSED, gfx::Point(101, 203), kTouchId, tes.LeapForward(200)); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press2); + DispatchEventUsingWindowDispatcher(&press2); ui::TouchEvent release2(ui::ET_TOUCH_RELEASED, gfx::Point(102, 206), kTouchId, tes.LeapForward(50)); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&release2); + DispatchEventUsingWindowDispatcher(&release2); EXPECT_TRUE(delegate->tap()); EXPECT_TRUE(delegate->tap_down()); @@ -3251,7 +3412,7 @@ TEST_F(GestureRecognizerTest, GestureEventDoubleTap) { } // Check that appropriate touch events generate triple tap gesture events. -TEST_F(GestureRecognizerTest, GestureEventTripleTap) { +TEST_P(GestureRecognizerTest, GestureEventTripleTap) { scoped_ptr<GestureEventConsumeDelegate> delegate( new GestureEventConsumeDelegate()); const int kWindowWidth = 123; @@ -3265,10 +3426,10 @@ TEST_F(GestureRecognizerTest, GestureEventTripleTap) { // First tap (tested in GestureEventTap) ui::TouchEvent press1(ui::ET_TOUCH_PRESSED, gfx::Point(104, 201), kTouchId, tes.Now()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press1); + DispatchEventUsingWindowDispatcher(&press1); ui::TouchEvent release1(ui::ET_TOUCH_RELEASED, gfx::Point(104, 201), kTouchId, tes.LeapForward(50)); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&release1); + DispatchEventUsingWindowDispatcher(&release1); EXPECT_EQ(1, delegate->tap_count()); delegate->Reset(); @@ -3276,10 +3437,10 @@ TEST_F(GestureRecognizerTest, GestureEventTripleTap) { // Second tap (tested in GestureEventDoubleTap) ui::TouchEvent press2(ui::ET_TOUCH_PRESSED, gfx::Point(101, 203), kTouchId, tes.LeapForward(200)); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press2); + DispatchEventUsingWindowDispatcher(&press2); ui::TouchEvent release2(ui::ET_TOUCH_RELEASED, gfx::Point(102, 206), kTouchId, tes.LeapForward(50)); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&release2); + DispatchEventUsingWindowDispatcher(&release2); EXPECT_EQ(2, delegate->tap_count()); delegate->Reset(); @@ -3287,26 +3448,44 @@ TEST_F(GestureRecognizerTest, GestureEventTripleTap) { // Third tap ui::TouchEvent press3(ui::ET_TOUCH_PRESSED, gfx::Point(102, 206), kTouchId, tes.LeapForward(200)); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press3); + DispatchEventUsingWindowDispatcher(&press3); ui::TouchEvent release3(ui::ET_TOUCH_RELEASED, gfx::Point(102, 206), kTouchId, tes.LeapForward(50)); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&release3); - - - EXPECT_TRUE(delegate->tap()); - EXPECT_TRUE(delegate->tap_down()); - EXPECT_FALSE(delegate->tap_cancel()); - EXPECT_TRUE(delegate->begin()); - EXPECT_TRUE(delegate->end()); - EXPECT_FALSE(delegate->scroll_begin()); - EXPECT_FALSE(delegate->scroll_update()); - EXPECT_FALSE(delegate->scroll_end()); - - EXPECT_EQ(3, delegate->tap_count()); + DispatchEventUsingWindowDispatcher(&release3); + + // Third, Fourth and Fifth Taps. Taps after the third should have their + // |tap_count| wrap around back to 1. + for (int i = 3; i < 5; ++i) { + ui::TouchEvent press3(ui::ET_TOUCH_PRESSED, + gfx::Point(102, 206), + kTouchId, + tes.LeapForward(200)); + DispatchEventUsingWindowDispatcher(&press3); + ui::TouchEvent release3(ui::ET_TOUCH_RELEASED, + gfx::Point(102, 206), + kTouchId, + tes.LeapForward(50)); + DispatchEventUsingWindowDispatcher(&release3); + + EXPECT_TRUE(delegate->tap()); + EXPECT_TRUE(delegate->tap_down()); + EXPECT_FALSE(delegate->tap_cancel()); + EXPECT_TRUE(delegate->begin()); + EXPECT_TRUE(delegate->end()); + EXPECT_FALSE(delegate->scroll_begin()); + EXPECT_FALSE(delegate->scroll_update()); + EXPECT_FALSE(delegate->scroll_end()); + + // The behavior for the Aura GR is incorrect. + if (UsingUnifiedGR()) + EXPECT_EQ(1 + (i % 3), delegate->tap_count()); + else + EXPECT_EQ(3, delegate->tap_count()); + } } // Check that we don't get a double tap when the two taps are far apart. -TEST_F(GestureRecognizerTest, TwoTapsFarApart) { +TEST_P(GestureRecognizerTest, TwoTapsFarApart) { scoped_ptr<GestureEventConsumeDelegate> delegate( new GestureEventConsumeDelegate()); const int kWindowWidth = 123; @@ -3320,19 +3499,19 @@ TEST_F(GestureRecognizerTest, TwoTapsFarApart) { // First tap (tested in GestureEventTap) ui::TouchEvent press1(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), kTouchId, tes.Now()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press1); + DispatchEventUsingWindowDispatcher(&press1); ui::TouchEvent release1(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), kTouchId, tes.LeapForward(50)); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&release1); + DispatchEventUsingWindowDispatcher(&release1); delegate->Reset(); // Second tap, close in time but far in distance ui::TouchEvent press2(ui::ET_TOUCH_PRESSED, gfx::Point(201, 201), kTouchId, tes.LeapForward(200)); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press2); + DispatchEventUsingWindowDispatcher(&press2); ui::TouchEvent release2(ui::ET_TOUCH_RELEASED, gfx::Point(201, 201), kTouchId, tes.LeapForward(50)); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&release2); + DispatchEventUsingWindowDispatcher(&release2); EXPECT_TRUE(delegate->tap()); EXPECT_TRUE(delegate->tap_down()); @@ -3348,7 +3527,7 @@ TEST_F(GestureRecognizerTest, TwoTapsFarApart) { // Check that we don't get a double tap when the two taps have a long enough // delay in between. -TEST_F(GestureRecognizerTest, TwoTapsWithDelayBetween) { +TEST_P(GestureRecognizerTest, TwoTapsWithDelayBetween) { scoped_ptr<GestureEventConsumeDelegate> delegate( new GestureEventConsumeDelegate()); const int kWindowWidth = 123; @@ -3362,19 +3541,19 @@ TEST_F(GestureRecognizerTest, TwoTapsWithDelayBetween) { // First tap (tested in GestureEventTap) ui::TouchEvent press1(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), kTouchId, tes.Now()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press1); + DispatchEventUsingWindowDispatcher(&press1); ui::TouchEvent release1(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), kTouchId, tes.LeapForward(50)); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&release1); + DispatchEventUsingWindowDispatcher(&release1); delegate->Reset(); // Second tap, close in distance but after some delay ui::TouchEvent press2(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), kTouchId, tes.LeapForward(2000)); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press2); + DispatchEventUsingWindowDispatcher(&press2); ui::TouchEvent release2(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), kTouchId, tes.LeapForward(50)); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&release2); + DispatchEventUsingWindowDispatcher(&release2); EXPECT_TRUE(delegate->tap()); EXPECT_TRUE(delegate->tap_down()); @@ -3391,7 +3570,12 @@ TEST_F(GestureRecognizerTest, TwoTapsWithDelayBetween) { // Checks that if the bounding-box of a gesture changes because of change in // radius of a touch-point, and not because of change in position, then there // are not gesture events from that. -TEST_F(GestureRecognizerTest, BoundingBoxRadiusChange) { +TEST_P(GestureRecognizerTest, BoundingBoxRadiusChange) { + // TODO(tdresser): enable this test with unified GR when (if?) bounding box + // behavior is unified. + if (UsingUnifiedGR()) + return; + scoped_ptr<GestureEventConsumeDelegate> delegate( new GestureEventConsumeDelegate()); const int kWindowWidth = 234; @@ -3404,7 +3588,7 @@ TEST_F(GestureRecognizerTest, BoundingBoxRadiusChange) { ui::TouchEvent press1( ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), kTouchId, tes.Now()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press1); + DispatchEventUsingWindowDispatcher(&press1); EXPECT_TRUE(delegate->bounding_box().IsEmpty()); delegate->Reset(); @@ -3413,7 +3597,7 @@ TEST_F(GestureRecognizerTest, BoundingBoxRadiusChange) { ui::ET_TOUCH_PRESSED, gfx::Point(201, 201), kTouchId2, tes.LeapForward(400)); press2.set_radius_x(5); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press2); + DispatchEventUsingWindowDispatcher(&press2); EXPECT_FALSE(delegate->pinch_begin()); EXPECT_EQ(gfx::Rect(101, 201, 100, 0).ToString(), delegate->bounding_box().ToString()); @@ -3422,7 +3606,7 @@ TEST_F(GestureRecognizerTest, BoundingBoxRadiusChange) { ui::TouchEvent move1(ui::ET_TOUCH_MOVED, gfx::Point(141, 201), kTouchId, tes.LeapForward(40)); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&move1); + DispatchEventUsingWindowDispatcher(&move1); EXPECT_TRUE(delegate->pinch_begin()); EXPECT_EQ(gfx::Rect(141, 201, 60, 0).ToString(), delegate->bounding_box().ToString()); @@ -3434,7 +3618,7 @@ TEST_F(GestureRecognizerTest, BoundingBoxRadiusChange) { tes.LeapForward(40)); move2.set_radius_x(50); move2.set_radius_y(60); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&move2); + DispatchEventUsingWindowDispatcher(&move2); EXPECT_FALSE(delegate->tap()); EXPECT_FALSE(delegate->tap_cancel()); EXPECT_FALSE(delegate->scroll_update()); @@ -3445,7 +3629,7 @@ TEST_F(GestureRecognizerTest, BoundingBoxRadiusChange) { // Checks that slow scrolls deliver the correct deltas. // In particular, fix for http;//crbug.com/150573. -TEST_F(GestureRecognizerTest, NoDriftInScroll) { +TEST_P(GestureRecognizerTest, NoDriftInScroll) { ui::GestureConfiguration::set_max_touch_move_in_pixels_for_click(3); ui::GestureConfiguration::set_min_scroll_delta_squared(9); scoped_ptr<GestureEventConsumeDelegate> delegate( @@ -3460,38 +3644,40 @@ TEST_F(GestureRecognizerTest, NoDriftInScroll) { ui::TouchEvent press1( ui::ET_TOUCH_PRESSED, gfx::Point(101, 208), kTouchId, tes.Now()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press1); + DispatchEventUsingWindowDispatcher(&press1); EXPECT_TRUE(delegate->begin()); delegate->Reset(); ui::TouchEvent move1(ui::ET_TOUCH_MOVED, gfx::Point(101, 206), kTouchId, tes.LeapForward(40)); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&move1); + DispatchEventUsingWindowDispatcher(&move1); EXPECT_FALSE(delegate->scroll_begin()); delegate->Reset(); ui::TouchEvent move2(ui::ET_TOUCH_MOVED, gfx::Point(101, 204), kTouchId, tes.LeapForward(40)); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&move2); + DispatchEventUsingWindowDispatcher(&move2); EXPECT_TRUE(delegate->tap_cancel()); EXPECT_TRUE(delegate->scroll_begin()); EXPECT_TRUE(delegate->scroll_update()); - EXPECT_EQ(-4, delegate->scroll_y()); + // 3 px consumed by touch slop region. + EXPECT_EQ(-1, delegate->scroll_y()); + EXPECT_EQ(-4, delegate->scroll_y_hint()); delegate->Reset(); ui::TouchEvent move3(ui::ET_TOUCH_MOVED, gfx::Point(101, 204), kTouchId, tes.LeapForward(40)); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&move3); + DispatchEventUsingWindowDispatcher(&move3); EXPECT_FALSE(delegate->scroll_update()); delegate->Reset(); ui::TouchEvent move4(ui::ET_TOUCH_MOVED, gfx::Point(101, 203), kTouchId, tes.LeapForward(40)); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&move4); + DispatchEventUsingWindowDispatcher(&move4); EXPECT_TRUE(delegate->scroll_update()); EXPECT_EQ(-1, delegate->scroll_y()); @@ -3501,7 +3687,7 @@ TEST_F(GestureRecognizerTest, NoDriftInScroll) { // Ensure that move events which are preventDefaulted will cause a tap // cancel gesture event to be fired if the move would normally cause a // scroll. See bug http://crbug.com/146397. -TEST_F(GestureRecognizerTest, GestureEventConsumedTouchMoveCanFireTapCancel) { +TEST_P(GestureRecognizerTest, GestureEventConsumedTouchMoveCanFireTapCancel) { scoped_ptr<ConsumesTouchMovesDelegate> delegate( new ConsumesTouchMovesDelegate()); const int kTouchId = 5; @@ -3515,13 +3701,13 @@ TEST_F(GestureRecognizerTest, GestureEventConsumedTouchMoveCanFireTapCancel) { kTouchId, tes.Now()); delegate->set_consume_touch_move(false); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press); + DispatchEventUsingWindowDispatcher(&press); delegate->set_consume_touch_move(true); delegate->Reset(); // Move the touch-point enough so that it would normally be considered a // scroll. But since the touch-moves will be consumed, the scroll should not // start. - tes.SendScrollEvent(dispatcher(), 130, 230, kTouchId, delegate.get()); + tes.SendScrollEvent(event_processor(), 130, 230, kTouchId, delegate.get()); EXPECT_FALSE(delegate->tap()); EXPECT_FALSE(delegate->tap_down()); EXPECT_TRUE(delegate->tap_cancel()); @@ -3531,7 +3717,7 @@ TEST_F(GestureRecognizerTest, GestureEventConsumedTouchMoveCanFireTapCancel) { EXPECT_FALSE(delegate->scroll_end()); } -TEST_F(GestureRecognizerTest, +TEST_P(GestureRecognizerTest, TransferEventDispatchesTouchCancel) { scoped_ptr<GestureEventConsumeDelegate> delegate( new GestureEventConsumeDelegate()); @@ -3552,8 +3738,8 @@ TEST_F(GestureRecognizerTest, ui::TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), kTouchId, tes.Now()); ui::TouchEvent p2(ui::ET_TOUCH_PRESSED, gfx::Point(50, 50), 1, tes.Now()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&p2); + DispatchEventUsingWindowDispatcher(&press); + DispatchEventUsingWindowDispatcher(&p2); EXPECT_FALSE(delegate->tap()); EXPECT_TRUE(delegate->tap_down()); EXPECT_TRUE(delegate->tap_cancel()); @@ -3574,7 +3760,7 @@ TEST_F(GestureRecognizerTest, } // Check that appropriate touch events generate show press events -TEST_F(GestureRecognizerTest, GestureEventShowPress) { +TEST_P(GestureRecognizerTest, GestureEventShowPress) { scoped_ptr<GestureEventConsumeDelegate> delegate( new GestureEventConsumeDelegate()); TimedEvents tes; @@ -3594,7 +3780,7 @@ TEST_F(GestureRecognizerTest, GestureEventShowPress) { ui::TouchEvent press1(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), kTouchId, tes.Now()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press1); + DispatchEventUsingWindowDispatcher(&press1); EXPECT_TRUE(delegate->tap_down()); EXPECT_TRUE(delegate->begin()); EXPECT_FALSE(delegate->tap_cancel()); @@ -3610,15 +3796,16 @@ TEST_F(GestureRecognizerTest, GestureEventShowPress) { delegate->Reset(); ui::TouchEvent release1(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), kTouchId, tes.Now()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&release1); + DispatchEventUsingWindowDispatcher(&release1); EXPECT_FALSE(delegate->long_press()); - // Note the tap down isn't cancelled until the release - EXPECT_TRUE(delegate->tap_cancel()); + // Note the tap isn't dispatched until the release + EXPECT_FALSE(delegate->tap_cancel()); + EXPECT_TRUE(delegate->tap()); } // Check that scrolling cancels a show press -TEST_F(GestureRecognizerTest, GestureEventShowPressCancelledByScroll) { +TEST_P(GestureRecognizerTest, GestureEventShowPressCancelledByScroll) { scoped_ptr<GestureEventConsumeDelegate> delegate( new GestureEventConsumeDelegate()); TimedEvents tes; @@ -3642,7 +3829,7 @@ TEST_F(GestureRecognizerTest, GestureEventShowPressCancelledByScroll) { ui::TouchEvent press1(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), kTouchId, tes.Now()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press1); + DispatchEventUsingWindowDispatcher(&press1); EXPECT_TRUE(delegate->tap_down()); // We haven't pressed long enough for a show press to occur @@ -3650,7 +3837,7 @@ TEST_F(GestureRecognizerTest, GestureEventShowPressCancelledByScroll) { EXPECT_FALSE(delegate->tap_cancel()); // Scroll around, to cancel the show press - tes.SendScrollEvent(dispatcher(), 130, 230, kTouchId, delegate.get()); + tes.SendScrollEvent(event_processor(), 130, 230, kTouchId, delegate.get()); // Wait until the timer runs out gesture_sequence->ForceTimeout(); EXPECT_FALSE(delegate->show_press()); @@ -3659,13 +3846,13 @@ TEST_F(GestureRecognizerTest, GestureEventShowPressCancelledByScroll) { delegate->Reset(); ui::TouchEvent release1(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), kTouchId, tes.LeapForward(10)); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&release1); + DispatchEventUsingWindowDispatcher(&release1); EXPECT_FALSE(delegate->show_press()); EXPECT_FALSE(delegate->tap_cancel()); } // Test that show press events are sent immediately on tap -TEST_F(GestureRecognizerTest, GestureEventShowPressSentOnTap) { +TEST_P(GestureRecognizerTest, GestureEventShowPressSentOnTap) { scoped_ptr<GestureEventConsumeDelegate> delegate( new GestureEventConsumeDelegate()); TimedEvents tes; @@ -3680,7 +3867,7 @@ TEST_F(GestureRecognizerTest, GestureEventShowPressSentOnTap) { ui::TouchEvent press1(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), kTouchId, tes.Now()); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&press1); + DispatchEventUsingWindowDispatcher(&press1); EXPECT_TRUE(delegate->tap_down()); // We haven't pressed long enough for a show press to occur @@ -3690,11 +3877,516 @@ TEST_F(GestureRecognizerTest, GestureEventShowPressSentOnTap) { delegate->Reset(); ui::TouchEvent release1(ui::ET_TOUCH_RELEASED, gfx::Point(101, 201), kTouchId, tes.LeapForward(50)); - dispatcher()->AsRootWindowHostDelegate()->OnHostTouchEvent(&release1); + DispatchEventUsingWindowDispatcher(&release1); EXPECT_TRUE(delegate->show_press()); EXPECT_FALSE(delegate->tap_cancel()); EXPECT_TRUE(delegate->tap()); } +// Test that consuming the first move touch event prevents a scroll. +TEST_P(GestureRecognizerTest, GestureEventConsumedTouchMoveScrollTest) { + scoped_ptr<QueueTouchEventDelegate> delegate( + new QueueTouchEventDelegate(host()->dispatcher())); + TimedEvents tes; + const int kTouchId = 7; + gfx::Rect bounds(0, 0, 1000, 1000); + scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( + delegate.get(), -1234, bounds, root_window())); + + ui::TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(0, 0), + kTouchId, tes.Now()); + DispatchEventUsingWindowDispatcher(&press); + delegate->ReceivedAck(); + + // A touch move within the slop region is never consumed in web contents. The + // unified GR won't prevent scroll if a touch move within the slop region is + // consumed, so make sure this touch move exceeds the slop region. + ui::TouchEvent move1(ui::ET_TOUCH_MOVED, gfx::Point(10, 10), + kTouchId, tes.Now()); + DispatchEventUsingWindowDispatcher(&move1); + delegate->ReceivedAckPreventDefaulted(); + + ui::TouchEvent move2(ui::ET_TOUCH_MOVED, gfx::Point(20, 20), + kTouchId, tes.Now()); + DispatchEventUsingWindowDispatcher(&move2); + delegate->ReceivedAck(); + + EXPECT_FALSE(delegate->scroll_begin()); + EXPECT_FALSE(delegate->scroll_update()); +} + +// Test that consuming the first touch move event of a touch point doesn't +// prevent pinching once an additional touch has been pressed. +TEST_P(GestureRecognizerTest, GestureEventConsumedTouchMovePinchTest) { + // Consuming moves within the touch slop and the the disposition handling of + // pinch events behave differently between the Unified GR and the Aura GR. + if (UsingUnifiedGR()) + return; + + scoped_ptr<QueueTouchEventDelegate> delegate( + new QueueTouchEventDelegate(host()->dispatcher())); + TimedEvents tes; + const int kTouchId1 = 7; + const int kTouchId2 = 4; + gfx::Rect bounds(0, 0, 1000, 1000); + scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( + delegate.get(), -1234, bounds, root_window())); + + ui::TouchEvent press1(ui::ET_TOUCH_PRESSED, gfx::Point(0, 0), + kTouchId1, tes.Now()); + DispatchEventUsingWindowDispatcher(&press1); + delegate->ReceivedAck(); + + ui::TouchEvent move1(ui::ET_TOUCH_MOVED, gfx::Point(2, 2), + kTouchId1, tes.Now()); + DispatchEventUsingWindowDispatcher(&move1); + delegate->ReceivedAckPreventDefaulted(); + + ui::TouchEvent move2(ui::ET_TOUCH_MOVED, gfx::Point(20, 20), + kTouchId1, tes.Now()); + DispatchEventUsingWindowDispatcher(&move2); + delegate->ReceivedAck(); + + // We can't scroll, because a move has been consumed. + EXPECT_FALSE(delegate->scroll_begin()); + EXPECT_FALSE(delegate->scroll_update()); + EXPECT_FALSE(delegate->pinch_begin()); + + // An additional press will allow us to pinch. + ui::TouchEvent press2(ui::ET_TOUCH_PRESSED, gfx::Point(0, 0), + kTouchId2, tes.Now()); + DispatchEventUsingWindowDispatcher(&press2); + delegate->ReceivedAck(); + + ui::TouchEvent move3(ui::ET_TOUCH_MOVED, gfx::Point(20, 20), + kTouchId2, tes.Now()); + DispatchEventUsingWindowDispatcher(&move3); + delegate->ReceivedAck(); + + EXPECT_TRUE(delegate->pinch_begin()); + EXPECT_FALSE(delegate->pinch_update()); + + delegate->Reset(); + + ui::TouchEvent move4(ui::ET_TOUCH_MOVED, gfx::Point(40, 40), + kTouchId2, tes.Now()); + DispatchEventUsingWindowDispatcher(&move4); + delegate->ReceivedAck(); + + EXPECT_TRUE(delegate->pinch_update()); + EXPECT_EQ(10, delegate->scroll_x()); + EXPECT_EQ(10, delegate->scroll_y()); +} + +// Test that consuming the first move touch doesn't prevent a tap. +TEST_P(GestureRecognizerTest, GestureEventConsumedTouchMoveTapTest) { + scoped_ptr<QueueTouchEventDelegate> delegate( + new QueueTouchEventDelegate(host()->dispatcher())); + TimedEvents tes; + const int kTouchId = 7; + gfx::Rect bounds(0, 0, 1000, 1000); + scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( + delegate.get(), -1234, bounds, root_window())); + + ui::TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(0, 0), + kTouchId, tes.Now()); + DispatchEventUsingWindowDispatcher(&press); + delegate->ReceivedAck(); + + ui::TouchEvent move(ui::ET_TOUCH_MOVED, gfx::Point(2, 2), + kTouchId, tes.Now()); + DispatchEventUsingWindowDispatcher(&move); + delegate->ReceivedAckPreventDefaulted(); + + ui::TouchEvent release(ui::ET_TOUCH_RELEASED, gfx::Point(2, 2), + kTouchId, tes.LeapForward(50)); + DispatchEventUsingWindowDispatcher(&release); + delegate->ReceivedAck(); + + EXPECT_TRUE(delegate->tap()); +} + +// Test that consuming the first move touch doesn't prevent a long press. +TEST_P(GestureRecognizerTest, GestureEventConsumedTouchMoveLongPressTest) { + scoped_ptr<QueueTouchEventDelegate> delegate( + new QueueTouchEventDelegate(host()->dispatcher())); + TimedEvents tes; + const int kWindowWidth = 123; + const int kWindowHeight = 45; + const int kTouchId = 2; + gfx::Rect bounds(100, 200, kWindowWidth, kWindowHeight); + scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( + delegate.get(), -1234, bounds, root_window())); + + delegate->Reset(); + + TimerTestGestureRecognizer* gesture_recognizer = + new TimerTestGestureRecognizer(); + + ScopedGestureRecognizerSetter gr_setter(gesture_recognizer); + + ui::TouchEvent press1(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), + kTouchId, tes.Now()); + DispatchEventUsingWindowDispatcher(&press1); + delegate->ReceivedAck(); + + ui::TouchEvent move(ui::ET_TOUCH_MOVED, gfx::Point(103, 203), + kTouchId, tes.Now()); + DispatchEventUsingWindowDispatcher(&move); + delegate->ReceivedAckPreventDefaulted(); + + // Wait until the timer runs out + delegate->WaitUntilReceivedGesture(ui::ET_GESTURE_LONG_PRESS); + EXPECT_TRUE(delegate->long_press()); +} + +// Tests that the deltas are correct when leaving the slop region very slowly. +TEST_P(GestureRecognizerTest, TestExceedingSlopSlowly) { + // Disabled for unified GR due to subtle differences in touch slop handling. + if (UsingUnifiedGR()) + return; + + ui::GestureConfiguration::set_max_touch_move_in_pixels_for_click(3); + scoped_ptr<GestureEventConsumeDelegate> delegate( + new GestureEventConsumeDelegate()); + const int kWindowWidth = 234; + const int kWindowHeight = 345; + const int kTouchId = 5; + TimedEvents tes; + gfx::Rect bounds(0, 0, kWindowWidth, kWindowHeight); + scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( + delegate.get(), -1234, bounds, root_window())); + + ui::TouchEvent press( + ui::ET_TOUCH_PRESSED, gfx::Point(10, 10), kTouchId, tes.Now()); + DispatchEventUsingWindowDispatcher(&press); + EXPECT_FALSE(delegate->scroll_begin()); + EXPECT_FALSE(delegate->scroll_update()); + delegate->Reset(); + + ui::TouchEvent move1(ui::ET_TOUCH_MOVED, gfx::Point(11, 10), kTouchId, + tes.LeapForward(40)); + DispatchEventUsingWindowDispatcher(&move1); + EXPECT_FALSE(delegate->scroll_begin()); + EXPECT_FALSE(delegate->scroll_update()); + EXPECT_EQ(0, delegate->scroll_x()); + EXPECT_EQ(0, delegate->scroll_x_hint()); + delegate->Reset(); + + ui::TouchEvent move2(ui::ET_TOUCH_MOVED, gfx::Point(12, 10), kTouchId, + tes.LeapForward(40)); + DispatchEventUsingWindowDispatcher(&move2); + EXPECT_FALSE(delegate->scroll_begin()); + EXPECT_FALSE(delegate->scroll_update()); + EXPECT_EQ(0, delegate->scroll_x()); + EXPECT_EQ(0, delegate->scroll_x_hint()); + delegate->Reset(); + + + ui::TouchEvent move3(ui::ET_TOUCH_MOVED, gfx::Point(13, 10), kTouchId, + tes.LeapForward(40)); + DispatchEventUsingWindowDispatcher(&move3); + EXPECT_TRUE(delegate->scroll_begin()); + EXPECT_FALSE(delegate->scroll_update()); + EXPECT_EQ(0, delegate->scroll_x()); + EXPECT_EQ(3, delegate->scroll_x_hint()); + delegate->Reset(); + + + ui::TouchEvent move4(ui::ET_TOUCH_MOVED, gfx::Point(14, 10), kTouchId, + tes.LeapForward(40)); + DispatchEventUsingWindowDispatcher(&move4); + EXPECT_FALSE(delegate->scroll_begin()); + EXPECT_TRUE(delegate->scroll_update()); + EXPECT_EQ(1, delegate->scroll_x()); + EXPECT_EQ(0, delegate->scroll_x_hint()); + delegate->Reset(); +} + +TEST_P(GestureRecognizerTest, ScrollAlternatelyConsumedTest) { + scoped_ptr<QueueTouchEventDelegate> delegate( + new QueueTouchEventDelegate(host()->dispatcher())); + TimedEvents tes; + const int kWindowWidth = 3000; + const int kWindowHeight = 3000; + const int kTouchId = 2; + gfx::Rect bounds(0, 0, kWindowWidth, kWindowHeight); + scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( + delegate.get(), -1234, bounds, root_window())); + + delegate->Reset(); + + int x = 0; + int y = 0; + + ui::TouchEvent press1(ui::ET_TOUCH_PRESSED, gfx::Point(x, y), + kTouchId, tes.Now()); + DispatchEventUsingWindowDispatcher(&press1); + delegate->ReceivedAck(); + EXPECT_FALSE(delegate->scroll_begin()); + EXPECT_FALSE(delegate->scroll_update()); + delegate->Reset(); + + x += 100; + y += 100; + ui::TouchEvent move1(ui::ET_TOUCH_MOVED, gfx::Point(x, y), + kTouchId, tes.Now()); + DispatchEventUsingWindowDispatcher(&move1); + delegate->ReceivedAck(); + EXPECT_TRUE(delegate->scroll_begin()); + EXPECT_TRUE(delegate->scroll_update()); + delegate->Reset(); + + for (int i = 0; i < 3; ++i) { + x += 10; + y += 10; + ui::TouchEvent move2( + ui::ET_TOUCH_MOVED, gfx::Point(x, y), kTouchId, tes.Now()); + DispatchEventUsingWindowDispatcher(&move2); + delegate->ReceivedAck(); + EXPECT_FALSE(delegate->scroll_begin()); + EXPECT_TRUE(delegate->scroll_update()); + EXPECT_EQ(10, delegate->scroll_x()); + EXPECT_EQ(10, delegate->scroll_y()); + delegate->Reset(); + + x += 20; + y += 20; + ui::TouchEvent move3( + ui::ET_TOUCH_MOVED, gfx::Point(x, y), kTouchId, tes.Now()); + DispatchEventUsingWindowDispatcher(&move3); + delegate->ReceivedAckPreventDefaulted(); + EXPECT_FALSE(delegate->scroll_begin()); + EXPECT_FALSE(delegate->scroll_update()); + delegate->Reset(); + } +} + +TEST_P(GestureRecognizerTest, PinchAlternatelyConsumedTest) { + // Disabled for unified GR due to differences in when scroll update is + // sent. The Aura GR will never send a ScrollUpdate with a ScrollBegin, but + // the unified GR will. + if (UsingUnifiedGR()) + return; + + scoped_ptr<QueueTouchEventDelegate> delegate( + new QueueTouchEventDelegate(host()->dispatcher())); + TimedEvents tes; + const int kWindowWidth = 3000; + const int kWindowHeight = 3000; + const int kTouchId1 = 5; + const int kTouchId2 = 7; + gfx::Rect bounds(0, 0, kWindowWidth, kWindowHeight); + scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( + delegate.get(), -1234, bounds, root_window())); + + delegate->Reset(); + + ui::TouchEvent press1(ui::ET_TOUCH_PRESSED, gfx::Point(0, 0), + kTouchId1, tes.Now()); + DispatchEventUsingWindowDispatcher(&press1); + delegate->ReceivedAck(); + EXPECT_FALSE(delegate->scroll_begin()); + EXPECT_FALSE(delegate->scroll_update()); + delegate->Reset(); + + int x = 0; + int y = 0; + + ui::TouchEvent press2(ui::ET_TOUCH_PRESSED, gfx::Point(x, y), + kTouchId2, tes.Now()); + DispatchEventUsingWindowDispatcher(&press2); + delegate->ReceivedAck(); + EXPECT_FALSE(delegate->scroll_begin()); + EXPECT_FALSE(delegate->scroll_update()); + EXPECT_FALSE(delegate->pinch_begin()); + EXPECT_FALSE(delegate->pinch_update()); + + delegate->Reset(); + + x += 100; + y += 100; + ui::TouchEvent move1(ui::ET_TOUCH_MOVED, gfx::Point(x, y), + kTouchId2, tes.Now()); + DispatchEventUsingWindowDispatcher(&move1); + delegate->ReceivedAck(); + EXPECT_TRUE(delegate->scroll_begin()); + EXPECT_FALSE(delegate->scroll_update()); + EXPECT_TRUE(delegate->pinch_begin()); + EXPECT_FALSE(delegate->pinch_update()); + delegate->Reset(); + + const float expected_scales[] = {1.5f, 1.2f, 1.125f}; + + for (int i = 0; i < 3; ++i) { + x += 50; + y += 50; + ui::TouchEvent move2( + ui::ET_TOUCH_MOVED, gfx::Point(x, y), kTouchId2, tes.Now()); + DispatchEventUsingWindowDispatcher(&move2); + delegate->ReceivedAck(); + EXPECT_FALSE(delegate->scroll_begin()); + EXPECT_TRUE(delegate->scroll_update()); + EXPECT_FALSE(delegate->scroll_end()); + EXPECT_FALSE(delegate->pinch_begin()); + EXPECT_TRUE(delegate->pinch_update()); + EXPECT_FALSE(delegate->pinch_end()); + EXPECT_EQ(25, delegate->scroll_x()); + EXPECT_EQ(25, delegate->scroll_y()); + EXPECT_FLOAT_EQ(expected_scales[i], delegate->scale()); + delegate->Reset(); + + x += 100; + y += 100; + ui::TouchEvent move3( + ui::ET_TOUCH_MOVED, gfx::Point(x, y), kTouchId2, tes.Now()); + DispatchEventUsingWindowDispatcher(&move3); + delegate->ReceivedAckPreventDefaulted(); + EXPECT_FALSE(delegate->scroll_begin()); + EXPECT_FALSE(delegate->scroll_update()); + EXPECT_FALSE(delegate->scroll_end()); + EXPECT_FALSE(delegate->pinch_begin()); + EXPECT_FALSE(delegate->pinch_update()); + EXPECT_FALSE(delegate->pinch_end()); + delegate->Reset(); + } +} + +// Test that touch event flags are passed through to the gesture event. +TEST_P(GestureRecognizerTest, GestureEventFlagsPassedFromTouchEvent) { + scoped_ptr<GestureEventConsumeDelegate> delegate( + new GestureEventConsumeDelegate()); + TimedEvents tes; + const int kWindowWidth = 123; + const int kWindowHeight = 45; + const int kTouchId = 6; + gfx::Rect bounds(100, 200, kWindowWidth, kWindowHeight); + scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( + delegate.get(), -1234, bounds, root_window())); + + delegate->Reset(); + + ui::TouchEvent press1(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), + kTouchId, tes.Now()); + DispatchEventUsingWindowDispatcher(&press1); + EXPECT_TRUE(delegate->tap_down()); + + int default_flags = delegate->flags(); + + ui::TouchEvent move1( + ui::ET_TOUCH_MOVED, gfx::Point(397, 149), kTouchId, tes.LeapForward(50)); + move1.set_flags(992); + + DispatchEventUsingWindowDispatcher(&move1); + EXPECT_NE(default_flags, delegate->flags()); +} + +// Test that latency info is passed through to the gesture event. +TEST_P(GestureRecognizerTest, LatencyPassedFromTouchEvent) { + scoped_ptr<GestureEventConsumeDelegate> delegate( + new GestureEventConsumeDelegate()); + TimedEvents tes; + const int kWindowWidth = 123; + const int kWindowHeight = 45; + const int kTouchId = 6; + + const base::TimeTicks time_original = base::TimeTicks::FromInternalValue(100); + const base::TimeTicks time_ui = base::TimeTicks::FromInternalValue(200); + const base::TimeTicks time_acked = base::TimeTicks::FromInternalValue(300); + + gfx::Rect bounds(100, 200, kWindowWidth, kWindowHeight); + scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( + delegate.get(), -1234, bounds, root_window())); + + delegate->Reset(); + + ui::TouchEvent press1(ui::ET_TOUCH_PRESSED, gfx::Point(101, 201), + kTouchId, tes.Now()); + + // Ensure the only components around are the ones we add. + press1.latency()->Clear(); + + press1.latency()->AddLatencyNumberWithTimestamp( + ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, 0, 0, time_original, 1); + + press1.latency()->AddLatencyNumberWithTimestamp( + ui::INPUT_EVENT_LATENCY_UI_COMPONENT, 0, 0, time_ui, 1); + + press1.latency()->AddLatencyNumberWithTimestamp( + ui::INPUT_EVENT_LATENCY_ACKED_TOUCH_COMPONENT, 0, 0, time_acked, 1); + + DispatchEventUsingWindowDispatcher(&press1); + EXPECT_TRUE(delegate->tap_down()); + + ui::LatencyInfo::LatencyComponent component; + + EXPECT_EQ(3U, delegate->latency_info().latency_components.size()); + ASSERT_TRUE(delegate->latency_info().FindLatency( + ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, 0, &component)); + EXPECT_EQ(time_original, component.event_time); + + ASSERT_TRUE(delegate->latency_info().FindLatency( + ui::INPUT_EVENT_LATENCY_UI_COMPONENT, 0, &component)); + EXPECT_EQ(time_ui, component.event_time); + + ASSERT_TRUE(delegate->latency_info().FindLatency( + ui::INPUT_EVENT_LATENCY_ACKED_TOUCH_COMPONENT, 0, &component)); + EXPECT_EQ(time_acked, component.event_time); + + delegate->WaitUntilReceivedGesture(ui::ET_GESTURE_SHOW_PRESS); + EXPECT_TRUE(delegate->show_press()); + EXPECT_EQ(0U, delegate->latency_info().latency_components.size()); +} + +// A delegate that deletes a window on long press. +class GestureEventDeleteWindowOnLongPress : public GestureEventConsumeDelegate { + public: + GestureEventDeleteWindowOnLongPress() + : window_(NULL) {} + + void set_window(aura::Window** window) { window_ = window; } + + virtual void OnGestureEvent(ui::GestureEvent* gesture) OVERRIDE { + GestureEventConsumeDelegate::OnGestureEvent(gesture); + if (gesture->type() != ui::ET_GESTURE_LONG_PRESS) + return; + ui::GestureRecognizer::Get()->CleanupStateForConsumer(*window_); + delete *window_; + *window_ = NULL; + } + + private: + aura::Window** window_; + DISALLOW_COPY_AND_ASSIGN(GestureEventDeleteWindowOnLongPress); +}; + +// Check that deleting the window in response to a long press gesture doesn't +// crash. +TEST_P(GestureRecognizerTest, GestureEventLongPressDeletingWindow) { + GestureEventDeleteWindowOnLongPress delegate; + const int kWindowWidth = 123; + const int kWindowHeight = 45; + const int kTouchId = 2; + gfx::Rect bounds(100, 200, kWindowWidth, kWindowHeight); + aura::Window* window(CreateTestWindowWithDelegate( + &delegate, -1234, bounds, root_window())); + delegate.set_window(&window); + + ui::TouchEvent press1(ui::ET_TOUCH_PRESSED, + gfx::Point(101, 201), + kTouchId, + ui::EventTimeForNow()); + DispatchEventUsingWindowDispatcher(&press1); + EXPECT_TRUE(window != NULL); + + // Wait until the timer runs out. + delegate.WaitUntilReceivedGesture(ui::ET_GESTURE_LONG_PRESS); + EXPECT_EQ(NULL, window); +} + +INSTANTIATE_TEST_CASE_P(GestureRecognizer, + GestureRecognizerTest, + ::testing::Bool()); + } // namespace test } // namespace aura |