Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(184)

Side by Side Diff: content/browser/renderer_host/input/passthrough_touch_event_queue.cc

Issue 2816613003: Add suppresion of slop region touches in browser (Closed)
Patch Set: Fix the tests Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2017 The Chromium Authors. All rights reserved. 1 // Copyright 2017 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/passthrough_touch_event_queue.h" 5 #include "content/browser/renderer_host/input/passthrough_touch_event_queue.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/auto_reset.h" 9 #include "base/auto_reset.h"
10 #include "base/macros.h" 10 #include "base/macros.h"
11 #include "base/memory/ptr_util.h" 11 #include "base/memory/ptr_util.h"
12 #include "base/metrics/histogram_macros.h" 12 #include "base/metrics/histogram_macros.h"
13 #include "base/trace_event/trace_event.h" 13 #include "base/trace_event/trace_event.h"
14 #include "content/browser/renderer_host/input/touch_timeout_handler.h" 14 #include "content/browser/renderer_host/input/touch_timeout_handler.h"
15 #include "content/common/input/web_touch_event_traits.h" 15 #include "content/common/input/web_touch_event_traits.h"
16 #include "ui/events/base_event_utils.h" 16 #include "ui/events/base_event_utils.h"
17 #include "ui/gfx/geometry/point_f.h" 17 #include "ui/gfx/geometry/point_f.h"
18 18
19 using blink::WebInputEvent; 19 using blink::WebInputEvent;
20 using blink::WebTouchEvent; 20 using blink::WebTouchEvent;
21 using blink::WebTouchPoint; 21 using blink::WebTouchPoint;
22 using ui::LatencyInfo; 22 using ui::LatencyInfo;
23 23
24 namespace content { 24 namespace content {
25 namespace { 25 namespace {
26 26
27 // A sanity check on touches received to ensure that touch movement outside
28 // the platform slop region will cause scrolling.
29 const double kMaxConceivablePlatformSlopRegionLengthDipsSquared = 60. * 60.;
30
27 // Compare all properties of touch points to determine the state. 31 // Compare all properties of touch points to determine the state.
28 bool HasPointChanged(const WebTouchPoint& point_1, 32 bool HasPointChanged(const WebTouchPoint& point_1,
29 const WebTouchPoint& point_2) { 33 const WebTouchPoint& point_2) {
30 DCHECK_EQ(point_1.id, point_2.id); 34 DCHECK_EQ(point_1.id, point_2.id);
31 if (point_1.screen_position != point_2.screen_position || 35 if (point_1.screen_position != point_2.screen_position ||
32 point_1.position != point_2.position || 36 point_1.position != point_2.position ||
33 point_1.radius_x != point_2.radius_x || 37 point_1.radius_x != point_2.radius_x ||
34 point_1.radius_y != point_2.radius_y || 38 point_1.radius_y != point_2.radius_y ||
35 point_1.rotation_angle != point_2.rotation_angle || 39 point_1.rotation_angle != point_2.rotation_angle ||
36 point_1.force != point_2.force || point_1.tilt_x != point_2.tilt_x || 40 point_1.force != point_2.force || point_1.tilt_x != point_2.tilt_x ||
37 point_1.tilt_y != point_2.tilt_y) { 41 point_1.tilt_y != point_2.tilt_y) {
38 return true; 42 return true;
39 } 43 }
40 return false; 44 return false;
41 } 45 }
42 46
43 } // namespace 47 } // namespace
44 48
49 // Provides touchmove slop suppression for a touch sequence until a
50 // (unprevented) touch will trigger immediate scrolling.
51 class TouchMoveSlopSuppressor {
tdresser 2017/04/13 18:13:35 Should this move to another file? Or the anonymous
Navid Zolghadr 2017/04/18 14:47:41 This wasn't quite possible. At least I couldn't ge
tdresser 2017/04/18 15:20:26 Acknowledged.
52 public:
53 TouchMoveSlopSuppressor() : suppressing_touchmoves_(false) {}
54
55 bool FilterEvent(const WebTouchEvent& event) {
56 if (WebTouchEventTraits::IsTouchSequenceStart(event)) {
57 suppressing_touchmoves_ = true;
58 touch_start_location_ = gfx::PointF(event.touches[0].position);
59 }
60
61 if (event.GetType() == WebInputEvent::kTouchEnd ||
62 event.GetType() == WebInputEvent::kTouchCancel)
63 suppressing_touchmoves_ = false;
64
65 if (event.GetType() != WebInputEvent::kTouchMove)
66 return false;
67
68 if (suppressing_touchmoves_) {
69 if (event.touches_length > 1) {
70 suppressing_touchmoves_ = false;
71 } else if (event.moved_beyond_slop_region) {
72 suppressing_touchmoves_ = false;
73 } else {
74 // No sane slop region should be larger than 60 DIPs.
75 DCHECK_LT(
76 (gfx::PointF(event.touches[0].position) - touch_start_location_)
77 .LengthSquared(),
78 kMaxConceivablePlatformSlopRegionLengthDipsSquared);
79 }
80 }
81
82 return suppressing_touchmoves_;
83 }
84
85 void ConfirmTouchEvent(InputEventAckState ack_result) {
86 if (ack_result == INPUT_EVENT_ACK_STATE_CONSUMED)
87 suppressing_touchmoves_ = false;
88 }
89
90 bool suppressing_touchmoves() const { return suppressing_touchmoves_; }
91
92 private:
93 bool suppressing_touchmoves_;
94
95 // Sanity check that the upstream touch provider is properly reporting whether
96 // the touch sequence will cause scrolling.
97 gfx::PointF touch_start_location_;
98
99 DISALLOW_COPY_AND_ASSIGN(TouchMoveSlopSuppressor);
100 };
101
45 PassthroughTouchEventQueue::TouchEventWithLatencyInfoAndAckState:: 102 PassthroughTouchEventQueue::TouchEventWithLatencyInfoAndAckState::
46 TouchEventWithLatencyInfoAndAckState(const TouchEventWithLatencyInfo& event) 103 TouchEventWithLatencyInfoAndAckState(const TouchEventWithLatencyInfo& event)
47 : TouchEventWithLatencyInfo(event), 104 : TouchEventWithLatencyInfo(event),
48 ack_state_(INPUT_EVENT_ACK_STATE_UNKNOWN) {} 105 ack_state_(INPUT_EVENT_ACK_STATE_UNKNOWN) {}
49 106
50 bool PassthroughTouchEventQueue::TouchEventWithLatencyInfoAndAckState:: 107 bool PassthroughTouchEventQueue::TouchEventWithLatencyInfoAndAckState::
51 operator<(const TouchEventWithLatencyInfoAndAckState& other) const { 108 operator<(const TouchEventWithLatencyInfoAndAckState& other) const {
52 return event.unique_touch_event_id < other.event.unique_touch_event_id; 109 return event.unique_touch_event_id < other.event.unique_touch_event_id;
53 } 110 }
54 111
55 PassthroughTouchEventQueue::PassthroughTouchEventQueue( 112 PassthroughTouchEventQueue::PassthroughTouchEventQueue(
56 TouchEventQueueClient* client, 113 TouchEventQueueClient* client,
57 const Config& config) 114 const Config& config)
58 : client_(client), 115 : client_(client),
59 has_handlers_(true), 116 has_handlers_(true),
60 maybe_has_handler_for_current_sequence_(false), 117 maybe_has_handler_for_current_sequence_(false),
61 drop_remaining_touches_in_sequence_(false), 118 drop_remaining_touches_in_sequence_(false),
119 touchmove_slop_suppressor_(new TouchMoveSlopSuppressor),
62 send_touch_events_async_(false) { 120 send_touch_events_async_(false) {
63 if (config.touch_ack_timeout_supported) { 121 if (config.touch_ack_timeout_supported) {
64 timeout_handler_.reset( 122 timeout_handler_.reset(
65 new TouchTimeoutHandler(this, config.desktop_touch_ack_timeout_delay, 123 new TouchTimeoutHandler(this, config.desktop_touch_ack_timeout_delay,
66 config.mobile_touch_ack_timeout_delay)); 124 config.mobile_touch_ack_timeout_delay));
67 } 125 }
68 } 126 }
69 127
70 PassthroughTouchEventQueue::~PassthroughTouchEventQueue() {} 128 PassthroughTouchEventQueue::~PassthroughTouchEventQueue() {}
71 129
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
113 171
114 void PassthroughTouchEventQueue::ProcessTouchAck( 172 void PassthroughTouchEventQueue::ProcessTouchAck(
115 InputEventAckState ack_result, 173 InputEventAckState ack_result,
116 const LatencyInfo& latency_info, 174 const LatencyInfo& latency_info,
117 const uint32_t unique_touch_event_id) { 175 const uint32_t unique_touch_event_id) {
118 TRACE_EVENT0("input", "PassthroughTouchEventQueue::ProcessTouchAck"); 176 TRACE_EVENT0("input", "PassthroughTouchEventQueue::ProcessTouchAck");
119 if (timeout_handler_ && 177 if (timeout_handler_ &&
120 timeout_handler_->ConfirmTouchEvent(unique_touch_event_id, ack_result)) 178 timeout_handler_->ConfirmTouchEvent(unique_touch_event_id, ack_result))
121 return; 179 return;
122 180
181 touchmove_slop_suppressor_->ConfirmTouchEvent(ack_result);
182
123 auto touch_event_iter = outstanding_touches_.begin(); 183 auto touch_event_iter = outstanding_touches_.begin();
124 while (touch_event_iter != outstanding_touches_.end()) { 184 while (touch_event_iter != outstanding_touches_.end()) {
125 if (unique_touch_event_id == touch_event_iter->event.unique_touch_event_id) 185 if (unique_touch_event_id == touch_event_iter->event.unique_touch_event_id)
126 break; 186 break;
127 ++touch_event_iter; 187 ++touch_event_iter;
128 } 188 }
129 189
130 if (touch_event_iter == outstanding_touches_.end()) 190 if (touch_event_iter == outstanding_touches_.end())
131 return; 191 return;
132 192
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
290 drop_remaining_touches_in_sequence_ = false; 350 drop_remaining_touches_in_sequence_ = false;
291 if (!has_handlers_) { 351 if (!has_handlers_) {
292 drop_remaining_touches_in_sequence_ = true; 352 drop_remaining_touches_in_sequence_ = true;
293 return ACK_WITH_NO_CONSUMER_EXISTS; 353 return ACK_WITH_NO_CONSUMER_EXISTS;
294 } 354 }
295 } 355 }
296 356
297 if (timeout_handler_ && timeout_handler_->FilterEvent(event)) 357 if (timeout_handler_ && timeout_handler_->FilterEvent(event))
298 return ACK_WITH_NO_CONSUMER_EXISTS; 358 return ACK_WITH_NO_CONSUMER_EXISTS;
299 359
360 if (touchmove_slop_suppressor_->FilterEvent(event))
361 return ACK_WITH_NOT_CONSUMED;
362
300 if (drop_remaining_touches_in_sequence_ && 363 if (drop_remaining_touches_in_sequence_ &&
301 event.GetType() != WebInputEvent::kTouchCancel) { 364 event.GetType() != WebInputEvent::kTouchCancel) {
302 return ACK_WITH_NO_CONSUMER_EXISTS; 365 return ACK_WITH_NO_CONSUMER_EXISTS;
303 } 366 }
304 367
305 if (event.GetType() == WebInputEvent::kTouchStart) { 368 if (event.GetType() == WebInputEvent::kTouchStart) {
306 return (has_handlers_ || maybe_has_handler_for_current_sequence_) 369 return (has_handlers_ || maybe_has_handler_for_current_sequence_)
307 ? FORWARD_TO_RENDERER 370 ? FORWARD_TO_RENDERER
308 : ACK_WITH_NO_CONSUMER_EXISTS; 371 : ACK_WITH_NO_CONSUMER_EXISTS;
309 } 372 }
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
374 bool PassthroughTouchEventQueue::IsTimeoutRunningForTesting() const { 437 bool PassthroughTouchEventQueue::IsTimeoutRunningForTesting() const {
375 return timeout_handler_ && timeout_handler_->IsTimeoutTimerRunning(); 438 return timeout_handler_ && timeout_handler_->IsTimeoutTimerRunning();
376 } 439 }
377 440
378 const TouchEventWithLatencyInfo& 441 const TouchEventWithLatencyInfo&
379 PassthroughTouchEventQueue::GetLatestEventForTesting() const { 442 PassthroughTouchEventQueue::GetLatestEventForTesting() const {
380 return *outstanding_touches_.rbegin(); 443 return *outstanding_touches_.rbegin();
381 } 444 }
382 445
383 } // namespace content 446 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698