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 | |
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
21 files changed, 232 insertions, 139 deletions
diff --git a/content/browser/frame_host/render_widget_host_view_guest.cc b/content/browser/frame_host/render_widget_host_view_guest.cc index c7ef31b..c564a28 100644 --- a/content/browser/frame_host/render_widget_host_view_guest.cc +++ b/content/browser/frame_host/render_widget_host_view_guest.cc @@ -13,6 +13,7 @@ #include "content/common/frame_messages.h" #include "content/common/gpu/gpu_messages.h" #include "content/common/host_shared_bitmap_manager.h" +#include "content/common/input/web_touch_event_traits.h" #include "content/common/view_messages.h" #include "content/common/webplugin_geometry.h" #include "content/public/common/content_switches.h" @@ -531,8 +532,12 @@ void RenderWidgetHostViewGuest::DispatchCancelTouchEvent( return; blink::WebTouchEvent cancel_event; - cancel_event.type = blink::WebInputEvent::TouchCancel; - cancel_event.timeStampSeconds = event->time_stamp().InSecondsF(); + // TODO(rbyers): This event has no touches in it. Don't we need to know what + // touches are currently active in order to cancel them all properly? + WebTouchEventTraits::ResetType(blink::WebInputEvent::TouchCancel, + event->time_stamp().InSecondsF(), + &cancel_event); + host_->ForwardTouchEventWithLatencyInfo(cancel_event, *event->latency()); } 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; diff --git a/content/common/input/synthetic_web_input_event_builders.cc b/content/common/input/synthetic_web_input_event_builders.cc index f5a8aa3..1bdea99 100644 --- a/content/common/input/synthetic_web_input_event_builders.cc +++ b/content/common/input/synthetic_web_input_event_builders.cc @@ -5,6 +5,7 @@ #include "content/common/input/synthetic_web_input_event_builders.h" #include "base/logging.h" +#include "content/common/input/web_touch_event_traits.h" #include "ui/events/keycodes/keyboard_codes.h" namespace content { @@ -169,7 +170,8 @@ int SyntheticWebTouchEvent::PressPoint(float x, float y) { point.state = WebTouchPoint::StatePressed; point.radiusX = point.radiusY = 1.f; ++touchesLength; - type = WebInputEvent::TouchStart; + WebTouchEventTraits::ResetType( + WebInputEvent::TouchStart, timeStampSeconds, this); return point.id; } @@ -179,31 +181,26 @@ void SyntheticWebTouchEvent::MovePoint(int index, float x, float y) { point.position.x = point.screenPosition.x = x; point.position.y = point.screenPosition.y = y; touches[index].state = WebTouchPoint::StateMoved; - type = WebInputEvent::TouchMove; + WebTouchEventTraits::ResetType( + WebInputEvent::TouchMove, timeStampSeconds, this); } void SyntheticWebTouchEvent::ReleasePoint(int index) { CHECK(index >= 0 && index < touchesLengthCap); touches[index].state = WebTouchPoint::StateReleased; - type = WebInputEvent::TouchEnd; + WebTouchEventTraits::ResetType( + WebInputEvent::TouchEnd, timeStampSeconds, this); } void SyntheticWebTouchEvent::CancelPoint(int index) { CHECK(index >= 0 && index < touchesLengthCap); touches[index].state = WebTouchPoint::StateCancelled; - type = WebInputEvent::TouchCancel; + WebTouchEventTraits::ResetType( + WebInputEvent::TouchCancel, timeStampSeconds, this); } void SyntheticWebTouchEvent::SetTimestamp(base::TimeDelta timestamp) { timeStampSeconds = timestamp.InSecondsF(); } -SyntheticWebTouchEvent SyntheticWebTouchEventBuilder::Build( - WebInputEvent::Type type) { - DCHECK(WebInputEvent::isTouchEventType(type)); - SyntheticWebTouchEvent result; - result.type = type; - return result; -}; - } // namespace content diff --git a/content/common/input/synthetic_web_input_event_builders.h b/content/common/input/synthetic_web_input_event_builders.h index 622199d..5df4cd6 100644 --- a/content/common/input/synthetic_web_input_event_builders.h +++ b/content/common/input/synthetic_web_input_event_builders.h @@ -74,11 +74,6 @@ class CONTENT_EXPORT SyntheticWebTouchEvent void SetTimestamp(base::TimeDelta timestamp); }; -class CONTENT_EXPORT SyntheticWebTouchEventBuilder { - public: - static SyntheticWebTouchEvent Build(blink::WebInputEvent::Type type); -}; - } // namespace content #endif // CONTENT_COMMON_INPUT_SYNTHETIC_WEB_INPUT_EVENT_BUILDERS_H_ diff --git a/content/common/input/web_touch_event_traits.cc b/content/common/input/web_touch_event_traits.cc new file mode 100644 index 0000000..d1003bac --- /dev/null +++ b/content/common/input/web_touch_event_traits.cc @@ -0,0 +1,70 @@ +// 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/common/input/web_touch_event_traits.h" + +#include "base/logging.h" + +using blink::WebInputEvent; +using blink::WebTouchEvent; +using blink::WebTouchPoint; + +namespace content { + +bool WebTouchEventTraits::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; +} + +bool WebTouchEventTraits::IsTouchSequenceStart(const WebTouchEvent& event) { + DCHECK(event.touchesLength); + if (event.type != WebInputEvent::TouchStart) + return false; + return AllTouchPointsHaveState(event, blink::WebTouchPoint::StatePressed); +} + +void WebTouchEventTraits::ResetType(WebInputEvent::Type type, + double timestamp_sec, + WebTouchEvent* event) { + DCHECK(WebInputEvent::isTouchEventType(type)); + event->type = type; + event->cancelable = (type != WebInputEvent::TouchCancel); + event->timeStampSeconds = timestamp_sec; +} + +void WebTouchEventTraits::ResetTypeAndTouchStates(WebInputEvent::Type type, + double timestamp_sec, + WebTouchEvent* event) { + ResetType(type, timestamp_sec, event); + + WebTouchPoint::State newState = WebTouchPoint::StateUndefined; + switch (event->type) { + case WebInputEvent::TouchStart: + newState = WebTouchPoint::StatePressed; + break; + case WebInputEvent::TouchMove: + newState = WebTouchPoint::StateMoved; + break; + case WebInputEvent::TouchEnd: + newState = WebTouchPoint::StateReleased; + break; + case WebInputEvent::TouchCancel: + newState = WebTouchPoint::StateCancelled; + break; + default: + NOTREACHED(); + break; + } + for (size_t i = 0; i < event->touchesLength; ++i) + event->touches[i].state = newState; +} + +} // namespace content diff --git a/content/common/input/web_touch_event_traits.h b/content/common/input/web_touch_event_traits.h new file mode 100644 index 0000000..74e9d6e --- /dev/null +++ b/content/common/input/web_touch_event_traits.h @@ -0,0 +1,41 @@ +// 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: + // Returns whether all touches in the event have the specified state. + static bool AllTouchPointsHaveState(const blink::WebTouchEvent& event, + blink::WebTouchPoint::State state); + + // Returns whether this event represents a transition from no active + // touches to some active touches (the start of a new "touch sequence"). + static bool IsTouchSequenceStart(const blink::WebTouchEvent& event); + + // Sets the type of |event| to |type|, resetting any other type-specific + // properties and updating the timestamp. + static void ResetType(blink::WebInputEvent::Type type, + double timestamp_sec, + blink::WebTouchEvent* event); + + // Like ResetType but also resets the state of all active touches + // to match the event type. This is particularly useful, for example, + // in sending a touchcancel for all active touches. + static void ResetTypeAndTouchStates(blink::WebInputEvent::Type type, + double timestamp_sec, + blink::WebTouchEvent* event); +}; + +} // namespace content + +#endif // CONTENT_COMMON_INPUT_WEB_TOUCH_EVENT_TRAITS_H_ diff --git a/content/content_browser.gypi b/content/content_browser.gypi index 139f946..1b4362b 100644 --- a/content/content_browser.gypi +++ b/content/content_browser.gypi @@ -948,8 +948,6 @@ 'browser/renderer_host/input/web_input_event_util.h', 'browser/renderer_host/input/web_input_event_util_posix.cc', 'browser/renderer_host/input/web_input_event_util_posix.h', - 'browser/renderer_host/input/web_touch_event_traits.cc', - 'browser/renderer_host/input/web_touch_event_traits.h', 'browser/renderer_host/java/java_bound_object.cc', 'browser/renderer_host/java/java_bound_object.h', 'browser/renderer_host/java/java_bridge_channel_host.cc', diff --git a/content/content_common.gypi b/content/content_common.gypi index c9aa6a7..837a085 100644 --- a/content/content_common.gypi +++ b/content/content_common.gypi @@ -321,6 +321,8 @@ 'common/input/synthetic_web_input_event_builders.h', 'common/input/web_input_event_traits.cc', 'common/input/web_input_event_traits.h', + 'common/input/web_touch_event_traits.cc', + 'common/input/web_touch_event_traits.h', 'common/input_messages.h', 'common/inter_process_time_ticks_converter.cc', 'common/inter_process_time_ticks_converter.h', diff --git a/content/renderer/pepper/event_conversion.cc b/content/renderer/pepper/event_conversion.cc index d44e38f..d08e3d5 100644 --- a/content/renderer/pepper/event_conversion.cc +++ b/content/renderer/pepper/event_conversion.cc @@ -14,6 +14,7 @@ #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversion_utils.h" #include "base/strings/utf_string_conversions.h" +#include "content/common/input/web_touch_event_traits.h" #include "content/renderer/pepper/common.h" #include "content/renderer/pepper/usb_key_code_conversion.h" #include "ppapi/c/pp_input_event.h" @@ -291,33 +292,34 @@ void SetWebTouchPoints(const std::vector<PP_TouchPoint>& pp_touches, WebTouchEvent* BuildTouchEvent(const InputEventData& event) { WebTouchEvent* web_event = new WebTouchEvent(); WebTouchPoint::State state = WebTouchPoint::StateUndefined; + WebInputEvent::Type type = WebInputEvent::Undefined; switch (event.event_type) { case PP_INPUTEVENT_TYPE_TOUCHSTART: - web_event->type = WebInputEvent::TouchStart; + type = WebInputEvent::TouchStart; state = WebTouchPoint::StatePressed; break; case PP_INPUTEVENT_TYPE_TOUCHMOVE: - web_event->type = WebInputEvent::TouchMove; + type = WebInputEvent::TouchMove; state = WebTouchPoint::StateMoved; break; case PP_INPUTEVENT_TYPE_TOUCHEND: - web_event->type = WebInputEvent::TouchEnd; + type = WebInputEvent::TouchEnd; state = WebTouchPoint::StateReleased; break; case PP_INPUTEVENT_TYPE_TOUCHCANCEL: - web_event->type = WebInputEvent::TouchCancel; + type = WebInputEvent::TouchCancel; state = WebTouchPoint::StateCancelled; break; default: NOTREACHED(); } + WebTouchEventTraits::ResetType( + type, PPTimeTicksToEventTime(event.event_time_stamp), web_event); TouchStateMap states_map; for (uint32_t i = 0; i < event.changed_touches.size(); i++) states_map[event.changed_touches[i].id] = state; - web_event->timeStampSeconds = PPTimeTicksToEventTime(event.event_time_stamp); - SetWebTouchPoints(event.changed_touches, states_map, web_event->changedTouches, diff --git a/content/shell/renderer/test_runner/event_sender.cc b/content/shell/renderer/test_runner/event_sender.cc index 164d412..88686df 100644 --- a/content/shell/renderer/test_runner/event_sender.cc +++ b/content/shell/renderer/test_runner/event_sender.cc @@ -341,6 +341,7 @@ class EventSenderBindings : public gin::Wrappable<EventSenderBindings> { void UpdateTouchPoint(unsigned index, double x, double y); void CancelTouchPoint(unsigned index); void SetTouchModifier(const std::string& key_name, bool set_mask); + void SetTouchCancelable(bool cancelable); void DumpFilenameBeingDragged(); void GestureFlingCancel(); void GestureFlingStart(float x, float y, float velocity_x, float velocity_y); @@ -458,6 +459,7 @@ EventSenderBindings::GetObjectTemplateBuilder(v8::Isolate* isolate) { .SetMethod("updateTouchPoint", &EventSenderBindings::UpdateTouchPoint) .SetMethod("cancelTouchPoint", &EventSenderBindings::CancelTouchPoint) .SetMethod("setTouchModifier", &EventSenderBindings::SetTouchModifier) + .SetMethod("setTouchCancelable", &EventSenderBindings::SetTouchCancelable) .SetMethod("dumpFilenameBeingDragged", &EventSenderBindings::DumpFilenameBeingDragged) .SetMethod("gestureFlingCancel", &EventSenderBindings::GestureFlingCancel) @@ -624,6 +626,11 @@ void EventSenderBindings::SetTouchModifier(const std::string& key_name, sender_->SetTouchModifier(key_name, set_mask); } +void EventSenderBindings::SetTouchCancelable(bool cancelable) { + if (sender_) + sender_->SetTouchCancelable(cancelable); +} + void EventSenderBindings::DumpFilenameBeingDragged() { if (sender_) sender_->DumpFilenameBeingDragged(); @@ -992,6 +999,7 @@ EventSender::EventSender(WebTestRunner::TestInterfaces* interfaces) force_layout_on_events_(false), is_drag_mode_(true), touch_modifiers_(0), + touch_cancelable_(true), replaying_saved_events_(false), current_drag_effects_allowed_(blink::WebDragOperationNone), last_click_time_sec_(0), @@ -1046,6 +1054,10 @@ void EventSender::Reset() { time_offset_ms_ = 0; click_count_ = 0; + + touch_modifiers_ = 0; + touch_cancelable_ = true; + touch_points_.clear(); } void EventSender::Install(WebFrame* frame) { @@ -1435,6 +1447,10 @@ void EventSender::SetTouchModifier(const std::string& key_name, touch_modifiers_ &= ~mask; } +void EventSender::SetTouchCancelable(bool cancelable) { + touch_cancelable_ = cancelable; +} + void EventSender::DumpFilenameBeingDragged() { WebString filename; WebVector<WebDragData::Item> items = current_drag_data_.items(); @@ -1763,6 +1779,7 @@ void EventSender::SendCurrentTouchEvent(WebInputEvent::Type type) { WebTouchEvent touch_event; touch_event.type = type; touch_event.modifiers = touch_modifiers_; + touch_event.cancelable = touch_cancelable_; touch_event.timeStampSeconds = GetCurrentEventTimeSec(); touch_event.touchesLength = touch_points_.size(); for (size_t i = 0; i < touch_points_.size(); ++i) diff --git a/content/shell/renderer/test_runner/event_sender.h b/content/shell/renderer/test_runner/event_sender.h index e942c17..4784602 100644 --- a/content/shell/renderer/test_runner/event_sender.h +++ b/content/shell/renderer/test_runner/event_sender.h @@ -107,6 +107,7 @@ class EventSender : public base::SupportsWeakPtr<EventSender> { void UpdateTouchPoint(unsigned index, int x, int y); void CancelTouchPoint(unsigned index); void SetTouchModifier(const std::string& key_name, bool set_mask); + void SetTouchCancelable(bool cancelable); void ThrowTouchPointError(); void DumpFilenameBeingDragged(); @@ -232,6 +233,7 @@ class EventSender : public base::SupportsWeakPtr<EventSender> { bool is_drag_mode_; int touch_modifiers_; + bool touch_cancelable_; std::vector<blink::WebTouchPoint> touch_points_; scoped_ptr<blink::WebContextMenuData> last_context_menu_data_; |