| OLD | NEW | 
|    1 // Copyright 2014 The Chromium Authors. All rights reserved. |    1 // Copyright 2014 The Chromium Authors. All rights reserved. | 
|    2 // Use of this source code is governed by a BSD-style license that can be |    2 // Use of this source code is governed by a BSD-style license that can be | 
|    3 // found in the LICENSE file. |    3 // found in the LICENSE file. | 
|    4  |    4  | 
|    5 #include "content/browser/renderer_host/input/gesture_event_queue.h" |    5 #include "content/browser/renderer_host/input/gesture_event_queue.h" | 
|    6  |    6  | 
|    7 #include "base/trace_event/trace_event.h" |    7 #include "base/trace_event/trace_event.h" | 
|    8 #include "content/browser/renderer_host/input/touchpad_tap_suppression_controlle
     r.h" |    8 #include "content/browser/renderer_host/input/touchpad_tap_suppression_controlle
     r.h" | 
|    9 #include "content/browser/renderer_host/input/touchscreen_tap_suppression_contro
     ller.h" |    9 #include "content/browser/renderer_host/input/touchscreen_tap_suppression_contro
     ller.h" | 
|   10 #include "ui/events/blink/web_input_event_traits.h" |   10 #include "ui/events/blink/web_input_event_traits.h" | 
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   50   QueueAndForwardIfNecessary(gesture_event); |   50   QueueAndForwardIfNecessary(gesture_event); | 
|   51 } |   51 } | 
|   52  |   52  | 
|   53 bool GestureEventQueue::ShouldDiscardFlingCancelEvent( |   53 bool GestureEventQueue::ShouldDiscardFlingCancelEvent( | 
|   54     const GestureEventWithLatencyInfo& gesture_event) const { |   54     const GestureEventWithLatencyInfo& gesture_event) const { | 
|   55   if (coalesced_gesture_events_.empty() && fling_in_progress_) |   55   if (coalesced_gesture_events_.empty() && fling_in_progress_) | 
|   56     return false; |   56     return false; | 
|   57   GestureQueue::const_reverse_iterator it = |   57   GestureQueue::const_reverse_iterator it = | 
|   58       coalesced_gesture_events_.rbegin(); |   58       coalesced_gesture_events_.rbegin(); | 
|   59   while (it != coalesced_gesture_events_.rend()) { |   59   while (it != coalesced_gesture_events_.rend()) { | 
|   60     if (it->event.type == WebInputEvent::GestureFlingStart) |   60     if (it->event.type() == WebInputEvent::GestureFlingStart) | 
|   61       return false; |   61       return false; | 
|   62     if (it->event.type == WebInputEvent::GestureFlingCancel) |   62     if (it->event.type() == WebInputEvent::GestureFlingCancel) | 
|   63       return true; |   63       return true; | 
|   64     it++; |   64     it++; | 
|   65   } |   65   } | 
|   66   return true; |   66   return true; | 
|   67 } |   67 } | 
|   68  |   68  | 
|   69 bool GestureEventQueue::ShouldForwardForBounceReduction( |   69 bool GestureEventQueue::ShouldForwardForBounceReduction( | 
|   70     const GestureEventWithLatencyInfo& gesture_event) { |   70     const GestureEventWithLatencyInfo& gesture_event) { | 
|   71   if (debounce_interval_ <= base::TimeDelta()) |   71   if (debounce_interval_ <= base::TimeDelta()) | 
|   72     return true; |   72     return true; | 
|   73   switch (gesture_event.event.type) { |   73   switch (gesture_event.event.type()) { | 
|   74     case WebInputEvent::GestureScrollUpdate: |   74     case WebInputEvent::GestureScrollUpdate: | 
|   75       if (!scrolling_in_progress_) { |   75       if (!scrolling_in_progress_) { | 
|   76         debounce_deferring_timer_.Start( |   76         debounce_deferring_timer_.Start( | 
|   77             FROM_HERE, |   77             FROM_HERE, | 
|   78             debounce_interval_, |   78             debounce_interval_, | 
|   79             this, |   79             this, | 
|   80             &GestureEventQueue::SendScrollEndingEventsNow); |   80             &GestureEventQueue::SendScrollEndingEventsNow); | 
|   81       } else { |   81       } else { | 
|   82         // Extend the bounce interval. |   82         // Extend the bounce interval. | 
|   83         debounce_deferring_timer_.Reset(); |   83         debounce_deferring_timer_.Reset(); | 
| (...skipping 11 matching lines...) Expand all  Loading... | 
|   95       if (scrolling_in_progress_) { |   95       if (scrolling_in_progress_) { | 
|   96         debouncing_deferral_queue_.push_back(gesture_event); |   96         debouncing_deferral_queue_.push_back(gesture_event); | 
|   97         return false; |   97         return false; | 
|   98       } |   98       } | 
|   99       return true; |   99       return true; | 
|  100   } |  100   } | 
|  101 } |  101 } | 
|  102  |  102  | 
|  103 bool GestureEventQueue::ShouldForwardForGFCFiltering( |  103 bool GestureEventQueue::ShouldForwardForGFCFiltering( | 
|  104     const GestureEventWithLatencyInfo& gesture_event) const { |  104     const GestureEventWithLatencyInfo& gesture_event) const { | 
|  105   return gesture_event.event.type != WebInputEvent::GestureFlingCancel || |  105   return gesture_event.event.type() != WebInputEvent::GestureFlingCancel || | 
|  106       !ShouldDiscardFlingCancelEvent(gesture_event); |  106          !ShouldDiscardFlingCancelEvent(gesture_event); | 
|  107 } |  107 } | 
|  108  |  108  | 
|  109 bool GestureEventQueue::ShouldForwardForTapSuppression( |  109 bool GestureEventQueue::ShouldForwardForTapSuppression( | 
|  110     const GestureEventWithLatencyInfo& gesture_event) { |  110     const GestureEventWithLatencyInfo& gesture_event) { | 
|  111   switch (gesture_event.event.type) { |  111   switch (gesture_event.event.type()) { | 
|  112     case WebInputEvent::GestureFlingCancel: |  112     case WebInputEvent::GestureFlingCancel: | 
|  113       if (gesture_event.event.sourceDevice == |  113       if (gesture_event.event.sourceDevice == | 
|  114           blink::WebGestureDeviceTouchscreen) |  114           blink::WebGestureDeviceTouchscreen) | 
|  115         touchscreen_tap_suppression_controller_.GestureFlingCancel(); |  115         touchscreen_tap_suppression_controller_.GestureFlingCancel(); | 
|  116       else |  116       else | 
|  117         touchpad_tap_suppression_controller_.GestureFlingCancel(); |  117         touchpad_tap_suppression_controller_.GestureFlingCancel(); | 
|  118       return true; |  118       return true; | 
|  119     case WebInputEvent::GestureTapDown: |  119     case WebInputEvent::GestureTapDown: | 
|  120     case WebInputEvent::GestureShowPress: |  120     case WebInputEvent::GestureShowPress: | 
|  121     case WebInputEvent::GestureTapUnconfirmed: |  121     case WebInputEvent::GestureTapUnconfirmed: | 
|  122     case WebInputEvent::GestureTapCancel: |  122     case WebInputEvent::GestureTapCancel: | 
|  123     case WebInputEvent::GestureTap: |  123     case WebInputEvent::GestureTap: | 
|  124     case WebInputEvent::GestureDoubleTap: |  124     case WebInputEvent::GestureDoubleTap: | 
|  125     case WebInputEvent::GestureLongPress: |  125     case WebInputEvent::GestureLongPress: | 
|  126     case WebInputEvent::GestureLongTap: |  126     case WebInputEvent::GestureLongTap: | 
|  127     case WebInputEvent::GestureTwoFingerTap: |  127     case WebInputEvent::GestureTwoFingerTap: | 
|  128       if (gesture_event.event.sourceDevice == |  128       if (gesture_event.event.sourceDevice == | 
|  129           blink::WebGestureDeviceTouchscreen) { |  129           blink::WebGestureDeviceTouchscreen) { | 
|  130         return !touchscreen_tap_suppression_controller_.FilterTapEvent( |  130         return !touchscreen_tap_suppression_controller_.FilterTapEvent( | 
|  131             gesture_event); |  131             gesture_event); | 
|  132       } |  132       } | 
|  133       return true; |  133       return true; | 
|  134     default: |  134     default: | 
|  135       return true; |  135       return true; | 
|  136   } |  136   } | 
|  137 } |  137 } | 
|  138  |  138  | 
|  139 void GestureEventQueue::QueueAndForwardIfNecessary( |  139 void GestureEventQueue::QueueAndForwardIfNecessary( | 
|  140     const GestureEventWithLatencyInfo& gesture_event) { |  140     const GestureEventWithLatencyInfo& gesture_event) { | 
|  141   switch (gesture_event.event.type) { |  141   switch (gesture_event.event.type()) { | 
|  142     case WebInputEvent::GestureFlingCancel: |  142     case WebInputEvent::GestureFlingCancel: | 
|  143       fling_in_progress_ = false; |  143       fling_in_progress_ = false; | 
|  144       break; |  144       break; | 
|  145     case WebInputEvent::GestureFlingStart: |  145     case WebInputEvent::GestureFlingStart: | 
|  146       fling_in_progress_ = true; |  146       fling_in_progress_ = true; | 
|  147       break; |  147       break; | 
|  148     case WebInputEvent::GesturePinchUpdate: |  148     case WebInputEvent::GesturePinchUpdate: | 
|  149     case WebInputEvent::GestureScrollUpdate: |  149     case WebInputEvent::GestureScrollUpdate: | 
|  150       QueueScrollOrPinchAndForwardIfNecessary(gesture_event); |  150       QueueScrollOrPinchAndForwardIfNecessary(gesture_event); | 
|  151       return; |  151       return; | 
| (...skipping 12 matching lines...) Expand all  Loading... | 
|  164 bool GestureEventQueue::OnScrollBegin( |  164 bool GestureEventQueue::OnScrollBegin( | 
|  165     const GestureEventWithLatencyInfo& gesture_event) { |  165     const GestureEventWithLatencyInfo& gesture_event) { | 
|  166   // If a synthetic scroll begin is encountered, it can cancel out a previous |  166   // If a synthetic scroll begin is encountered, it can cancel out a previous | 
|  167   // synthetic scroll end. This allows a later gesture scroll update to coalesce |  167   // synthetic scroll end. This allows a later gesture scroll update to coalesce | 
|  168   // with the previous one. crbug.com/607340. |  168   // with the previous one. crbug.com/607340. | 
|  169   bool synthetic = gesture_event.event.data.scrollBegin.synthetic; |  169   bool synthetic = gesture_event.event.data.scrollBegin.synthetic; | 
|  170   bool have_unsent_events = |  170   bool have_unsent_events = | 
|  171       EventsInFlightCount() < coalesced_gesture_events_.size(); |  171       EventsInFlightCount() < coalesced_gesture_events_.size(); | 
|  172   if (synthetic && have_unsent_events) { |  172   if (synthetic && have_unsent_events) { | 
|  173     GestureEventWithLatencyInfo* last_event = &coalesced_gesture_events_.back(); |  173     GestureEventWithLatencyInfo* last_event = &coalesced_gesture_events_.back(); | 
|  174     if (last_event->event.type == WebInputEvent::GestureScrollEnd && |  174     if (last_event->event.type() == WebInputEvent::GestureScrollEnd && | 
|  175         last_event->event.data.scrollEnd.synthetic) { |  175         last_event->event.data.scrollEnd.synthetic) { | 
|  176       coalesced_gesture_events_.pop_back(); |  176       coalesced_gesture_events_.pop_back(); | 
|  177       return true; |  177       return true; | 
|  178     } |  178     } | 
|  179   } |  179   } | 
|  180   return false; |  180   return false; | 
|  181 } |  181 } | 
|  182  |  182  | 
|  183 void GestureEventQueue::ProcessGestureAck(InputEventAckState ack_result, |  183 void GestureEventQueue::ProcessGestureAck(InputEventAckState ack_result, | 
|  184                                           WebInputEvent::Type type, |  184                                           WebInputEvent::Type type, | 
|  185                                           const ui::LatencyInfo& latency) { |  185                                           const ui::LatencyInfo& latency) { | 
|  186   TRACE_EVENT0("input", "GestureEventQueue::ProcessGestureAck"); |  186   TRACE_EVENT0("input", "GestureEventQueue::ProcessGestureAck"); | 
|  187  |  187  | 
|  188   if (coalesced_gesture_events_.empty()) { |  188   if (coalesced_gesture_events_.empty()) { | 
|  189     DLOG(ERROR) << "Received unexpected ACK for event type " << type; |  189     DLOG(ERROR) << "Received unexpected ACK for event type " << type; | 
|  190     return; |  190     return; | 
|  191   } |  191   } | 
|  192  |  192  | 
|  193   // It's possible that the ack for the second event in an in-flight, coalesced |  193   // It's possible that the ack for the second event in an in-flight, coalesced | 
|  194   // Gesture{Scroll,Pinch}Update pair is received prior to the first event ack. |  194   // Gesture{Scroll,Pinch}Update pair is received prior to the first event ack. | 
|  195   size_t event_index = 0; |  195   size_t event_index = 0; | 
|  196   if (ignore_next_ack_ && |  196   if (ignore_next_ack_ && coalesced_gesture_events_.size() > 1 && | 
|  197       coalesced_gesture_events_.size() > 1 && |  197       coalesced_gesture_events_[0].event.type() != type && | 
|  198       coalesced_gesture_events_[0].event.type != type && |  198       coalesced_gesture_events_[1].event.type() == type) { | 
|  199       coalesced_gesture_events_[1].event.type == type) { |  | 
|  200     event_index = 1; |  199     event_index = 1; | 
|  201   } |  200   } | 
|  202   GestureEventWithLatencyInfo event_with_latency = |  201   GestureEventWithLatencyInfo event_with_latency = | 
|  203       coalesced_gesture_events_[event_index]; |  202       coalesced_gesture_events_[event_index]; | 
|  204   DCHECK_EQ(event_with_latency.event.type, type); |  203   DCHECK_EQ(event_with_latency.event.type(), type); | 
|  205   event_with_latency.latency.AddNewLatencyFrom(latency); |  204   event_with_latency.latency.AddNewLatencyFrom(latency); | 
|  206  |  205  | 
|  207   // Ack'ing an event may enqueue additional gesture events.  By ack'ing the |  206   // Ack'ing an event may enqueue additional gesture events.  By ack'ing the | 
|  208   // event before the forwarding of queued events below, such additional events |  207   // event before the forwarding of queued events below, such additional events | 
|  209   // can be coalesced with existing queued events prior to dispatch. |  208   // can be coalesced with existing queued events prior to dispatch. | 
|  210   client_->OnGestureEventAck(event_with_latency, ack_result); |  209   client_->OnGestureEventAck(event_with_latency, ack_result); | 
|  211  |  210  | 
|  212   const bool processed = (INPUT_EVENT_ACK_STATE_CONSUMED == ack_result); |  211   const bool processed = (INPUT_EVENT_ACK_STATE_CONSUMED == ack_result); | 
|  213   if (type == WebInputEvent::GestureFlingCancel) { |  212   if (type == WebInputEvent::GestureFlingCancel) { | 
|  214     if (event_with_latency.event.sourceDevice == |  213     if (event_with_latency.event.sourceDevice == | 
| (...skipping 13 matching lines...) Expand all  Loading... | 
|  228  |  227  | 
|  229   if (coalesced_gesture_events_.empty()) |  228   if (coalesced_gesture_events_.empty()) | 
|  230     return; |  229     return; | 
|  231  |  230  | 
|  232   const GestureEventWithLatencyInfo& first_gesture_event = |  231   const GestureEventWithLatencyInfo& first_gesture_event = | 
|  233       coalesced_gesture_events_.front(); |  232       coalesced_gesture_events_.front(); | 
|  234  |  233  | 
|  235   // Check for the coupled GesturePinchUpdate before sending either event, |  234   // Check for the coupled GesturePinchUpdate before sending either event, | 
|  236   // handling the case where the first GestureScrollUpdate ack is synchronous. |  235   // handling the case where the first GestureScrollUpdate ack is synchronous. | 
|  237   GestureEventWithLatencyInfo second_gesture_event; |  236   GestureEventWithLatencyInfo second_gesture_event; | 
|  238   if (first_gesture_event.event.type == WebInputEvent::GestureScrollUpdate && |  237   if (first_gesture_event.event.type() == WebInputEvent::GestureScrollUpdate && | 
|  239       coalesced_gesture_events_.size() > 1 && |  238       coalesced_gesture_events_.size() > 1 && | 
|  240       coalesced_gesture_events_[1].event.type == |  239       coalesced_gesture_events_[1].event.type() == | 
|  241           WebInputEvent::GesturePinchUpdate) { |  240           WebInputEvent::GesturePinchUpdate) { | 
|  242     second_gesture_event = coalesced_gesture_events_[1]; |  241     second_gesture_event = coalesced_gesture_events_[1]; | 
|  243     ignore_next_ack_ = true; |  242     ignore_next_ack_ = true; | 
|  244   } |  243   } | 
|  245  |  244  | 
|  246   client_->SendGestureEventImmediately(first_gesture_event); |  245   client_->SendGestureEventImmediately(first_gesture_event); | 
|  247   if (second_gesture_event.event.type != WebInputEvent::Undefined) |  246   if (second_gesture_event.event.type() != WebInputEvent::Undefined) | 
|  248     client_->SendGestureEventImmediately(second_gesture_event); |  247     client_->SendGestureEventImmediately(second_gesture_event); | 
|  249 } |  248 } | 
|  250  |  249  | 
|  251 TouchpadTapSuppressionController* |  250 TouchpadTapSuppressionController* | 
|  252     GestureEventQueue::GetTouchpadTapSuppressionController() { |  251     GestureEventQueue::GetTouchpadTapSuppressionController() { | 
|  253   return &touchpad_tap_suppression_controller_; |  252   return &touchpad_tap_suppression_controller_; | 
|  254 } |  253 } | 
|  255  |  254  | 
|  256 void GestureEventQueue::FlingHasBeenHalted() { |  255 void GestureEventQueue::FlingHasBeenHalted() { | 
|  257   fling_in_progress_ = false; |  256   fling_in_progress_ = false; | 
| (...skipping 28 matching lines...) Expand all  Loading... | 
|  286     coalesced_gesture_events_.push_back(gesture_event); |  285     coalesced_gesture_events_.push_back(gesture_event); | 
|  287     if (coalesced_gesture_events_.size() == 1) { |  286     if (coalesced_gesture_events_.size() == 1) { | 
|  288       client_->SendGestureEventImmediately(gesture_event); |  287       client_->SendGestureEventImmediately(gesture_event); | 
|  289     } else if (coalesced_gesture_events_.size() == 2) { |  288     } else if (coalesced_gesture_events_.size() == 2) { | 
|  290       DCHECK(!ignore_next_ack_); |  289       DCHECK(!ignore_next_ack_); | 
|  291       // If there is an in-flight scroll, the new pinch can be forwarded |  290       // If there is an in-flight scroll, the new pinch can be forwarded | 
|  292       // immediately, avoiding a potential frame delay between the two |  291       // immediately, avoiding a potential frame delay between the two | 
|  293       // (similarly for an in-flight pinch with a new scroll). |  292       // (similarly for an in-flight pinch with a new scroll). | 
|  294       const GestureEventWithLatencyInfo& first_event = |  293       const GestureEventWithLatencyInfo& first_event = | 
|  295           coalesced_gesture_events_.front(); |  294           coalesced_gesture_events_.front(); | 
|  296       if (gesture_event.event.type != first_event.event.type && |  295       if (gesture_event.event.type() != first_event.event.type() && | 
|  297           ui::IsCompatibleScrollorPinch(gesture_event.event, |  296           ui::IsCompatibleScrollorPinch(gesture_event.event, | 
|  298                                         first_event.event)) { |  297                                         first_event.event)) { | 
|  299         ignore_next_ack_ = true; |  298         ignore_next_ack_ = true; | 
|  300         client_->SendGestureEventImmediately(gesture_event); |  299         client_->SendGestureEventImmediately(gesture_event); | 
|  301       } |  300       } | 
|  302     } |  301     } | 
|  303     return; |  302     return; | 
|  304   } |  303   } | 
|  305  |  304  | 
|  306   GestureEventWithLatencyInfo* last_event = &coalesced_gesture_events_.back(); |  305   GestureEventWithLatencyInfo* last_event = &coalesced_gesture_events_.back(); | 
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  361     return 0; |  360     return 0; | 
|  362  |  361  | 
|  363   if (!ignore_next_ack_) |  362   if (!ignore_next_ack_) | 
|  364     return 1; |  363     return 1; | 
|  365  |  364  | 
|  366   DCHECK_GT(coalesced_gesture_events_.size(), 1U); |  365   DCHECK_GT(coalesced_gesture_events_.size(), 1U); | 
|  367   return 2; |  366   return 2; | 
|  368 } |  367 } | 
|  369  |  368  | 
|  370 }  // namespace content |  369 }  // namespace content | 
| OLD | NEW |