diff options
11 files changed, 152 insertions, 281 deletions
diff --git a/content/browser/renderer_host/input/gesture_event_queue.cc b/content/browser/renderer_host/input/gesture_event_queue.cc index b9cabbb..f4c0c8e 100644 --- a/content/browser/renderer_host/input/gesture_event_queue.cc +++ b/content/browser/renderer_host/input/gesture_event_queue.cc @@ -133,16 +133,17 @@ bool GestureEventQueue::ShouldForwardForTapSuppression( touchpad_tap_suppression_controller_->GestureFlingCancel(); return true; case WebInputEvent::GestureTapDown: + return !touchscreen_tap_suppression_controller_-> + ShouldDeferGestureTapDown(gesture_event); case WebInputEvent::GestureShowPress: - case WebInputEvent::GestureTapUnconfirmed: + return !touchscreen_tap_suppression_controller_-> + ShouldDeferGestureShowPress(gesture_event); case WebInputEvent::GestureTapCancel: case WebInputEvent::GestureTap: + case WebInputEvent::GestureTapUnconfirmed: case WebInputEvent::GestureDoubleTap: - if (gesture_event.event.sourceDevice == WebGestureEvent::Touchscreen) { - return !touchscreen_tap_suppression_controller_-> - FilterTapEvent(gesture_event); - } - return true; + return !touchscreen_tap_suppression_controller_-> + ShouldSuppressGestureTapEnd(); default: return true; } diff --git a/content/browser/renderer_host/input/touchscreen_tap_suppression_controller.cc b/content/browser/renderer_host/input/touchscreen_tap_suppression_controller.cc index 7f024b3..b05407b 100644 --- a/content/browser/renderer_host/input/touchscreen_tap_suppression_controller.cc +++ b/content/browser/renderer_host/input/touchscreen_tap_suppression_controller.cc @@ -12,8 +12,6 @@ #include "ui/gfx/android/view_configuration.h" #endif -using blink::WebInputEvent; - namespace content { TouchscreenTapSuppressionController::TouchscreenTapSuppressionController( @@ -33,33 +31,25 @@ void TouchscreenTapSuppressionController::GestureFlingCancelAck( controller_->GestureFlingCancelAck(processed); } -bool TouchscreenTapSuppressionController::FilterTapEvent( +bool TouchscreenTapSuppressionController::ShouldDeferGestureTapDown( + const GestureEventWithLatencyInfo& event) { + bool should_defer = controller_->ShouldDeferTapDown(); + if (should_defer) + stashed_tap_down_.reset(new GestureEventWithLatencyInfo(event)); + return should_defer; +} + +bool TouchscreenTapSuppressionController::ShouldDeferGestureShowPress( const GestureEventWithLatencyInfo& event) { - switch (event.event.type) { - case WebInputEvent::GestureTapDown: - if (!controller_->ShouldDeferTapDown()) - return false; - stashed_tap_down_.reset(new GestureEventWithLatencyInfo(event)); - return true; - - case WebInputEvent::GestureShowPress: - if (!stashed_tap_down_) - return false; - stashed_show_press_.reset(new GestureEventWithLatencyInfo(event)); - return true; - - case WebInputEvent::GestureTapUnconfirmed: - return stashed_tap_down_; - - case WebInputEvent::GestureTapCancel: - case WebInputEvent::GestureTap: - case WebInputEvent::GestureDoubleTap: - return controller_->ShouldSuppressTapEnd(); - - default: - break; - } - return false; + if (!stashed_tap_down_) + return false; + + stashed_show_press_.reset(new GestureEventWithLatencyInfo(event)); + return true; +} + +bool TouchscreenTapSuppressionController::ShouldSuppressGestureTapEnd() { + return controller_->ShouldSuppressTapEnd(); } #if defined(OS_ANDROID) diff --git a/content/browser/renderer_host/input/touchscreen_tap_suppression_controller.h b/content/browser/renderer_host/input/touchscreen_tap_suppression_controller.h index 02b5b06..ad376a6 100644 --- a/content/browser/renderer_host/input/touchscreen_tap_suppression_controller.h +++ b/content/browser/renderer_host/input/touchscreen_tap_suppression_controller.h @@ -29,9 +29,17 @@ class TouchscreenTapSuppressionController // |processed| is true if the GestureFlingCancel successfully stopped a fling. void GestureFlingCancelAck(bool processed); - // Should be called on arrival of any tap-related events. Returns true if the - // caller should stop normal handling of the gesture. - bool FilterTapEvent(const GestureEventWithLatencyInfo& event); + // Should be called on arrival of GestureTapDown events. Returns true if the + // caller should stop normal handling of the GestureTapDown. + bool ShouldDeferGestureTapDown(const GestureEventWithLatencyInfo& event); + + // Should be called on arrival of GestureShowPress events. Returns true if the + // caller should stop normal handling of the GestureShowPress. + bool ShouldDeferGestureShowPress(const GestureEventWithLatencyInfo& event); + + // Should be called on arrival of tap-ending gesture events. Returns true if + // the caller should stop normal handling of the GestureTap. + bool ShouldSuppressGestureTapEnd(); private: // TapSuppressionControllerClient implementation. diff --git a/ui/events/gesture_detection/gesture_event_data_packet.h b/ui/events/gesture_detection/gesture_event_data_packet.h index 877f446..4d83f21 100644 --- a/ui/events/gesture_detection/gesture_event_data_packet.h +++ b/ui/events/gesture_detection/gesture_event_data_packet.h @@ -20,7 +20,7 @@ class GESTURE_DETECTION_EXPORT GestureEventDataPacket { UNDEFINED = -1, // Used only for a default-constructed packet. INVALID, // The source of the gesture was invalid. TOUCH_SEQUENCE_START, // The start of a new gesture sequence. - TOUCH_SEQUENCE_END, // The end of a gesture sequence. + TOUCH_SEQUENCE_END, // The end of gesture sequence. TOUCH_START, // A touch down occured during a gesture sequence. TOUCH_MOVE, // A touch move occured during a gesture sequence. TOUCH_END, // A touch up occured during a gesture sequence. diff --git a/ui/events/gesture_detection/gesture_provider.cc b/ui/events/gesture_detection/gesture_provider.cc index c96a30a..6c581fe 100644 --- a/ui/events/gesture_detection/gesture_provider.cc +++ b/ui/events/gesture_detection/gesture_provider.cc @@ -361,6 +361,7 @@ class GestureProvider::GestureListenerImpl virtual bool OnSingleTapUp(const MotionEvent& e) OVERRIDE { if (IsPointOutsideCurrentSlopRegion(e.GetRawX(), e.GetRawY())) { + provider_->SendTapCancelIfNecessary(e); ignore_single_tap_ = true; return true; } @@ -527,6 +528,8 @@ class GestureProvider::GestureListenerImpl GestureProvider::GestureProvider(const Config& config, GestureProviderClient* client) : client_(client), + needs_show_press_event_(false), + needs_tap_ending_event_(false), touch_scroll_in_progress_(false), pinch_in_progress_(false), double_tap_support_for_page_(true), @@ -651,29 +654,49 @@ void GestureProvider::Send(const GestureEventData& gesture) { gesture.type == ET_GESTURE_SHOW_PRESS); switch (gesture.type) { + case ET_GESTURE_TAP_DOWN: + needs_tap_ending_event_ = true; + needs_show_press_event_ = true; + break; + case ET_GESTURE_TAP_UNCONFIRMED: + needs_show_press_event_ = false; + break; + case ET_GESTURE_TAP: + if (needs_show_press_event_) + Send(CreateGesture(ET_GESTURE_SHOW_PRESS, + gesture.motion_event_id, + gesture.time, + gesture.x, + gesture.y)); + needs_tap_ending_event_ = false; + break; + case ET_GESTURE_DOUBLE_TAP: + needs_tap_ending_event_ = false; + break; + case ET_GESTURE_TAP_CANCEL: + if (!needs_tap_ending_event_) + return; + needs_tap_ending_event_ = false; + break; + case ET_GESTURE_SHOW_PRESS: + needs_show_press_event_ = false; + break; case ET_GESTURE_LONG_PRESS: DCHECK(!scale_gesture_listener_->IsScaleGestureDetectionInProgress()); current_longpress_time_ = gesture.time; break; case ET_GESTURE_LONG_TAP: + needs_tap_ending_event_ = false; current_longpress_time_ = base::TimeTicks(); break; case ET_GESTURE_SCROLL_BEGIN: - DCHECK(!touch_scroll_in_progress_); touch_scroll_in_progress_ = true; + SendTapCancelIfNecessary(gesture); break; case ET_GESTURE_SCROLL_END: - DCHECK(touch_scroll_in_progress_); - if (pinch_in_progress_) - Send(CreateGesture(ET_GESTURE_PINCH_END, - gesture.motion_event_id, - gesture.time, - gesture.x, - gesture.y)); touch_scroll_in_progress_ = false; break; case ET_GESTURE_PINCH_BEGIN: - DCHECK(!pinch_in_progress_); if (!touch_scroll_in_progress_) Send(CreateGesture(ET_GESTURE_SCROLL_BEGIN, gesture.motion_event_id, @@ -683,15 +706,8 @@ void GestureProvider::Send(const GestureEventData& gesture) { pinch_in_progress_ = true; break; case ET_GESTURE_PINCH_END: - DCHECK(pinch_in_progress_); pinch_in_progress_ = false; break; - case ET_GESTURE_SHOW_PRESS: - // It's possible that a double-tap drag zoom (from ScaleGestureDetector) - // will start before the press gesture fires (from GestureDetector), in - // which case the press should simply be dropped. - if (pinch_in_progress_ || touch_scroll_in_progress_) - return; default: break; }; @@ -699,10 +715,30 @@ void GestureProvider::Send(const GestureEventData& gesture) { client_->OnGestureEvent(gesture); } +void GestureProvider::SendTapCancelIfNecessary(const MotionEvent& event) { + if (!needs_tap_ending_event_) + return; + current_longpress_time_ = base::TimeTicks(); + Send(CreateGesture(ET_GESTURE_TAP_CANCEL, event)); +} + +void GestureProvider::SendTapCancelIfNecessary( + const GestureEventData& gesture) { + if (!needs_tap_ending_event_) + return; + current_longpress_time_ = base::TimeTicks(); + Send(CreateGesture(ET_GESTURE_TAP_CANCEL, + gesture.motion_event_id, + gesture.time, + gesture.x, + gesture.y)); +} + bool GestureProvider::SendLongTapIfNecessary(const MotionEvent& event) { if (event.GetAction() == MotionEvent::ACTION_UP && !current_longpress_time_.is_null() && !scale_gesture_listener_->IsScaleGestureDetectionInProgress()) { + SendTapCancelIfNecessary(event); GestureEventDetails long_tap_details(ET_GESTURE_LONG_TAP, 0, 0); long_tap_details.set_bounding_box( gfx::RectF(event.GetTouchMajor(), event.GetTouchMajor())); @@ -716,13 +752,13 @@ void GestureProvider::EndTouchScrollIfNecessary(const MotionEvent& event, bool send_scroll_end_event) { if (!touch_scroll_in_progress_) return; + touch_scroll_in_progress_ = false; if (send_scroll_end_event) Send(CreateGesture(ET_GESTURE_SCROLL_END, event)); - touch_scroll_in_progress_ = false; } void GestureProvider::UpdateDoubleTapDetectionSupport() { - if (current_down_event_ || IsDoubleTapInProgress()) + if (IsDoubleTapInProgress()) return; const bool supports_double_tap = IsDoubleTapSupported(); @@ -735,8 +771,9 @@ void GestureProvider::OnTouchEventHandlingBegin(const MotionEvent& event) { case MotionEvent::ACTION_DOWN: current_down_event_ = event.Clone(); touch_scroll_in_progress_ = false; - pinch_in_progress_ = false; + needs_show_press_event_ = false; current_longpress_time_ = base::TimeTicks(); + SendTapCancelIfNecessary(event); if (gesture_begin_end_types_enabled_) Send(CreateGesture(ET_GESTURE_BEGIN, event)); break; @@ -760,12 +797,17 @@ void GestureProvider::OnTouchEventHandlingEnd(const MotionEvent& event) { // |Fling()| will have already signalled an end to touch-scrolling. EndTouchScrollIfNecessary(event, true); + // We shouldn't necessarily cancel a tap on ACTION_UP, as the double-tap + // timeout may yet trigger a SINGLE_TAP. + if (event.GetAction() == MotionEvent::ACTION_CANCEL) + SendTapCancelIfNecessary(event); + + UpdateDoubleTapDetectionSupport(); + if (gesture_begin_end_types_enabled_) Send(CreateGesture(ET_GESTURE_END, event)); current_down_event_.reset(); - - UpdateDoubleTapDetectionSupport(); break; case MotionEvent::ACTION_POINTER_UP: if (gesture_begin_end_types_enabled_) diff --git a/ui/events/gesture_detection/gesture_provider.h b/ui/events/gesture_detection/gesture_provider.h index b8e85b7..10f2cb1 100644 --- a/ui/events/gesture_detection/gesture_provider.h +++ b/ui/events/gesture_detection/gesture_provider.h @@ -100,6 +100,8 @@ class GESTURE_DETECTION_EXPORT GestureProvider { void Fling(const MotionEvent& e, float velocity_x, float velocity_y); void Send(const GestureEventData& gesture); + void SendTapCancelIfNecessary(const MotionEvent& event); + void SendTapCancelIfNecessary(const GestureEventData& event); bool SendLongTapIfNecessary(const MotionEvent& event); void EndTouchScrollIfNecessary(const MotionEvent& event, bool send_scroll_end_event); @@ -119,6 +121,15 @@ class GESTURE_DETECTION_EXPORT GestureProvider { scoped_ptr<MotionEvent> current_down_event_; + // Whether a GESTURE_SHOW_PRESS was sent for the current touch sequence. + // Sending a GESTURE_TAP event will forward a GESTURE_SHOW_PRESS if one has + // not yet been sent. + bool needs_show_press_event_; + + // Whether a sent GESTURE_TAP_DOWN event has yet to be accompanied by a + // corresponding GESTURE_TAP, GESTURE_TAP_CANCEL or GESTURE_DOUBLE_TAP. + bool needs_tap_ending_event_; + // Whether the respective {SCROLL,PINCH}_BEGIN gestures have been terminated // with a {SCROLL,PINCH}_END. bool touch_scroll_in_progress_; diff --git a/ui/events/gesture_detection/gesture_provider_unittest.cc b/ui/events/gesture_detection/gesture_provider_unittest.cc index 0392acc..6ec8a5b 100644 --- a/ui/events/gesture_detection/gesture_provider_unittest.cc +++ b/ui/events/gesture_detection/gesture_provider_unittest.cc @@ -150,8 +150,6 @@ class GestureProviderTest : public testing::Test, public GestureProviderClient { gesture_provider_->SetMultiTouchSupportEnabled(false); } - bool HasDownEvent() const { return gesture_provider_->current_down_event(); } - protected: void CheckScrollEventSequenceForEndActionType( MotionEvent::Action end_action_type) { @@ -177,13 +175,15 @@ class GestureProviderTest : public testing::Test, public GestureProviderClient { EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN)); EXPECT_EQ(motion_event_id, GetMostRecentGestureEvent().motion_event_id); EXPECT_EQ(ET_GESTURE_SCROLL_UPDATE, GetMostRecentGestureEventType()); - ASSERT_EQ(3U, GetReceivedGestureCount()) << "Only TapDown, " + ASSERT_EQ(4U, GetReceivedGestureCount()) << "Only TapDown, TapCancel, " "ScrollBegin and ScrollBy " "should have been sent"; - EXPECT_EQ(ET_GESTURE_SCROLL_BEGIN, GetReceivedGesture(1).type); + EXPECT_EQ(ET_GESTURE_TAP_CANCEL, GetReceivedGesture(1).type); EXPECT_EQ(motion_event_id, GetReceivedGesture(1).motion_event_id); - EXPECT_EQ(event_time + kOneSecond, GetReceivedGesture(1).time) + EXPECT_EQ(ET_GESTURE_SCROLL_BEGIN, GetReceivedGesture(2).type); + EXPECT_EQ(motion_event_id, GetReceivedGesture(2).motion_event_id); + EXPECT_EQ(event_time + kOneSecond, GetReceivedGesture(2).time) << "ScrollBegin should have the time of the ACTION_MOVE"; event = ObtainMotionEvent( @@ -342,14 +342,14 @@ TEST_F(GestureProviderTest, FlingEventSequence) { EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN)); EXPECT_EQ(ET_GESTURE_SCROLL_UPDATE, GetMostRecentGestureEventType()); EXPECT_EQ(motion_event_id, GetMostRecentGestureEvent().motion_event_id); - ASSERT_EQ(3U, GetReceivedGestureCount()); - ASSERT_EQ(ET_GESTURE_SCROLL_BEGIN, GetReceivedGesture(1).type); - EXPECT_EQ(motion_event_id, GetReceivedGesture(1).motion_event_id); + ASSERT_EQ(4U, GetReceivedGestureCount()); + ASSERT_EQ(ET_GESTURE_SCROLL_BEGIN, GetReceivedGesture(2).type); + EXPECT_EQ(motion_event_id, GetReceivedGesture(2).motion_event_id); // We don't want to take a dependency here on exactly how hints are calculated // for a fling (eg. may depend on velocity), so just validate the direction. - int hint_x = GetReceivedGesture(1).details.scroll_x_hint(); - int hint_y = GetReceivedGesture(1).details.scroll_y_hint(); + int hint_x = GetReceivedGesture(2).details.scroll_x_hint(); + int hint_y = GetReceivedGesture(2).details.scroll_y_hint(); EXPECT_TRUE(hint_x > 0 && hint_y > 0 && hint_x > hint_y) << "ScrollBegin hint should be in positive X axis"; @@ -368,7 +368,7 @@ TEST_F(GestureProviderTest, FlingEventSequence) { << "FlingStart should have the time of the ACTION_UP"; } -TEST_F(GestureProviderTest, GestureCancelledWhenWindowFocusLost) { +TEST_F(GestureProviderTest, TapCancelledWhenWindowFocusLost) { const base::TimeTicks event_time = TimeTicks::Now(); MockMotionEvent event = @@ -381,17 +381,12 @@ TEST_F(GestureProviderTest, GestureCancelledWhenWindowFocusLost) { EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SHOW_PRESS)); EXPECT_EQ(ET_GESTURE_LONG_PRESS, GetMostRecentGestureEventType()); - // The long press triggers window focus loss by opening a context menu. + // The long press triggers window focus loss by opening a context menu EXPECT_TRUE(CancelActiveTouchSequence()); - EXPECT_FALSE(HasDownEvent()); - - // A final ACTION_UP should have no effect. - event = ObtainMotionEvent(event_time + kOneMicrosecond * 2, - MotionEvent::ACTION_UP); - EXPECT_FALSE(gesture_provider_->OnTouchEvent(event)); + EXPECT_EQ(ET_GESTURE_TAP_CANCEL, GetMostRecentGestureEventType()); } -TEST_F(GestureProviderTest, NoTapAfterScrollBegins) { +TEST_F(GestureProviderTest, TapCancelledWhenScrollBegins) { base::TimeTicks event_time = base::TimeTicks::Now(); MockMotionEvent event = @@ -405,15 +400,9 @@ TEST_F(GestureProviderTest, NoTapAfterScrollBegins) { kFakeCoordX + 50, kFakeCoordY + 50); EXPECT_TRUE(gesture_provider_->OnTouchEvent(event)); - EXPECT_EQ(ET_GESTURE_SCROLL_UPDATE, GetMostRecentGestureEventType()); - event = ObtainMotionEvent(event_time + kOneSecond, - MotionEvent::ACTION_UP, - kFakeCoordX + 50, - kFakeCoordY + 50); - EXPECT_TRUE(gesture_provider_->OnTouchEvent(event)); - EXPECT_EQ(ET_GESTURE_SCROLL_END, GetMostRecentGestureEventType()); - EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_LONG_TAP)); + EXPECT_EQ(ET_GESTURE_SCROLL_UPDATE, GetMostRecentGestureEventType()); + EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_TAP_CANCEL)); } TEST_F(GestureProviderTest, DoubleTap) { @@ -704,6 +693,7 @@ TEST_F(GestureProviderTest, GestureLongPressDoesNotPreventScrolling) { EXPECT_EQ(ET_GESTURE_SCROLL_UPDATE, GetMostRecentGestureEventType()); EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN)); + EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_TAP_CANCEL)); event = ObtainMotionEvent(event_time + long_press_timeout, MotionEvent::ACTION_UP); @@ -920,9 +910,6 @@ TEST_F(GestureProviderTest, FixedPageScaleDuringDoubleTapDragZoom) { base::TimeTicks down_time_1 = TimeTicks::Now(); base::TimeTicks down_time_2 = down_time_1 + kOneMicrosecond * 2; - gesture_provider_->SetDoubleTapSupportForPageEnabled(true); - gesture_provider_->SetDoubleTapSupportForPlatformEnabled(true); - // Start a double-tap drag gesture. MockMotionEvent event = ObtainMotionEvent(down_time_1, MotionEvent::ACTION_DOWN); @@ -1011,8 +998,6 @@ TEST_F(GestureProviderTest, PinchZoom) { const int scaled_touch_slop = GetTouchSlop(); int motion_event_id = 0; - gesture_provider_->SetDoubleTapSupportForPageEnabled(false); - gesture_provider_->SetDoubleTapSupportForPlatformEnabled(true); gesture_provider_->SetMultiTouchSupportEnabled(true); int secondary_coord_x = kFakeCoordX + 20 * scaled_touch_slop; @@ -1024,9 +1009,6 @@ TEST_F(GestureProviderTest, PinchZoom) { EXPECT_TRUE(gesture_provider_->OnTouchEvent(event)); EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType()); - // Toggling double-tap support should not take effect until the next sequence. - gesture_provider_->SetDoubleTapSupportForPageEnabled(true); - event = ObtainMotionEvent(event_time, MotionEvent::ACTION_POINTER_DOWN, kFakeCoordX, @@ -1048,9 +1030,6 @@ TEST_F(GestureProviderTest, PinchZoom) { secondary_coord_y); event.SetId(++motion_event_id); - // Toggling double-tap support should not take effect until the next sequence. - gesture_provider_->SetDoubleTapSupportForPageEnabled(false); - EXPECT_TRUE(gesture_provider_->OnTouchEvent(event)); EXPECT_EQ(motion_event_id, GetMostRecentGestureEvent().motion_event_id); EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_PINCH_BEGIN)); @@ -1067,9 +1046,6 @@ TEST_F(GestureProviderTest, PinchZoom) { secondary_coord_y); event.SetId(++motion_event_id); - // Toggling double-tap support should not take effect until the next sequence. - gesture_provider_->SetDoubleTapSupportForPageEnabled(true); - EXPECT_TRUE(gesture_provider_->OnTouchEvent(event)); EXPECT_EQ(motion_event_id, GetMostRecentGestureEvent().motion_event_id); EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_UPDATE)); @@ -1109,7 +1085,7 @@ TEST_F(GestureProviderTest, GesturesCancelledAfterLongPressCausesLostFocus) { EXPECT_EQ(ET_GESTURE_LONG_PRESS, GetMostRecentGestureEventType()); EXPECT_TRUE(CancelActiveTouchSequence()); - EXPECT_FALSE(HasDownEvent()); + EXPECT_EQ(ET_GESTURE_TAP_CANCEL, GetMostRecentGestureEventType()); event = ObtainMotionEvent(event_time + long_press_timeout, MotionEvent::ACTION_UP); @@ -1134,7 +1110,7 @@ TEST_F(GestureProviderTest, CancelActiveTouchSequence) { EXPECT_EQ(motion_event_id, GetMostRecentGestureEvent().motion_event_id); ASSERT_TRUE(CancelActiveTouchSequence()); - EXPECT_FALSE(HasDownEvent()); + EXPECT_EQ(ET_GESTURE_TAP_CANCEL, GetMostRecentGestureEventType()); EXPECT_EQ(motion_event_id, GetMostRecentGestureEvent().motion_event_id); // Subsequent MotionEvent's are dropped until ACTION_DOWN. @@ -1152,60 +1128,6 @@ TEST_F(GestureProviderTest, CancelActiveTouchSequence) { EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType()); } -TEST_F(GestureProviderTest, DoubleTapDragZoomCancelledOnSecondaryPointerDown) { - const base::TimeTicks down_time_1 = TimeTicks::Now(); - const base::TimeTicks down_time_2 = down_time_1 + kOneMicrosecond * 2; - - gesture_provider_->SetDoubleTapSupportForPlatformEnabled(true); - - MockMotionEvent event = - ObtainMotionEvent(down_time_1, MotionEvent::ACTION_DOWN); - EXPECT_TRUE(gesture_provider_->OnTouchEvent(event)); - EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType()); - - event = - ObtainMotionEvent(down_time_1 + kOneMicrosecond, MotionEvent::ACTION_UP); - gesture_provider_->OnTouchEvent(event); - EXPECT_EQ(ET_GESTURE_TAP_UNCONFIRMED, GetMostRecentGestureEventType()); - - event = ObtainMotionEvent(down_time_2, MotionEvent::ACTION_DOWN); - EXPECT_TRUE(gesture_provider_->OnTouchEvent(event)); - EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType()); - - event = ObtainMotionEvent(down_time_2 + kOneMicrosecond, - MotionEvent::ACTION_MOVE, - kFakeCoordX, - kFakeCoordY - 30); - EXPECT_TRUE(gesture_provider_->OnTouchEvent(event)); - EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN)); - EXPECT_EQ(ET_GESTURE_PINCH_BEGIN, GetMostRecentGestureEventType()); - - event = ObtainMotionEvent(down_time_2 + kOneMicrosecond * 2, - MotionEvent::ACTION_POINTER_DOWN, - kFakeCoordX, - kFakeCoordY - 30, - kFakeCoordX + 50, - kFakeCoordY + 50); - EXPECT_TRUE(gesture_provider_->OnTouchEvent(event)); - EXPECT_EQ(ET_GESTURE_PINCH_END, GetMostRecentGestureEventType()); - - const size_t gesture_count = GetReceivedGestureCount(); - event = ObtainMotionEvent(down_time_2 + kOneMicrosecond * 3, - MotionEvent::ACTION_POINTER_UP, - kFakeCoordX, - kFakeCoordY - 30, - kFakeCoordX + 50, - kFakeCoordY + 50); - EXPECT_TRUE(gesture_provider_->OnTouchEvent(event)); - EXPECT_EQ(gesture_count, GetReceivedGestureCount()); - - event = ObtainMotionEvent(down_time_2 + kOneSecond, - MotionEvent::ACTION_UP); - EXPECT_TRUE(gesture_provider_->OnTouchEvent(event)); - EXPECT_EQ(gesture_count + 1, GetReceivedGestureCount()); - EXPECT_EQ(ET_GESTURE_SCROLL_END, GetMostRecentGestureEventType()); -} - // Verify that gesture begin and gesture end events are dispatched correctly. TEST_F(GestureProviderTest, GestureBeginAndEnd) { SetBeginEndTypesEnabled(true); @@ -1256,14 +1178,16 @@ TEST_F(GestureProviderTest, GestureBeginAndEnd) { event = ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN); EXPECT_TRUE(gesture_provider_->OnTouchEvent(event)); - EXPECT_EQ(ET_GESTURE_BEGIN, GetReceivedGesture(9).type); + EXPECT_EQ(ET_GESTURE_TAP_CANCEL, GetReceivedGesture(9).type); + EXPECT_EQ(ET_GESTURE_BEGIN, GetReceivedGesture(10).type); EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType()); - EXPECT_EQ(11U, GetReceivedGestureCount()); + EXPECT_EQ(12U, GetReceivedGestureCount()); event = ObtainMotionEvent(event_time, MotionEvent::ACTION_CANCEL); EXPECT_TRUE(gesture_provider_->OnTouchEvent(event)); + EXPECT_EQ(ET_GESTURE_TAP_CANCEL, GetReceivedGesture(12).type); EXPECT_EQ(ET_GESTURE_END, GetMostRecentGestureEventType()); - EXPECT_EQ(12U, GetReceivedGestureCount()); + EXPECT_EQ(14U, GetReceivedGestureCount()); } diff --git a/ui/events/gesture_detection/scale_gesture_detector.cc b/ui/events/gesture_detection/scale_gesture_detector.cc index bf8a0d3..e6c35b8 100644 --- a/ui/events/gesture_detection/scale_gesture_detector.cc +++ b/ui/events/gesture_detection/scale_gesture_detector.cc @@ -92,9 +92,7 @@ bool ScaleGestureDetector::OnTouchEvent(const MotionEvent& event) { } const bool stream_complete = - action == MotionEvent::ACTION_UP || - action == MotionEvent::ACTION_CANCEL || - (action == MotionEvent::ACTION_POINTER_DOWN && InDoubleTapMode()); + action == MotionEvent::ACTION_UP || action == MotionEvent::ACTION_CANCEL; if (action == MotionEvent::ACTION_DOWN || stream_complete) { // Reset any scale in progress with the listener. @@ -105,7 +103,8 @@ bool ScaleGestureDetector::OnTouchEvent(const MotionEvent& event) { in_progress_ = false; initial_span_ = 0; double_tap_mode_ = DOUBLE_TAP_MODE_NONE; - } else if (InDoubleTapMode() && stream_complete) { + } else if (double_tap_mode_ == DOUBLE_TAP_MODE_IN_PROGRESS && + stream_complete) { in_progress_ = false; initial_span_ = 0; double_tap_mode_ = DOUBLE_TAP_MODE_NONE; @@ -130,7 +129,7 @@ bool ScaleGestureDetector::OnTouchEvent(const MotionEvent& event) { const int div = pointer_up ? count - 1 : count; float focus_x; float focus_y; - if (InDoubleTapMode()) { + if (double_tap_mode_ == DOUBLE_TAP_MODE_IN_PROGRESS) { // In double tap mode, the focal pt is always where the double tap // gesture started. focus_x = double_tap_focus_x_; diff --git a/ui/events/gesture_detection/touch_disposition_gesture_filter.cc b/ui/events/gesture_detection/touch_disposition_gesture_filter.cc index 6f405e5..f3e8514b 100644 --- a/ui/events/gesture_detection/touch_disposition_gesture_filter.cc +++ b/ui/events/gesture_detection/touch_disposition_gesture_filter.cc @@ -116,7 +116,6 @@ TouchDispositionGestureFilter::TouchDispositionGestureFilter( TouchDispositionGestureFilterClient* client) : client_(client), needs_tap_ending_event_(false), - needs_show_press_event_(false), needs_fling_ending_event_(false), needs_scroll_ending_event_(false) { DCHECK(client_); @@ -154,8 +153,13 @@ void TouchDispositionGestureFilter::OnTouchEventAck(bool event_consumed) { if (IsEmpty() || (Head().empty() && sequences_.size() == 1)) return; - if (Head().empty()) - PopGestureSequence(); + if (Head().empty()) { + CancelTapIfNecessary(); + CancelFlingIfNecessary(); + EndScrollIfNecessary(); + state_ = GestureHandlingState(); + sequences_.pop(); + } GestureSequence& sequence = Head(); @@ -167,8 +171,7 @@ void TouchDispositionGestureFilter::OnTouchEventAck(bool event_consumed) { DCHECK_NE(packet.gesture_source(), GestureEventDataPacket::UNDEFINED); DCHECK_NE(packet.gesture_source(), GestureEventDataPacket::INVALID); - GestureEventDataPacket::GestureSource source = packet.gesture_source(); - if (source != GestureEventDataPacket::TOUCH_TIMEOUT) { + if (packet.gesture_source() != GestureEventDataPacket::TOUCH_TIMEOUT) { // We should handle at most one non-timeout based packet. if (touch_packet_for_current_ack_handled) break; @@ -198,8 +201,6 @@ void TouchDispositionGestureFilter::FilterAndSendPacket( } SendGesture(gesture); } - if (packet.gesture_source() == GestureEventDataPacket::TOUCH_SEQUENCE_END) - EndScrollIfNecessary(); } void TouchDispositionGestureFilter::SendGesture(const GestureEventData& event) { @@ -207,37 +208,18 @@ void TouchDispositionGestureFilter::SendGesture(const GestureEventData& event) { // utility class. switch (event.type) { case ET_GESTURE_LONG_TAP: - if (!needs_tap_ending_event_) - return; CancelTapIfNecessary(); CancelFlingIfNecessary(); break; case ET_GESTURE_TAP_DOWN: DCHECK(!needs_tap_ending_event_); ending_event_motion_event_id_ = event.motion_event_id; - needs_show_press_event_ = true; needs_tap_ending_event_ = true; break; - case ET_GESTURE_SHOW_PRESS: - if (!needs_show_press_event_) - return; - needs_show_press_event_ = false; - break; - case ET_GESTURE_DOUBLE_TAP: - CancelTapIfNecessary(); - needs_show_press_event_ = false; - break; case ET_GESTURE_TAP: - if (needs_show_press_event_) { - GestureEventData show_press_event(event); - show_press_event.type = ET_GESTURE_SHOW_PRESS; - SendGesture(show_press_event); - DCHECK(!needs_show_press_event_); - } - needs_tap_ending_event_ = false; - break; case ET_GESTURE_TAP_CANCEL: - needs_show_press_event_ = false; + case ET_GESTURE_TAP_UNCONFIRMED: + case ET_GESTURE_DOUBLE_TAP: needs_tap_ending_event_ = false; break; case ET_GESTURE_SCROLL_BEGIN: @@ -292,15 +274,6 @@ void TouchDispositionGestureFilter::EndScrollIfNecessary() { DCHECK(!needs_scroll_ending_event_); } -void TouchDispositionGestureFilter::PopGestureSequence() { - DCHECK(Head().empty()); - CancelTapIfNecessary(); - CancelFlingIfNecessary(); - EndScrollIfNecessary(); - state_ = GestureHandlingState(); - sequences_.pop(); -} - TouchDispositionGestureFilter::GestureSequence& TouchDispositionGestureFilter::Head() { DCHECK(!sequences_.empty()); diff --git a/ui/events/gesture_detection/touch_disposition_gesture_filter.h b/ui/events/gesture_detection/touch_disposition_gesture_filter.h index 6d5e51f..cb511ff 100644 --- a/ui/events/gesture_detection/touch_disposition_gesture_filter.h +++ b/ui/events/gesture_detection/touch_disposition_gesture_filter.h @@ -81,7 +81,6 @@ class GESTURE_DETECTION_EXPORT TouchDispositionGestureFilter { void CancelTapIfNecessary(); void CancelFlingIfNecessary(); void EndScrollIfNecessary(); - void PopGestureSequence(); GestureSequence& Head(); GestureSequence& Tail(); @@ -95,7 +94,6 @@ class GESTURE_DETECTION_EXPORT TouchDispositionGestureFilter { // GestureFlingCancel when a user taps following a GestureFlingStart. int ending_event_motion_event_id_; bool needs_tap_ending_event_; - bool needs_show_press_event_; bool needs_fling_ending_event_; bool needs_scroll_ending_event_; diff --git a/ui/events/gesture_detection/touch_disposition_gesture_filter_unittest.cc b/ui/events/gesture_detection/touch_disposition_gesture_filter_unittest.cc index 4491229..562d2dd 100644 --- a/ui/events/gesture_detection/touch_disposition_gesture_filter_unittest.cc +++ b/ui/events/gesture_detection/touch_disposition_gesture_filter_unittest.cc @@ -664,8 +664,7 @@ TEST_F(TouchDispositionGestureFilterTest, PushGesture(ET_GESTURE_TAP); ReleaseTouchPoint(); SendTouchNotConsumedAck(); - EXPECT_TRUE(GesturesMatch(Gestures(ET_GESTURE_SHOW_PRESS, - ET_GESTURE_TAP), + EXPECT_TRUE(GesturesMatch(Gestures(ET_GESTURE_TAP), GetAndResetSentGestures())); // The tap should not be cancelled as it was terminated by a |ET_GESTURE_TAP|. @@ -677,11 +676,9 @@ TEST_F(TouchDispositionGestureFilterTest, TEST_F(TouchDispositionGestureFilterTest, TimeoutGestures) { // If the sequence is allowed, and there are no preceding gestures, the // timeout gestures should be forwarded immediately. - PushGesture(ET_GESTURE_TAP_DOWN); PressTouchPoint(1, 1); SendTouchNotConsumedAck(); - EXPECT_TRUE(GesturesMatch(Gestures(ET_GESTURE_TAP_DOWN), - GetAndResetSentGestures())); + EXPECT_FALSE(GesturesSent()); SendTimeoutGesture(ET_GESTURE_SHOW_PRESS); EXPECT_TRUE(GesturesMatch(Gestures(ET_GESTURE_SHOW_PRESS), @@ -691,16 +688,11 @@ TEST_F(TouchDispositionGestureFilterTest, TimeoutGestures) { EXPECT_TRUE(GesturesMatch(Gestures(ET_GESTURE_LONG_PRESS), GetAndResetSentGestures())); - PushGesture(ET_GESTURE_LONG_TAP); ReleaseTouchPoint(); SendTouchNotConsumedAck(); - EXPECT_TRUE(GesturesMatch(Gestures(ET_GESTURE_TAP_CANCEL, - ET_GESTURE_LONG_TAP), - GetAndResetSentGestures())); // If the sequence is disallowed, and there are no preceding gestures, the // timeout gestures should be dropped immediately. - PushGesture(ET_GESTURE_TAP_DOWN); PressTouchPoint(1, 1); SendTouchConsumedAck(); EXPECT_FALSE(GesturesSent()); @@ -712,7 +704,6 @@ TEST_F(TouchDispositionGestureFilterTest, TimeoutGestures) { // If the sequence has a pending ack, the timeout gestures should // remain queued until the ack is received. - PushGesture(ET_GESTURE_TAP_DOWN); PressTouchPoint(1, 1); EXPECT_FALSE(GesturesSent()); @@ -720,8 +711,7 @@ TEST_F(TouchDispositionGestureFilterTest, TimeoutGestures) { EXPECT_FALSE(GesturesSent()); SendTouchNotConsumedAck(); - EXPECT_TRUE(GesturesMatch(Gestures(ET_GESTURE_TAP_DOWN, - ET_GESTURE_LONG_PRESS), + EXPECT_TRUE(GesturesMatch(Gestures(ET_GESTURE_LONG_PRESS), GetAndResetSentGestures())); } @@ -796,69 +786,4 @@ TEST_F(TouchDispositionGestureFilterTest, TimeoutEventAfterRelease) { GetAndResetSentGestures())); } -TEST_F(TouchDispositionGestureFilterTest, ShowPressInsertedBeforeTap) { - PushGesture(ET_GESTURE_TAP_DOWN); - PressTouchPoint(1, 1); - SendTouchNotConsumedAck(); - EXPECT_TRUE(GesturesMatch(Gestures(ET_GESTURE_TAP_DOWN), - GetAndResetSentGestures())); - - SendTimeoutGesture(ET_GESTURE_TAP_UNCONFIRMED); - EXPECT_TRUE(GesturesMatch(Gestures(ET_GESTURE_TAP_UNCONFIRMED), - GetAndResetSentGestures())); - - PushGesture(ET_GESTURE_TAP); - ReleaseTouchPoint(); - SendTouchNotConsumedAck(); - EXPECT_TRUE(GesturesMatch(Gestures(ET_GESTURE_SHOW_PRESS, - ET_GESTURE_TAP), - GetAndResetSentGestures())); -} - -TEST_F(TouchDispositionGestureFilterTest, ShowPressNotInsertedIfAlreadySent) { - PushGesture(ET_GESTURE_TAP_DOWN); - PressTouchPoint(1, 1); - SendTouchNotConsumedAck(); - EXPECT_TRUE(GesturesMatch(Gestures(ET_GESTURE_TAP_DOWN), - GetAndResetSentGestures())); - - SendTimeoutGesture(ET_GESTURE_SHOW_PRESS); - EXPECT_TRUE(GesturesMatch(Gestures(ET_GESTURE_SHOW_PRESS), - GetAndResetSentGestures())); - - PushGesture(ET_GESTURE_TAP); - ReleaseTouchPoint(); - SendTouchNotConsumedAck(); - EXPECT_TRUE(GesturesMatch(Gestures(ET_GESTURE_TAP), - GetAndResetSentGestures())); -} - -TEST_F(TouchDispositionGestureFilterTest, TapAndScrollCancelledOnTouchCancel) { - PushGesture(ET_GESTURE_TAP_DOWN); - PressTouchPoint(1, 1); - SendTouchNotConsumedAck(); - EXPECT_TRUE(GesturesMatch(Gestures(ET_GESTURE_TAP_DOWN), - GetAndResetSentGestures())); - - // A cancellation motion event should cancel the tap (though the TAP_CANCEL - // will not be dispatched until the following touch sequence). - CancelTouchPoint(); - SendTouchNotConsumedAck(); - EXPECT_FALSE(GesturesSent()); - - PushGesture(ET_GESTURE_SCROLL_BEGIN); - PressTouchPoint(1, 1); - SendTouchNotConsumedAck(); - EXPECT_TRUE(GesturesMatch(Gestures(ET_GESTURE_TAP_CANCEL, - ET_GESTURE_SCROLL_BEGIN), - GetAndResetSentGestures())); - - // A cancellation motion event should end the scroll, even if the touch was - // consumed. - CancelTouchPoint(); - SendTouchConsumedAck(); - EXPECT_TRUE(GesturesMatch(Gestures(ET_GESTURE_SCROLL_END), - GetAndResetSentGestures())); -} - } // namespace ui |