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

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

Issue 41703006: Move fling implementation from renderer to browser: (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: patch Created 7 years, 1 month 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 | Annotate | Revision Log
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/auto_reset.h" 7 #include "base/auto_reset.h"
8 #include "base/command_line.h" 8 #include "base/command_line.h"
9 #include "base/metrics/histogram.h" 9 #include "base/metrics/histogram.h"
10 #include "content/browser/renderer_host/input/gesture_event_filter.h" 10 #include "content/browser/renderer_host/input/gesture_event_filter.h"
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
63 case INPUT_EVENT_ACK_STATE_CONSUMED: return "CONSUMED"; 63 case INPUT_EVENT_ACK_STATE_CONSUMED: return "CONSUMED";
64 case INPUT_EVENT_ACK_STATE_NOT_CONSUMED: return "NOT_CONSUMED"; 64 case INPUT_EVENT_ACK_STATE_NOT_CONSUMED: return "NOT_CONSUMED";
65 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";
66 default: 66 default:
67 DLOG(WARNING) << "Unhandled InputEventAckState in GetEventAckName.\n"; 67 DLOG(WARNING) << "Unhandled InputEventAckState in GetEventAckName.\n";
68 break; 68 break;
69 } 69 }
70 return ""; 70 return "";
71 } 71 }
72 72
73 bool BrowserSideFlingEnabled() {
74 return CommandLine::ForCurrentProcess()->HasSwitch(
75 switches::kEnableBrowserSideFling);
76 }
77
73 } // namespace 78 } // namespace
74 79
80 // A helper class that based on the value of the |kEnableBrowserSideFling| flag
81 // does event filtering using either |BaseGestureEventFilter| or
82 // |GestureEventFilter|.
83 class ImmediateInputRouter::EventFilteringHelper {
84 public:
85 // |router| must outlive us.
86 explicit EventFilteringHelper(ImmediateInputRouter* router) {
87 if (BrowserSideFlingEnabled())
88 gesture_event_filter_.reset(new BaseGestureEventFilter(router));
89 else
90 gesture_event_filter_.reset(new GestureEventFilter(router, router));
91 }
92 virtual ~EventFilteringHelper() {}
93
94 bool ShouldDeferMouseDown(const MouseEventWithLatencyInfo& mouse_event) {
95 if (BrowserSideFlingEnabled())
96 return false;
97
98 return static_cast<GestureEventFilter*>(gesture_event_filter_.get())->
99 GetTouchpadTapSuppressionController()->ShouldDeferMouseDown(
100 mouse_event);
101 }
102
103 bool ShouldDeferMouseUp(const MouseEventWithLatencyInfo& mouse_event) {
104 if (BrowserSideFlingEnabled())
105 return false;
106
107 return static_cast<GestureEventFilter*>(gesture_event_filter_.get())->
108 GetTouchpadTapSuppressionController()->ShouldSuppressMouseUp();
109 }
110
111 void FlingHasBeenHalted() {
112 if (BrowserSideFlingEnabled())
113 return;
114
115 static_cast<GestureEventFilter*>(gesture_event_filter_.get())->
116 FlingHasBeenHalted();
117 }
118
119 bool ShouldForwardGesture(const GestureEventWithLatencyInfo& gesture_event) {
120 return gesture_event_filter_->ShouldForward(gesture_event);
121 }
122
123 bool HasQueuedGestureEvents() {
124 return gesture_event_filter_->HasQueuedGestureEvents();
125 }
126
127 void ProcessGestureAck(InputEventAckState ack_result,
128 blink::WebInputEvent::Type type,
129 const ui::LatencyInfo& latency) {
130 gesture_event_filter_->ProcessGestureAck(ack_result, type, latency);
131 }
132
133 private:
134 friend class ImmediateInputRouter;
135 scoped_ptr<BaseGestureEventFilter> gesture_event_filter_;
136
137 DISALLOW_COPY_AND_ASSIGN(EventFilteringHelper);
138 };
139
75 ImmediateInputRouter::ImmediateInputRouter(IPC::Sender* sender, 140 ImmediateInputRouter::ImmediateInputRouter(IPC::Sender* sender,
76 InputRouterClient* client, 141 InputRouterClient* client,
77 InputAckHandler* ack_handler, 142 InputAckHandler* ack_handler,
78 int routing_id) 143 int routing_id)
79 : sender_(sender), 144 : sender_(sender),
80 client_(client), 145 client_(client),
81 ack_handler_(ack_handler), 146 ack_handler_(ack_handler),
82 routing_id_(routing_id), 147 routing_id_(routing_id),
83 select_range_pending_(false), 148 select_range_pending_(false),
84 move_caret_pending_(false), 149 move_caret_pending_(false),
85 mouse_move_pending_(false), 150 mouse_move_pending_(false),
86 mouse_wheel_pending_(false), 151 mouse_wheel_pending_(false),
87 has_touch_handler_(false), 152 has_touch_handler_(false),
88 current_ack_source_(ACK_SOURCE_NONE), 153 current_ack_source_(ACK_SOURCE_NONE),
89 touch_event_queue_(new TouchEventQueue(this)), 154 touch_event_queue_(new TouchEventQueue(this)),
90 gesture_event_filter_(new GestureEventFilter(this, this)) { 155 flinger_(new Flinger(this)),
156 event_filter_(new EventFilteringHelper(this)) {
91 DCHECK(sender); 157 DCHECK(sender);
92 DCHECK(client); 158 DCHECK(client);
93 DCHECK(ack_handler); 159 DCHECK(ack_handler);
94 } 160 }
95 161
96 ImmediateInputRouter::~ImmediateInputRouter() { 162 ImmediateInputRouter::~ImmediateInputRouter() {
97 } 163 }
98 164
99 void ImmediateInputRouter::Flush() { 165 void ImmediateInputRouter::Flush() {
100 NOTREACHED() << "ImmediateInputRouter will never request a flush."; 166 NOTREACHED() << "ImmediateInputRouter will never request a flush.";
(...skipping 18 matching lines...) Expand all
119 void ImmediateInputRouter::SendMouseEvent( 185 void ImmediateInputRouter::SendMouseEvent(
120 const MouseEventWithLatencyInfo& mouse_event) { 186 const MouseEventWithLatencyInfo& mouse_event) {
121 // Order is important here; we need to convert all MouseEvents before they 187 // Order is important here; we need to convert all MouseEvents before they
122 // propagate further, e.g., to the tap suppression controller. 188 // propagate further, e.g., to the tap suppression controller.
123 if (CommandLine::ForCurrentProcess()->HasSwitch( 189 if (CommandLine::ForCurrentProcess()->HasSwitch(
124 switches::kSimulateTouchScreenWithMouse)) { 190 switches::kSimulateTouchScreenWithMouse)) {
125 SimulateTouchGestureWithMouse(mouse_event); 191 SimulateTouchGestureWithMouse(mouse_event);
126 return; 192 return;
127 } 193 }
128 194
195 if (BrowserSideFlingEnabled() && flinger_->HandleMouseEvent(mouse_event))
196 return;
197
129 if (mouse_event.event.type == WebInputEvent::MouseDown && 198 if (mouse_event.event.type == WebInputEvent::MouseDown &&
130 gesture_event_filter_->GetTouchpadTapSuppressionController()-> 199 event_filter_->ShouldDeferMouseDown(mouse_event))
131 ShouldDeferMouseDown(mouse_event))
132 return; 200 return;
133 if (mouse_event.event.type == WebInputEvent::MouseUp && 201 if (mouse_event.event.type == WebInputEvent::MouseUp &&
134 gesture_event_filter_->GetTouchpadTapSuppressionController()-> 202 event_filter_->ShouldDeferMouseUp(mouse_event))
135 ShouldSuppressMouseUp())
136 return; 203 return;
137 204
138 SendMouseEventImmediately(mouse_event); 205 SendMouseEventImmediately(mouse_event);
139 } 206 }
140 207
141 void ImmediateInputRouter::SendWheelEvent( 208 void ImmediateInputRouter::SendWheelEvent(
142 const MouseWheelEventWithLatencyInfo& wheel_event) { 209 const MouseWheelEventWithLatencyInfo& wheel_event) {
210 if (BrowserSideFlingEnabled() && flinger_->HandleWheelEvent(wheel_event))
211 return;
212
143 // If there's already a mouse wheel event waiting to be sent to the renderer, 213 // If there's already a mouse wheel event waiting to be sent to the renderer,
144 // add the new deltas to that event. Not doing so (e.g., by dropping the old 214 // add the new deltas to that event. Not doing so (e.g., by dropping the old
145 // event, as for mouse moves) results in very slow scrolling on the Mac (on 215 // event, as for mouse moves) results in very slow scrolling on the Mac (on
146 // which many, very small wheel events are sent). 216 // which many, very small wheel events are sent).
147 if (mouse_wheel_pending_) { 217 if (mouse_wheel_pending_) {
148 if (coalesced_mouse_wheel_events_.empty() || 218 if (coalesced_mouse_wheel_events_.empty() ||
149 !coalesced_mouse_wheel_events_.back().CanCoalesceWith(wheel_event)) { 219 !coalesced_mouse_wheel_events_.back().CanCoalesceWith(wheel_event)) {
150 coalesced_mouse_wheel_events_.push_back(wheel_event); 220 coalesced_mouse_wheel_events_.push_back(wheel_event);
151 } else { 221 } else {
152 coalesced_mouse_wheel_events_.back().CoalesceWith(wheel_event); 222 coalesced_mouse_wheel_events_.back().CoalesceWith(wheel_event);
153 } 223 }
154 return; 224 return;
155 } 225 }
156 mouse_wheel_pending_ = true; 226 mouse_wheel_pending_ = true;
157 current_wheel_event_ = wheel_event; 227 current_wheel_event_ = wheel_event;
158 228
159 HISTOGRAM_COUNTS_100("Renderer.WheelQueueSize", 229 HISTOGRAM_COUNTS_100("Renderer.WheelQueueSize",
160 coalesced_mouse_wheel_events_.size()); 230 coalesced_mouse_wheel_events_.size());
161 231
162 FilterAndSendWebInputEvent(wheel_event.event, wheel_event.latency, false); 232 FilterAndSendWebInputEvent(wheel_event.event, wheel_event.latency, false);
163 } 233 }
164 234
165 void ImmediateInputRouter::SendKeyboardEvent( 235 void ImmediateInputRouter::SendKeyboardEvent(
166 const NativeWebKeyboardEvent& key_event, 236 const NativeWebKeyboardEvent& key_event,
167 const ui::LatencyInfo& latency_info, 237 const ui::LatencyInfo& latency_info,
168 bool is_keyboard_shortcut) { 238 bool is_keyboard_shortcut) {
239 if (BrowserSideFlingEnabled() && flinger_->HandleKeyboardEvent())
240 return;
241
169 // Put all WebKeyboardEvent objects in a queue since we can't trust the 242 // Put all WebKeyboardEvent objects in a queue since we can't trust the
170 // renderer and we need to give something to the HandleKeyboardEvent 243 // renderer and we need to give something to the HandleKeyboardEvent
171 // handler. 244 // handler.
172 key_queue_.push_back(key_event); 245 key_queue_.push_back(key_event);
173 HISTOGRAM_COUNTS_100("Renderer.KeyboardQueueSize", key_queue_.size()); 246 HISTOGRAM_COUNTS_100("Renderer.KeyboardQueueSize", key_queue_.size());
174 247
175 gesture_event_filter_->FlingHasBeenHalted(); 248 event_filter_->FlingHasBeenHalted();
176 249
177 // Only forward the non-native portions of our event. 250 // Only forward the non-native portions of our event.
178 FilterAndSendWebInputEvent(key_event, latency_info, is_keyboard_shortcut); 251 FilterAndSendWebInputEvent(key_event, latency_info, is_keyboard_shortcut);
179 } 252 }
180 253
181 void ImmediateInputRouter::SendGestureEvent( 254 void ImmediateInputRouter::SendGestureEvent(
182 const GestureEventWithLatencyInfo& gesture_event) { 255 const GestureEventWithLatencyInfo& gesture_event) {
183 HandleGestureScroll(gesture_event); 256 HandleGestureScroll(gesture_event);
184 257
258 if (BrowserSideFlingEnabled() && flinger_->HandleGestureEvent(gesture_event))
259 return;
260
185 if (!IsInOverscrollGesture() && 261 if (!IsInOverscrollGesture() &&
186 !gesture_event_filter_->ShouldForward(gesture_event)) { 262 !event_filter_->ShouldForwardGesture(gesture_event)) {
187 OverscrollController* controller = client_->GetOverscrollController(); 263 OverscrollController* controller = client_->GetOverscrollController();
188 if (controller) 264 if (controller)
189 controller->DiscardingGestureEvent(gesture_event.event); 265 controller->DiscardingGestureEvent(gesture_event.event);
190 return; 266 return;
191 } 267 }
192 268
193 FilterAndSendWebInputEvent(gesture_event.event, gesture_event.latency, false); 269 FilterAndSendWebInputEvent(gesture_event.event, gesture_event.latency, false);
194 } 270 }
195 271
196 void ImmediateInputRouter::SendTouchEvent( 272 void ImmediateInputRouter::SendTouchEvent(
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
270 ack_handler_->OnTouchEventAck(event, ack_result); 346 ack_handler_->OnTouchEventAck(event, ack_result);
271 } 347 }
272 348
273 void ImmediateInputRouter::OnGestureEventAck( 349 void ImmediateInputRouter::OnGestureEventAck(
274 const GestureEventWithLatencyInfo& event, 350 const GestureEventWithLatencyInfo& event,
275 InputEventAckState ack_result) { 351 InputEventAckState ack_result) {
276 ProcessAckForOverscroll(event.event, ack_result); 352 ProcessAckForOverscroll(event.event, ack_result);
277 ack_handler_->OnGestureEventAck(event, ack_result); 353 ack_handler_->OnGestureEventAck(event, ack_result);
278 } 354 }
279 355
356 void ImmediateInputRouter::SendEventForFling(
357 const blink::WebInputEvent& event) {
358 ui::LatencyInfo latency_info;
359 if (Send(new InputMsg_HandleInputEvent(
360 routing_id(), &event, latency_info, false)))
361 in_process_messages_sources_.push(MESSAGE_SOURCE_FLING);
362 }
363
364 void ImmediateInputRouter::FlingFinished(
365 blink::WebGestureEvent::SourceDevice source) {
366 if (source == blink::WebGestureEvent::Touchscreen) {
367 ui::LatencyInfo latency_info;
368 blink::WebGestureEvent synthetic_gesture;
369 synthetic_gesture.type = blink::WebInputEvent::GestureScrollEnd;
370 synthetic_gesture.sourceDevice = blink::WebGestureEvent::Touchscreen;
371 OfferToRenderer(synthetic_gesture, latency_info, false);
372 }
373 }
374
280 bool ImmediateInputRouter::SendSelectRange(scoped_ptr<IPC::Message> message) { 375 bool ImmediateInputRouter::SendSelectRange(scoped_ptr<IPC::Message> message) {
281 DCHECK(message->type() == InputMsg_SelectRange::ID); 376 DCHECK(message->type() == InputMsg_SelectRange::ID);
282 if (select_range_pending_) { 377 if (select_range_pending_) {
283 next_selection_range_ = message.Pass(); 378 next_selection_range_ = message.Pass();
284 return true; 379 return true;
285 } 380 }
286 381
287 select_range_pending_ = true; 382 select_range_pending_ = true;
288 return Send(message.release()); 383 return Send(message.release());
289 } 384 }
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
351 OverscrollController::Disposition disposition = 446 OverscrollController::Disposition disposition =
352 controller->DispatchEvent(input_event, latency_info); 447 controller->DispatchEvent(input_event, latency_info);
353 448
354 bool consumed = disposition == OverscrollController::CONSUMED; 449 bool consumed = disposition == OverscrollController::CONSUMED;
355 450
356 if (disposition == OverscrollController::SHOULD_FORWARD_TO_GESTURE_FILTER) { 451 if (disposition == OverscrollController::SHOULD_FORWARD_TO_GESTURE_FILTER) {
357 DCHECK(WebInputEvent::isGestureEventType(input_event.type)); 452 DCHECK(WebInputEvent::isGestureEventType(input_event.type));
358 const blink::WebGestureEvent& gesture_event = 453 const blink::WebGestureEvent& gesture_event =
359 static_cast<const blink::WebGestureEvent&>(input_event); 454 static_cast<const blink::WebGestureEvent&>(input_event);
360 // An ACK is expected for the event, so mark it as consumed. 455 // An ACK is expected for the event, so mark it as consumed.
361 consumed = !gesture_event_filter_->ShouldForward( 456 consumed = !event_filter_->ShouldForwardGesture(
362 GestureEventWithLatencyInfo(gesture_event, latency_info)); 457 GestureEventWithLatencyInfo(gesture_event, latency_info));
363 } 458 }
364 459
365 if (consumed) { 460 if (consumed) {
366 InputEventAckState overscroll_ack = 461 InputEventAckState overscroll_ack =
367 WebInputEvent::isTouchEventType(input_event.type) ? 462 WebInputEvent::isTouchEventType(input_event.type) ?
368 INPUT_EVENT_ACK_STATE_NOT_CONSUMED : INPUT_EVENT_ACK_STATE_CONSUMED; 463 INPUT_EVENT_ACK_STATE_NOT_CONSUMED : INPUT_EVENT_ACK_STATE_CONSUMED;
369 ProcessInputEventAck(input_event.type, 464 ProcessInputEventAck(input_event.type,
370 overscroll_ack, 465 overscroll_ack,
371 latency_info, 466 latency_info,
(...skipping 29 matching lines...) Expand all
401 496
402 return consumed; 497 return consumed;
403 } 498 }
404 499
405 bool ImmediateInputRouter::OfferToRenderer(const WebInputEvent& input_event, 500 bool ImmediateInputRouter::OfferToRenderer(const WebInputEvent& input_event,
406 const ui::LatencyInfo& latency_info, 501 const ui::LatencyInfo& latency_info,
407 bool is_keyboard_shortcut) { 502 bool is_keyboard_shortcut) {
408 input_event_start_time_ = TimeTicks::Now(); 503 input_event_start_time_ = TimeTicks::Now();
409 if (Send(new InputMsg_HandleInputEvent( 504 if (Send(new InputMsg_HandleInputEvent(
410 routing_id(), &input_event, latency_info, is_keyboard_shortcut))) { 505 routing_id(), &input_event, latency_info, is_keyboard_shortcut))) {
506 in_process_messages_sources_.push(MESSAGE_SOURCE_REGULAR);
411 client_->IncrementInFlightEventCount(); 507 client_->IncrementInFlightEventCount();
412 return true; 508 return true;
413 } 509 }
414 return false; 510 return false;
415 } 511 }
416 512
417 void ImmediateInputRouter::OnInputEventAck( 513 void ImmediateInputRouter::OnInputEventAck(
418 WebInputEvent::Type event_type, 514 WebInputEvent::Type event_type,
419 InputEventAckState ack_result, 515 InputEventAckState ack_result,
420 const ui::LatencyInfo& latency_info) { 516 const ui::LatencyInfo& latency_info) {
421 // Log the time delta for processing an input event. 517 // Log the time delta for processing an input event.
422 TimeDelta delta = TimeTicks::Now() - input_event_start_time_; 518 TimeDelta delta = TimeTicks::Now() - input_event_start_time_;
423 UMA_HISTOGRAM_TIMES("MPArch.IIR_InputEventDelta", delta); 519 UMA_HISTOGRAM_TIMES("MPArch.IIR_InputEventDelta", delta);
424 520
521 InputMessageSource source = in_process_messages_sources_.front();
522 in_process_messages_sources_.pop();
523 if (source == MESSAGE_SOURCE_FLING) {
524 flinger_->ProcessEventAck(event_type, ack_result, latency_info);
525 return;
526 }
527
425 client_->DecrementInFlightEventCount(); 528 client_->DecrementInFlightEventCount();
426 529
427 ProcessInputEventAck(event_type, ack_result, latency_info, RENDERER); 530 ProcessInputEventAck(event_type, ack_result, latency_info, RENDERER);
428 // WARNING: |this| may be deleted at this point. 531 // WARNING: |this| may be deleted at this point.
429 532
430 // This is used only for testing, and the other end does not use the 533 // This is used only for testing, and the other end does not use the
431 // source object. On linux, specifying 534 // source object. On linux, specifying
432 // Source<RenderWidgetHost> results in a very strange 535 // Source<RenderWidgetHost> results in a very strange
433 // runtime error in the epilogue of the enclosing 536 // runtime error in the epilogue of the enclosing
434 // (ProcessInputEventAck) method, but not on other platforms; using 537 // (ProcessInputEventAck) method, but not on other platforms; using
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
553 SendWheelEvent(next_wheel_event); 656 SendWheelEvent(next_wheel_event);
554 } 657 }
555 } 658 }
556 659
557 void ImmediateInputRouter::ProcessGestureAck(WebInputEvent::Type type, 660 void ImmediateInputRouter::ProcessGestureAck(WebInputEvent::Type type,
558 InputEventAckState ack_result, 661 InputEventAckState ack_result,
559 const ui::LatencyInfo& latency) { 662 const ui::LatencyInfo& latency) {
560 // If |ack_result| originated from the overscroll controller, only 663 // If |ack_result| originated from the overscroll controller, only
561 // feed |gesture_event_filter_| the ack if it was expecting one. 664 // feed |gesture_event_filter_| the ack if it was expecting one.
562 if (current_ack_source_ == OVERSCROLL_CONTROLLER && 665 if (current_ack_source_ == OVERSCROLL_CONTROLLER &&
563 !gesture_event_filter_->HasQueuedGestureEvents()) { 666 !event_filter_->HasQueuedGestureEvents()) {
564 return; 667 return;
565 } 668 }
566 669
567 // |gesture_event_filter_| will forward to OnGestureEventAck when appropriate. 670 // |gesture_event_filter_| will forward to OnGestureEventAck when appropriate.
568 gesture_event_filter_->ProcessGestureAck(ack_result, type, latency); 671 event_filter_->ProcessGestureAck(ack_result, type, latency);
569 } 672 }
570 673
571 void ImmediateInputRouter::ProcessTouchAck( 674 void ImmediateInputRouter::ProcessTouchAck(
572 InputEventAckState ack_result, 675 InputEventAckState ack_result,
573 const ui::LatencyInfo& latency) { 676 const ui::LatencyInfo& latency) {
574 // |touch_event_queue_| will forward to OnTouchEventAck when appropriate. 677 // |touch_event_queue_| will forward to OnTouchEventAck when appropriate.
575 touch_event_queue_->ProcessTouchAck(ack_result, latency); 678 touch_event_queue_->ProcessTouchAck(ack_result, latency);
576 } 679 }
577 680
578 void ImmediateInputRouter::ProcessAckForOverscroll( 681 void ImmediateInputRouter::ProcessAckForOverscroll(
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
674 case WebMouseEvent::ButtonNone: 777 case WebMouseEvent::ButtonNone:
675 break; 778 break;
676 } 779 }
677 } 780 }
678 781
679 bool ImmediateInputRouter::IsInOverscrollGesture() const { 782 bool ImmediateInputRouter::IsInOverscrollGesture() const {
680 OverscrollController* controller = client_->GetOverscrollController(); 783 OverscrollController* controller = client_->GetOverscrollController();
681 return controller && controller->overscroll_mode() != OVERSCROLL_NONE; 784 return controller && controller->overscroll_mode() != OVERSCROLL_NONE;
682 } 785 }
683 786
787 BaseGestureEventFilter* ImmediateInputRouter::gesture_event_filter() {
788 return event_filter_->gesture_event_filter_.get();
789 }
790
684 } // namespace content 791 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698