summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjdduke <jdduke@chromium.org>2015-02-26 08:16:18 -0800
committerCommit bot <commit-bot@chromium.org>2015-02-26 16:17:24 +0000
commitdfb809f04aa38b0fc0a6ce8c69649377b83a20df (patch)
treec28ec3663a9e16c9287851cf5b325449518d0e25
parentcab20570232799a8c60e988469cd2676b7a57010 (diff)
downloadchromium_src-dfb809f04aa38b0fc0a6ce8c69649377b83a20df.zip
chromium_src-dfb809f04aa38b0fc0a6ce8c69649377b83a20df.tar.gz
chromium_src-dfb809f04aa38b0fc0a6ce8c69649377b83a20df.tar.bz2
Always forward touch events to the TouchEventQueue
There's currently a shortcut that the RWHView can take with touch events when there is no registered touch handler. This avoids the overhead of passing the touch to the InputRouter/TouchEventQueue, but the predicate for conditionally forwarding the events is racy. This can lead to scenarios where a touch event stream is interrupted and the pipeline only sees a partial touch sequence. As the cost of always forwarding the events is relatively small, remove this optimization entirely, instead relying on the TouchEventQueue to filter events as appropriate. BUG=461583 Review URL: https://codereview.chromium.org/954973003 Cr-Commit-Position: refs/heads/master@{#318243}
-rw-r--r--content/browser/renderer_host/input/input_router.h5
-rw-r--r--content/browser/renderer_host/input/input_router_impl.cc6
-rw-r--r--content/browser/renderer_host/input/input_router_impl.h1
-rw-r--r--content/browser/renderer_host/input/input_router_impl_unittest.cc5
-rw-r--r--content/browser/renderer_host/render_widget_host_impl.cc11
-rw-r--r--content/browser/renderer_host/render_widget_host_impl.h3
-rw-r--r--content/browser/renderer_host/render_widget_host_unittest.cc1
-rw-r--r--content/browser/renderer_host/render_widget_host_view_android.cc16
-rw-r--r--content/browser/renderer_host/render_widget_host_view_aura.cc18
-rw-r--r--content/browser/renderer_host/render_widget_host_view_aura_unittest.cc80
-rw-r--r--ui/events/gesture_detection/filtered_gesture_provider.h2
11 files changed, 57 insertions, 91 deletions
diff --git a/content/browser/renderer_host/input/input_router.h b/content/browser/renderer_host/input/input_router.h
index 96b68c3..dde441a 100644
--- a/content/browser/renderer_host/input/input_router.h
+++ b/content/browser/renderer_host/input/input_router.h
@@ -50,11 +50,6 @@ class InputRouter : public IPC::Listener {
// Returns the oldest queued or in-flight keyboard event sent to the router.
virtual const NativeWebKeyboardEvent* GetLastKeyboardEvent() const = 0;
- // Returns |true| if the caller should immediately forward touch events to the
- // router. When |false|, the caller can forego sending touch events, and
- // instead consume them directly.
- virtual bool ShouldForwardTouchEvent() const = 0;
-
// Allow the router to make more informed input handling decisions based on
// the current view.
enum ViewFlags {
diff --git a/content/browser/renderer_host/input/input_router_impl.cc b/content/browser/renderer_host/input/input_router_impl.cc
index 8714548..54bf892 100644
--- a/content/browser/renderer_host/input/input_router_impl.cc
+++ b/content/browser/renderer_host/input/input_router_impl.cc
@@ -237,12 +237,6 @@ const NativeWebKeyboardEvent* InputRouterImpl::GetLastKeyboardEvent() const {
return &key_queue_.front();
}
-bool InputRouterImpl::ShouldForwardTouchEvent() const {
- // Always send a touch event if the renderer has a touch-event handler or
- // there are pending touch events.
- return touch_event_queue_.has_handlers() || !touch_event_queue_.empty();
-}
-
void InputRouterImpl::OnViewUpdated(int view_flags) {
current_view_flags_ = view_flags;
diff --git a/content/browser/renderer_host/input/input_router_impl.h b/content/browser/renderer_host/input/input_router_impl.h
index 11ebdf5..e869640 100644
--- a/content/browser/renderer_host/input/input_router_impl.h
+++ b/content/browser/renderer_host/input/input_router_impl.h
@@ -68,7 +68,6 @@ class CONTENT_EXPORT InputRouterImpl
const GestureEventWithLatencyInfo& gesture_event) override;
void SendTouchEvent(const TouchEventWithLatencyInfo& touch_event) override;
const NativeWebKeyboardEvent* GetLastKeyboardEvent() const override;
- bool ShouldForwardTouchEvent() const override;
void OnViewUpdated(int view_flags) override;
bool HasPendingEvents() const override;
diff --git a/content/browser/renderer_host/input/input_router_impl_unittest.cc b/content/browser/renderer_host/input/input_router_impl_unittest.cc
index d285cef..ec62671 100644
--- a/content/browser/renderer_host/input/input_router_impl_unittest.cc
+++ b/content/browser/renderer_host/input/input_router_impl_unittest.cc
@@ -818,8 +818,6 @@ TEST_F(InputRouterImplTest, TouchEventQueueFlush) {
EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
EXPECT_TRUE(TouchEventQueueEmpty());
- EXPECT_TRUE(input_router_->ShouldForwardTouchEvent());
-
// Send a touch-press event.
PressTouchPoint(1, 1);
SendTouchEvent();
@@ -834,14 +832,12 @@ TEST_F(InputRouterImplTest, TouchEventQueueFlush) {
EXPECT_FALSE(client_->has_touch_handler());
EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
EXPECT_FALSE(TouchEventQueueEmpty());
- EXPECT_TRUE(input_router_->ShouldForwardTouchEvent());
// After the ack, the touch-event queue should be empty, and none of the
// flushed touch-events should have been sent to the renderer.
SendInputEventACK(WebInputEvent::TouchStart, INPUT_EVENT_ACK_STATE_CONSUMED);
EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
EXPECT_TRUE(TouchEventQueueEmpty());
- EXPECT_FALSE(input_router_->ShouldForwardTouchEvent());
}
#if defined(USE_AURA)
@@ -851,7 +847,6 @@ TEST_F(InputRouterImplTest, AckedTouchEventState) {
input_router_->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, true));
EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
EXPECT_TRUE(TouchEventQueueEmpty());
- EXPECT_TRUE(input_router_->ShouldForwardTouchEvent());
// Send a bunch of events, and make sure the ACKed events are correct.
ScopedVector<ui::TouchEvent> expected_events;
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc
index 717e2c0..b2b8dca 100644
--- a/content/browser/renderer_host/render_widget_host_impl.cc
+++ b/content/browser/renderer_host/render_widget_host_impl.cc
@@ -1902,17 +1902,6 @@ bool RenderWidgetHostImpl::IgnoreInputEvents() const {
return ignore_input_events_ || process_->IgnoreInputEvents();
}
-bool RenderWidgetHostImpl::ShouldForwardTouchEvent() const {
- // It's important that the emulator sees a complete native touch stream,
- // allowing it to perform touch filtering as appropriate.
- // TODO(dgozman): Remove when touch stream forwarding issues resolved, see
- // crbug.com/375940.
- if (touch_emulator_ && touch_emulator_->enabled())
- return true;
-
- return input_router_->ShouldForwardTouchEvent();
-}
-
void RenderWidgetHostImpl::StartUserGesture() {
OnUserGesture();
}
diff --git a/content/browser/renderer_host/render_widget_host_impl.h b/content/browser/renderer_host/render_widget_host_impl.h
index 3516a0c..4d7d0f9 100644
--- a/content/browser/renderer_host/render_widget_host_impl.h
+++ b/content/browser/renderer_host/render_widget_host_impl.h
@@ -380,9 +380,6 @@ class CONTENT_EXPORT RenderWidgetHostImpl
// |ignore_input_events_| or |process_->IgnoreInputEvents()| is true.
bool IgnoreInputEvents() const;
- // Event queries delegated to the |input_router_|.
- bool ShouldForwardTouchEvent() const;
-
bool has_touch_handler() const { return has_touch_handler_; }
// Notification that the user has made some kind of input that could
diff --git a/content/browser/renderer_host/render_widget_host_unittest.cc b/content/browser/renderer_host/render_widget_host_unittest.cc
index ea9d84e..121bbf3 100644
--- a/content/browser/renderer_host/render_widget_host_unittest.cc
+++ b/content/browser/renderer_host/render_widget_host_unittest.cc
@@ -100,7 +100,6 @@ class MockInputRouter : public InputRouter {
NOTREACHED();
return NULL;
}
- bool ShouldForwardTouchEvent() const override { return true; }
void OnViewUpdated(int view_flags) override {}
bool HasPendingEvents() const override { return false; }
diff --git a/content/browser/renderer_host/render_widget_host_view_android.cc b/content/browser/renderer_host/render_widget_host_view_android.cc
index cc6ab4e..339fec9 100644
--- a/content/browser/renderer_host/render_widget_host_view_android.cc
+++ b/content/browser/renderer_host/render_widget_host_view_android.cc
@@ -810,19 +810,15 @@ bool RenderWidgetHostViewAndroid::OnTouchEvent(
if (stylus_text_selector_.OnTouchEvent(event))
return true;
- auto result = gesture_provider_.OnTouchEvent(event);
+ ui::FilteredGestureProvider::TouchHandlingResult result =
+ gesture_provider_.OnTouchEvent(event);
if (!result.succeeded)
return false;
- if (host_->ShouldForwardTouchEvent()) {
- blink::WebTouchEvent web_event =
- CreateWebTouchEventFromMotionEvent(event, result.did_generate_scroll);
- host_->ForwardTouchEventWithLatencyInfo(web_event,
- CreateLatencyInfo(web_event));
- } else {
- const bool event_consumed = false;
- gesture_provider_.OnAsyncTouchEventAck(event_consumed);
- }
+ blink::WebTouchEvent web_event =
+ CreateWebTouchEventFromMotionEvent(event, result.did_generate_scroll);
+ host_->ForwardTouchEventWithLatencyInfo(web_event,
+ CreateLatencyInfo(web_event));
// Send a proactive BeginFrame on the next vsync to reduce latency.
// This is good enough as long as the first touch event has Begin semantics
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc
index 63c1609..71d03da 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura.cc
+++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
@@ -2067,18 +2067,12 @@ void RenderWidgetHostViewAura::OnTouchEvent(ui::TouchEvent* event) {
pointer_state_, event->may_cause_scrolling());
pointer_state_.CleanupRemovedTouchPoints(*event);
- // Forward the touch event only if a touch point was updated, and
- // there's a touch-event handler in the page, and no other
- // touch-event is in the queue. It is important to always mark
- // events as being handled asynchronously if there is a touch-event
- // handler in the page, or some touch-event is already in the queue,
- // even if no point has been updated. This ensures that this event
- // does not get processed by the gesture recognizer before events
- // currently awaiting dispatch in the touch queue.
- if (host_->ShouldForwardTouchEvent()) {
- event->DisableSynchronousHandling();
- host_->ForwardTouchEventWithLatencyInfo(touch_event, *event->latency());
- }
+ // It is important to always mark events as being handled asynchronously when
+ // they are forwarded. This ensures that the current event does not get
+ // processed by the gesture recognizer before events currently awaiting
+ // dispatch in the touch queue.
+ event->DisableSynchronousHandling();
+ host_->ForwardTouchEventWithLatencyInfo(touch_event, *event->latency());
}
void RenderWidgetHostViewAura::OnGestureEvent(ui::GestureEvent* event) {
diff --git a/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc b/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc
index 9a6042d..50ca24c 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc
+++ b/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc
@@ -448,6 +448,28 @@ class RenderWidgetHostViewAuraTest : public testing::Test {
widget_host_->OnMessageReceived(response);
}
+ size_t GetSentMessageCountAndResetSink() {
+ size_t count = sink_->message_count();
+ sink_->ClearMessages();
+ return count;
+ }
+
+ void AckLastSentInputEventIfNecessary(InputEventAckState ack_result) {
+ if (!sink_->message_count())
+ return;
+
+ InputMsg_HandleInputEvent::Param params;
+ if (!InputMsg_HandleInputEvent::Read(
+ sink_->GetMessageAt(sink_->message_count() - 1), &params)) {
+ return;
+ }
+
+ if (WebInputEventTraits::IgnoresAckDisposition(*get<0>(params)))
+ return;
+
+ SendInputEventACK(get<0>(params)->type, ack_result);
+ }
+
protected:
// If true, then calls RWH::Shutdown() instead of deleting RWH.
bool widget_host_uses_shutdown_to_destroy_;
@@ -693,28 +715,6 @@ class RenderWidgetHostViewAuraOverscrollTest
SendTouchEvent();
}
- size_t GetSentMessageCountAndResetSink() {
- size_t count = sink_->message_count();
- sink_->ClearMessages();
- return count;
- }
-
- void AckLastSentInputEventIfNecessary(InputEventAckState ack_result) {
- if (!sink_->message_count())
- return;
-
- InputMsg_HandleInputEvent::Param params;
- if (!InputMsg_HandleInputEvent::Read(
- sink_->GetMessageAt(sink_->message_count() - 1), &params)) {
- return;
- }
-
- if (WebInputEventTraits::IgnoresAckDisposition(*get<0>(params)))
- return;
-
- SendInputEventACK(get<0>(params)->type, ack_result);
- }
-
SyntheticWebTouchEvent touch_event_;
scoped_ptr<TestOverscrollDelegate> overscroll_delegate_;
@@ -1021,10 +1021,10 @@ TEST_F(RenderWidgetHostViewAuraTest, FinishCompositionByMouse) {
TEST_F(RenderWidgetHostViewAuraTest, TouchEventState) {
view_->InitAsChild(NULL);
view_->Show();
+ GetSentMessageCountAndResetSink();
// Start with no touch-event handler in the renderer.
widget_host_->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, false));
- EXPECT_FALSE(widget_host_->ShouldForwardTouchEvent());
ui::TouchEvent press(ui::ET_TOUCH_PRESSED,
gfx::Point(30, 30),
@@ -1039,8 +1039,11 @@ TEST_F(RenderWidgetHostViewAuraTest, TouchEventState) {
0,
ui::EventTimeForNow());
+ // The touch events should get forwared from the view, but they should not
+ // reach the renderer.
view_->OnTouchEvent(&press);
- EXPECT_FALSE(press.handled());
+ EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
+ EXPECT_TRUE(press.synchronous_handling_disabled());
EXPECT_EQ(blink::WebInputEvent::TouchStart, view_->touch_event_->type);
EXPECT_TRUE(view_->touch_event_->cancelable);
EXPECT_EQ(1U, view_->touch_event_->touchesLength);
@@ -1048,7 +1051,8 @@ TEST_F(RenderWidgetHostViewAuraTest, TouchEventState) {
view_->touch_event_->touches[0].state);
view_->OnTouchEvent(&move);
- EXPECT_FALSE(move.handled());
+ EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
+ EXPECT_TRUE(press.synchronous_handling_disabled());
EXPECT_EQ(blink::WebInputEvent::TouchMove, view_->touch_event_->type);
EXPECT_TRUE(view_->touch_event_->cancelable);
EXPECT_EQ(1U, view_->touch_event_->touchesLength);
@@ -1056,16 +1060,17 @@ TEST_F(RenderWidgetHostViewAuraTest, TouchEventState) {
view_->touch_event_->touches[0].state);
view_->OnTouchEvent(&release);
- EXPECT_FALSE(release.handled());
+ EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
+ EXPECT_TRUE(press.synchronous_handling_disabled());
EXPECT_EQ(nullptr, view_->touch_event_);
// Now install some touch-event handlers and do the same steps. The touch
// events should now be consumed. However, the touch-event state should be
// updated as before.
widget_host_->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, true));
- EXPECT_TRUE(widget_host_->ShouldForwardTouchEvent());
view_->OnTouchEvent(&press);
+ EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
EXPECT_TRUE(press.synchronous_handling_disabled());
EXPECT_EQ(blink::WebInputEvent::TouchStart, view_->touch_event_->type);
EXPECT_TRUE(view_->touch_event_->cancelable);
@@ -1093,19 +1098,18 @@ TEST_F(RenderWidgetHostViewAuraTest, TouchEventState) {
view_->touch_event_->touches[0].state);
widget_host_->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, false));
- EXPECT_TRUE(widget_host_->ShouldForwardTouchEvent());
// Ack'ing the outstanding event should flush the pending touch queue.
InputHostMsg_HandleInputEvent_ACK_Params ack;
ack.type = blink::WebInputEvent::TouchStart;
ack.state = INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS;
widget_host_->OnMessageReceived(InputHostMsg_HandleInputEvent_ACK(0, ack));
- EXPECT_FALSE(widget_host_->ShouldForwardTouchEvent());
+ EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
ui::TouchEvent move2(ui::ET_TOUCH_MOVED, gfx::Point(20, 20), 0,
base::Time::NowFromSystemTime() - base::Time());
view_->OnTouchEvent(&move2);
- EXPECT_FALSE(move2.handled());
+ EXPECT_TRUE(press.synchronous_handling_disabled());
EXPECT_EQ(blink::WebInputEvent::TouchMove, view_->touch_event_->type);
EXPECT_EQ(1U, view_->touch_event_->touchesLength);
EXPECT_EQ(blink::WebTouchPoint::StateMoved,
@@ -1114,7 +1118,7 @@ TEST_F(RenderWidgetHostViewAuraTest, TouchEventState) {
ui::TouchEvent release2(ui::ET_TOUCH_RELEASED, gfx::Point(20, 20), 0,
base::Time::NowFromSystemTime() - base::Time());
view_->OnTouchEvent(&release2);
- EXPECT_FALSE(release2.handled());
+ EXPECT_TRUE(press.synchronous_handling_disabled());
EXPECT_EQ(nullptr, view_->touch_event_);
}
@@ -1125,7 +1129,6 @@ TEST_F(RenderWidgetHostViewAuraTest, TouchEventSyncAsync) {
view_->Show();
widget_host_->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, true));
- EXPECT_TRUE(widget_host_->ShouldForwardTouchEvent());
ui::TouchEvent press(ui::ET_TOUCH_PRESSED,
gfx::Point(30, 30),
@@ -3102,9 +3105,9 @@ TEST_F(RenderWidgetHostViewAuraTest,
InvalidEventsHaveSyncHandlingDisabled) {
view_->InitAsChild(NULL);
view_->Show();
+ GetSentMessageCountAndResetSink();
widget_host_->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, true));
- EXPECT_TRUE(widget_host_->ShouldForwardTouchEvent());
ui::TouchEvent press(ui::ET_TOUCH_PRESSED, gfx::Point(30, 30), 0,
ui::EventTimeForNow());
@@ -3113,11 +3116,16 @@ TEST_F(RenderWidgetHostViewAuraTest,
ui::TouchEvent invalid_move(ui::ET_TOUCH_MOVED, gfx::Point(30, 30), 1,
ui::EventTimeForNow());
- view_->OnTouchEvent(&press);
- view_->OnTouchEvent(&invalid_move);
// Valid press is handled asynchronously.
+ view_->OnTouchEvent(&press);
EXPECT_TRUE(press.synchronous_handling_disabled());
- // Invalid move is handled synchronously, but is consumed.
+ EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
+ AckLastSentInputEventIfNecessary(INPUT_EVENT_ACK_STATE_CONSUMED);
+
+ // Invalid move is handled synchronously, but is consumed. It should not
+ // be forwarded to the renderer.
+ view_->OnTouchEvent(&invalid_move);
+ EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
EXPECT_FALSE(invalid_move.synchronous_handling_disabled());
EXPECT_TRUE(invalid_move.stopped_propagation());
}
diff --git a/ui/events/gesture_detection/filtered_gesture_provider.h b/ui/events/gesture_detection/filtered_gesture_provider.h
index 5f937c1..21b9a96 100644
--- a/ui/events/gesture_detection/filtered_gesture_provider.h
+++ b/ui/events/gesture_detection/filtered_gesture_provider.h
@@ -29,7 +29,7 @@ class GESTURE_DETECTION_EXPORT FilteredGestureProvider
// True if |event| was both valid and successfully handled by the
// gesture provider. Otherwise, false, in which case the caller should drop
- // |event| and cease furthe propagation.
+ // |event| and cease further propagation.
bool succeeded;
// Whether |event| produced scrolling motion, either the start of a scroll,