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 "ui/events/gesture_detection/touch_disposition_gesture_filter.h" | 5 #include "ui/events/gesture_detection/touch_disposition_gesture_filter.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include "base/auto_reset.h" | 9 #include "base/auto_reset.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
11 #include "ui/events/gesture_event_details.h" | 11 #include "ui/events/gesture_event_details.h" |
12 | 12 |
13 namespace ui { | 13 namespace ui { |
14 namespace { | 14 namespace { |
15 | 15 |
16 // A BitSet32 is used for tracking dropped gesture types. | 16 // A BitSet32 is used for tracking dropped gesture types. |
17 static_assert(ET_GESTURE_TYPE_END - ET_GESTURE_TYPE_START < 32, | 17 static_assert(ET_GESTURE_TYPE_END - ET_GESTURE_TYPE_START < 32, |
18 "gesture type count too large"); | 18 "gesture type count too large"); |
19 | 19 |
20 GestureEventData CreateGesture(EventType type, | 20 GestureEventData CreateGesture(EventType type, |
21 int motion_event_id, | 21 int motion_event_id, |
22 MotionEvent::ToolType primary_tool_type, | 22 MotionEvent::ToolType primary_tool_type, |
23 const GestureEventDataPacket& packet) { | 23 const GestureEventDataPacket& packet) { |
24 // As the event is purely synthetic, we needn't be strict with event flags. | 24 // As the event is purely synthetic, we needn't be strict with event flags. |
25 int flags = EF_NONE; | 25 int flags = EF_NONE; |
26 GestureEventDetails details(type); | 26 GestureEventDetails details(type); |
27 details.set_device_type(GestureDeviceType::DEVICE_TOUCHSCREEN); | 27 details.set_device_type(GestureDeviceType::DEVICE_TOUCHSCREEN); |
28 return GestureEventData( | 28 return GestureEventData(details, |
29 details, motion_event_id, primary_tool_type, packet.timestamp(), | 29 motion_event_id, |
30 packet.touch_location().x(), packet.touch_location().y(), | 30 primary_tool_type, |
31 packet.raw_touch_location().x(), packet.raw_touch_location().y(), 1, | 31 packet.timestamp(), |
32 gfx::RectF(packet.touch_location(), gfx::SizeF()), flags); | 32 packet.touch_location().x(), |
| 33 packet.touch_location().y(), |
| 34 packet.raw_touch_location().x(), |
| 35 packet.raw_touch_location().y(), |
| 36 1, |
| 37 gfx::RectF(packet.touch_location(), gfx::SizeF()), |
| 38 flags, |
| 39 packet.unique_touch_event_id()); |
33 } | 40 } |
34 | 41 |
35 enum RequiredTouches { | 42 enum RequiredTouches { |
36 RT_NONE = 0, | 43 RT_NONE = 0, |
37 RT_START = 1 << 0, | 44 RT_START = 1 << 0, |
38 RT_CURRENT = 1 << 1, | 45 RT_CURRENT = 1 << 1, |
39 }; | 46 }; |
40 | 47 |
41 struct DispositionHandlingInfo { | 48 struct DispositionHandlingInfo { |
42 // A bitwise-OR of |RequiredTouches|. | 49 // A bitwise-OR of |RequiredTouches|. |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
176 if (!Head().empty()) { | 183 if (!Head().empty()) { |
177 DCHECK_NE(packet.unique_touch_event_id(), | 184 DCHECK_NE(packet.unique_touch_event_id(), |
178 Head().front().unique_touch_event_id()); | 185 Head().front().unique_touch_event_id()); |
179 | 186 |
180 } | 187 } |
181 | 188 |
182 Tail().push(packet); | 189 Tail().push(packet); |
183 return SUCCESS; | 190 return SUCCESS; |
184 } | 191 } |
185 | 192 |
186 void TouchDispositionGestureFilter::OnTouchEventAck(uint32_t unique_event_id, | 193 void TouchDispositionGestureFilter::OnTouchEventAck( |
187 bool event_consumed) { | 194 uint32_t unique_touch_event_id, bool event_consumed) { |
188 // Spurious asynchronous acks should not trigger a crash. | 195 // Spurious asynchronous acks should not trigger a crash. |
189 if (IsEmpty() || (Head().empty() && sequences_.size() == 1)) | 196 if (IsEmpty() || (Head().empty() && sequences_.size() == 1)) |
190 return; | 197 return; |
191 | 198 |
192 if (Head().empty()) | 199 if (Head().empty()) |
193 PopGestureSequence(); | 200 PopGestureSequence(); |
194 | 201 |
195 if (!Tail().empty() && | 202 if (!Tail().empty() && |
196 Tail().back().unique_touch_event_id() == unique_event_id) { | 203 Tail().back().unique_touch_event_id() == unique_touch_event_id) { |
197 Tail().back().Ack(event_consumed); | 204 Tail().back().Ack(event_consumed); |
198 if (sequences_.size() == 1 && Tail().size() == 1) | 205 if (sequences_.size() == 1 && Tail().size() == 1) |
199 SendAckedEvents(); | 206 SendAckedEvents(); |
200 } else { | 207 } else { |
201 DCHECK(!Head().empty()); | 208 DCHECK(!Head().empty()); |
202 DCHECK_EQ(Head().front().unique_touch_event_id(), unique_event_id); | 209 DCHECK_EQ(Head().front().unique_touch_event_id(), unique_touch_event_id); |
203 Head().front().Ack(event_consumed); | 210 Head().front().Ack(event_consumed); |
204 SendAckedEvents(); | 211 SendAckedEvents(); |
205 } | 212 } |
206 } | 213 } |
207 | 214 |
208 void TouchDispositionGestureFilter::SendAckedEvents() { | 215 void TouchDispositionGestureFilter::SendAckedEvents() { |
209 // Dispatch all packets corresponding to ack'ed touches, as well as | 216 // Dispatch all packets corresponding to ack'ed touches, as well as |
210 // any pending timeout-based packets. | 217 // any pending timeout-based packets. |
211 bool touch_packet_for_current_ack_handled = false; | 218 bool touch_packet_for_current_ack_handled = false; |
212 while (!IsEmpty() && (!Head().empty() || sequences_.size() != 1)) { | 219 while (!IsEmpty() && (!Head().empty() || sequences_.size() != 1)) { |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
295 EndScrollIfNecessary(packet); | 302 EndScrollIfNecessary(packet); |
296 } | 303 } |
297 // Always send the ET_GESTURE_END event as the last one for every touch event. | 304 // Always send the ET_GESTURE_END event as the last one for every touch event. |
298 if (gesture_end_index >= 0) | 305 if (gesture_end_index >= 0) |
299 SendGesture(packet.gesture(gesture_end_index), packet); | 306 SendGesture(packet.gesture(gesture_end_index), packet); |
300 } | 307 } |
301 | 308 |
302 void TouchDispositionGestureFilter::SendGesture( | 309 void TouchDispositionGestureFilter::SendGesture( |
303 const GestureEventData& event, | 310 const GestureEventData& event, |
304 const GestureEventDataPacket& packet_being_sent) { | 311 const GestureEventDataPacket& packet_being_sent) { |
| 312 DCHECK(event.unique_touch_event_id == |
| 313 packet_being_sent.unique_touch_event_id()); |
| 314 |
305 // TODO(jdduke): Factor out gesture stream reparation code into a standalone | 315 // TODO(jdduke): Factor out gesture stream reparation code into a standalone |
306 // utility class. | 316 // utility class. |
307 switch (event.type()) { | 317 switch (event.type()) { |
308 case ET_GESTURE_LONG_TAP: | 318 case ET_GESTURE_LONG_TAP: |
309 if (!needs_tap_ending_event_) | 319 if (!needs_tap_ending_event_) |
310 return; | 320 return; |
311 CancelTapIfNecessary(packet_being_sent); | 321 CancelTapIfNecessary(packet_being_sent); |
312 CancelFlingIfNecessary(packet_being_sent); | 322 CancelFlingIfNecessary(packet_being_sent); |
313 break; | 323 break; |
314 case ET_GESTURE_TAP_DOWN: | 324 case ET_GESTURE_TAP_DOWN: |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
468 return false; | 478 return false; |
469 } | 479 } |
470 | 480 |
471 bool TouchDispositionGestureFilter::GestureHandlingState:: | 481 bool TouchDispositionGestureFilter::GestureHandlingState:: |
472 HasFilteredGestureType(EventType gesture_type) const { | 482 HasFilteredGestureType(EventType gesture_type) const { |
473 return any_gesture_of_type_dropped_.has_bit( | 483 return any_gesture_of_type_dropped_.has_bit( |
474 GetGestureTypeIndex(gesture_type)); | 484 GetGestureTypeIndex(gesture_type)); |
475 } | 485 } |
476 | 486 |
477 } // namespace content | 487 } // namespace content |
OLD | NEW |