| Index: content/browser/renderer_host/input/input_router_impl.cc
|
| diff --git a/content/browser/renderer_host/input/input_router_impl.cc b/content/browser/renderer_host/input/input_router_impl.cc
|
| index 364f7ca5a9d884f7cb1d0809517fe7fdd5834fac..5edebe204a9df48c1e76d3e4999b505b17789dc3 100644
|
| --- a/content/browser/renderer_host/input/input_router_impl.cc
|
| +++ b/content/browser/renderer_host/input/input_router_impl.cc
|
| @@ -18,6 +18,7 @@
|
| #include "content/common/content_constants_internal.h"
|
| #include "content/common/edit_command.h"
|
| #include "content/common/input/input_event_ack_state.h"
|
| +#include "content/common/input/input_event_stream_validator.h"
|
| #include "content/common/input/touch_action.h"
|
| #include "content/common/input/web_touch_event_traits.h"
|
| #include "content/common/input_messages.h"
|
| @@ -56,7 +57,7 @@ const char* GetEventAckName(InputEventAckState ack_result) {
|
|
|
| } // namespace
|
|
|
| -InputRouterImpl::Config::Config() {
|
| +InputRouterImpl::Config::Config() : validate_event_stream(false) {
|
| }
|
|
|
| InputRouterImpl::InputRouterImpl(IPC::Sender* sender,
|
| @@ -75,23 +76,24 @@ InputRouterImpl::InputRouterImpl(IPC::Sender* sender,
|
| current_view_flags_(0),
|
| current_ack_source_(ACK_SOURCE_NONE),
|
| flush_requested_(false),
|
| + in_recycle_(false),
|
| touch_event_queue_(this, config.touch_config),
|
| gesture_event_queue_(this, this, config.gesture_config) {
|
| DCHECK(sender);
|
| DCHECK(client);
|
| DCHECK(ack_handler);
|
| UpdateTouchAckTimeoutEnabled();
|
| + if (config.validate_event_stream) {
|
| + optional_input_stream_validator_.reset(new InputEventStreamValidator());
|
| + optional_output_stream_validator_.reset(new InputEventStreamValidator());
|
| + }
|
| }
|
|
|
| InputRouterImpl::~InputRouterImpl() {}
|
|
|
| -void InputRouterImpl::Flush() {
|
| - flush_requested_ = true;
|
| - SignalFlushedIfNecessary();
|
| -}
|
| -
|
| bool InputRouterImpl::SendInput(scoped_ptr<IPC::Message> message) {
|
| - DCHECK(IPC_MESSAGE_ID_CLASS(message->type()) == InputMsgStart);
|
| + DCHECK(!in_recycle_);
|
| + DCHECK_EQ(IPC_MESSAGE_ID_CLASS(message->type()), InputMsgStart);
|
| switch (message->type()) {
|
| // Check for types that require an ACK.
|
| case InputMsg_SelectRange::ID:
|
| @@ -108,6 +110,7 @@ bool InputRouterImpl::SendInput(scoped_ptr<IPC::Message> message) {
|
|
|
| void InputRouterImpl::SendMouseEvent(
|
| const MouseEventWithLatencyInfo& mouse_event) {
|
| + DCHECK(!in_recycle_);
|
| if (mouse_event.event.type == WebInputEvent::MouseDown &&
|
| gesture_event_queue_.GetTouchpadTapSuppressionController()->
|
| ShouldDeferMouseDown(mouse_event))
|
| @@ -122,10 +125,12 @@ void InputRouterImpl::SendMouseEvent(
|
|
|
| void InputRouterImpl::SendWheelEvent(
|
| const MouseWheelEventWithLatencyInfo& wheel_event) {
|
| + DCHECK(!in_recycle_);
|
| SendWheelEvent(QueuedWheelEvent(wheel_event, false));
|
| }
|
|
|
| void InputRouterImpl::SendWheelEvent(const QueuedWheelEvent& wheel_event) {
|
| + DCHECK(!in_recycle_);
|
| if (mouse_wheel_pending_) {
|
| // If there's already a mouse wheel event waiting to be sent to the
|
| // renderer, add the new deltas to that event. Not doing so (e.g., by
|
| @@ -160,6 +165,7 @@ void InputRouterImpl::SendWheelEvent(const QueuedWheelEvent& wheel_event) {
|
| void InputRouterImpl::SendKeyboardEvent(const NativeWebKeyboardEvent& key_event,
|
| const ui::LatencyInfo& latency_info,
|
| bool is_keyboard_shortcut) {
|
| + DCHECK(!in_recycle_);
|
| // Put all WebKeyboardEvent objects in a queue since we can't trust the
|
| // renderer and we need to give something to the HandleKeyboardEvent
|
| // handler.
|
| @@ -174,7 +180,11 @@ void InputRouterImpl::SendKeyboardEvent(const NativeWebKeyboardEvent& key_event,
|
|
|
| void InputRouterImpl::SendGestureEvent(
|
| const GestureEventWithLatencyInfo& original_gesture_event) {
|
| - input_stream_validator_.Validate(original_gesture_event.event);
|
| + if (in_recycle_)
|
| + return;
|
| +
|
| + if (optional_input_stream_validator_)
|
| + optional_input_stream_validator_->Validate(original_gesture_event.event);
|
|
|
| GestureEventWithLatencyInfo gesture_event(original_gesture_event);
|
|
|
| @@ -192,10 +202,45 @@ void InputRouterImpl::SendGestureEvent(
|
|
|
| void InputRouterImpl::SendTouchEvent(
|
| const TouchEventWithLatencyInfo& touch_event) {
|
| - input_stream_validator_.Validate(touch_event.event);
|
| + DCHECK(!in_recycle_);
|
| + if (optional_input_stream_validator_)
|
| + optional_input_stream_validator_->Validate(touch_event.event);
|
| touch_event_queue_.QueueEvent(touch_event);
|
| }
|
|
|
| +void InputRouterImpl::Recycle() {
|
| + DCHECK(!in_recycle_);
|
| + DCHECK_EQ(current_ack_source_, ACK_SOURCE_NONE);
|
| + base::AutoReset<bool> auto_reset_in_recycle(&in_recycle_, true);
|
| +
|
| + key_queue_.clear();
|
| + coalesced_mouse_wheel_events_.clear();
|
| + next_mouse_move_.reset();
|
| + next_selection_range_.reset();
|
| + next_move_caret_.reset();
|
| +
|
| + // It's *extremely* important that all touches currently queued be ack'ed to
|
| + // the view. Though all (potentially) derived gestures will be ignored, the
|
| + // touches must be ack'ed to the client, ensuring upstream gesture detection
|
| + // is properly flushed.
|
| + touch_event_queue_.Flush(INPUT_EVENT_ACK_STATE_CONSUMED);
|
| + gesture_event_queue_.Recycle();
|
| + touch_action_filter_.ResetTouchAction();
|
| +
|
| + if (optional_input_stream_validator_)
|
| + optional_input_stream_validator_.reset(new InputEventStreamValidator());
|
| + if (optional_output_stream_validator_)
|
| + optional_output_stream_validator_.reset(new InputEventStreamValidator());
|
| +
|
| + DCHECK(!HasPendingEvents());
|
| + SignalFlushedIfNecessary();
|
| +}
|
| +
|
| +void InputRouterImpl::RequestFlushedNotification() {
|
| + flush_requested_ = true;
|
| + SignalFlushedIfNecessary();
|
| +}
|
| +
|
| // Forwards MouseEvent without passing it through
|
| // TouchpadTapSuppressionController.
|
| void InputRouterImpl::SendMouseEventImmediately(
|
| @@ -310,7 +355,7 @@ bool InputRouterImpl::SendSelectRange(scoped_ptr<IPC::Message> message) {
|
| }
|
|
|
| bool InputRouterImpl::SendMoveCaret(scoped_ptr<IPC::Message> message) {
|
| - DCHECK(message->type() == InputMsg_MoveCaret::ID);
|
| + DCHECK_EQ(message->type(), InputMsg_MoveCaret::ID);
|
| if (move_caret_pending_) {
|
| next_move_caret_ = message.Pass();
|
| return true;
|
| @@ -342,7 +387,9 @@ void InputRouterImpl::FilterAndSendWebInputEvent(
|
| void InputRouterImpl::OfferToHandlers(const WebInputEvent& input_event,
|
| const ui::LatencyInfo& latency_info,
|
| bool is_keyboard_shortcut) {
|
| - output_stream_validator_.Validate(input_event);
|
| + DCHECK(!in_recycle_);
|
| + if (optional_output_stream_validator_)
|
| + optional_output_stream_validator_->Validate(input_event);
|
|
|
| if (OfferToClient(input_event, latency_info))
|
| return;
|
| @@ -507,7 +554,6 @@ void InputRouterImpl::OnHasTouchEventHandlers(bool has_handlers) {
|
| touch_action_filter_.ResetTouchAction();
|
|
|
| touch_event_queue_.OnHasTouchEventHandlers(has_handlers);
|
| - client_->OnHasTouchEventHandlers(has_handlers);
|
| }
|
|
|
| void InputRouterImpl::OnSetTouchAction(TouchAction touch_action) {
|
|
|