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 4848f6dc6f41075434b458e3baa78175298962aa..348a47358244cedca9cfd9558d4f019de21e70c4 100644 |
--- a/content/browser/renderer_host/input/input_router_impl.cc |
+++ b/content/browser/renderer_host/input/input_router_impl.cc |
@@ -75,6 +75,7 @@ InputRouterImpl::InputRouterImpl(IPC::Sender* sender, |
current_view_flags_(0), |
current_ack_source_(ACK_SOURCE_NONE), |
flush_requested_(false), |
+ in_shutdown_(false), |
touch_event_queue_(this, config.touch_config), |
gesture_event_queue_(this, this, config.gesture_config) { |
DCHECK(sender); |
@@ -85,15 +86,20 @@ InputRouterImpl::InputRouterImpl(IPC::Sender* sender, |
InputRouterImpl::~InputRouterImpl() { |
STLDeleteElements(&pending_select_messages_); |
-} |
- |
-void InputRouterImpl::Flush() { |
- flush_requested_ = true; |
- SignalFlushedIfNecessary(); |
+ in_shutdown_ = true; |
+ // As upstream code may depend on acks for currently queued touch events, |
+ // explicitly flush the touch queue, dropping any generated gesture events. |
+ touch_event_queue_.Flush(INPUT_EVENT_ACK_STATE_CONSUMED); |
+ if (flush_requested_) { |
+ flush_requested_ = false; |
+ client_->DidFlush(); |
+ } |
} |
bool InputRouterImpl::SendInput(scoped_ptr<IPC::Message> message) { |
- DCHECK(IPC_MESSAGE_ID_CLASS(message->type()) == InputMsgStart); |
+ DCHECK(!in_shutdown_); |
+ DCHECK_EQ(IPC_MESSAGE_ID_CLASS(message->type()), |
+ static_cast<uint32>(InputMsgStart)); |
switch (message->type()) { |
// Check for types that require an ACK. |
case InputMsg_SelectRange::ID: |
@@ -111,6 +117,7 @@ bool InputRouterImpl::SendInput(scoped_ptr<IPC::Message> message) { |
void InputRouterImpl::SendMouseEvent( |
const MouseEventWithLatencyInfo& mouse_event) { |
+ DCHECK(!in_shutdown_); |
if (mouse_event.event.type == WebInputEvent::MouseDown && |
gesture_event_queue_.GetTouchpadTapSuppressionController()-> |
ShouldDeferMouseDown(mouse_event)) |
@@ -125,10 +132,12 @@ void InputRouterImpl::SendMouseEvent( |
void InputRouterImpl::SendWheelEvent( |
const MouseWheelEventWithLatencyInfo& wheel_event) { |
+ DCHECK(!in_shutdown_); |
SendWheelEvent(QueuedWheelEvent(wheel_event, false)); |
} |
void InputRouterImpl::SendWheelEvent(const QueuedWheelEvent& wheel_event) { |
+ DCHECK(!in_shutdown_); |
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 |
@@ -163,6 +172,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_shutdown_); |
// Put all WebKeyboardEvent objects in a queue since we can't trust the |
// renderer and we need to give something to the HandleKeyboardEvent |
// handler. |
@@ -177,6 +187,9 @@ void InputRouterImpl::SendKeyboardEvent(const NativeWebKeyboardEvent& key_event, |
void InputRouterImpl::SendGestureEvent( |
const GestureEventWithLatencyInfo& original_gesture_event) { |
+ if (in_shutdown_) |
+ return; |
+ |
input_stream_validator_.Validate(original_gesture_event.event); |
GestureEventWithLatencyInfo gesture_event(original_gesture_event); |
@@ -195,10 +208,16 @@ void InputRouterImpl::SendGestureEvent( |
void InputRouterImpl::SendTouchEvent( |
const TouchEventWithLatencyInfo& touch_event) { |
+ DCHECK(!in_shutdown_); |
input_stream_validator_.Validate(touch_event.event); |
touch_event_queue_.QueueEvent(touch_event); |
} |
+void InputRouterImpl::RequestFlushedNotification() { |
+ flush_requested_ = true; |
+ SignalFlushedIfNecessary(); |
+} |
+ |
// Forwards MouseEvent without passing it through |
// TouchpadTapSuppressionController. |
void InputRouterImpl::SendMouseEventImmediately( |
@@ -326,7 +345,7 @@ bool InputRouterImpl::SendSelectMessage( |
} |
bool InputRouterImpl::SendMoveCaret(scoped_ptr<IPC::Message> message) { |
- DCHECK(message->type() == InputMsg_MoveCaret::ID); |
+ DCHECK_EQ(message->type(), static_cast<uint32>(InputMsg_MoveCaret::ID)); |
if (move_caret_pending_) { |
next_move_caret_ = message.Pass(); |
return true; |
@@ -358,6 +377,7 @@ void InputRouterImpl::FilterAndSendWebInputEvent( |
void InputRouterImpl::OfferToHandlers(const WebInputEvent& input_event, |
const ui::LatencyInfo& latency_info, |
bool is_keyboard_shortcut) { |
+ DCHECK(!in_shutdown_); |
output_stream_validator_.Validate(input_event); |
if (OfferToClient(input_event, latency_info)) |
@@ -528,7 +548,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) { |
@@ -581,9 +600,10 @@ void InputRouterImpl::ProcessInputEventAck( |
void InputRouterImpl::ProcessKeyboardAck(blink::WebInputEvent::Type type, |
InputEventAckState ack_result) { |
- if (key_queue_.empty()) { |
- ack_handler_->OnUnexpectedEventAck(InputAckHandler::UNEXPECTED_ACK); |
- } else if (key_queue_.front().type != type) { |
+ if (key_queue_.empty()) |
+ return; |
+ |
+ if (key_queue_.front().type != type) { |
// Something must be wrong. Clear the |key_queue_| and char event |
// suppression so that we can resume from the error. |
key_queue_.clear(); |
@@ -605,11 +625,10 @@ void InputRouterImpl::ProcessMouseAck(blink::WebInputEvent::Type type, |
if (type != WebInputEvent::MouseMove) |
return; |
- DCHECK(mouse_move_pending_); |
mouse_move_pending_ = false; |
if (next_mouse_move_) { |
- DCHECK(next_mouse_move_->event.type == WebInputEvent::MouseMove); |
+ DCHECK_EQ(next_mouse_move_->event.type, WebInputEvent::MouseMove); |
scoped_ptr<MouseEventWithLatencyInfo> next_mouse_move |
= next_mouse_move_.Pass(); |
SendMouseEvent(*next_mouse_move); |