OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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/render_widget_host_input_event_router.h" | 5 #include "content/browser/renderer_host/render_widget_host_input_event_router.h" |
6 | 6 |
| 7 #include "base/metrics/histogram_macros.h" |
7 #include "cc/quads/surface_draw_quad.h" | 8 #include "cc/quads/surface_draw_quad.h" |
8 #include "cc/surfaces/surface_id_allocator.h" | 9 #include "cc/surfaces/surface_id_allocator.h" |
9 #include "cc/surfaces/surface_manager.h" | 10 #include "cc/surfaces/surface_manager.h" |
10 #include "content/browser/renderer_host/render_widget_host_impl.h" | 11 #include "content/browser/renderer_host/render_widget_host_impl.h" |
11 #include "content/browser/renderer_host/render_widget_host_view_base.h" | 12 #include "content/browser/renderer_host/render_widget_host_view_base.h" |
12 #include "content/common/frame_messages.h" | 13 #include "content/common/frame_messages.h" |
13 #include "third_party/WebKit/public/web/WebInputEvent.h" | 14 #include "third_party/WebKit/public/web/WebInputEvent.h" |
14 | 15 |
15 namespace { | 16 namespace { |
16 | 17 |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
181 break; | 182 break; |
182 case blink::WebGestureDeviceTouchpad: | 183 case blink::WebGestureDeviceTouchpad: |
183 RouteTouchpadGestureEvent(root_view, event, latency); | 184 RouteTouchpadGestureEvent(root_view, event, latency); |
184 break; | 185 break; |
185 case blink::WebGestureDeviceTouchscreen: | 186 case blink::WebGestureDeviceTouchscreen: |
186 RouteTouchscreenGestureEvent(root_view, event, latency); | 187 RouteTouchscreenGestureEvent(root_view, event, latency); |
187 break; | 188 break; |
188 }; | 189 }; |
189 } | 190 } |
190 | 191 |
| 192 namespace { |
| 193 |
| 194 unsigned CountChangedTouchPoints(const blink::WebTouchEvent& event) { |
| 195 unsigned changed_count = 0; |
| 196 |
| 197 blink::WebTouchPoint::State required_state = |
| 198 blink::WebTouchPoint::StateUndefined; |
| 199 switch (event.type) { |
| 200 case blink::WebInputEvent::TouchStart: |
| 201 required_state = blink::WebTouchPoint::StatePressed; |
| 202 break; |
| 203 case blink::WebInputEvent::TouchEnd: |
| 204 required_state = blink::WebTouchPoint::StateReleased; |
| 205 break; |
| 206 case blink::WebInputEvent::TouchCancel: |
| 207 required_state = blink::WebTouchPoint::StateCancelled; |
| 208 break; |
| 209 default: |
| 210 // We'll only ever call this method for TouchStart, TouchEnd |
| 211 // and TounchCancel events, so mark the rest as not-reached. |
| 212 NOTREACHED(); |
| 213 } |
| 214 for (unsigned i = 0; i < event.touchesLength; ++i) { |
| 215 if (event.touches[i].state == required_state) |
| 216 ++changed_count; |
| 217 } |
| 218 |
| 219 DCHECK(event.type == blink::WebInputEvent::TouchCancel || changed_count == 1); |
| 220 return changed_count; |
| 221 } |
| 222 |
| 223 } // namespace |
| 224 |
191 void RenderWidgetHostInputEventRouter::RouteTouchEvent( | 225 void RenderWidgetHostInputEventRouter::RouteTouchEvent( |
192 RenderWidgetHostViewBase* root_view, | 226 RenderWidgetHostViewBase* root_view, |
193 blink::WebTouchEvent* event, | 227 blink::WebTouchEvent* event, |
194 const ui::LatencyInfo& latency) { | 228 const ui::LatencyInfo& latency) { |
195 switch (event->type) { | 229 switch (event->type) { |
196 case blink::WebInputEvent::TouchStart: { | 230 case blink::WebInputEvent::TouchStart: { |
197 if (!active_touches_) { | 231 active_touches_ += CountChangedTouchPoints(*event); |
| 232 if (active_touches_ == 1) { |
198 // Since this is the first touch, it defines the target for the rest | 233 // Since this is the first touch, it defines the target for the rest |
199 // of this sequence. | 234 // of this sequence. |
200 DCHECK(!touch_target_.target); | 235 DCHECK(!touch_target_.target); |
201 gfx::Point transformed_point; | 236 gfx::Point transformed_point; |
202 gfx::Point original_point(event->touches[0].position.x, | 237 gfx::Point original_point(event->touches[0].position.x, |
203 event->touches[0].position.y); | 238 event->touches[0].position.y); |
204 touch_target_.target = | 239 touch_target_.target = |
205 FindEventTarget(root_view, original_point, &transformed_point); | 240 FindEventTarget(root_view, original_point, &transformed_point); |
206 | 241 |
207 // TODO(wjmaclean): Instead of just computing a delta, we should extract | 242 // TODO(wjmaclean): Instead of just computing a delta, we should extract |
208 // the complete transform. We assume it doesn't change for the duration | 243 // the complete transform. We assume it doesn't change for the duration |
209 // of the touch sequence, though this could be wrong; a better approach | 244 // of the touch sequence, though this could be wrong; a better approach |
210 // might be to always transform each point to the |touch_target_.target| | 245 // might be to always transform each point to the |touch_target_.target| |
211 // for the duration of the sequence. | 246 // for the duration of the sequence. |
212 touch_target_.delta = transformed_point - original_point; | 247 touch_target_.delta = transformed_point - original_point; |
213 touchscreen_gesture_target_queue_.push_back(touch_target_); | 248 touchscreen_gesture_target_queue_.push_back(touch_target_); |
214 | 249 |
215 if (!touch_target_.target) { | 250 if (!touch_target_.target) |
216 return; | 251 return; |
217 } else if (touch_target_.target == | 252 |
218 bubbling_gesture_scroll_target_.target) { | 253 if (touch_target_.target == bubbling_gesture_scroll_target_.target) { |
219 SendGestureScrollEnd(bubbling_gesture_scroll_target_.target, | 254 SendGestureScrollEnd(bubbling_gesture_scroll_target_.target, |
220 blink::WebGestureEvent()); | 255 blink::WebGestureEvent()); |
221 CancelScrollBubbling(bubbling_gesture_scroll_target_.target); | 256 CancelScrollBubbling(bubbling_gesture_scroll_target_.target); |
222 } | 257 } |
223 } | 258 } |
224 | 259 |
225 ++active_touches_; | |
226 if (touch_target_.target) { | 260 if (touch_target_.target) { |
227 TransformEventTouchPositions(event, touch_target_.delta); | 261 TransformEventTouchPositions(event, touch_target_.delta); |
228 touch_target_.target->ProcessTouchEvent(*event, latency); | 262 touch_target_.target->ProcessTouchEvent(*event, latency); |
229 } | 263 } |
230 break; | 264 break; |
231 } | 265 } |
232 case blink::WebInputEvent::TouchMove: | 266 case blink::WebInputEvent::TouchMove: |
233 if (touch_target_.target) { | 267 if (touch_target_.target) { |
234 TransformEventTouchPositions(event, touch_target_.delta); | 268 TransformEventTouchPositions(event, touch_target_.delta); |
235 touch_target_.target->ProcessTouchEvent(*event, latency); | 269 touch_target_.target->ProcessTouchEvent(*event, latency); |
236 } | 270 } |
237 break; | 271 break; |
238 case blink::WebInputEvent::TouchEnd: | 272 case blink::WebInputEvent::TouchEnd: |
239 case blink::WebInputEvent::TouchCancel: | 273 case blink::WebInputEvent::TouchCancel: |
| 274 DCHECK(active_touches_); |
| 275 active_touches_ -= CountChangedTouchPoints(*event); |
240 if (!touch_target_.target) | 276 if (!touch_target_.target) |
241 break; | 277 return; |
242 | 278 |
243 DCHECK(active_touches_); | |
244 TransformEventTouchPositions(event, touch_target_.delta); | 279 TransformEventTouchPositions(event, touch_target_.delta); |
245 touch_target_.target->ProcessTouchEvent(*event, latency); | 280 touch_target_.target->ProcessTouchEvent(*event, latency); |
246 --active_touches_; | |
247 if (!active_touches_) | 281 if (!active_touches_) |
248 touch_target_.target = nullptr; | 282 touch_target_.target = nullptr; |
249 break; | 283 break; |
250 default: | 284 default: |
251 NOTREACHED(); | 285 NOTREACHED(); |
252 } | 286 } |
253 } | 287 } |
254 | 288 |
255 void RenderWidgetHostInputEventRouter::BubbleScrollEvent( | 289 void RenderWidgetHostInputEventRouter::BubbleScrollEvent( |
256 RenderWidgetHostViewBase* target_view, | 290 RenderWidgetHostViewBase* target_view, |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
434 } | 468 } |
435 return; | 469 return; |
436 } | 470 } |
437 | 471 |
438 // We use GestureTapDown to detect the start of a gesture sequence since there | 472 // We use GestureTapDown to detect the start of a gesture sequence since there |
439 // is no WebGestureEvent equivalent for ET_GESTURE_BEGIN. Note that this | 473 // is no WebGestureEvent equivalent for ET_GESTURE_BEGIN. Note that this |
440 // means the GestureFlingCancel that always comes between ET_GESTURE_BEGIN and | 474 // means the GestureFlingCancel that always comes between ET_GESTURE_BEGIN and |
441 // GestureTapDown is sent to the previous target, in case it is still in a | 475 // GestureTapDown is sent to the previous target, in case it is still in a |
442 // fling. | 476 // fling. |
443 if (event->type == blink::WebInputEvent::GestureTapDown) { | 477 if (event->type == blink::WebInputEvent::GestureTapDown) { |
444 if (touchscreen_gesture_target_queue_.empty()) { | 478 bool no_target = touchscreen_gesture_target_queue_.empty(); |
| 479 // This UMA metric is temporary, and will be removed once it has fulfilled |
| 480 // it's purpose, namely telling us when the incidents of empty |
| 481 // gesture-queues has dropped to zero. https://crbug.com/642008 |
| 482 UMA_HISTOGRAM_BOOLEAN("Event.FrameEventRouting.NoGestureTarget", no_target); |
| 483 if (no_target) { |
445 LOG(ERROR) << "Gesture sequence start detected with no target available."; | 484 LOG(ERROR) << "Gesture sequence start detected with no target available."; |
446 // Ignore this gesture sequence as no target is available. | 485 // Ignore this gesture sequence as no target is available. |
447 // TODO(wjmaclean): this only happens on Windows, and should not happen. | 486 // TODO(wjmaclean): this only happens on Windows, and should not happen. |
448 // https://crbug.com/595422 | 487 // https://crbug.com/595422 |
449 touchscreen_gesture_target_.target = nullptr; | 488 touchscreen_gesture_target_.target = nullptr; |
450 return; | 489 return; |
451 } | 490 } |
452 | 491 |
453 touchscreen_gesture_target_ = touchscreen_gesture_target_queue_.front(); | 492 touchscreen_gesture_target_ = touchscreen_gesture_target_queue_.front(); |
454 touchscreen_gesture_target_queue_.pop_front(); | 493 touchscreen_gesture_target_queue_.pop_front(); |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
504 if (!touchpad_gesture_target_.target) | 543 if (!touchpad_gesture_target_.target) |
505 return; | 544 return; |
506 | 545 |
507 // TODO(mohsen): Add tests to check event location. | 546 // TODO(mohsen): Add tests to check event location. |
508 event->x += touchpad_gesture_target_.delta.x(); | 547 event->x += touchpad_gesture_target_.delta.x(); |
509 event->y += touchpad_gesture_target_.delta.y(); | 548 event->y += touchpad_gesture_target_.delta.y(); |
510 touchpad_gesture_target_.target->ProcessGestureEvent(*event, latency); | 549 touchpad_gesture_target_.target->ProcessGestureEvent(*event, latency); |
511 } | 550 } |
512 | 551 |
513 } // namespace content | 552 } // namespace content |
OLD | NEW |