Index: content/browser/renderer_host/render_widget_host_unittest.cc |
diff --git a/content/browser/renderer_host/render_widget_host_unittest.cc b/content/browser/renderer_host/render_widget_host_unittest.cc |
index 08296202e2b73d32f4bb61acbb04d763f64eb921..26063651b22e76f3697ed8c9a5e6a2c70a55e0a9 100644 |
--- a/content/browser/renderer_host/render_widget_host_unittest.cc |
+++ b/content/browser/renderer_host/render_widget_host_unittest.cc |
@@ -140,14 +140,19 @@ class MockRenderWidgetHost : public RenderWidgetHostImpl { |
hung_renderer_delay_ms_ = delay_ms; |
} |
- WebGestureEvent GestureEventLastQueueEvent() { |
- return gesture_event_filter_->coalesced_gesture_events_.back(); |
- } |
- |
unsigned GestureEventLastQueueEventSize() { |
return gesture_event_filter_->coalesced_gesture_events_.size(); |
} |
+ WebGestureEvent GestureEventSecondFromLastQueueEvent() { |
+ return gesture_event_filter_->coalesced_gesture_events_.at( |
+ GestureEventLastQueueEventSize() - 2); |
+ } |
+ |
+ WebGestureEvent GestureEventLastQueueEvent() { |
+ return gesture_event_filter_->coalesced_gesture_events_.back(); |
+ } |
+ |
unsigned GestureEventDebouncingQueueSize() { |
return gesture_event_filter_->debouncing_deferral_queue_.size(); |
} |
@@ -168,6 +173,10 @@ class MockRenderWidgetHost : public RenderWidgetHostImpl { |
return gesture_event_filter_->fling_in_progress_; |
} |
+ bool WillIgnoreNextACK() { |
+ return gesture_event_filter_->ignore_next_ack_; |
+ } |
+ |
TapSuppressionState TapSuppressionControllerState() { |
return static_cast<TapSuppressionState>( |
gesture_event_filter_->tap_suppression_controller_->state_); |
@@ -587,6 +596,19 @@ class RenderWidgetHostTest : public testing::Test { |
WebGestureEvent::Touchscreen, &gesture_event); |
} |
+ void SimulateGesturePinchUpdateEvent(float scale, |
+ float anchorX, |
+ float anchorY, |
+ int modifiers) { |
+ WebGestureEvent gesture_event; |
+ gesture_event.data.pinchUpdate.scale = scale; |
+ gesture_event.x = anchorX; |
+ gesture_event.y = anchorY; |
+ gesture_event.modifiers = modifiers; |
+ SimulateGestureEventCore(WebInputEvent::GesturePinchUpdate, |
+ WebGestureEvent::Touchscreen, &gesture_event); |
+ } |
+ |
// Inject synthetic GestureFlingStart events. |
void SimulateGestureFlingStartEvent( |
float velocityX, |
@@ -1161,11 +1183,11 @@ TEST_F(RenderWidgetHostTest, CoalescesWheelEventsQueuedPhaseEndIsNotDropped) { |
EXPECT_EQ(WebInputEvent::GestureScrollEnd, input_event->type); |
} |
-TEST_F(RenderWidgetHostTest, CoalescesGesturesEvents) { |
+TEST_F(RenderWidgetHostTest, CoalescesScrollGestureEvents) { |
// Turn off debounce handling for test isolation. |
host_->set_debounce_interval_time_ms(0); |
process_->sink().ClearMessages(); |
- // Only GestureScrollUpdate events can be coalesced. |
+ // Test coalescing of only GestureScrollUpdate events. |
// Simulate gesture events. |
// Sent. |
@@ -1242,6 +1264,237 @@ TEST_F(RenderWidgetHostTest, CoalescesGesturesEvents) { |
EXPECT_EQ(0U, process_->sink().message_count()); |
} |
+TEST_F(RenderWidgetHostTest, CoalescesScrollAndPinchEvents) { |
+ // Turn off debounce handling for test isolation. |
+ host_->set_debounce_interval_time_ms(0); |
+ process_->sink().ClearMessages(); |
+ // Test coalescing of only GestureScrollUpdate events. |
+ // Simulate gesture events. |
+ |
+ // Sent. |
+ SimulateGestureEvent(WebInputEvent::GestureScrollBegin, |
+ WebGestureEvent::Touchscreen); |
+ |
+ // Sent. |
+ SimulateGestureEvent(WebInputEvent::GesturePinchBegin, |
+ WebGestureEvent::Touchscreen); |
+ |
+ // Enqueued. |
+ SimulateGestureScrollUpdateEvent(8, -4, 1); |
+ |
+ // Make sure that the queue contains what we think it should. |
+ WebGestureEvent merged_event = host_->GestureEventLastQueueEvent(); |
+ EXPECT_EQ(3U, host_->GestureEventLastQueueEventSize()); |
+ EXPECT_EQ(WebInputEvent::GestureScrollUpdate, merged_event.type); |
+ |
+ // Coalesced without changing event order. Note anchor at (60, 60). Anchoring |
+ // from a poinht that is not the origin should still give us the wight scroll. |
+ SimulateGesturePinchUpdateEvent(1.5, 60, 60, 1); |
+ EXPECT_EQ(4U, host_->GestureEventLastQueueEventSize()); |
+ merged_event = host_->GestureEventLastQueueEvent(); |
+ EXPECT_EQ(WebInputEvent::GesturePinchUpdate, merged_event.type); |
+ EXPECT_EQ(1.5, merged_event.data.pinchUpdate.scale); |
+ EXPECT_EQ(1, merged_event.modifiers); |
+ merged_event = host_->GestureEventSecondFromLastQueueEvent(); |
+ EXPECT_EQ(WebInputEvent::GestureScrollUpdate, merged_event.type); |
+ EXPECT_EQ(8, merged_event.data.scrollUpdate.deltaX); |
+ EXPECT_EQ(-4, merged_event.data.scrollUpdate.deltaY); |
+ EXPECT_EQ(1, merged_event.modifiers); |
+ |
+ // Enqueued. |
+ SimulateGestureScrollUpdateEvent(6, -3, 1); |
+ |
+ // Check whether coalesced correctly. |
+ EXPECT_EQ(4U, host_->GestureEventLastQueueEventSize()); |
+ merged_event = host_->GestureEventLastQueueEvent(); |
+ EXPECT_EQ(WebInputEvent::GesturePinchUpdate, merged_event.type); |
+ EXPECT_EQ(1.5, merged_event.data.pinchUpdate.scale); |
+ EXPECT_EQ(1, merged_event.modifiers); |
+ merged_event = host_->GestureEventSecondFromLastQueueEvent(); |
+ EXPECT_EQ(WebInputEvent::GestureScrollUpdate, merged_event.type); |
+ EXPECT_EQ(12, merged_event.data.scrollUpdate.deltaX); |
+ EXPECT_EQ(-6, merged_event.data.scrollUpdate.deltaY); |
+ EXPECT_EQ(1, merged_event.modifiers); |
+ |
+ // Enqueued. |
+ SimulateGesturePinchUpdateEvent(2, 60, 60, 1); |
+ |
+ // Check whether coalesced correctly. |
+ EXPECT_EQ(4U, host_->GestureEventLastQueueEventSize()); |
+ merged_event = host_->GestureEventLastQueueEvent(); |
+ EXPECT_EQ(WebInputEvent::GesturePinchUpdate, merged_event.type); |
+ EXPECT_EQ(3, merged_event.data.pinchUpdate.scale); |
+ EXPECT_EQ(1, merged_event.modifiers); |
+ merged_event = host_->GestureEventSecondFromLastQueueEvent(); |
+ EXPECT_EQ(WebInputEvent::GestureScrollUpdate, merged_event.type); |
+ EXPECT_EQ(12, merged_event.data.scrollUpdate.deltaX); |
+ EXPECT_EQ(-6, merged_event.data.scrollUpdate.deltaY); |
+ EXPECT_EQ(1, merged_event.modifiers); |
+ |
+ // Enqueued. |
+ SimulateGesturePinchUpdateEvent(2, 60, 60, 1); |
+ |
+ // Check whether coalesced correctly. |
+ EXPECT_EQ(4U, host_->GestureEventLastQueueEventSize()); |
+ merged_event = host_->GestureEventLastQueueEvent(); |
+ EXPECT_EQ(WebInputEvent::GesturePinchUpdate, merged_event.type); |
+ EXPECT_EQ(6, merged_event.data.pinchUpdate.scale); |
+ EXPECT_EQ(1, merged_event.modifiers); |
+ merged_event = host_->GestureEventSecondFromLastQueueEvent(); |
+ EXPECT_EQ(WebInputEvent::GestureScrollUpdate, merged_event.type); |
+ EXPECT_EQ(12, merged_event.data.scrollUpdate.deltaX); |
+ EXPECT_EQ(-6, merged_event.data.scrollUpdate.deltaY); |
+ EXPECT_EQ(1, merged_event.modifiers); |
+ |
+ // Check that only the first event was sent. |
+ EXPECT_EQ(1U, process_->sink().message_count()); |
+ EXPECT_TRUE(process_->sink().GetUniqueMessageMatching( |
+ ViewMsg_HandleInputEvent::ID)); |
+ process_->sink().ClearMessages(); |
+ |
+ // Check that the ACK sends the second message. |
+ SendInputEventACK(WebInputEvent::GestureScrollBegin, |
+ INPUT_EVENT_ACK_STATE_CONSUMED); |
+ MessageLoop::current()->RunUntilIdle(); |
+ EXPECT_EQ(1U, process_->sink().message_count()); |
+ EXPECT_TRUE(process_->sink().GetUniqueMessageMatching( |
+ ViewMsg_HandleInputEvent::ID)); |
+ process_->sink().ClearMessages(); |
+ |
+ // Enqueued. |
+ SimulateGestureScrollUpdateEvent(6, -6, 1); |
+ |
+ // Check whether coalesced correctly. |
+ EXPECT_EQ(3U, host_->GestureEventLastQueueEventSize()); |
+ merged_event = host_->GestureEventLastQueueEvent(); |
+ EXPECT_EQ(WebInputEvent::GesturePinchUpdate, merged_event.type); |
+ EXPECT_EQ(6, merged_event.data.pinchUpdate.scale); |
+ EXPECT_EQ(1, merged_event.modifiers); |
+ merged_event = host_->GestureEventSecondFromLastQueueEvent(); |
+ EXPECT_EQ(WebInputEvent::GestureScrollUpdate, merged_event.type); |
+ EXPECT_EQ(13, merged_event.data.scrollUpdate.deltaX); |
+ EXPECT_EQ(-7, merged_event.data.scrollUpdate.deltaY); |
+ EXPECT_EQ(1, merged_event.modifiers); |
+ |
+ // At this point ACKs shouldn't be getting ignored. |
+ EXPECT_FALSE(host_->WillIgnoreNextACK()); |
+ |
+ // Check that the ACK sends both scroll and pinch updates. |
+ SendInputEventACK(WebInputEvent::GesturePinchBegin, |
+ INPUT_EVENT_ACK_STATE_CONSUMED); |
+ MessageLoop::current()->RunUntilIdle(); |
+ EXPECT_EQ(2U, process_->sink().message_count()); |
+ EXPECT_TRUE(process_->sink().GetFirstMessageMatching( |
+ ViewMsg_HandleInputEvent::ID)); |
+ EXPECT_FALSE(process_->sink().GetUniqueMessageMatching( |
+ ViewMsg_HandleInputEvent::ID)); |
+ process_->sink().ClearMessages(); |
+ |
+ // The next ACK should be getting ignored. |
+ EXPECT_TRUE(host_->WillIgnoreNextACK()); |
+ |
+ // Enqueued. |
+ SimulateGestureScrollUpdateEvent(1, -1, 1); |
+ |
+ // Check whether coalesced correctly. |
+ EXPECT_EQ(3U, host_->GestureEventLastQueueEventSize()); |
+ merged_event = host_->GestureEventLastQueueEvent(); |
+ EXPECT_EQ(WebInputEvent::GestureScrollUpdate, merged_event.type); |
+ EXPECT_EQ(1, merged_event.data.scrollUpdate.deltaX); |
+ EXPECT_EQ(-1, merged_event.data.scrollUpdate.deltaY); |
+ EXPECT_EQ(1, merged_event.modifiers); |
+ merged_event = host_->GestureEventSecondFromLastQueueEvent(); |
+ EXPECT_EQ(WebInputEvent::GesturePinchUpdate, merged_event.type); |
+ EXPECT_EQ(6, merged_event.data.pinchUpdate.scale); |
+ EXPECT_EQ(1, merged_event.modifiers); |
+ |
+ // Enqueued. |
+ SimulateGestureScrollUpdateEvent(2, -2, 1); |
+ |
+ // Coalescing scrolls should still work. |
+ EXPECT_EQ(3U, host_->GestureEventLastQueueEventSize()); |
+ merged_event = host_->GestureEventLastQueueEvent(); |
+ EXPECT_EQ(WebInputEvent::GestureScrollUpdate, merged_event.type); |
+ EXPECT_EQ(3, merged_event.data.scrollUpdate.deltaX); |
+ EXPECT_EQ(-3, merged_event.data.scrollUpdate.deltaY); |
+ EXPECT_EQ(1, merged_event.modifiers); |
+ merged_event = host_->GestureEventSecondFromLastQueueEvent(); |
+ EXPECT_EQ(WebInputEvent::GesturePinchUpdate, merged_event.type); |
+ EXPECT_EQ(6, merged_event.data.pinchUpdate.scale); |
+ EXPECT_EQ(1, merged_event.modifiers); |
+ |
+ // Enqueued. |
+ SimulateGesturePinchUpdateEvent(0.5, 60, 60, 1); |
+ |
+ // Check whether coalesced correctly. |
+ EXPECT_EQ(4U, host_->GestureEventLastQueueEventSize()); |
+ merged_event = host_->GestureEventLastQueueEvent(); |
+ EXPECT_EQ(WebInputEvent::GesturePinchUpdate, merged_event.type); |
+ EXPECT_EQ(0.5, merged_event.data.pinchUpdate.scale); |
+ EXPECT_EQ(1, merged_event.modifiers); |
+ merged_event = host_->GestureEventSecondFromLastQueueEvent(); |
+ EXPECT_EQ(WebInputEvent::GestureScrollUpdate, merged_event.type); |
+ EXPECT_EQ(3, merged_event.data.scrollUpdate.deltaX); |
+ EXPECT_EQ(-3, merged_event.data.scrollUpdate.deltaY); |
+ EXPECT_EQ(1, merged_event.modifiers); |
+ |
+ // Check that the ACK gets ignored. |
+ SendInputEventACK(WebInputEvent::GestureScrollUpdate, |
+ INPUT_EVENT_ACK_STATE_CONSUMED); |
+ MessageLoop::current()->RunUntilIdle(); |
+ EXPECT_EQ(0U, process_->sink().message_count()); |
+ // The flag should have been flipped back to false. |
+ EXPECT_FALSE(host_->WillIgnoreNextACK()); |
+ |
+ // Enqueued. |
+ SimulateGestureScrollUpdateEvent(2, -2, 2); |
+ |
+ // Shouldn't coalesce with different modifiers. |
+ EXPECT_EQ(4U, host_->GestureEventLastQueueEventSize()); |
+ merged_event = host_->GestureEventLastQueueEvent(); |
+ EXPECT_EQ(WebInputEvent::GestureScrollUpdate, merged_event.type); |
+ EXPECT_EQ(2, merged_event.data.scrollUpdate.deltaX); |
+ EXPECT_EQ(-2, merged_event.data.scrollUpdate.deltaY); |
+ EXPECT_EQ(2, merged_event.modifiers); |
+ merged_event = host_->GestureEventSecondFromLastQueueEvent(); |
+ EXPECT_EQ(WebInputEvent::GesturePinchUpdate, merged_event.type); |
+ EXPECT_EQ(0.5, merged_event.data.pinchUpdate.scale); |
+ EXPECT_EQ(1, merged_event.modifiers); |
+ |
+ // Check that the ACK sends the next scroll pinch pair. |
+ SendInputEventACK(WebInputEvent::GesturePinchUpdate, |
+ INPUT_EVENT_ACK_STATE_CONSUMED); |
+ MessageLoop::current()->RunUntilIdle(); |
+ EXPECT_EQ(2U, process_->sink().message_count()); |
+ EXPECT_TRUE(process_->sink().GetFirstMessageMatching( |
+ ViewMsg_HandleInputEvent::ID)); |
+ EXPECT_FALSE(process_->sink().GetUniqueMessageMatching( |
+ ViewMsg_HandleInputEvent::ID)); |
+ process_->sink().ClearMessages(); |
+ |
+ // Check that the ACK sends the second message. |
+ SendInputEventACK(WebInputEvent::GestureScrollUpdate, |
+ INPUT_EVENT_ACK_STATE_CONSUMED); |
+ MessageLoop::current()->RunUntilIdle(); |
+ EXPECT_EQ(0U, process_->sink().message_count()); |
+ |
+ // Check that the ACK sends the second message. |
+ SendInputEventACK(WebInputEvent::GesturePinchUpdate, |
+ INPUT_EVENT_ACK_STATE_CONSUMED); |
+ MessageLoop::current()->RunUntilIdle(); |
+ EXPECT_EQ(1U, process_->sink().message_count()); |
+ EXPECT_TRUE(process_->sink().GetUniqueMessageMatching( |
+ ViewMsg_HandleInputEvent::ID)); |
+ process_->sink().ClearMessages(); |
+ |
+ // Check that the queue is empty after ACK and no messages get sent. |
+ SendInputEventACK(WebInputEvent::GestureScrollUpdate, |
+ INPUT_EVENT_ACK_STATE_CONSUMED); |
+ MessageLoop::current()->RunUntilIdle(); |
+ EXPECT_EQ(0U, process_->sink().message_count()); |
+ EXPECT_EQ(0U, host_->GestureEventLastQueueEventSize()); |
+} |
+ |
#if GTEST_HAS_PARAM_TEST |
TEST_P(RenderWidgetHostWithSourceTest, GestureFlingCancelsFiltered) { |
WebGestureEvent::SourceDevice source_device = GetParam(); |