diff options
author | rbyers@chromium.org <rbyers@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-04-24 21:05:30 +0000 |
---|---|---|
committer | rbyers@chromium.org <rbyers@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-04-24 21:05:30 +0000 |
commit | ace1cd5043cedb0676240c74e69a8faf7e6d9a49 (patch) | |
tree | 823dbbbfd11d88a977880d10d567e56a334d03c4 /content/browser/renderer_host | |
parent | 3301058a73caf3d4322993e65ee91fcec75b046a (diff) | |
download | chromium_src-ace1cd5043cedb0676240c74e69a8faf7e6d9a49.zip chromium_src-ace1cd5043cedb0676240c74e69a8faf7e6d9a49.tar.gz chromium_src-ace1cd5043cedb0676240c74e69a8faf7e6d9a49.tar.bz2 |
Mark touchcancel events as uncancelable
The touch events spec says that all touch events are cancelable except for
touchcancel, and this is exposed to JS via the cancelable property.
Previously we were marking all touch events as cancelable, but as of
https://src.chromium.org/viewvc/blink?revision=172329&view=revision the
decision is up to the browser (since only it can decide if it will wait for
an ACK). This change ensures all touchcancel events are marked as
uncancelable, and all other touch events remain cancelable.
There are a lot of different places that create WebTouchEvents, and we
don't want some central location (like the InputRouter) to be modifying
these events. So I've added a WebTouchEventTraits::ResetType function to
reset properties of a WebTouchEvent, applying appropriate default policy
like cancelable state.
Then we can DCHECK at the central location that an a event is cancelable
if and only if we intend to wait for it's ACK.
I've updated a handful of unit tests to verify that the cancelable bit
is set correctly in various scenarios.
This also extends EventSender to allow the cancelable bit to be set so that
we can add a blink LayoutTest, and removes an unused
SyntheticWebTouchEventBuilder.
BUG=365681
Review URL: https://codereview.chromium.org/247433003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@265991 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content/browser/renderer_host')
11 files changed, 76 insertions, 112 deletions
diff --git a/content/browser/renderer_host/input/input_router_impl.cc b/content/browser/renderer_host/input/input_router_impl.cc index 129f346..36a7a26 100644 --- a/content/browser/renderer_host/input/input_router_impl.cc +++ b/content/browser/renderer_host/input/input_router_impl.cc @@ -13,11 +13,11 @@ #include "content/browser/renderer_host/input/input_router_client.h" #include "content/browser/renderer_host/input/touch_event_queue.h" #include "content/browser/renderer_host/input/touchpad_tap_suppression_controller.h" -#include "content/browser/renderer_host/input/web_touch_event_traits.h" #include "content/browser/renderer_host/overscroll_controller.h" #include "content/common/content_constants_internal.h" #include "content/common/edit_command.h" #include "content/common/input/touch_action.h" +#include "content/common/input/web_touch_event_traits.h" #include "content/common/input_messages.h" #include "content/common/view_messages.h" #include "content/port/common/input_event_ack_state.h" @@ -446,8 +446,17 @@ void InputRouterImpl::OfferToHandlers(const WebInputEvent& input_event, OfferToRenderer(input_event, latency_info, is_keyboard_shortcut); + // Touch events should always indicate in the event whether they are + // cancelable (respect ACK disposition) or not. + bool ignoresAck = + WebInputEventTraits::IgnoresAckDisposition(input_event.type); + if (WebInputEvent::isTouchEventType(input_event.type)) { + DCHECK(!ignoresAck == + static_cast<const blink::WebTouchEvent&>(input_event).cancelable); + } + // If we don't care about the ack disposition, send the ack immediately. - if (WebInputEventTraits::IgnoresAckDisposition(input_event.type)) { + if (ignoresAck) { ProcessInputEventAck(input_event.type, INPUT_EVENT_ACK_STATE_IGNORED, latency_info, diff --git a/content/browser/renderer_host/input/motion_event_web.cc b/content/browser/renderer_host/input/motion_event_web.cc index 07b6514..31ae995 100644 --- a/content/browser/renderer_host/input/motion_event_web.cc +++ b/content/browser/renderer_host/input/motion_event_web.cc @@ -5,6 +5,7 @@ #include "content/browser/renderer_host/input/motion_event_web.h" #include "base/logging.h" +#include "content/common/input/web_touch_event_traits.h" using blink::WebInputEvent; using blink::WebTouchEvent; @@ -13,31 +14,24 @@ using blink::WebTouchPoint; namespace content { namespace { -bool AllTouchPointsHaveState(const WebTouchEvent& event, - WebTouchPoint::State state) { - for (size_t i = 0; i < event.touchesLength; ++i) { - if (event.touches[i].state != state) - return false; - } - return true; -} - ui::MotionEvent::Action GetActionFrom(const WebTouchEvent& event) { - // TODO(jdduke): Use WebTouchEventTraits. DCHECK(event.touchesLength); switch (event.type) { case WebInputEvent::TouchStart: - if (AllTouchPointsHaveState(event, WebTouchPoint::StatePressed)) + if (WebTouchEventTraits::AllTouchPointsHaveState( + event, WebTouchPoint::StatePressed)) return ui::MotionEvent::ACTION_DOWN; else return ui::MotionEvent::ACTION_POINTER_DOWN; case WebInputEvent::TouchEnd: - if (AllTouchPointsHaveState(event, WebTouchPoint::StateReleased)) + if (WebTouchEventTraits::AllTouchPointsHaveState( + event, WebTouchPoint::StateReleased)) return ui::MotionEvent::ACTION_UP; else return ui::MotionEvent::ACTION_POINTER_UP; case WebInputEvent::TouchCancel: - DCHECK(AllTouchPointsHaveState(event, WebTouchPoint::StateCancelled)); + DCHECK(WebTouchEventTraits::AllTouchPointsHaveState( + event, WebTouchPoint::StateCancelled)); return ui::MotionEvent::ACTION_CANCEL; case WebInputEvent::TouchMove: return ui::MotionEvent::ACTION_MOVE; @@ -145,11 +139,11 @@ scoped_ptr<ui::MotionEvent> MotionEventWeb::Clone() const { scoped_ptr<ui::MotionEvent> MotionEventWeb::Cancel() const { WebTouchEvent cancel_event(event_); - - cancel_event.type = WebInputEvent::TouchCancel; - for (size_t i = 0; i < cancel_event.touchesLength; ++i) - cancel_event.touches[i].state = WebTouchPoint::StateCancelled; - + WebTouchEventTraits::ResetTypeAndTouchStates( + blink::WebInputEvent::TouchCancel, + // TODO(rbyers): Shouldn't we use a fresh timestamp? + event_.timeStampSeconds, + &cancel_event); return scoped_ptr<MotionEvent>(new MotionEventWeb(cancel_event)); } diff --git a/content/browser/renderer_host/input/touch_emulator.cc b/content/browser/renderer_host/input/touch_emulator.cc index 785935f..42b4310 100644 --- a/content/browser/renderer_host/input/touch_emulator.cc +++ b/content/browser/renderer_host/input/touch_emulator.cc @@ -6,6 +6,7 @@ #include "content/browser/renderer_host/input/motion_event_web.h" #include "content/browser/renderer_host/input/web_input_event_util.h" +#include "content/common/input/web_touch_event_traits.h" #include "content/public/common/content_client.h" #include "content/public/common/content_switches.h" #include "grit/content_resources.h" @@ -261,10 +262,10 @@ void TouchEmulator::CancelTouch() { if (!touch_active_) return; - touch_event_.timeStampSeconds = - (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF(); - touch_event_.type = WebInputEvent::TouchCancel; - touch_event_.touches[0].state = WebTouchPoint::StateCancelled; + WebTouchEventTraits::ResetTypeAndTouchStates( + WebInputEvent::TouchCancel, + (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF(), + &touch_event_); touch_active_ = false; if (gesture_provider_.OnTouchEvent(MotionEventWeb(touch_event_))) client_->ForwardTouchEvent(touch_event_); @@ -339,9 +340,26 @@ bool TouchEmulator::FillTouchEventAndPoint(const WebMouseEvent& mouse_event) { return false; } + WebInputEvent::Type eventType; + switch (mouse_event.type) { + case WebInputEvent::MouseDown: + eventType = WebInputEvent::TouchStart; + touch_active_ = true; + break; + case WebInputEvent::MouseMove: + eventType = WebInputEvent::TouchMove; + break; + case WebInputEvent::MouseUp: + eventType = WebInputEvent::TouchEnd; + break; + default: + eventType = WebInputEvent::Undefined; + NOTREACHED(); + } touch_event_.touchesLength = 1; - touch_event_.timeStampSeconds = mouse_event.timeStampSeconds; touch_event_.modifiers = mouse_event.modifiers; + WebTouchEventTraits::ResetTypeAndTouchStates( + eventType, mouse_event.timeStampSeconds, &touch_event_); WebTouchPoint& point = touch_event_.touches[0]; point.id = 0; @@ -353,24 +371,6 @@ bool TouchEmulator::FillTouchEventAndPoint(const WebMouseEvent& mouse_event) { point.position.y = mouse_event.y; point.screenPosition.y = mouse_event.globalY; - switch (mouse_event.type) { - case WebInputEvent::MouseDown: - touch_event_.type = WebInputEvent::TouchStart; - touch_active_ = true; - point.state = WebTouchPoint::StatePressed; - break; - case WebInputEvent::MouseMove: - touch_event_.type = WebInputEvent::TouchMove; - point.state = WebTouchPoint::StateMoved; - break; - case WebInputEvent::MouseUp: - touch_event_.type = WebInputEvent::TouchEnd; - touch_active_ = false; - point.state = WebTouchPoint::StateReleased; - break; - default: - NOTREACHED(); - } return true; } diff --git a/content/browser/renderer_host/input/touch_emulator_unittest.cc b/content/browser/renderer_host/input/touch_emulator_unittest.cc index 7593fb7..88ba251 100644 --- a/content/browser/renderer_host/input/touch_emulator_unittest.cc +++ b/content/browser/renderer_host/input/touch_emulator_unittest.cc @@ -76,6 +76,8 @@ class TouchEmulatorTest : public testing::Test, EXPECT_EQ(1U, event.touchesLength); EXPECT_EQ(last_mouse_x_, event.touches[0].position.x); EXPECT_EQ(last_mouse_y_, event.touches[0].position.y); + int expectedCancelable = event.type != WebInputEvent::TouchCancel; + EXPECT_EQ(expectedCancelable, event.cancelable); emulator()->HandleTouchEventAck(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS); } diff --git a/content/browser/renderer_host/input/touch_event_queue.cc b/content/browser/renderer_host/input/touch_event_queue.cc index 8662f4a..4f4aa7b 100644 --- a/content/browser/renderer_host/input/touch_event_queue.cc +++ b/content/browser/renderer_host/input/touch_event_queue.cc @@ -9,7 +9,7 @@ #include "base/debug/trace_event.h" #include "base/stl_util.h" #include "content/browser/renderer_host/input/timeout_monitor.h" -#include "content/browser/renderer_host/input/web_touch_event_traits.h" +#include "content/common/input/web_touch_event_traits.h" #include "content/public/common/content_switches.h" #include "ui/gfx/geometry/point_f.h" @@ -31,9 +31,11 @@ typedef std::vector<TouchEventWithLatencyInfo> WebTouchEventWithLatencyList; TouchEventWithLatencyInfo ObtainCancelEventForTouchEvent( const TouchEventWithLatencyInfo& event_to_cancel) { TouchEventWithLatencyInfo event = event_to_cancel; - event.event.type = WebInputEvent::TouchCancel; - for (size_t i = 0; i < event.event.touchesLength; i++) - event.event.touches[i].state = WebTouchPoint::StateCancelled; + WebTouchEventTraits::ResetTypeAndTouchStates( + WebInputEvent::TouchCancel, + // TODO(rbyers): Shouldn't we use a fresh timestamp? + event.event.timeStampSeconds, + &event.event); return event; } diff --git a/content/browser/renderer_host/input/touch_event_queue_unittest.cc b/content/browser/renderer_host/input/touch_event_queue_unittest.cc index f74d155..99fd921 100644 --- a/content/browser/renderer_host/input/touch_event_queue_unittest.cc +++ b/content/browser/renderer_host/input/touch_event_queue_unittest.cc @@ -259,6 +259,7 @@ TEST_F(TouchEventQueueTest, Basic) { EXPECT_EQ(1U, GetAndResetSentEventCount()); EXPECT_EQ(1U, GetAndResetAckedEventCount()); EXPECT_EQ(WebInputEvent::TouchStart, acked_event().type); + EXPECT_TRUE(acked_event().cancelable); // Receive an ACK for the second touch-event. SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED); @@ -266,6 +267,7 @@ TEST_F(TouchEventQueueTest, Basic) { EXPECT_EQ(0U, GetAndResetSentEventCount()); EXPECT_EQ(1U, GetAndResetAckedEventCount()); EXPECT_EQ(WebInputEvent::TouchMove, acked_event().type); + EXPECT_TRUE(acked_event().cancelable); } // Tests that the touch-queue is emptied if a page stops listening for touch @@ -854,6 +856,7 @@ TEST_F(TouchEventQueueTest, TouchCancelOnScroll) { EXPECT_EQ(1U, GetAndResetAckedEventCount()); EXPECT_EQ(2U, queued_event_count()); EXPECT_EQ(WebInputEvent::TouchCancel, sent_event().type); + EXPECT_FALSE(sent_event().cancelable); EXPECT_EQ(WebInputEvent::TouchStart, latest_event().type); // Acking the TouchCancel will result in dispatch of the next TouchStart. @@ -1053,6 +1056,8 @@ TEST_F(TouchEventQueueTest, TouchTimeoutBasic) { EXPECT_FALSE(IsTimeoutRunning()); EXPECT_EQ(0U, GetAndResetAckedEventCount()); EXPECT_EQ(1U, GetAndResetSentEventCount()); + EXPECT_EQ(WebInputEvent::TouchCancel, sent_event().type); + EXPECT_FALSE(sent_event().cancelable); // Touch events should not be forwarded until we receive the cancel acks. MoveTouchPoint(0, 1, 1); @@ -1073,6 +1078,8 @@ TEST_F(TouchEventQueueTest, TouchTimeoutBasic) { PressTouchPoint(0, 1); EXPECT_EQ(1U, GetAndResetSentEventCount()); EXPECT_EQ(0U, GetAndResetAckedEventCount()); + EXPECT_EQ(WebInputEvent::TouchStart, sent_event().type); + EXPECT_TRUE(sent_event().cancelable); } // Tests that the timeout is never started if the renderer consumes diff --git a/content/browser/renderer_host/input/web_input_event_util.cc b/content/browser/renderer_host/input/web_input_event_util.cc index 8bce2c6..611ee4d 100644 --- a/content/browser/renderer_host/input/web_input_event_util.cc +++ b/content/browser/renderer_host/input/web_input_event_util.cc @@ -5,6 +5,7 @@ #include "content/browser/renderer_host/input/web_input_event_util.h" #include "base/strings/string_util.h" +#include "content/common/input/web_touch_event_traits.h" #include "ui/events/gesture_detection/gesture_event_data.h" #include "ui/events/gesture_detection/motion_event.h" @@ -216,11 +217,10 @@ blink::WebTouchEvent CreateWebTouchEventFromMotionEvent( const ui::MotionEvent& event) { blink::WebTouchEvent result; - result.type = ToWebInputEventType(event.GetAction()); - DCHECK(WebInputEvent::isTouchEventType(result.type)); - - result.timeStampSeconds = - (event.GetEventTime() - base::TimeTicks()).InSecondsF(); + WebTouchEventTraits::ResetType( + ToWebInputEventType(event.GetAction()), + (event.GetEventTime() - base::TimeTicks()).InSecondsF(), + &result); result.touchesLength = std::min(event.GetPointerCount(), diff --git a/content/browser/renderer_host/input/web_touch_event_traits.cc b/content/browser/renderer_host/input/web_touch_event_traits.cc deleted file mode 100644 index c691c13..0000000 --- a/content/browser/renderer_host/input/web_touch_event_traits.cc +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "content/browser/renderer_host/input/web_touch_event_traits.h" - -#include "base/logging.h" - -using blink::WebInputEvent; -using blink::WebTouchEvent; - -namespace content { - -namespace { - -bool AllTouchPointsHaveState(const WebTouchEvent& event, - blink::WebTouchPoint::State state) { - if(!event.touchesLength) - return false; - for (size_t i = 0; i < event.touchesLength; ++i) { - if (event.touches[i].state != state) - return false; - } - return true; -} - -} // namespace - -bool WebTouchEventTraits::IsTouchSequenceStart(const WebTouchEvent& event) { - DCHECK(event.touchesLength); - if (event.type != WebInputEvent::TouchStart) - return false; - return AllTouchPointsHaveState(event, blink::WebTouchPoint::StatePressed); -} - -} // namespace content diff --git a/content/browser/renderer_host/input/web_touch_event_traits.h b/content/browser/renderer_host/input/web_touch_event_traits.h deleted file mode 100644 index 4e9b445..0000000 --- a/content/browser/renderer_host/input/web_touch_event_traits.h +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CONTENT_COMMON_INPUT_WEB_TOUCH_EVENT_TRAITS_H_ -#define CONTENT_COMMON_INPUT_WEB_TOUCH_EVENT_TRAITS_H_ - -#include "base/basictypes.h" -#include "content/common/input/scoped_web_input_event.h" -#include "third_party/WebKit/public/web/WebInputEvent.h" - -namespace content { - -// Utility class for performing operations on and with WebTouchEvents. -class CONTENT_EXPORT WebTouchEventTraits { - public: - static bool IsTouchSequenceStart(const blink::WebTouchEvent& event); -}; - -} // namespace content - -#endif // CONTENT_COMMON_INPUT_WEB_TOUCH_EVENT_TRAITS_H_ 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 81137d9..31474d4 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 @@ -535,6 +535,7 @@ TEST_F(RenderWidgetHostViewAuraTest, TouchEventState) { view_->OnTouchEvent(&press); EXPECT_FALSE(press.handled()); EXPECT_EQ(blink::WebInputEvent::TouchStart, view_->touch_event_.type); + EXPECT_TRUE(view_->touch_event_.cancelable); EXPECT_EQ(1U, view_->touch_event_.touchesLength); EXPECT_EQ(blink::WebTouchPoint::StatePressed, view_->touch_event_.touches[0].state); @@ -542,6 +543,7 @@ TEST_F(RenderWidgetHostViewAuraTest, TouchEventState) { view_->OnTouchEvent(&move); EXPECT_FALSE(move.handled()); EXPECT_EQ(blink::WebInputEvent::TouchMove, view_->touch_event_.type); + EXPECT_TRUE(view_->touch_event_.cancelable); EXPECT_EQ(1U, view_->touch_event_.touchesLength); EXPECT_EQ(blink::WebTouchPoint::StateMoved, view_->touch_event_.touches[0].state); @@ -549,6 +551,7 @@ TEST_F(RenderWidgetHostViewAuraTest, TouchEventState) { view_->OnTouchEvent(&release); EXPECT_FALSE(release.handled()); EXPECT_EQ(blink::WebInputEvent::TouchEnd, view_->touch_event_.type); + EXPECT_TRUE(view_->touch_event_.cancelable); EXPECT_EQ(0U, view_->touch_event_.touchesLength); // Now install some touch-event handlers and do the same steps. The touch @@ -560,6 +563,7 @@ TEST_F(RenderWidgetHostViewAuraTest, TouchEventState) { view_->OnTouchEvent(&press); EXPECT_TRUE(press.stopped_propagation()); EXPECT_EQ(blink::WebInputEvent::TouchStart, view_->touch_event_.type); + EXPECT_TRUE(view_->touch_event_.cancelable); EXPECT_EQ(1U, view_->touch_event_.touchesLength); EXPECT_EQ(blink::WebTouchPoint::StatePressed, view_->touch_event_.touches[0].state); @@ -567,6 +571,7 @@ TEST_F(RenderWidgetHostViewAuraTest, TouchEventState) { view_->OnTouchEvent(&move); EXPECT_TRUE(move.stopped_propagation()); EXPECT_EQ(blink::WebInputEvent::TouchMove, view_->touch_event_.type); + EXPECT_TRUE(view_->touch_event_.cancelable); EXPECT_EQ(1U, view_->touch_event_.touchesLength); EXPECT_EQ(blink::WebTouchPoint::StateMoved, view_->touch_event_.touches[0].state); @@ -574,6 +579,7 @@ TEST_F(RenderWidgetHostViewAuraTest, TouchEventState) { view_->OnTouchEvent(&release); EXPECT_TRUE(release.stopped_propagation()); EXPECT_EQ(blink::WebInputEvent::TouchEnd, view_->touch_event_.type); + EXPECT_TRUE(view_->touch_event_.cancelable); EXPECT_EQ(0U, view_->touch_event_.touchesLength); // Now start a touch event, and remove the event-handlers before the release. diff --git a/content/browser/renderer_host/ui_events_helper.cc b/content/browser/renderer_host/ui_events_helper.cc index 8c2a9a9..00bc2f3 100644 --- a/content/browser/renderer_host/ui_events_helper.cc +++ b/content/browser/renderer_host/ui_events_helper.cc @@ -4,6 +4,7 @@ #include "content/browser/renderer_host/ui_events_helper.h" +#include "content/common/input/web_touch_event_traits.h" #include "third_party/WebKit/public/web/WebInputEvent.h" #include "ui/events/event.h" #include "ui/events/event_constants.h" @@ -325,8 +326,9 @@ blink::WebTouchPoint* UpdateWebTouchEventFromUIEvent( } // Update the type of the touch event. - web_event->type = TouchEventTypeFromEvent(event); - web_event->timeStampSeconds = event.time_stamp().InSecondsF(); + WebTouchEventTraits::ResetType(TouchEventTypeFromEvent(event), + event.time_stamp().InSecondsF(), + web_event); web_event->modifiers = EventFlagsToWebEventModifiers(event.flags()); return point; |