Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(910)

Side by Side Diff: content/browser/renderer_host/input/immediate_input_router.cc

Issue 20356003: Provided batched input delivery with a BufferedInputRouter (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Code review Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/immediate_input_router.h" 5 #include "content/browser/renderer_host/input/immediate_input_router.h"
6 6
7 #include "base/command_line.h" 7 #include "base/command_line.h"
8 #include "base/metrics/histogram.h" 8 #include "base/metrics/histogram.h"
9 #include "content/browser/renderer_host/input/gesture_event_filter.h" 9 #include "content/browser/renderer_host/input/gesture_event_filter.h"
10 #include "content/browser/renderer_host/input/input_ack_handler.h"
10 #include "content/browser/renderer_host/input/input_router_client.h" 11 #include "content/browser/renderer_host/input/input_router_client.h"
11 #include "content/browser/renderer_host/input/touch_event_queue.h" 12 #include "content/browser/renderer_host/input/touch_event_queue.h"
12 #include "content/browser/renderer_host/input/touchpad_tap_suppression_controlle r.h" 13 #include "content/browser/renderer_host/input/touchpad_tap_suppression_controlle r.h"
13 #include "content/browser/renderer_host/render_process_host_impl.h" 14 #include "content/browser/renderer_host/render_process_host_impl.h"
14 #include "content/common/content_constants_internal.h" 15 #include "content/common/content_constants_internal.h"
15 #include "content/common/edit_command.h" 16 #include "content/common/edit_command.h"
16 #include "content/common/input_messages.h" 17 #include "content/common/input_messages.h"
17 #include "content/common/view_messages.h" 18 #include "content/common/view_messages.h"
18 #include "content/port/common/input_event_ack_state.h" 19 #include "content/port/common/input_event_ack_state.h"
19 #include "content/public/browser/notification_service.h" 20 #include "content/public/browser/notification_service.h"
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
64 case INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS: return "NO_CONSUMER_EXISTS"; 65 case INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS: return "NO_CONSUMER_EXISTS";
65 default: 66 default:
66 DLOG(WARNING) << "Unhandled InputEventAckState in GetEventAckName.\n"; 67 DLOG(WARNING) << "Unhandled InputEventAckState in GetEventAckName.\n";
67 break; 68 break;
68 } 69 }
69 return ""; 70 return "";
70 } 71 }
71 72
72 } // namespace 73 } // namespace
73 74
74 ImmediateInputRouter::ImmediateInputRouter( 75 ImmediateInputRouter::ImmediateInputRouter(RenderProcessHost* process,
75 RenderProcessHost* process, 76 InputRouterClient* client,
76 InputRouterClient* client, 77 InputAckHandler* ack_handler,
77 int routing_id) 78 int routing_id)
78 : process_(process), 79 : process_(process),
79 client_(client), 80 client_(client),
81 ack_handler_(ack_handler),
80 routing_id_(routing_id), 82 routing_id_(routing_id),
81 select_range_pending_(false), 83 select_range_pending_(false),
82 move_caret_pending_(false), 84 move_caret_pending_(false),
83 mouse_move_pending_(false), 85 mouse_move_pending_(false),
84 mouse_wheel_pending_(false), 86 mouse_wheel_pending_(false),
85 has_touch_handler_(false), 87 has_touch_handler_(false),
86 touch_event_queue_(new TouchEventQueue(this)), 88 touch_event_queue_(new TouchEventQueue(this)),
87 gesture_event_filter_(new GestureEventFilter(this)) { 89 gesture_event_filter_(new GestureEventFilter(this)) {
88 DCHECK(process); 90 DCHECK(process);
89 DCHECK(client); 91 DCHECK(client);
90 } 92 }
91 93
92 ImmediateInputRouter::~ImmediateInputRouter() { 94 ImmediateInputRouter::~ImmediateInputRouter() {
93 } 95 }
94 96
95 bool ImmediateInputRouter::SendInput(IPC::Message* message) { 97 void ImmediateInputRouter::Flush() {
98 NOTREACHED() << "ImmediateInputRouter will never request a flush.";
99 }
100
101 bool ImmediateInputRouter::SendInput(scoped_ptr<IPC::Message> message) {
96 DCHECK(IPC_MESSAGE_ID_CLASS(message->type()) == InputMsgStart); 102 DCHECK(IPC_MESSAGE_ID_CLASS(message->type()) == InputMsgStart);
97 scoped_ptr<IPC::Message> scoped_message(message); 103 switch (message->type()) {
98 switch (scoped_message->type()) {
99 // Check for types that require an ACK. 104 // Check for types that require an ACK.
100 case InputMsg_SelectRange::ID: 105 case InputMsg_SelectRange::ID:
101 return SendSelectRange(scoped_message.release()); 106 return SendSelectRange(message.Pass());
102 case InputMsg_MoveCaret::ID: 107 case InputMsg_MoveCaret::ID:
103 return SendMoveCaret(scoped_message.release()); 108 return SendMoveCaret(message.Pass());
104 case InputMsg_HandleInputEvent::ID: 109 case InputMsg_HandleInputEvent::ID:
105 NOTREACHED() << "WebInputEvents should never be sent via SendInput."; 110 NOTREACHED() << "WebInputEvents should never be sent via SendInput.";
106 return false; 111 return false;
107 default: 112 default:
108 return Send(scoped_message.release()); 113 return Send(message.release());
109 } 114 }
110 } 115 }
111 116
112 void ImmediateInputRouter::SendMouseEvent( 117 void ImmediateInputRouter::SendMouseEvent(
113 const MouseEventWithLatencyInfo& mouse_event) { 118 const MouseEventWithLatencyInfo& mouse_event) {
114 if (!client_->OnSendMouseEvent(mouse_event)) 119 if (!client_->OnSendMouseEvent(mouse_event))
115 return; 120 return;
116 121
117 if (mouse_event.event.type == WebInputEvent::MouseDown && 122 if (mouse_event.event.type == WebInputEvent::MouseDown &&
118 gesture_event_filter_->GetTouchpadTapSuppressionController()-> 123 gesture_event_filter_->GetTouchpadTapSuppressionController()->
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
287 IPC_BEGIN_MESSAGE_MAP_EX(ImmediateInputRouter, message, message_is_ok) 292 IPC_BEGIN_MESSAGE_MAP_EX(ImmediateInputRouter, message, message_is_ok)
288 IPC_MESSAGE_HANDLER(InputHostMsg_HandleInputEvent_ACK, OnInputEventAck) 293 IPC_MESSAGE_HANDLER(InputHostMsg_HandleInputEvent_ACK, OnInputEventAck)
289 IPC_MESSAGE_HANDLER(ViewHostMsg_MoveCaret_ACK, OnMsgMoveCaretAck) 294 IPC_MESSAGE_HANDLER(ViewHostMsg_MoveCaret_ACK, OnMsgMoveCaretAck)
290 IPC_MESSAGE_HANDLER(ViewHostMsg_SelectRange_ACK, OnSelectRangeAck) 295 IPC_MESSAGE_HANDLER(ViewHostMsg_SelectRange_ACK, OnSelectRangeAck)
291 IPC_MESSAGE_HANDLER(ViewHostMsg_HasTouchEventHandlers, 296 IPC_MESSAGE_HANDLER(ViewHostMsg_HasTouchEventHandlers,
292 OnHasTouchEventHandlers) 297 OnHasTouchEventHandlers)
293 IPC_MESSAGE_UNHANDLED(handled = false) 298 IPC_MESSAGE_UNHANDLED(handled = false)
294 IPC_END_MESSAGE_MAP() 299 IPC_END_MESSAGE_MAP()
295 300
296 if (!message_is_ok) 301 if (!message_is_ok)
297 client_->OnUnexpectedEventAck(true); 302 ack_handler_->OnUnexpectedEventAck(true);
298 303
299 return handled; 304 return handled;
300 } 305 }
301 306
302 void ImmediateInputRouter::OnTouchEventAck( 307 void ImmediateInputRouter::OnTouchEventAck(
303 const TouchEventWithLatencyInfo& event, 308 const TouchEventWithLatencyInfo& event,
304 InputEventAckState ack_result) { 309 InputEventAckState ack_result) {
305 client_->OnTouchEventAck(event, ack_result); 310 ack_handler_->OnTouchEventAck(event, ack_result);
306 } 311 }
307 312
308 bool ImmediateInputRouter::SendSelectRange(IPC::Message* message) { 313 bool ImmediateInputRouter::SendSelectRange(scoped_ptr<IPC::Message> message) {
309 DCHECK(message->type() == InputMsg_SelectRange::ID); 314 DCHECK(message->type() == InputMsg_SelectRange::ID);
310 if (select_range_pending_) { 315 if (select_range_pending_) {
311 next_selection_range_.reset(message); 316 next_selection_range_ = message.Pass();
312 return true; 317 return true;
313 } 318 }
314 319
315 select_range_pending_ = true; 320 select_range_pending_ = true;
316 return Send(message); 321 return Send(message.release());
317 } 322 }
318 323
319 bool ImmediateInputRouter::SendMoveCaret(IPC::Message* message) { 324 bool ImmediateInputRouter::SendMoveCaret(scoped_ptr<IPC::Message> message) {
320 DCHECK(message->type() == InputMsg_MoveCaret::ID); 325 DCHECK(message->type() == InputMsg_MoveCaret::ID);
321 if (move_caret_pending_) { 326 if (move_caret_pending_) {
322 next_move_caret_.reset(message); 327 next_move_caret_ = message.Pass();
323 return true; 328 return true;
324 } 329 }
325 330
326 move_caret_pending_ = true; 331 move_caret_pending_ = true;
327 return Send(message); 332 return Send(message.release());
328 } 333 }
329 334
330 bool ImmediateInputRouter::Send(IPC::Message* message) { 335 bool ImmediateInputRouter::Send(IPC::Message* message) {
331 return process_->Send(message); 336 return process_->Send(message);
332 } 337 }
333 338
334 void ImmediateInputRouter::SendWebInputEvent( 339 void ImmediateInputRouter::SendWebInputEvent(
335 const WebInputEvent& input_event, 340 const WebInputEvent& input_event,
336 const ui::LatencyInfo& latency_info, 341 const ui::LatencyInfo& latency_info,
337 bool is_keyboard_shortcut) { 342 bool is_keyboard_shortcut) {
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
427 UMA_HISTOGRAM_TIMES("MPArch.IIR_InputEventDelta", delta); 432 UMA_HISTOGRAM_TIMES("MPArch.IIR_InputEventDelta", delta);
428 433
429 client_->DecrementInFlightEventCount(); 434 client_->DecrementInFlightEventCount();
430 435
431 ProcessInputEventAck(event_type, ack_result, latency_info); 436 ProcessInputEventAck(event_type, ack_result, latency_info);
432 } 437 }
433 438
434 void ImmediateInputRouter::OnMsgMoveCaretAck() { 439 void ImmediateInputRouter::OnMsgMoveCaretAck() {
435 move_caret_pending_ = false; 440 move_caret_pending_ = false;
436 if (next_move_caret_) 441 if (next_move_caret_)
437 SendMoveCaret(next_move_caret_.release()); 442 SendMoveCaret(next_move_caret_.Pass());
438 } 443 }
439 444
440 void ImmediateInputRouter::OnSelectRangeAck() { 445 void ImmediateInputRouter::OnSelectRangeAck() {
441 select_range_pending_ = false; 446 select_range_pending_ = false;
442 if (next_selection_range_) 447 if (next_selection_range_)
443 SendSelectRange(next_selection_range_.release()); 448 SendSelectRange(next_selection_range_.Pass());
444 } 449 }
445 450
446 void ImmediateInputRouter::OnHasTouchEventHandlers(bool has_handlers) { 451 void ImmediateInputRouter::OnHasTouchEventHandlers(bool has_handlers) {
447 if (has_touch_handler_ == has_handlers) 452 if (has_touch_handler_ == has_handlers)
448 return; 453 return;
449 has_touch_handler_ = has_handlers; 454 has_touch_handler_ = has_handlers;
450 if (!has_handlers) 455 if (!has_handlers)
451 touch_event_queue_->FlushQueue(); 456 touch_event_queue_->FlushQueue();
452 client_->OnHasTouchEventHandlers(has_handlers); 457 client_->OnHasTouchEventHandlers(has_handlers);
453 } 458 }
454 459
455 void ImmediateInputRouter::ProcessInputEventAck( 460 void ImmediateInputRouter::ProcessInputEventAck(
456 WebInputEvent::Type event_type, 461 WebInputEvent::Type event_type,
457 InputEventAckState ack_result, 462 InputEventAckState ack_result,
458 const ui::LatencyInfo& latency_info) { 463 const ui::LatencyInfo& latency_info) {
459 TRACE_EVENT1("input", "ImmediateInputRouter::ProcessInputEventAck", 464 TRACE_EVENT1("input", "ImmediateInputRouter::ProcessInputEventAck",
460 "ack", GetEventAckName(ack_result)); 465 "ack", GetEventAckName(ack_result));
461 466
462 int type = static_cast<int>(event_type); 467 int type = static_cast<int>(event_type);
463 if (type < WebInputEvent::Undefined) { 468 if (type < WebInputEvent::Undefined) {
464 client_->OnUnexpectedEventAck(true); 469 ack_handler_->OnUnexpectedEventAck(true);
465 } else if (type == WebInputEvent::MouseMove) { 470 } else if (type == WebInputEvent::MouseMove) {
466 mouse_move_pending_ = false; 471 mouse_move_pending_ = false;
467 472
468 // now, we can send the next mouse move event 473 // now, we can send the next mouse move event
469 if (next_mouse_move_) { 474 if (next_mouse_move_) {
470 DCHECK(next_mouse_move_->event.type == WebInputEvent::MouseMove); 475 DCHECK(next_mouse_move_->event.type == WebInputEvent::MouseMove);
471 scoped_ptr<MouseEventWithLatencyInfo> next_mouse_move 476 scoped_ptr<MouseEventWithLatencyInfo> next_mouse_move
472 = next_mouse_move_.Pass(); 477 = next_mouse_move_.Pass();
473 SendMouseEvent(*next_mouse_move); 478 SendMouseEvent(*next_mouse_move);
474 } 479 }
(...skipping 29 matching lines...) Expand all
504 LOG(ERROR) << "Got a KeyEvent back from the renderer but we " 509 LOG(ERROR) << "Got a KeyEvent back from the renderer but we "
505 << "don't seem to have sent it to the renderer!"; 510 << "don't seem to have sent it to the renderer!";
506 } else if (key_queue_.front().type != type) { 511 } else if (key_queue_.front().type != type) {
507 LOG(ERROR) << "We seem to have a different key type sent from " 512 LOG(ERROR) << "We seem to have a different key type sent from "
508 << "the renderer. (" << key_queue_.front().type << " vs. " 513 << "the renderer. (" << key_queue_.front().type << " vs. "
509 << type << "). Ignoring event."; 514 << type << "). Ignoring event.";
510 515
511 // Something must be wrong. Clear the |key_queue_| and char event 516 // Something must be wrong. Clear the |key_queue_| and char event
512 // suppression so that we can resume from the error. 517 // suppression so that we can resume from the error.
513 key_queue_.clear(); 518 key_queue_.clear();
514 client_->OnUnexpectedEventAck(false); 519 ack_handler_->OnUnexpectedEventAck(false);
515 } else { 520 } else {
516 NativeWebKeyboardEvent front_item = key_queue_.front(); 521 NativeWebKeyboardEvent front_item = key_queue_.front();
517 key_queue_.pop_front(); 522 key_queue_.pop_front();
518 523
519 client_->OnKeyboardEventAck(front_item, ack_result); 524 ack_handler_->OnKeyboardEventAck(front_item, ack_result);
520
521 // WARNING: This ImmediateInputRouter can be deallocated at this point 525 // WARNING: This ImmediateInputRouter can be deallocated at this point
522 // (i.e. in the case of Ctrl+W, where the call to 526 // (i.e. in the case of Ctrl+W, where the call to
523 // HandleKeyboardEvent destroys this ImmediateInputRouter). 527 // HandleKeyboardEvent destroys this ImmediateInputRouter).
524 } 528 }
525 } 529 }
526 530
527 void ImmediateInputRouter::ProcessWheelAck(InputEventAckState ack_result) { 531 void ImmediateInputRouter::ProcessWheelAck(InputEventAckState ack_result) {
528 mouse_wheel_pending_ = false; 532 mouse_wheel_pending_ = false;
529 533
530 // Process the unhandled wheel event here before calling 534 // Process the unhandled wheel event here before calling
531 // ForwardWheelEventWithLatencyInfo() since it will mutate 535 // ForwardWheelEventWithLatencyInfo() since it will mutate
532 // current_wheel_event_. 536 // current_wheel_event_.
533 client_->OnWheelEventAck(current_wheel_event_.event, ack_result); 537 ack_handler_->OnWheelEventAck(current_wheel_event_.event, ack_result);
534 538
535 // Now send the next (coalesced) mouse wheel event. 539 // Now send the next (coalesced) mouse wheel event.
536 if (!coalesced_mouse_wheel_events_.empty()) { 540 if (!coalesced_mouse_wheel_events_.empty()) {
537 MouseWheelEventWithLatencyInfo next_wheel_event = 541 MouseWheelEventWithLatencyInfo next_wheel_event =
538 coalesced_mouse_wheel_events_.front(); 542 coalesced_mouse_wheel_events_.front();
539 coalesced_mouse_wheel_events_.pop_front(); 543 coalesced_mouse_wheel_events_.pop_front();
540 SendWheelEvent(next_wheel_event); 544 SendWheelEvent(next_wheel_event);
541 } 545 }
542 } 546 }
543 547
544 void ImmediateInputRouter::ProcessGestureAck(int type, 548 void ImmediateInputRouter::ProcessGestureAck(int type,
545 InputEventAckState ack_result) { 549 InputEventAckState ack_result) {
546 const bool processed = (INPUT_EVENT_ACK_STATE_CONSUMED == ack_result); 550 const bool processed = (INPUT_EVENT_ACK_STATE_CONSUMED == ack_result);
547 client_->OnGestureEventAck( 551 ack_handler_->OnGestureEventAck(
548 gesture_event_filter_->GetGestureEventAwaitingAck(), ack_result); 552 gesture_event_filter_->GetGestureEventAwaitingAck(), ack_result);
549 gesture_event_filter_->ProcessGestureAck(processed, type); 553 gesture_event_filter_->ProcessGestureAck(processed, type);
550 } 554 }
551 555
552 void ImmediateInputRouter::ProcessTouchAck( 556 void ImmediateInputRouter::ProcessTouchAck(
553 InputEventAckState ack_result, 557 InputEventAckState ack_result,
554 const ui::LatencyInfo& latency_info) { 558 const ui::LatencyInfo& latency_info) {
555 // |touch_event_queue_| will forward to OnTouchEventAck when appropriate. 559 // |touch_event_queue_| will forward to OnTouchEventAck when appropriate.
556 touch_event_queue_->ProcessTouchAck(ack_result, latency_info); 560 touch_event_queue_->ProcessTouchAck(ack_result, latency_info);
557 } 561 }
558 562
559 } // namespace content 563 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698