Index: ui/aura/gestures/gesture_recognizer_unittest.cc |
diff --git a/ui/aura/gestures/gesture_recognizer_unittest.cc b/ui/aura/gestures/gesture_recognizer_unittest.cc |
index f7d1a4288ad95666b1c97a77ceca15628cfbacc3..64f9a927ca14cbc7f12ec96804d9120550d5d298 100644 |
--- a/ui/aura/gestures/gesture_recognizer_unittest.cc |
+++ b/ui/aura/gestures/gesture_recognizer_unittest.cc |
@@ -337,7 +337,8 @@ class QueueTouchEventDelegate : public GestureEventConsumeDelegate { |
explicit QueueTouchEventDelegate(WindowEventDispatcher* dispatcher) |
: window_(NULL), |
dispatcher_(dispatcher), |
- queue_events_(true) { |
+ queue_events_(true), |
+ treat_next_event_as_invalid_(false) { |
} |
~QueueTouchEventDelegate() override { |
while(!queue_.empty()) { |
@@ -347,9 +348,13 @@ class QueueTouchEventDelegate : public GestureEventConsumeDelegate { |
} |
void OnTouchEvent(ui::TouchEvent* event) override { |
+ event->DisableSynchronousHandling(); |
+ if (treat_next_event_as_invalid_) { |
+ treat_next_event_as_invalid_ = false; |
+ dispatcher_->IgnoreLastTouchEvent(window_); |
+ } |
if (queue_events_) { |
queue_.push(new ui::TouchEvent(*event, window_, window_)); |
- event->StopPropagation(); |
} |
} |
@@ -363,6 +368,9 @@ class QueueTouchEventDelegate : public GestureEventConsumeDelegate { |
void set_window(Window* w) { window_ = w; } |
void set_queue_events(bool queue) { queue_events_ = queue; } |
+ void treat_next_event_as_invalid() { |
+ treat_next_event_as_invalid_ = true; |
+ } |
private: |
void ReceivedAckImpl(bool prevent_defaulted) { |
@@ -376,6 +384,7 @@ class QueueTouchEventDelegate : public GestureEventConsumeDelegate { |
Window* window_; |
WindowEventDispatcher* dispatcher_; |
bool queue_events_; |
+ bool treat_next_event_as_invalid_; |
DISALLOW_COPY_AND_ASSIGN(QueueTouchEventDelegate); |
}; |
@@ -4247,7 +4256,7 @@ TEST_F(GestureRecognizerTest, GestureEventSmallPinchEnabled) { |
// Tests that delaying the ack of a touch release doesn't trigger a long press |
// gesture. |
-TEST_F(GestureRecognizerTest, DISABLED_EagerGestureDetection) { |
+TEST_F(GestureRecognizerTest, EagerGestureDetection) { |
scoped_ptr<QueueTouchEventDelegate> delegate( |
new QueueTouchEventDelegate(host()->dispatcher())); |
TimedEvents tes; |
@@ -4280,9 +4289,9 @@ TEST_F(GestureRecognizerTest, DISABLED_EagerGestureDetection) { |
EXPECT_FALSE(delegate->long_press()); |
} |
-// This tests crbug.com/405519, in which events which the gesture detector |
-// ignores cause future events to also be thrown away. |
-TEST_F(GestureRecognizerTest, IgnoredEventsDontPreventFutureEvents) { |
+// This tests crbug.com/405519, in which touch events which the gesture detector |
+// ignores interfere with gesture recognition. |
+TEST_F(GestureRecognizerTest, IgnoredEventsDontBreakGestureRecognition) { |
scoped_ptr<QueueTouchEventDelegate> delegate( |
new QueueTouchEventDelegate(host()->dispatcher())); |
TimedEvents tes; |
@@ -4315,9 +4324,12 @@ TEST_F(GestureRecognizerTest, IgnoredEventsDontPreventFutureEvents) { |
ui::ET_GESTURE_SCROLL_UPDATE); |
delegate->Reset(); |
+ |
+ // Send a valid event, but don't ack it. |
ui::TouchEvent move2( |
ui::ET_TOUCH_MOVED, gfx::Point(65, 202), kTouchId1, tes.Now()); |
DispatchEventUsingWindowDispatcher(&move2); |
+ EXPECT_0_EVENTS(delegate->events()); |
// Send a touchmove event at the same location as the previous touchmove |
// event. This shouldn't do anything. |
@@ -4325,7 +4337,67 @@ TEST_F(GestureRecognizerTest, IgnoredEventsDontPreventFutureEvents) { |
ui::ET_TOUCH_MOVED, gfx::Point(65, 202), kTouchId1, tes.Now()); |
DispatchEventUsingWindowDispatcher(&move3); |
+ // Ack the previous valid event. The intermediary invalid event shouldn't |
+ // interfere. |
+ delegate->ReceivedAck(); |
+ EXPECT_1_EVENT(delegate->events(), ui::ET_GESTURE_SCROLL_UPDATE); |
+} |
+ |
+// Tests that an event found invalid after gesture recognition has |
+// taken place can't cause out of order acks. |
+TEST_F(GestureRecognizerTest, IgnoredEventsAfterGRDontCauseOutOfOrderAcks) { |
+ scoped_ptr<QueueTouchEventDelegate> delegate( |
+ new QueueTouchEventDelegate(host()->dispatcher())); |
+ TimedEvents tes; |
+ const int kWindowWidth = 300; |
+ const int kWindowHeight = 400; |
+ const int kTouchId1 = 3; |
+ gfx::Rect bounds(0, 0, kWindowWidth, kWindowHeight); |
+ scoped_ptr<aura::Window> window(CreateTestWindowWithDelegate( |
+ delegate.get(), -1234, bounds, root_window())); |
+ delegate->set_window(window.get()); |
+ |
+ // Start a scroll gesture. |
+ 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(100, 100), kTouchId1, tes.Now()); |
+ DispatchEventUsingWindowDispatcher(&move1); |
+ delegate->ReceivedAck(); |
+ |
+ delegate->Reset(); |
+ // Dispatch an invalid touch move, which should be ignored. |
+ delegate->treat_next_event_as_invalid(); |
+ ui::TouchEvent move2(ui::ET_TOUCH_MOVED, gfx::Point(200, 200), kTouchId1, |
+ tes.Now()); |
+ DispatchEventUsingWindowDispatcher(&move2); |
+ EXPECT_0_EVENTS(delegate->events()); |
+ |
+ // Dispatch a valid touch move, but don't ack it. |
+ ui::TouchEvent move3(ui::ET_TOUCH_MOVED, gfx::Point(300, 300), kTouchId1, |
+ tes.Now()); |
+ DispatchEventUsingWindowDispatcher(&move3); |
+ |
+ // Dispatch two invalid touch moves, which should be ignored. |
+ delegate->treat_next_event_as_invalid(); |
+ ui::TouchEvent move4( |
+ ui::ET_TOUCH_MOVED, gfx::Point(400, 400), kTouchId1, tes.Now()); |
+ DispatchEventUsingWindowDispatcher(&move4); |
+ |
+ delegate->treat_next_event_as_invalid(); |
+ ui::TouchEvent move5( |
+ ui::ET_TOUCH_MOVED, gfx::Point(500, 500), kTouchId1, tes.Now()); |
+ DispatchEventUsingWindowDispatcher(&move5); |
+ |
+ EXPECT_0_EVENTS(delegate->events()); |
+ EXPECT_EQ(100, delegate->bounding_box().x()); |
+ // Ack the valid touch, and ensure the most recent gesture event |
+ // used its co-ordinates. |
delegate->ReceivedAck(); |
+ EXPECT_EQ(300, delegate->bounding_box().x()); |
EXPECT_1_EVENT(delegate->events(), ui::ET_GESTURE_SCROLL_UPDATE); |
} |