| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/input_router_impl.h" | 5 #include "content/browser/renderer_host/input/input_router_impl.h" |
| 6 | 6 |
| 7 #include <math.h> | 7 #include <math.h> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/auto_reset.h" | 10 #include "base/auto_reset.h" |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 137 const NativeWebKeyboardEventWithLatencyInfo& key_event) { | 137 const NativeWebKeyboardEventWithLatencyInfo& key_event) { |
| 138 // Put all WebKeyboardEvent objects in a queue since we can't trust the | 138 // Put all WebKeyboardEvent objects in a queue since we can't trust the |
| 139 // renderer and we need to give something to the HandleKeyboardEvent | 139 // renderer and we need to give something to the HandleKeyboardEvent |
| 140 // handler. | 140 // handler. |
| 141 key_queue_.push_back(key_event); | 141 key_queue_.push_back(key_event); |
| 142 LOCAL_HISTOGRAM_COUNTS_100("Renderer.KeyboardQueueSize", key_queue_.size()); | 142 LOCAL_HISTOGRAM_COUNTS_100("Renderer.KeyboardQueueSize", key_queue_.size()); |
| 143 | 143 |
| 144 gesture_event_queue_.FlingHasBeenHalted(); | 144 gesture_event_queue_.FlingHasBeenHalted(); |
| 145 | 145 |
| 146 // Only forward the non-native portions of our event. | 146 // Only forward the non-native portions of our event. |
| 147 FilterAndSendWebInputEvent(key_event.event, key_event.latency); | 147 FilterAndSendWebInputEvent(key_event.event, &key_event.latency); |
| 148 } | 148 } |
| 149 | 149 |
| 150 void InputRouterImpl::SendGestureEvent( | 150 void InputRouterImpl::SendGestureEvent( |
| 151 const GestureEventWithLatencyInfo& original_gesture_event) { | 151 const GestureEventWithLatencyInfo& original_gesture_event) { |
| 152 input_stream_validator_.Validate(original_gesture_event.event); | 152 input_stream_validator_.Validate(original_gesture_event.event); |
| 153 | 153 |
| 154 GestureEventWithLatencyInfo gesture_event(original_gesture_event); | 154 GestureEventWithLatencyInfo gesture_event(original_gesture_event); |
| 155 | 155 |
| 156 if (touch_action_filter_.FilterGestureEvent(&gesture_event.event)) | 156 if (touch_action_filter_.FilterGestureEvent(&gesture_event.event)) |
| 157 return; | 157 return; |
| (...skipping 25 matching lines...) Expand all Loading... |
| 183 if (!next_mouse_move_) | 183 if (!next_mouse_move_) |
| 184 next_mouse_move_.reset(new MouseEventWithLatencyInfo(mouse_event)); | 184 next_mouse_move_.reset(new MouseEventWithLatencyInfo(mouse_event)); |
| 185 else | 185 else |
| 186 next_mouse_move_->CoalesceWith(mouse_event); | 186 next_mouse_move_->CoalesceWith(mouse_event); |
| 187 return; | 187 return; |
| 188 } | 188 } |
| 189 mouse_move_pending_ = true; | 189 mouse_move_pending_ = true; |
| 190 current_mouse_move_ = mouse_event; | 190 current_mouse_move_ = mouse_event; |
| 191 } | 191 } |
| 192 | 192 |
| 193 FilterAndSendWebInputEvent(mouse_event.event, mouse_event.latency); | 193 FilterAndSendWebInputEvent(mouse_event.event, &mouse_event.latency); |
| 194 } | 194 } |
| 195 | 195 |
| 196 void InputRouterImpl::SendTouchEventImmediately( | 196 void InputRouterImpl::SendTouchEventImmediately( |
| 197 const TouchEventWithLatencyInfo& touch_event) { | 197 const TouchEventWithLatencyInfo& touch_event) { |
| 198 if (WebTouchEventTraits::IsTouchSequenceStart(touch_event.event)) { | 198 if (WebTouchEventTraits::IsTouchSequenceStart(touch_event.event)) { |
| 199 touch_action_filter_.ResetTouchAction(); | 199 touch_action_filter_.ResetTouchAction(); |
| 200 // Note that if the previous touch-action was TOUCH_ACTION_NONE, enabling | 200 // Note that if the previous touch-action was TOUCH_ACTION_NONE, enabling |
| 201 // the timeout here will not take effect until the *following* touch | 201 // the timeout here will not take effect until the *following* touch |
| 202 // sequence. This is a desirable side-effect, giving the renderer a chance | 202 // sequence. This is a desirable side-effect, giving the renderer a chance |
| 203 // to send a touch-action response without racing against the ack timeout. | 203 // to send a touch-action response without racing against the ack timeout. |
| 204 UpdateTouchAckTimeoutEnabled(); | 204 UpdateTouchAckTimeoutEnabled(); |
| 205 } | 205 } |
| 206 | 206 |
| 207 FilterAndSendWebInputEvent(touch_event.event, touch_event.latency); | 207 FilterAndSendWebInputEvent(touch_event.event, &touch_event.latency); |
| 208 } | 208 } |
| 209 | 209 |
| 210 void InputRouterImpl::SendGestureEventImmediately( | 210 void InputRouterImpl::SendGestureEventImmediately( |
| 211 const GestureEventWithLatencyInfo& gesture_event) { | 211 const GestureEventWithLatencyInfo& gesture_event) { |
| 212 FilterAndSendWebInputEvent(gesture_event.event, gesture_event.latency); | 212 FilterAndSendWebInputEvent(gesture_event.event, &gesture_event.latency); |
| 213 } | 213 } |
| 214 | 214 |
| 215 const NativeWebKeyboardEvent* InputRouterImpl::GetLastKeyboardEvent() const { | 215 const NativeWebKeyboardEvent* InputRouterImpl::GetLastKeyboardEvent() const { |
| 216 if (key_queue_.empty()) | 216 if (key_queue_.empty()) |
| 217 return NULL; | 217 return NULL; |
| 218 return &key_queue_.front().event; | 218 return &key_queue_.front().event; |
| 219 } | 219 } |
| 220 | 220 |
| 221 void InputRouterImpl::NotifySiteIsMobileOptimized(bool is_mobile_optimized) { | 221 void InputRouterImpl::NotifySiteIsMobileOptimized(bool is_mobile_optimized) { |
| 222 touch_event_queue_.SetIsMobileOptimizedSite(is_mobile_optimized); | 222 touch_event_queue_.SetIsMobileOptimizedSite(is_mobile_optimized); |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 284 | 284 |
| 285 void InputRouterImpl::OnGestureEventAck( | 285 void InputRouterImpl::OnGestureEventAck( |
| 286 const GestureEventWithLatencyInfo& event, | 286 const GestureEventWithLatencyInfo& event, |
| 287 InputEventAckState ack_result) { | 287 InputEventAckState ack_result) { |
| 288 touch_event_queue_.OnGestureEventAck(event, ack_result); | 288 touch_event_queue_.OnGestureEventAck(event, ack_result); |
| 289 ack_handler_->OnGestureEventAck(event, ack_result); | 289 ack_handler_->OnGestureEventAck(event, ack_result); |
| 290 } | 290 } |
| 291 | 291 |
| 292 void InputRouterImpl::SendMouseWheelEventImmediately( | 292 void InputRouterImpl::SendMouseWheelEventImmediately( |
| 293 const MouseWheelEventWithLatencyInfo& wheel_event) { | 293 const MouseWheelEventWithLatencyInfo& wheel_event) { |
| 294 FilterAndSendWebInputEvent(wheel_event.event, wheel_event.latency); | 294 FilterAndSendWebInputEvent(wheel_event.event, &wheel_event.latency); |
| 295 } | 295 } |
| 296 | 296 |
| 297 void InputRouterImpl::OnMouseWheelEventAck( | 297 void InputRouterImpl::OnMouseWheelEventAck( |
| 298 const MouseWheelEventWithLatencyInfo& event, | 298 const MouseWheelEventWithLatencyInfo& event, |
| 299 InputEventAckState ack_result) { | 299 InputEventAckState ack_result) { |
| 300 ack_handler_->OnWheelEventAck(event, ack_result); | 300 ack_handler_->OnWheelEventAck(event, ack_result); |
| 301 } | 301 } |
| 302 | 302 |
| 303 bool InputRouterImpl::SendSelectMessage( | 303 bool InputRouterImpl::SendSelectMessage( |
| 304 scoped_ptr<IPC::Message> message) { | 304 scoped_ptr<IPC::Message> message) { |
| (...skipping 27 matching lines...) Expand all Loading... |
| 332 move_caret_pending_ = true; | 332 move_caret_pending_ = true; |
| 333 return Send(message.release()); | 333 return Send(message.release()); |
| 334 } | 334 } |
| 335 | 335 |
| 336 bool InputRouterImpl::Send(IPC::Message* message) { | 336 bool InputRouterImpl::Send(IPC::Message* message) { |
| 337 return sender_->Send(message); | 337 return sender_->Send(message); |
| 338 } | 338 } |
| 339 | 339 |
| 340 void InputRouterImpl::FilterAndSendWebInputEvent( | 340 void InputRouterImpl::FilterAndSendWebInputEvent( |
| 341 const WebInputEvent& input_event, | 341 const WebInputEvent& input_event, |
| 342 const ui::LatencyInfo& latency_info) { | 342 ui::LatencyInfo* latency_info) { |
| 343 TRACE_EVENT1("input", | 343 TRACE_EVENT1("input", |
| 344 "InputRouterImpl::FilterAndSendWebInputEvent", | 344 "InputRouterImpl::FilterAndSendWebInputEvent", |
| 345 "type", | 345 "type", |
| 346 WebInputEventTraits::GetName(input_event.type)); | 346 WebInputEventTraits::GetName(input_event.type)); |
| 347 TRACE_EVENT_WITH_FLOW2("input,benchmark,devtools.timeline", | 347 TRACE_EVENT_WITH_FLOW2("input,benchmark,devtools.timeline", |
| 348 "LatencyInfo.Flow", | 348 "LatencyInfo.Flow", |
| 349 TRACE_ID_DONT_MANGLE(latency_info.trace_id()), | 349 TRACE_ID_DONT_MANGLE(latency_info->trace_id()), |
| 350 TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, | 350 TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, |
| 351 "step", "SendInputEventUI", | 351 "step", "SendInputEventUI", |
| 352 "frameTreeNodeId", frame_tree_node_id_); | 352 "frameTreeNodeId", frame_tree_node_id_); |
| 353 | 353 |
| 354 // Any input event cancels a pending mouse move event. | 354 // Any input event cancels a pending mouse move event. |
| 355 next_mouse_move_.reset(); | 355 next_mouse_move_.reset(); |
| 356 | 356 |
| 357 OfferToHandlers(input_event, latency_info); | 357 OfferToHandlers(input_event, latency_info); |
| 358 } | 358 } |
| 359 | 359 |
| 360 void InputRouterImpl::OfferToHandlers(const WebInputEvent& input_event, | 360 void InputRouterImpl::OfferToHandlers(const WebInputEvent& input_event, |
| 361 const ui::LatencyInfo& latency_info) { | 361 ui::LatencyInfo* latency_info) { |
| 362 output_stream_validator_.Validate(input_event); | 362 output_stream_validator_.Validate(input_event); |
| 363 | 363 |
| 364 if (OfferToClient(input_event, latency_info)) | 364 if (OfferToClient(input_event, *latency_info)) |
| 365 return; | 365 return; |
| 366 | 366 |
| 367 // Touch events should always indicate in the event whether they are | 367 // Touch events should always indicate in the event whether they are |
| 368 // cancelable (respect ACK disposition) or not except touchmove. | 368 // cancelable (respect ACK disposition) or not except touchmove. |
| 369 bool should_block = WebInputEventTraits::ShouldBlockEventStream(input_event); | 369 bool should_block = WebInputEventTraits::ShouldBlockEventStream(input_event); |
| 370 | 370 |
| 371 OfferToRenderer(input_event, latency_info, | 371 OfferToRenderer(input_event, |
| 372 should_block | 372 should_block |
| 373 ? InputEventDispatchType::DISPATCH_TYPE_BLOCKING | 373 ? InputEventDispatchType::DISPATCH_TYPE_BLOCKING |
| 374 : InputEventDispatchType::DISPATCH_TYPE_NON_BLOCKING); | 374 : InputEventDispatchType::DISPATCH_TYPE_NON_BLOCKING, |
| 375 latency_info); |
| 375 | 376 |
| 376 if (WebInputEvent::isTouchEventType(input_event.type) && | 377 if (WebInputEvent::isTouchEventType(input_event.type) && |
| 377 input_event.type != WebInputEvent::TouchMove) { | 378 input_event.type != WebInputEvent::TouchMove) { |
| 378 const WebTouchEvent& touch = static_cast<const WebTouchEvent&>(input_event); | 379 const WebTouchEvent& touch = static_cast<const WebTouchEvent&>(input_event); |
| 379 DCHECK_EQ(should_block, touch.cancelable); | 380 DCHECK_EQ(should_block, touch.cancelable); |
| 380 } | 381 } |
| 381 | 382 |
| 382 // Generate a synthetic ack if the event was sent so it doesn't block. | 383 // Generate a synthetic ack if the event was sent so it doesn't block. |
| 383 if (!should_block) { | 384 if (!should_block) { |
| 384 ProcessInputEventAck( | 385 ProcessInputEventAck( |
| 385 input_event.type, INPUT_EVENT_ACK_STATE_IGNORED, latency_info, | 386 input_event.type, INPUT_EVENT_ACK_STATE_IGNORED, *latency_info, |
| 386 WebInputEventTraits::GetUniqueTouchEventId(input_event), | 387 WebInputEventTraits::GetUniqueTouchEventId(input_event), |
| 387 IGNORING_DISPOSITION); | 388 IGNORING_DISPOSITION); |
| 388 } | 389 } |
| 389 } | 390 } |
| 390 | 391 |
| 391 bool InputRouterImpl::OfferToClient(const WebInputEvent& input_event, | 392 bool InputRouterImpl::OfferToClient(const WebInputEvent& input_event, |
| 392 const ui::LatencyInfo& latency_info) { | 393 const ui::LatencyInfo& latency_info) { |
| 393 bool consumed = false; | 394 bool consumed = false; |
| 394 | 395 |
| 395 InputEventAckState filter_ack = | 396 InputEventAckState filter_ack = |
| (...skipping 14 matching lines...) Expand all Loading... |
| 410 consumed = true; | 411 consumed = true; |
| 411 break; | 412 break; |
| 412 default: | 413 default: |
| 413 break; | 414 break; |
| 414 } | 415 } |
| 415 | 416 |
| 416 return consumed; | 417 return consumed; |
| 417 } | 418 } |
| 418 | 419 |
| 419 bool InputRouterImpl::OfferToRenderer(const WebInputEvent& input_event, | 420 bool InputRouterImpl::OfferToRenderer(const WebInputEvent& input_event, |
| 420 const ui::LatencyInfo& latency_info, | 421 InputEventDispatchType dispatch_type, |
| 421 InputEventDispatchType dispatch_type) { | 422 ui::LatencyInfo* latency_info) { |
| 422 // This conversion is temporary. WebInputEvent should be generated | 423 // This conversion is temporary. WebInputEvent should be generated |
| 423 // directly from ui::Event with the viewport coordinates. See | 424 // directly from ui::Event with the viewport coordinates. See |
| 424 // crbug.com/563730. | 425 // crbug.com/563730. |
| 425 scoped_ptr<blink::WebInputEvent> event_in_viewport = | 426 scoped_ptr<blink::WebInputEvent> event_in_viewport = |
| 426 ui::ScaleWebInputEvent(input_event, device_scale_factor_); | 427 ui::ScaleWebInputEvent(input_event, device_scale_factor_); |
| 427 const WebInputEvent* event_to_send = | 428 const WebInputEvent* event_to_send = |
| 428 event_in_viewport ? event_in_viewport.get() : &input_event; | 429 event_in_viewport ? event_in_viewport.get() : &input_event; |
| 429 | 430 |
| 431 client_->OnForwardEventToRenderer(input_event, latency_info); |
| 430 if (Send(new InputMsg_HandleInputEvent(routing_id(), event_to_send, | 432 if (Send(new InputMsg_HandleInputEvent(routing_id(), event_to_send, |
| 431 latency_info, dispatch_type))) { | 433 *latency_info, dispatch_type))) { |
| 432 // Ack messages for ignored ack event types should never be sent by the | 434 // Ack messages for ignored ack event types should never be sent by the |
| 433 // renderer. Consequently, such event types should not affect event time | 435 // renderer. Consequently, such event types should not affect event time |
| 434 // or in-flight event count metrics. | 436 // or in-flight event count metrics. |
| 435 if (dispatch_type == InputEventDispatchType::DISPATCH_TYPE_BLOCKING) { | 437 if (dispatch_type == InputEventDispatchType::DISPATCH_TYPE_BLOCKING) { |
| 436 input_event_start_time_ = TimeTicks::Now(); | 438 input_event_start_time_ = TimeTicks::Now(); |
| 437 client_->IncrementInFlightEventCount(); | 439 client_->IncrementInFlightEventCount(); |
| 438 } | 440 } |
| 439 return true; | 441 return true; |
| 440 } | 442 } |
| 441 return false; | 443 return false; |
| (...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 638 | 640 |
| 639 flush_requested_ = false; | 641 flush_requested_ = false; |
| 640 client_->DidFlush(); | 642 client_->DidFlush(); |
| 641 } | 643 } |
| 642 | 644 |
| 643 void InputRouterImpl::SetFrameTreeNodeId(int frameTreeNodeId) { | 645 void InputRouterImpl::SetFrameTreeNodeId(int frameTreeNodeId) { |
| 644 frame_tree_node_id_ = frameTreeNodeId; | 646 frame_tree_node_id_ = frameTreeNodeId; |
| 645 } | 647 } |
| 646 | 648 |
| 647 } // namespace content | 649 } // namespace content |
| OLD | NEW |