summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrbyers@chromium.org <rbyers@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-04-24 21:05:30 +0000
committerrbyers@chromium.org <rbyers@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-04-24 21:05:30 +0000
commitace1cd5043cedb0676240c74e69a8faf7e6d9a49 (patch)
tree823dbbbfd11d88a977880d10d567e56a334d03c4
parent3301058a73caf3d4322993e65ee91fcec75b046a (diff)
downloadchromium_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
-rw-r--r--content/browser/frame_host/render_widget_host_view_guest.cc9
-rw-r--r--content/browser/renderer_host/input/input_router_impl.cc13
-rw-r--r--content/browser/renderer_host/input/motion_event_web.cc30
-rw-r--r--content/browser/renderer_host/input/touch_emulator.cc46
-rw-r--r--content/browser/renderer_host/input/touch_emulator_unittest.cc2
-rw-r--r--content/browser/renderer_host/input/touch_event_queue.cc10
-rw-r--r--content/browser/renderer_host/input/touch_event_queue_unittest.cc7
-rw-r--r--content/browser/renderer_host/input/web_input_event_util.cc10
-rw-r--r--content/browser/renderer_host/input/web_touch_event_traits.cc36
-rw-r--r--content/browser/renderer_host/input/web_touch_event_traits.h22
-rw-r--r--content/browser/renderer_host/render_widget_host_view_aura_unittest.cc6
-rw-r--r--content/browser/renderer_host/ui_events_helper.cc6
-rw-r--r--content/common/input/synthetic_web_input_event_builders.cc21
-rw-r--r--content/common/input/synthetic_web_input_event_builders.h5
-rw-r--r--content/common/input/web_touch_event_traits.cc70
-rw-r--r--content/common/input/web_touch_event_traits.h41
-rw-r--r--content/content_browser.gypi2
-rw-r--r--content/content_common.gypi2
-rw-r--r--content/renderer/pepper/event_conversion.cc14
-rw-r--r--content/shell/renderer/test_runner/event_sender.cc17
-rw-r--r--content/shell/renderer/test_runner/event_sender.h2
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_;