summaryrefslogtreecommitdiffstats
path: root/content/browser
diff options
context:
space:
mode:
authorjdduke@chromium.org <jdduke@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-05-03 21:39:24 +0000
committerjdduke@chromium.org <jdduke@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-05-03 21:39:24 +0000
commit208d64e7f240f9554a84ec0f2225c2302e6cde29 (patch)
tree0f5a3ee2405b848fe3869867e36d42e0a8964094 /content/browser
parent7009d9b8d8bee27f40080f6dca4af72281e579dc (diff)
downloadchromium_src-208d64e7f240f9554a84ec0f2225c2302e6cde29.zip
chromium_src-208d64e7f240f9554a84ec0f2225c2302e6cde29.tar.gz
chromium_src-208d64e7f240f9554a84ec0f2225c2302e6cde29.tar.bz2
Reland "Consolidate all touch/gesture related constants in content"
InputRouter, TouchEventQueue and GestureEventQueue all use a variety of configuration parameters that are littered through the code in a very ad-hoc and hard-to-follow fashion. Consolidate all such parameters into well-defined configuration structs, with helper functions to generate the appropriate parameters per platform. This simplifies testing and eases the mental burden of tracking down the origin of the various magic constants. Note that this change disables scroll gesture debounce by default, enabling it only for ChromeOS. The original patch landed in r268051 but was reverted in r268052 due to content_perftest compilation issues that have since been fixed. BUG=343917,353702 Review URL: https://codereview.chromium.org/235003005 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@268078 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content/browser')
-rw-r--r--content/browser/android/content_startup_flags.cc3
-rw-r--r--content/browser/renderer_host/input/gesture_event_queue.cc58
-rw-r--r--content/browser/renderer_host/input/gesture_event_queue.h48
-rw-r--r--content/browser/renderer_host/input/gesture_event_queue_unittest.cc51
-rw-r--r--content/browser/renderer_host/input/input_router_config_helper.cc144
-rw-r--r--content/browser/renderer_host/input/input_router_config_helper.h18
-rw-r--r--content/browser/renderer_host/input/input_router_impl.cc81
-rw-r--r--content/browser/renderer_host/input/input_router_impl.h18
-rw-r--r--content/browser/renderer_host/input/input_router_impl_perftest.cc32
-rw-r--r--content/browser/renderer_host/input/input_router_impl_unittest.cc44
-rw-r--r--content/browser/renderer_host/input/tap_suppression_controller.cc30
-rw-r--r--content/browser/renderer_host/input/tap_suppression_controller.h22
-rw-r--r--content/browser/renderer_host/input/tap_suppression_controller_client.h8
-rw-r--r--content/browser/renderer_host/input/tap_suppression_controller_unittest.cc103
-rw-r--r--content/browser/renderer_host/input/touch_event_queue.cc130
-rw-r--r--content/browser/renderer_host/input/touch_event_queue.h39
-rw-r--r--content/browser/renderer_host/input/touch_event_queue_unittest.cc38
-rw-r--r--content/browser/renderer_host/input/touchpad_tap_suppression_controller.cc40
-rw-r--r--content/browser/renderer_host/input/touchpad_tap_suppression_controller.h11
-rw-r--r--content/browser/renderer_host/input/touchpad_tap_suppression_controller_aura.cc58
-rw-r--r--content/browser/renderer_host/input/touchscreen_tap_suppression_controller.cc41
-rw-r--r--content/browser/renderer_host/input/touchscreen_tap_suppression_controller.h12
-rw-r--r--content/browser/renderer_host/input/touchscreen_tap_suppression_controller_stub.cc43
-rw-r--r--content/browser/renderer_host/render_widget_host_impl.cc7
-rw-r--r--content/browser/renderer_host/render_widget_host_unittest.cc50
25 files changed, 557 insertions, 572 deletions
diff --git a/content/browser/android/content_startup_flags.cc b/content/browser/android/content_startup_flags.cc
index ddcc86c..a771daa 100644
--- a/content/browser/android/content_startup_flags.cc
+++ b/content/browser/android/content_startup_flags.cc
@@ -62,14 +62,11 @@ void SetContentCommandLineFlags(int max_render_process_count,
parsed_command_line->AppendSwitch(switches::kEnableAcceleratedOverflowScroll);
parsed_command_line->AppendSwitch(switches::kEnableBeginFrameScheduling);
- parsed_command_line->AppendSwitch(switches::kDisableGestureDebounce);
parsed_command_line->AppendSwitch(switches::kEnableGestureTapHighlight);
parsed_command_line->AppendSwitch(switches::kEnablePinch);
parsed_command_line->AppendSwitch(switches::kEnableOverlayFullscreenVideo);
parsed_command_line->AppendSwitch(switches::kEnableOverlayScrollbar);
parsed_command_line->AppendSwitch(switches::kEnableOverscrollNotifications);
- parsed_command_line->AppendSwitchASCII(switches::kTouchAckTimeoutDelayMs,
- "200");
// Run the GPU service as a thread in the browser instead of as a
// standalone process.
diff --git a/content/browser/renderer_host/input/gesture_event_queue.cc b/content/browser/renderer_host/input/gesture_event_queue.cc
index 2fb46b6..9811e73 100644
--- a/content/browser/renderer_host/input/gesture_event_queue.cc
+++ b/content/browser/renderer_host/input/gesture_event_queue.cc
@@ -4,7 +4,6 @@
#include "content/browser/renderer_host/input/gesture_event_queue.h"
-#include "base/command_line.h"
#include "base/debug/trace_event.h"
#include "base/strings/string_number_conversions.h"
#include "content/browser/renderer_host/input/input_router.h"
@@ -16,34 +15,27 @@ using blink::WebGestureEvent;
using blink::WebInputEvent;
namespace content {
-namespace {
-// Default debouncing interval duration: if a scroll is in progress, non-scroll
-// events during this interval are deferred to either its end or discarded on
-// receipt of another GestureScrollUpdate.
-static const int kDebouncingIntervalTimeMs = 30;
-
-} // namespace
+GestureEventQueue::Config::Config() {
+}
GestureEventQueue::GestureEventQueue(
GestureEventQueueClient* client,
- TouchpadTapSuppressionControllerClient* touchpad_client)
- : client_(client),
- fling_in_progress_(false),
- scrolling_in_progress_(false),
- ignore_next_ack_(false),
- touchpad_tap_suppression_controller_(
- new TouchpadTapSuppressionController(touchpad_client)),
- touchscreen_tap_suppression_controller_(
- new TouchscreenTapSuppressionController(this)),
- debounce_interval_time_ms_(kDebouncingIntervalTimeMs),
- debounce_enabled_(true) {
+ TouchpadTapSuppressionControllerClient* touchpad_client,
+ const Config& config)
+ : client_(client),
+ fling_in_progress_(false),
+ scrolling_in_progress_(false),
+ ignore_next_ack_(false),
+ touchpad_tap_suppression_controller_(
+ touchpad_client,
+ config.touchpad_tap_suppression_config),
+ touchscreen_tap_suppression_controller_(
+ this,
+ config.touchscreen_tap_suppression_config),
+ debounce_interval_(config.debounce_interval) {
DCHECK(client);
- DCHECK(touchpad_tap_suppression_controller_);
- if (CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kDisableGestureDebounce)) {
- debounce_enabled_ = false;
- }
+ DCHECK(touchpad_client);
}
GestureEventQueue::~GestureEventQueue() { }
@@ -66,14 +58,14 @@ bool GestureEventQueue::ShouldDiscardFlingCancelEvent(
bool GestureEventQueue::ShouldForwardForBounceReduction(
const GestureEventWithLatencyInfo& gesture_event) {
- if (!debounce_enabled_)
+ if (debounce_interval_ <= base::TimeDelta())
return true;
switch (gesture_event.event.type) {
case WebInputEvent::GestureScrollUpdate:
if (!scrolling_in_progress_) {
debounce_deferring_timer_.Start(
FROM_HERE,
- base::TimeDelta::FromMilliseconds(debounce_interval_time_ms_),
+ debounce_interval_,
this,
&GestureEventQueue::SendScrollEndingEventsNow);
} else {
@@ -127,9 +119,9 @@ bool GestureEventQueue::ShouldForwardForTapSuppression(
switch (gesture_event.event.type) {
case WebInputEvent::GestureFlingCancel:
if (gesture_event.event.sourceDevice == WebGestureEvent::Touchscreen)
- touchscreen_tap_suppression_controller_->GestureFlingCancel();
+ touchscreen_tap_suppression_controller_.GestureFlingCancel();
else
- touchpad_tap_suppression_controller_->GestureFlingCancel();
+ touchpad_tap_suppression_controller_.GestureFlingCancel();
return true;
case WebInputEvent::GestureTapDown:
case WebInputEvent::GestureShowPress:
@@ -138,8 +130,8 @@ bool GestureEventQueue::ShouldForwardForTapSuppression(
case WebInputEvent::GestureTap:
case WebInputEvent::GestureDoubleTap:
if (gesture_event.event.sourceDevice == WebGestureEvent::Touchscreen) {
- return !touchscreen_tap_suppression_controller_->
- FilterTapEvent(gesture_event);
+ return !touchscreen_tap_suppression_controller_.FilterTapEvent(
+ gesture_event);
}
return true;
default:
@@ -200,9 +192,9 @@ void GestureEventQueue::ProcessGestureAck(InputEventAckState ack_result,
const bool processed = (INPUT_EVENT_ACK_STATE_CONSUMED == ack_result);
if (type == WebInputEvent::GestureFlingCancel) {
if (event_with_latency.event.sourceDevice == WebGestureEvent::Touchscreen)
- touchscreen_tap_suppression_controller_->GestureFlingCancelAck(processed);
+ touchscreen_tap_suppression_controller_.GestureFlingCancelAck(processed);
else
- touchpad_tap_suppression_controller_->GestureFlingCancelAck(processed);
+ touchpad_tap_suppression_controller_.GestureFlingCancelAck(processed);
}
DCHECK_LT(event_index, coalesced_gesture_events_.size());
coalesced_gesture_events_.erase(coalesced_gesture_events_.begin() +
@@ -238,7 +230,7 @@ void GestureEventQueue::ProcessGestureAck(InputEventAckState ack_result,
TouchpadTapSuppressionController*
GestureEventQueue::GetTouchpadTapSuppressionController() {
- return touchpad_tap_suppression_controller_.get();
+ return &touchpad_tap_suppression_controller_;
}
bool GestureEventQueue::ExpectingGestureAck() const {
diff --git a/content/browser/renderer_host/input/gesture_event_queue.h b/content/browser/renderer_host/input/gesture_event_queue.h
index ca7f648..4832a29 100644
--- a/content/browser/renderer_host/input/gesture_event_queue.h
+++ b/content/browser/renderer_host/input/gesture_event_queue.h
@@ -10,6 +10,9 @@
#include "base/basictypes.h"
#include "base/memory/scoped_ptr.h"
#include "base/timer/timer.h"
+#include "content/browser/renderer_host/input/tap_suppression_controller.h"
+#include "content/browser/renderer_host/input/touchpad_tap_suppression_controller.h"
+#include "content/browser/renderer_host/input/touchscreen_tap_suppression_controller.h"
#include "content/common/content_export.h"
#include "content/port/browser/event_with_latency_info.h"
#include "content/port/common/input_event_ack_state.h"
@@ -20,9 +23,6 @@ namespace content {
class GestureEventQueueTest;
class InputRouter;
class MockRenderWidgetHost;
-class TouchpadTapSuppressionController;
-class TouchpadTapSuppressionControllerClient;
-class TouchscreenTapSuppressionController;
// Interface with which the GestureEventQueue can forward gesture events, and
// dispatch gesture event responses.
@@ -61,9 +61,25 @@ class CONTENT_EXPORT GestureEventQueueClient {
// http://crbug.com/148443.
class CONTENT_EXPORT GestureEventQueue {
public:
+ struct CONTENT_EXPORT Config {
+ Config();
+
+ // Controls touchpad-related tap suppression, disabled by default.
+ TapSuppressionController::Config touchpad_tap_suppression_config;
+
+ // Controls touchscreen-related tap suppression, disabled by default.
+ TapSuppressionController::Config touchscreen_tap_suppression_config;
+
+ // Determines whether non-scroll gesture events are "debounced" during an
+ // active scroll sequence, suppressing brief scroll interruptions.
+ // Zero by default (disabled).
+ base::TimeDelta debounce_interval;
+ };
+
// Both |client| and |touchpad_client| must outlive the GestureEventQueue.
GestureEventQueue(GestureEventQueueClient* client,
- TouchpadTapSuppressionControllerClient* touchpad_client);
+ TouchpadTapSuppressionControllerClient* touchpad_client,
+ const Config& config);
~GestureEventQueue();
// Returns |true| if the caller should immediately forward the provided
@@ -96,12 +112,8 @@ class CONTENT_EXPORT GestureEventQueue {
debouncing_deferral_queue_.empty();
}
- void set_debounce_enabled_for_testing(bool enabled) {
- debounce_enabled_ = enabled;
- }
-
- void set_debounce_interval_time_ms_for_testing(int interval_time_ms) {
- debounce_interval_time_ms_ = interval_time_ms;
+ void set_debounce_interval_time_ms_for_testing(int interval_ms) {
+ debounce_interval_ = base::TimeDelta::FromMilliseconds(interval_ms);
}
private:
@@ -188,14 +200,12 @@ class CONTENT_EXPORT GestureEventQueue {
// tap.
// TODO(mohsen): Move touchpad tap suppression out of GestureEventQueue since
// GEQ is meant to only be used for touchscreen gesture events.
- scoped_ptr<TouchpadTapSuppressionController>
- touchpad_tap_suppression_controller_;
+ TouchpadTapSuppressionController touchpad_tap_suppression_controller_;
// An object tracking the state of touchscreen on the delivery of gesture tap
// events to the renderer to filter taps immediately after a touchscreen fling
// canceling tap.
- scoped_ptr<TouchscreenTapSuppressionController>
- touchscreen_tap_suppression_controller_;
+ TouchscreenTapSuppressionController touchscreen_tap_suppression_controller_;
typedef std::deque<GestureEventWithLatencyInfo> GestureQueue;
@@ -213,13 +223,9 @@ class CONTENT_EXPORT GestureEventQueue {
// Queue of events that have been deferred for debounce.
GestureQueue debouncing_deferral_queue_;
- // Time window in which to debounce scroll/fling ends.
- // TODO(rjkroege): Make this dynamically configurable.
- int debounce_interval_time_ms_;
-
- // Whether scroll-ending events should be deferred when a scroll is active.
- // Defaults to true.
- bool debounce_enabled_;
+ // Time window in which to debounce scroll/fling ends. Note that an interval
+ // of zero effectively disables debouncing.
+ base::TimeDelta debounce_interval_;
DISALLOW_COPY_AND_ASSIGN(GestureEventQueue);
};
diff --git a/content/browser/renderer_host/input/gesture_event_queue_unittest.cc b/content/browser/renderer_host/input/gesture_event_queue_unittest.cc
index be989de..28d6995 100644
--- a/content/browser/renderer_host/input/gesture_event_queue_unittest.cc
+++ b/content/browser/renderer_host/input/gesture_event_queue_unittest.cc
@@ -34,7 +34,7 @@ class GestureEventQueueTest : public testing::Test,
// testing::Test
virtual void SetUp() OVERRIDE {
- queue_.reset(new GestureEventQueue(this, this));
+ queue_.reset(new GestureEventQueue(this, this, DefaultConfig()));
}
virtual void TearDown() OVERRIDE {
@@ -68,6 +68,13 @@ class GestureEventQueueTest : public testing::Test,
}
protected:
+ static GestureEventQueue::Config DefaultConfig() {
+ return GestureEventQueue::Config();
+ }
+
+ void SetUpForDebounce(int interval_ms) {
+ queue()->set_debounce_interval_time_ms_for_testing(interval_ms);
+ }
// Returns the result of |GestureEventQueue::ShouldForward()|.
bool SimulateGestureEvent(const WebGestureEvent& gesture) {
@@ -134,14 +141,6 @@ class GestureEventQueueTest : public testing::Test,
return last_acked_event_;
}
- void DisableDebounce() {
- queue()->set_debounce_enabled_for_testing(false);
- }
-
- void set_debounce_interval_time_ms(int ms) {
- queue()->set_debounce_interval_time_ms_for_testing(ms);
- }
-
void set_synchronous_ack(InputEventAckState ack_result) {
sync_ack_result_.reset(new InputEventAckState(ack_result));
}
@@ -208,9 +207,6 @@ class GestureEventQueueWithSourceTest
#endif // GTEST_HAS_PARAM_TEST
TEST_F(GestureEventQueueTest, CoalescesScrollGestureEvents) {
- // Turn off debounce handling for test isolation.
- DisableDebounce();
-
// Test coalescing of only GestureScrollUpdate events.
// Simulate gesture events.
@@ -286,9 +282,6 @@ TEST_F(GestureEventQueueTest, CoalescesScrollGestureEvents) {
TEST_F(GestureEventQueueTest,
DoesNotCoalesceScrollGestureEventsFromDifferentDevices) {
- // Turn off debounce handling for test isolation.
- DisableDebounce();
-
// Test that GestureScrollUpdate events from Touchscreen and Touchpad do not
// coalesce.
@@ -333,9 +326,6 @@ TEST_F(GestureEventQueueTest,
}
TEST_F(GestureEventQueueTest, CoalescesScrollAndPinchEvents) {
- // Turn off debounce handling for test isolation.
- DisableDebounce();
-
// Test coalescing of only GestureScrollUpdate events.
// Simulate gesture events.
@@ -568,9 +558,6 @@ TEST_F(GestureEventQueueTest, CoalescesScrollAndPinchEvents) {
}
TEST_F(GestureEventQueueTest, CoalescesMultiplePinchEventSequences) {
- // Turn off debounce handling for test isolation.
- DisableDebounce();
-
// Simulate a pinch sequence.
SimulateGestureEvent(WebInputEvent::GestureScrollBegin,
WebGestureEvent::Touchscreen);
@@ -661,9 +648,6 @@ TEST_F(GestureEventQueueTest, CoalescesMultiplePinchEventSequences) {
}
TEST_F(GestureEventQueueTest, CoalescesPinchSequencesWithEarlyAck) {
- // Turn off debounce handling for test isolation.
- DisableDebounce();
-
SimulateGestureEvent(WebInputEvent::GestureScrollBegin,
WebGestureEvent::Touchscreen);
SendInputEventACK(WebInputEvent::GestureScrollBegin,
@@ -727,9 +711,6 @@ TEST_F(GestureEventQueueTest, CoalescesPinchSequencesWithEarlyAck) {
TEST_F(GestureEventQueueTest,
DoesNotCoalescePinchGestureEventsWithDifferentModifiers) {
- // Turn off debounce handling for test isolation.
- DisableDebounce();
-
// Insert an event to force queueing of gestures.
SimulateGestureEvent(WebInputEvent::GestureTapCancel,
WebGestureEvent::Touchscreen);
@@ -793,9 +774,6 @@ TEST_F(GestureEventQueueTest,
}
TEST_F(GestureEventQueueTest, CoalescesScrollAndPinchEventsIdentity) {
- // Turn off debounce handling for test isolation.
- DisableDebounce();
-
// Insert an event to force queueing of gestures.
SimulateGestureEvent(WebInputEvent::GestureTapCancel,
WebGestureEvent::Touchscreen);
@@ -910,9 +888,6 @@ TEST_F(GestureEventQueueTest, SyncAckQueuesEvent) {
// Tests an event with an async ack followed by an event with a sync ack.
TEST_F(GestureEventQueueTest, AsyncThenSyncAck) {
- // Turn off debounce handling for test isolation.
- DisableDebounce();
-
SimulateGestureEvent(WebInputEvent::GestureTapDown,
WebGestureEvent::Touchscreen);
@@ -935,9 +910,6 @@ TEST_F(GestureEventQueueTest, AsyncThenSyncAck) {
}
TEST_F(GestureEventQueueTest, CoalescesScrollAndPinchEventWithSyncAck) {
- // Turn off debounce handling for test isolation.
- DisableDebounce();
-
// Simulate a pinch sequence.
SimulateGestureEvent(WebInputEvent::GestureScrollBegin,
WebGestureEvent::Touchscreen);
@@ -984,8 +956,6 @@ TEST_F(GestureEventQueueTest, CoalescesScrollAndPinchEventWithSyncAck) {
TEST_P(GestureEventQueueWithSourceTest, GestureFlingCancelsFiltered) {
WebGestureEvent::SourceDevice source_device = GetParam();
- // Turn off debounce handling for test isolation.
- DisableDebounce();
// GFC without previous GFS is dropped.
SimulateGestureEvent(WebInputEvent::GestureFlingCancel, source_device);
EXPECT_EQ(0U, GetAndResetSentGestureEventCount());
@@ -1081,7 +1051,7 @@ INSTANTIATE_TEST_CASE_P(AllSources,
// debounce interval, that Scrolls are not and that the deferred events are
// sent after that timer fires.
TEST_F(GestureEventQueueTest, DebounceDefersFollowingGestureEvents) {
- set_debounce_interval_time_ms(3);
+ SetUpForDebounce(3);
SimulateGestureEvent(WebInputEvent::GestureScrollUpdate,
WebGestureEvent::Touchscreen);
@@ -1144,7 +1114,8 @@ TEST_F(GestureEventQueueTest, DebounceDefersFollowingGestureEvents) {
// interval and are discarded if a GestureScrollUpdate event arrives before the
// interval end.
TEST_F(GestureEventQueueTest, DebounceDropsDeferredEvents) {
- set_debounce_interval_time_ms(3);
+ SetUpForDebounce(3);
+
EXPECT_FALSE(ScrollingInProgress());
SimulateGestureEvent(WebInputEvent::GestureScrollUpdate,
diff --git a/content/browser/renderer_host/input/input_router_config_helper.cc b/content/browser/renderer_host/input/input_router_config_helper.cc
new file mode 100644
index 0000000..bbd6f79
--- /dev/null
+++ b/content/browser/renderer_host/input/input_router_config_helper.cc
@@ -0,0 +1,144 @@
+// 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/input_router_config_helper.h"
+
+#include "base/command_line.h"
+#include "content/public/common/content_switches.h"
+#include "ui/events/gesture_detection/gesture_detector.h"
+
+#if defined(USE_AURA)
+#include "ui/events/gestures/gesture_configuration.h"
+#elif defined(OS_ANDROID)
+#include "ui/gfx/android/view_configuration.h"
+#include "ui/gfx/screen.h"
+#endif
+
+namespace content {
+namespace {
+
+#if defined(USE_AURA)
+
+GestureEventQueue::Config GetGestureEventQueueConfig() {
+ GestureEventQueue::Config config;
+
+#if defined(OS_CHROMEOS)
+ // Default debouncing interval duration on ChromeOS: if a scroll is in
+ // progress, non-scroll events during this interval are deferred to either its
+ // end or discarded on receipt of another GestureScrollUpdate.
+ // TODO(jdduke): Disable and remove entirely when issues with spurious
+ // scroll end detection on the Pixel are resolved, crbug.com/353702.
+ const int kDebouncingIntervalTimeMs = 30;
+ config.debounce_interval =
+ base::TimeDelta::FromMilliseconds(kDebouncingIntervalTimeMs);
+#endif
+
+ config.touchscreen_tap_suppression_config.enabled = true;
+ config.touchscreen_tap_suppression_config.max_cancel_to_down_time =
+ base::TimeDelta::FromMilliseconds(
+ ui::GestureConfiguration::fling_max_cancel_to_down_time_in_ms());
+
+ config.touchscreen_tap_suppression_config.max_tap_gap_time =
+ base::TimeDelta::FromMilliseconds(static_cast<int>(
+ ui::GestureConfiguration::semi_long_press_time_in_seconds() * 1000));
+
+ config.touchpad_tap_suppression_config.enabled = true;
+ config.touchpad_tap_suppression_config.max_cancel_to_down_time =
+ base::TimeDelta::FromMilliseconds(
+ ui::GestureConfiguration::fling_max_cancel_to_down_time_in_ms());
+
+ config.touchpad_tap_suppression_config.max_tap_gap_time =
+ base::TimeDelta::FromMilliseconds(static_cast<int>(
+ ui::GestureConfiguration::fling_max_tap_gap_time_in_ms() * 1000));
+
+ return config;
+}
+
+TouchEventQueue::Config GetTouchEventQueueConfig() {
+ TouchEventQueue::Config config;
+
+ config.touchmove_slop_suppression_length_dips =
+ ui::GestureConfiguration::max_touch_move_in_pixels_for_click();
+
+ return config;
+}
+
+#elif defined(OS_ANDROID)
+
+// Default time allowance for the touch ack delay before the touch sequence is
+// cancelled.
+const int kTouchAckTimeoutDelayMs = 200;
+
+GestureEventQueue::Config GetGestureEventQueueConfig() {
+ GestureEventQueue::Config config;
+
+ config.touchscreen_tap_suppression_config.enabled = true;
+ config.touchscreen_tap_suppression_config.max_cancel_to_down_time =
+ base::TimeDelta::FromMilliseconds(
+ gfx::ViewConfiguration::GetTapTimeoutInMs());
+ config.touchscreen_tap_suppression_config.max_tap_gap_time =
+ base::TimeDelta::FromMilliseconds(
+ gfx::ViewConfiguration::GetLongPressTimeoutInMs());
+
+ return config;
+}
+
+TouchEventQueue::Config GetTouchEventQueueConfig() {
+ TouchEventQueue::Config config;
+
+ config.touch_ack_timeout_delay =
+ base::TimeDelta::FromMilliseconds(kTouchAckTimeoutDelayMs);
+ config.touch_ack_timeout_supported = true;
+
+ const double touch_slop_length_pixels =
+ static_cast<double>(gfx::ViewConfiguration::GetTouchSlopInPixels());
+ const double device_scale_factor =
+ gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().device_scale_factor();
+ config.touchmove_slop_suppression_length_dips =
+ touch_slop_length_pixels / device_scale_factor;
+
+ return config;
+}
+
+#else
+
+GestureEventQueue::Config GetGestureEventQueueConfig() {
+ return GestureEventQueue::Config();
+}
+
+TouchEventQueue::Config GetTouchEventQueueConfig() {
+ TouchEventQueue::Config config;
+ config.touchmove_slop_suppression_length_dips =
+ ui::GestureDetector::Config().touch_slop;
+ return config;
+}
+
+#endif
+
+TouchEventQueue::TouchScrollingMode GetTouchScrollingMode() {
+ std::string modeString =
+ CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
+ switches::kTouchScrollingMode);
+ if (modeString == switches::kTouchScrollingModeAsyncTouchmove)
+ return TouchEventQueue::TOUCH_SCROLLING_MODE_ASYNC_TOUCHMOVE;
+ if (modeString == switches::kTouchScrollingModeSyncTouchmove)
+ return TouchEventQueue::TOUCH_SCROLLING_MODE_SYNC_TOUCHMOVE;
+ if (modeString == switches::kTouchScrollingModeTouchcancel)
+ return TouchEventQueue::TOUCH_SCROLLING_MODE_TOUCHCANCEL;
+ if (modeString != "")
+ LOG(ERROR) << "Invalid --touch-scrolling-mode option: " << modeString;
+ return TouchEventQueue::TOUCH_SCROLLING_MODE_DEFAULT;
+}
+
+} // namespace
+
+InputRouterImpl::Config GetInputRouterConfigForPlatform() {
+ InputRouterImpl::Config config;
+ config.gesture_config = GetGestureEventQueueConfig();
+ config.touch_config = GetTouchEventQueueConfig();
+ config.touch_config.touch_scrolling_mode = GetTouchScrollingMode();
+ return config;
+}
+
+} // namespace content
diff --git a/content/browser/renderer_host/input/input_router_config_helper.h b/content/browser/renderer_host/input/input_router_config_helper.h
new file mode 100644
index 0000000..46fbbd0
--- /dev/null
+++ b/content/browser/renderer_host/input/input_router_config_helper.h
@@ -0,0 +1,18 @@
+// 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_BROWSER_RENDERER_HOST_INPUT_INPUT_ROUTER_CONFIG_HELPER_H_
+#define CONTENT_BROWSER_RENDERER_HOST_INPUT_INPUT_ROUTER_CONFIG_HELPER_H_
+
+#include "content/browser/renderer_host/input/input_router_impl.h"
+
+namespace content {
+
+// Return an InputRouter configuration with parameters tailored to the current
+// platform.
+InputRouterImpl::Config GetInputRouterConfigForPlatform();
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_RENDERER_HOST_INPUT_INPUT_ROUTER_CONFIG_HELPER_H_
diff --git a/content/browser/renderer_host/input/input_router_impl.cc b/content/browser/renderer_host/input/input_router_impl.cc
index 3370120..97e68f4 100644
--- a/content/browser/renderer_host/input/input_router_impl.cc
+++ b/content/browser/renderer_host/input/input_router_impl.cc
@@ -31,13 +31,6 @@
#include "ui/events/event.h"
#include "ui/events/keycodes/keyboard_codes.h"
-#if defined(OS_ANDROID)
-#include "ui/gfx/android/view_configuration.h"
-#include "ui/gfx/screen.h"
-#else
-#include "ui/events/gestures/gesture_configuration.h"
-#endif
-
using base::Time;
using base::TimeDelta;
using base::TimeTicks;
@@ -50,57 +43,6 @@ using blink::WebMouseWheelEvent;
namespace content {
namespace {
-// TODO(jdduke): Instead of relying on command line flags or conditional
-// conditional compilation here, we should instead use an InputRouter::Settings
-// construct, supplied and customized by the RenderWidgetHostView. See
-// crbug.com/343917.
-bool GetTouchAckTimeoutDelay(base::TimeDelta* touch_ack_timeout_delay) {
- CommandLine* parsed_command_line = CommandLine::ForCurrentProcess();
- if (!parsed_command_line->HasSwitch(switches::kTouchAckTimeoutDelayMs))
- return false;
-
- std::string timeout_string = parsed_command_line->GetSwitchValueASCII(
- switches::kTouchAckTimeoutDelayMs);
- size_t timeout_ms;
- if (!base::StringToSizeT(timeout_string, &timeout_ms))
- return false;
-
- *touch_ack_timeout_delay = base::TimeDelta::FromMilliseconds(timeout_ms);
- return true;
-}
-
-#if defined(OS_ANDROID)
-double GetTouchMoveSlopSuppressionLengthDips() {
- const double touch_slop_length_pixels =
- static_cast<double>(gfx::ViewConfiguration::GetTouchSlopInPixels());
- const double device_scale_factor =
- gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().device_scale_factor();
- return touch_slop_length_pixels / device_scale_factor;
-}
-#elif defined(USE_AURA)
-double GetTouchMoveSlopSuppressionLengthDips() {
- return ui::GestureConfiguration::max_touch_move_in_pixels_for_click();
-}
-#else
-double GetTouchMoveSlopSuppressionLengthDips() {
- return 0;
-}
-#endif
-
-TouchEventQueue::TouchScrollingMode GetTouchScrollingMode() {
- std::string modeString = CommandLine::ForCurrentProcess()->
- GetSwitchValueASCII(switches::kTouchScrollingMode);
- if (modeString == switches::kTouchScrollingModeAsyncTouchmove)
- return TouchEventQueue::TOUCH_SCROLLING_MODE_ASYNC_TOUCHMOVE;
- if (modeString == switches::kTouchScrollingModeSyncTouchmove)
- return TouchEventQueue::TOUCH_SCROLLING_MODE_SYNC_TOUCHMOVE;
- if (modeString == switches::kTouchScrollingModeTouchcancel)
- return TouchEventQueue::TOUCH_SCROLLING_MODE_TOUCHCANCEL;
- if (modeString != "")
- LOG(ERROR) << "Invalid --touch-scrolling-mode option: " << modeString;
- return TouchEventQueue::TOUCH_SCROLLING_MODE_DEFAULT;
-}
-
const char* GetEventAckName(InputEventAckState ack_result) {
switch(ack_result) {
case INPUT_EVENT_ACK_STATE_UNKNOWN: return "UNKNOWN";
@@ -115,10 +57,14 @@ const char* GetEventAckName(InputEventAckState ack_result) {
} // namespace
+InputRouterImpl::Config::Config() {
+}
+
InputRouterImpl::InputRouterImpl(IPC::Sender* sender,
InputRouterClient* client,
InputAckHandler* ack_handler,
- int routing_id)
+ int routing_id,
+ const Config& config)
: sender_(sender),
client_(client),
ack_handler_(ack_handler),
@@ -127,19 +73,14 @@ InputRouterImpl::InputRouterImpl(IPC::Sender* sender,
move_caret_pending_(false),
mouse_move_pending_(false),
mouse_wheel_pending_(false),
- touch_ack_timeout_supported_(false),
current_view_flags_(0),
current_ack_source_(ACK_SOURCE_NONE),
flush_requested_(false),
- touch_event_queue_(this,
- GetTouchScrollingMode(),
- GetTouchMoveSlopSuppressionLengthDips()),
- gesture_event_queue_(this, this) {
+ touch_event_queue_(this, config.touch_config),
+ gesture_event_queue_(this, this, config.gesture_config) {
DCHECK(sender);
DCHECK(client);
DCHECK(ack_handler);
- touch_ack_timeout_supported_ =
- GetTouchAckTimeoutDelay(&touch_ack_timeout_delay_);
UpdateTouchAckTimeoutEnabled();
}
@@ -748,11 +689,6 @@ void InputRouterImpl::ProcessAckForOverscroll(const WebInputEvent& event,
}
void InputRouterImpl::UpdateTouchAckTimeoutEnabled() {
- if (!touch_ack_timeout_supported_) {
- touch_event_queue_.SetAckTimeoutEnabled(false, base::TimeDelta());
- return;
- }
-
// Mobile sites tend to be well-behaved with respect to touch handling, so
// they have less need for the touch timeout fallback.
const bool fixed_page_scale = (current_view_flags_ & FIXED_PAGE_SCALE) != 0;
@@ -767,8 +703,7 @@ void InputRouterImpl::UpdateTouchAckTimeoutEnabled() {
const bool touch_ack_timeout_enabled = !fixed_page_scale &&
!mobile_viewport &&
!touch_action_none;
- touch_event_queue_.SetAckTimeoutEnabled(touch_ack_timeout_enabled,
- touch_ack_timeout_delay_);
+ touch_event_queue_.SetAckTimeoutEnabled(touch_ack_timeout_enabled);
}
void InputRouterImpl::SignalFlushedIfNecessary() {
diff --git a/content/browser/renderer_host/input/input_router_impl.h b/content/browser/renderer_host/input/input_router_impl.h
index a586d5d..76af1c4 100644
--- a/content/browser/renderer_host/input/input_router_impl.h
+++ b/content/browser/renderer_host/input/input_router_impl.h
@@ -40,10 +40,17 @@ class CONTENT_EXPORT InputRouterImpl
public NON_EXPORTED_BASE(TouchEventQueueClient),
public NON_EXPORTED_BASE(TouchpadTapSuppressionControllerClient) {
public:
+ struct CONTENT_EXPORT Config {
+ Config();
+ GestureEventQueue::Config gesture_config;
+ TouchEventQueue::Config touch_config;
+ };
+
InputRouterImpl(IPC::Sender* sender,
InputRouterClient* client,
InputAckHandler* ack_handler,
- int routing_id);
+ int routing_id,
+ const Config& config);
virtual ~InputRouterImpl();
// InputRouter
@@ -193,8 +200,9 @@ private:
// Called when a touch timeout-affecting bit has changed, in turn toggling the
// touch ack timeout feature of the |touch_event_queue_| as appropriate. Input
- // to that determination includes current view properties, the allowed touch
- // action and the command-line configured |touch_ack_timeout_supported_|.
+ // to that determination includes current view properties and the allowed
+ // touch action. Note that this will only affect platforms that have a
+ // non-zero touch timeout configuration.
void UpdateTouchAckTimeoutEnabled();
// If a flush has been requested, signals a completed flush to the client if
@@ -257,10 +265,6 @@ private:
// The time when an input event was sent to the client.
base::TimeTicks input_event_start_time_;
- // Whether touch ack timeout handling has been enabled via the command line.
- bool touch_ack_timeout_supported_;
- base::TimeDelta touch_ack_timeout_delay_;
-
// Cached flags from |OnViewUpdated()|, defaults to 0.
int current_view_flags_;
diff --git a/content/browser/renderer_host/input/input_router_impl_perftest.cc b/content/browser/renderer_host/input/input_router_impl_perftest.cc
index 717ba4f..972fc49 100644
--- a/content/browser/renderer_host/input/input_router_impl_perftest.cc
+++ b/content/browser/renderer_host/input/input_router_impl_perftest.cc
@@ -3,7 +3,6 @@
// found in the LICENSE file.
#include "base/basictypes.h"
-#include "base/command_line.h"
#include "base/memory/scoped_ptr.h"
#include "content/browser/renderer_host/input/input_ack_handler.h"
#include "content/browser/renderer_host/input/input_router_client.h"
@@ -11,7 +10,6 @@
#include "content/common/input/web_input_event_traits.h"
#include "content/common/input_messages.h"
#include "content/common/view_messages.h"
-#include "content/public/common/content_switches.h"
#include "ipc/ipc_sender.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/perf/perf_test.h"
@@ -206,17 +204,14 @@ class InputRouterImplPerfTest : public testing::Test {
protected:
// testing::Test
virtual void SetUp() OVERRIDE {
- if (!CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kDisableGestureDebounce)) {
- CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kDisableGestureDebounce);
- }
-
sender_.reset(new NullIPCSender());
client_.reset(new NullInputRouterClient());
ack_handler_.reset(new NullInputAckHandler());
- input_router_.reset(new InputRouterImpl(
- sender_.get(), client_.get(), ack_handler_.get(), MSG_ROUTING_NONE));
+ input_router_.reset(new InputRouterImpl(sender_.get(),
+ client_.get(),
+ ack_handler_.get(),
+ MSG_ROUTING_NONE,
+ InputRouterImpl::Config()));
}
virtual void TearDown() OVERRIDE {
@@ -238,10 +233,12 @@ class InputRouterImplPerfTest : public testing::Test {
input_router_->SendTouchEvent(TouchEventWithLatencyInfo(touch, latency));
}
- void SendEventAck(blink::WebInputEvent::Type type,
- InputEventAckState ack_result) {
+ void SendEventAckIfNecessary(const blink::WebInputEvent& event,
+ InputEventAckState ack_result) {
+ if (WebInputEventTraits::IgnoresAckDisposition(event))
+ return;
InputHostMsg_HandleInputEvent_ACK response(
- 0, type, ack_result, ui::LatencyInfo());
+ 0, event.type, ack_result, ui::LatencyInfo());
input_router_->OnMessageReceived(response);
}
@@ -290,11 +287,11 @@ class InputRouterImplPerfTest : public testing::Test {
for (; i < event_count; ++i, ++ack_i) {
SendEvent(events[i], CreateLatencyInfo());
- SendEventAck(events[ack_i].type, INPUT_EVENT_ACK_STATE_CONSUMED);
+ SendEventAckIfNecessary(events[ack_i], INPUT_EVENT_ACK_STATE_CONSUMED);
}
if (ack_delay)
- SendEventAck(events.back().type, INPUT_EVENT_ACK_STATE_CONSUMED);
+ SendEventAckIfNecessary(events.back(), INPUT_EVENT_ACK_STATE_CONSUMED);
EXPECT_EQ(event_count, GetAndResetSentEventCount());
EXPECT_EQ(event_count, GetAndResetAckCount());
@@ -322,11 +319,12 @@ class InputRouterImplPerfTest : public testing::Test {
// Touches may not be forwarded after the scroll sequence has begun, so
// only ack if necessary.
if (!AckCount()) {
- SendEventAck(touches[i].type, INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ SendEventAckIfNecessary(touches[i],
+ INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
}
SendEvent(gestures[i], CreateLatencyInfo());
- SendEventAck(gestures[i].type, INPUT_EVENT_ACK_STATE_CONSUMED);
+ SendEventAckIfNecessary(gestures[i], INPUT_EVENT_ACK_STATE_CONSUMED);
EXPECT_EQ(2U, GetAndResetAckCount());
}
}
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 e72e691..1039e70 100644
--- a/content/browser/renderer_host/input/input_router_impl_unittest.cc
+++ b/content/browser/renderer_host/input/input_router_impl_unittest.cc
@@ -152,10 +152,11 @@ class InputRouterImplTest : public testing::Test {
ack_handler_.reset(new MockInputAckHandler());
CommandLine* command_line = CommandLine::ForCurrentProcess();
command_line->AppendSwitch(switches::kValidateInputEventStream);
- input_router_.reset(new InputRouterImpl(
- process_.get(), client_.get(), ack_handler_.get(), MSG_ROUTING_NONE));
- input_router_->gesture_event_queue_.set_debounce_enabled_for_testing(
- false);
+ input_router_.reset(new InputRouterImpl(process_.get(),
+ client_.get(),
+ ack_handler_.get(),
+ MSG_ROUTING_NONE,
+ config_));
client_->set_input_router(input_router());
ack_handler_->set_input_router(input_router());
}
@@ -170,6 +171,14 @@ class InputRouterImplTest : public testing::Test {
browser_context_.reset();
}
+ void SetUpForTouchAckTimeoutTest(int timeout_ms) {
+ config_.touch_config.touch_ack_timeout_delay =
+ base::TimeDelta::FromMilliseconds(timeout_ms);
+ config_.touch_config.touch_ack_timeout_supported = true;
+ TearDown();
+ SetUp();
+ }
+
void SimulateKeyboardEvent(WebInputEvent::Type type, bool is_shortcut) {
WebKeyboardEvent event = SyntheticWebKeyboardEventBuilder::Build(type);
NativeWebKeyboardEvent native_event;
@@ -336,6 +345,7 @@ class InputRouterImplTest : public testing::Test {
base::MessageLoop::current()->Run();
}
+ InputRouterImpl::Config config_;
scoped_ptr<MockRenderProcessHost> process_;
scoped_ptr<MockInputRouterClient> client_;
scoped_ptr<MockInputAckHandler> ack_handler_;
@@ -1027,17 +1037,11 @@ TEST_F(InputRouterImplTest, GestureShowPressIsInOrder) {
EXPECT_EQ(3U, ack_handler_->GetAndResetAckCount());
}
-// Test that touch ack timeout behavior is properly configured via the command
-// line, and toggled by view update flags and allowed touch actions.
+// Test that touch ack timeout behavior is properly toggled by view update flags
+// and allowed touch actions.
TEST_F(InputRouterImplTest, TouchAckTimeoutConfigured) {
- // Unless explicitly supported via the command-line, the touch timeout should
- // be disabled.
- EXPECT_FALSE(TouchEventTimeoutEnabled());
-
- CommandLine::ForCurrentProcess()->AppendSwitchASCII(
- switches::kTouchAckTimeoutDelayMs, "1");
- TearDown();
- SetUp();
+ const int timeout_ms = 1;
+ SetUpForTouchAckTimeoutTest(timeout_ms);
ASSERT_TRUE(TouchEventTimeoutEnabled());
// Verify that the touch ack timeout fires upon the delayed ack.
@@ -1045,7 +1049,7 @@ TEST_F(InputRouterImplTest, TouchAckTimeoutConfigured) {
SendTouchEvent();
EXPECT_EQ(0U, ack_handler_->GetAndResetAckCount());
EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
- RunTasksAndWait(base::TimeDelta::FromMilliseconds(2));
+ RunTasksAndWait(base::TimeDelta::FromMilliseconds(timeout_ms + 1));
// The timed-out event should have been ack'ed.
EXPECT_EQ(1U, ack_handler_->GetAndResetAckCount());
@@ -1111,10 +1115,8 @@ TEST_F(InputRouterImplTest, TouchAckTimeoutConfigured) {
// the touch timeout.
TEST_F(InputRouterImplTest,
TouchAckTimeoutDisabledForTouchSequenceAfterTouchActionNone) {
- CommandLine::ForCurrentProcess()->AppendSwitchASCII(
- switches::kTouchAckTimeoutDelayMs, "1");
- TearDown();
- SetUp();
+ const int timeout_ms = 1;
+ SetUpForTouchAckTimeoutTest(timeout_ms);
ASSERT_TRUE(TouchEventTimeoutEnabled());
OnHasTouchEventHandlers(true);
@@ -1144,7 +1146,7 @@ TEST_F(InputRouterImplTest,
EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
// Delay the ack. The timeout should *not* fire.
- RunTasksAndWait(base::TimeDelta::FromMilliseconds(2));
+ RunTasksAndWait(base::TimeDelta::FromMilliseconds(timeout_ms + 1));
EXPECT_EQ(0U, ack_handler_->GetAndResetAckCount());
EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
@@ -1170,7 +1172,7 @@ TEST_F(InputRouterImplTest,
EXPECT_EQ(1U, GetSentMessageCountAndResetSink());
// Wait for the touch ack timeout to fire.
- RunTasksAndWait(base::TimeDelta::FromMilliseconds(2));
+ RunTasksAndWait(base::TimeDelta::FromMilliseconds(timeout_ms + 1));
EXPECT_EQ(1U, ack_handler_->GetAndResetAckCount());
}
diff --git a/content/browser/renderer_host/input/tap_suppression_controller.cc b/content/browser/renderer_host/input/tap_suppression_controller.cc
index 641af6a..c6b17e6 100644
--- a/content/browser/renderer_host/input/tap_suppression_controller.cc
+++ b/content/browser/renderer_host/input/tap_suppression_controller.cc
@@ -10,16 +10,27 @@
namespace content {
+TapSuppressionController::Config::Config()
+ : enabled(false),
+ max_cancel_to_down_time(base::TimeDelta::FromMilliseconds(180)),
+ max_tap_gap_time(base::TimeDelta::FromMilliseconds(500)) {
+}
+
TapSuppressionController::TapSuppressionController(
- TapSuppressionControllerClient* client)
+ TapSuppressionControllerClient* client,
+ const Config& config)
: client_(client),
- state_(TapSuppressionController::NOTHING) {
+ state_(config.enabled ? NOTHING : DISABLED),
+ max_cancel_to_down_time_(config.max_cancel_to_down_time),
+ max_tap_gap_time_(config.max_tap_gap_time) {
}
TapSuppressionController::~TapSuppressionController() {}
void TapSuppressionController::GestureFlingCancel() {
switch (state_) {
+ case DISABLED:
+ break;
case NOTHING:
case GFC_IN_PROGRESS:
case LAST_CANCEL_STOPPED_FLING:
@@ -33,6 +44,7 @@ void TapSuppressionController::GestureFlingCancel() {
void TapSuppressionController::GestureFlingCancelAck(bool processed) {
base::TimeTicks event_time = Now();
switch (state_) {
+ case DISABLED:
case NOTHING:
break;
case GFC_IN_PROGRESS:
@@ -57,23 +69,21 @@ void TapSuppressionController::GestureFlingCancelAck(bool processed) {
bool TapSuppressionController::ShouldDeferTapDown() {
base::TimeTicks event_time = Now();
switch (state_) {
+ case DISABLED:
case NOTHING:
return false;
case GFC_IN_PROGRESS:
state_ = TAP_DOWN_STASHED;
- StartTapDownTimer(
- base::TimeDelta::FromMilliseconds(client_->MaxTapGapTimeInMs()));
+ StartTapDownTimer(max_tap_gap_time_);
return true;
case TAP_DOWN_STASHED:
NOTREACHED() << "TapDown on TAP_DOWN_STASHED state";
state_ = NOTHING;
return false;
case LAST_CANCEL_STOPPED_FLING:
- if ((event_time - fling_cancel_time_).InMilliseconds()
- < client_->MaxCancelToDownTimeInMs()) {
+ if ((event_time - fling_cancel_time_) < max_cancel_to_down_time_) {
state_ = TAP_DOWN_STASHED;
- StartTapDownTimer(
- base::TimeDelta::FromMilliseconds(client_->MaxTapGapTimeInMs()));
+ StartTapDownTimer(max_tap_gap_time_);
return true;
} else {
state_ = NOTHING;
@@ -86,6 +96,7 @@ bool TapSuppressionController::ShouldDeferTapDown() {
bool TapSuppressionController::ShouldSuppressTapEnd() {
switch (state_) {
+ case DISABLED:
case NOTHING:
case GFC_IN_PROGRESS:
return false;
@@ -115,7 +126,10 @@ void TapSuppressionController::StopTapDownTimer() {
void TapSuppressionController::TapDownTimerExpired() {
switch (state_) {
+ case DISABLED:
case NOTHING:
+ NOTREACHED() << "Timer fired on invalid state.";
+ break;
case GFC_IN_PROGRESS:
case LAST_CANCEL_STOPPED_FLING:
NOTREACHED() << "Timer fired on invalid state.";
diff --git a/content/browser/renderer_host/input/tap_suppression_controller.h b/content/browser/renderer_host/input/tap_suppression_controller.h
index ef662f3..93977f9 100644
--- a/content/browser/renderer_host/input/tap_suppression_controller.h
+++ b/content/browser/renderer_host/input/tap_suppression_controller.h
@@ -19,7 +19,22 @@ class TapSuppressionControllerClient;
// GestureFlingCancel are suppressed.
class CONTENT_EXPORT TapSuppressionController {
public:
- explicit TapSuppressionController(TapSuppressionControllerClient* client);
+ struct CONTENT_EXPORT Config {
+ Config();
+
+ // Defaults to false, in which case no suppression is performed.
+ bool enabled;
+
+ // The maximum time allowed between a GestureFlingCancel and its
+ // corresponding tap down.
+ base::TimeDelta max_cancel_to_down_time;
+
+ // The maximum time allowed between a single tap's down and up events.
+ base::TimeDelta max_tap_gap_time;
+ };
+
+ TapSuppressionController(TapSuppressionControllerClient* client,
+ const Config& config);
virtual ~TapSuppressionController();
// Should be called whenever a GestureFlingCancel event is received.
@@ -49,17 +64,20 @@ class CONTENT_EXPORT TapSuppressionController {
friend class MockTapSuppressionController;
enum State {
+ DISABLED,
NOTHING,
GFC_IN_PROGRESS,
TAP_DOWN_STASHED,
LAST_CANCEL_STOPPED_FLING,
};
-
TapSuppressionControllerClient* client_;
base::OneShotTimer<TapSuppressionController> tap_down_timer_;
State state_;
+ base::TimeDelta max_cancel_to_down_time_;
+ base::TimeDelta max_tap_gap_time_;
+
// TODO(rjkroege): During debugging, the event times did not prove reliable.
// Replace the use of base::TimeTicks with an accurate event time when they
// become available post http://crbug.com/119556.
diff --git a/content/browser/renderer_host/input/tap_suppression_controller_client.h b/content/browser/renderer_host/input/tap_suppression_controller_client.h
index fcea0e1f..075fa08 100644
--- a/content/browser/renderer_host/input/tap_suppression_controller_client.h
+++ b/content/browser/renderer_host/input/tap_suppression_controller_client.h
@@ -13,14 +13,6 @@ class TapSuppressionControllerClient {
public:
virtual ~TapSuppressionControllerClient() {}
- // Derived classes should implement this function to return the maximum time
- // they allow between a GestureFlingCancel and its corresponding tap down.
- virtual int MaxCancelToDownTimeInMs() = 0;
-
- // Derived classes should implement this function to return the maximum time
- // they allow between a single tap's down and up events.
- virtual int MaxTapGapTimeInMs() = 0;
-
// Called whenever the deferred tap down (if saved) should be dropped totally.
virtual void DropStashedTapDown() = 0;
diff --git a/content/browser/renderer_host/input/tap_suppression_controller_unittest.cc b/content/browser/renderer_host/input/tap_suppression_controller_unittest.cc
index d436f45a4..702dc6f 100644
--- a/content/browser/renderer_host/input/tap_suppression_controller_unittest.cc
+++ b/content/browser/renderer_host/input/tap_suppression_controller_unittest.cc
@@ -15,6 +15,7 @@ namespace content {
class MockTapSuppressionController : public TapSuppressionController,
public TapSuppressionControllerClient {
public:
+ using TapSuppressionController::DISABLED;
using TapSuppressionController::NOTHING;
using TapSuppressionController::GFC_IN_PROGRESS;
using TapSuppressionController::TAP_DOWN_STASHED;
@@ -32,14 +33,11 @@ class MockTapSuppressionController : public TapSuppressionController,
STASHED_TAP_DOWN_FORWARDED = 1 << 7,
};
- MockTapSuppressionController()
- : TapSuppressionController(this),
- max_cancel_to_down_time_in_ms_(1),
- max_tap_gap_time_in_ms_(1),
+ MockTapSuppressionController(const TapSuppressionController::Config& config)
+ : TapSuppressionController(this, config),
last_actions_(NONE),
time_(),
- timer_started_(false) {
- }
+ timer_started_(false) {}
virtual ~MockTapSuppressionController() {}
@@ -86,14 +84,6 @@ class MockTapSuppressionController : public TapSuppressionController,
}
}
- void set_max_cancel_to_down_time_in_ms(int val) {
- max_cancel_to_down_time_in_ms_ = val;
- }
-
- void set_max_tap_gap_time_in_ms(int val) {
- max_tap_gap_time_in_ms_ = val;
- }
-
State state() { return state_; }
int last_actions() { return last_actions_; }
@@ -114,14 +104,6 @@ class MockTapSuppressionController : public TapSuppressionController,
private:
// TapSuppressionControllerClient implementation
- virtual int MaxCancelToDownTimeInMs() OVERRIDE {
- return max_cancel_to_down_time_in_ms_;
- }
-
- virtual int MaxTapGapTimeInMs() OVERRIDE {
- return max_tap_gap_time_in_ms_;
- }
-
virtual void DropStashedTapDown() OVERRIDE {
last_actions_ |= TAP_DOWN_DROPPED;
}
@@ -136,9 +118,6 @@ class MockTapSuppressionController : public TapSuppressionController,
using TapSuppressionController::ShouldDeferTapDown;
using TapSuppressionController::ShouldSuppressTapEnd;
- int max_cancel_to_down_time_in_ms_;
- int max_tap_gap_time_in_ms_;
-
int last_actions_;
base::TimeTicks time_;
@@ -158,22 +137,28 @@ class TapSuppressionControllerTest : public testing::Test {
protected:
// testing::Test
virtual void SetUp() {
- tap_suppression_controller_.reset(new MockTapSuppressionController());
+ tap_suppression_controller_.reset(
+ new MockTapSuppressionController(GetConfig()));
}
virtual void TearDown() {
tap_suppression_controller_.reset();
}
+ static TapSuppressionController::Config GetConfig() {
+ TapSuppressionController::Config config;
+ config.enabled = true;
+ config.max_cancel_to_down_time = base::TimeDelta::FromMilliseconds(10);
+ config.max_tap_gap_time = base::TimeDelta::FromMilliseconds(10);
+ return config;
+ }
+
scoped_ptr<MockTapSuppressionController> tap_suppression_controller_;
};
// Test TapSuppressionController for when GestureFlingCancel Ack comes before
// TapDown and everything happens without any delays.
TEST_F(TapSuppressionControllerTest, GFCAckBeforeTapFast) {
- tap_suppression_controller_->set_max_cancel_to_down_time_in_ms(10);
- tap_suppression_controller_->set_max_tap_gap_time_in_ms(10);
-
// Send GestureFlingCancel.
tap_suppression_controller_->SendGestureFlingCancel();
EXPECT_EQ(MockTapSuppressionController::NONE,
@@ -207,9 +192,6 @@ TEST_F(TapSuppressionControllerTest, GFCAckBeforeTapFast) {
// Test TapSuppressionController for when GestureFlingCancel Ack comes before
// TapDown, but there is a small delay between TapDown and TapUp.
TEST_F(TapSuppressionControllerTest, GFCAckBeforeTapInsufficientlyLateTapUp) {
- tap_suppression_controller_->set_max_cancel_to_down_time_in_ms(10);
- tap_suppression_controller_->set_max_tap_gap_time_in_ms(10);
-
// Send GestureFlingCancel.
tap_suppression_controller_->SendGestureFlingCancel();
EXPECT_EQ(MockTapSuppressionController::NONE,
@@ -251,9 +233,6 @@ TEST_F(TapSuppressionControllerTest, GFCAckBeforeTapInsufficientlyLateTapUp) {
// Test TapSuppressionController for when GestureFlingCancel Ack comes before
// TapDown, but there is a long delay between TapDown and TapUp.
TEST_F(TapSuppressionControllerTest, GFCAckBeforeTapSufficientlyLateTapUp) {
- tap_suppression_controller_->set_max_cancel_to_down_time_in_ms(10);
- tap_suppression_controller_->set_max_tap_gap_time_in_ms(10);
-
// Send GestureFlingCancel.
tap_suppression_controller_->SendGestureFlingCancel();
EXPECT_EQ(MockTapSuppressionController::NONE,
@@ -294,9 +273,6 @@ TEST_F(TapSuppressionControllerTest, GFCAckBeforeTapSufficientlyLateTapUp) {
// Test TapSuppressionController for when GestureFlingCancel Ack comes before
// TapDown, but there is a small delay between the Ack and TapDown.
TEST_F(TapSuppressionControllerTest, GFCAckBeforeTapInsufficientlyLateTapDown) {
- tap_suppression_controller_->set_max_cancel_to_down_time_in_ms(10);
- tap_suppression_controller_->set_max_tap_gap_time_in_ms(10);
-
// Send GestureFlingCancel.
tap_suppression_controller_->SendGestureFlingCancel();
EXPECT_EQ(MockTapSuppressionController::NONE,
@@ -338,9 +314,6 @@ TEST_F(TapSuppressionControllerTest, GFCAckBeforeTapInsufficientlyLateTapDown) {
// Test TapSuppressionController for when GestureFlingCancel Ack comes before
// TapDown, but there is a long delay between the Ack and TapDown.
TEST_F(TapSuppressionControllerTest, GFCAckBeforeTapSufficientlyLateTapDown) {
- tap_suppression_controller_->set_max_cancel_to_down_time_in_ms(10);
- tap_suppression_controller_->set_max_tap_gap_time_in_ms(10);
-
// Send GestureFlingCancel.
tap_suppression_controller_->SendGestureFlingCancel();
EXPECT_EQ(MockTapSuppressionController::NONE,
@@ -381,9 +354,6 @@ TEST_F(TapSuppressionControllerTest, GFCAckBeforeTapSufficientlyLateTapDown) {
// Test TapSuppressionController for when unprocessed GestureFlingCancel Ack
// comes after TapDown and everything happens without any delay.
TEST_F(TapSuppressionControllerTest, GFCAckUnprocessedAfterTapFast) {
- tap_suppression_controller_->set_max_cancel_to_down_time_in_ms(10);
- tap_suppression_controller_->set_max_tap_gap_time_in_ms(10);
-
// Send GestureFlingCancel.
tap_suppression_controller_->SendGestureFlingCancel();
EXPECT_EQ(MockTapSuppressionController::NONE,
@@ -417,9 +387,6 @@ TEST_F(TapSuppressionControllerTest, GFCAckUnprocessedAfterTapFast) {
// Test TapSuppressionController for when processed GestureFlingCancel Ack comes
// after TapDown and everything happens without any delay.
TEST_F(TapSuppressionControllerTest, GFCAckProcessedAfterTapFast) {
- tap_suppression_controller_->set_max_cancel_to_down_time_in_ms(10);
- tap_suppression_controller_->set_max_tap_gap_time_in_ms(10);
-
// Send GestureFlingCancel.
tap_suppression_controller_->SendGestureFlingCancel();
EXPECT_EQ(MockTapSuppressionController::NONE,
@@ -453,9 +420,6 @@ TEST_F(TapSuppressionControllerTest, GFCAckProcessedAfterTapFast) {
// Test TapSuppressionController for when GestureFlingCancel Ack comes after
// TapDown and there is a small delay between the Ack and TapUp.
TEST_F(TapSuppressionControllerTest, GFCAckAfterTapInsufficientlyLateTapUp) {
- tap_suppression_controller_->set_max_cancel_to_down_time_in_ms(10);
- tap_suppression_controller_->set_max_tap_gap_time_in_ms(10);
-
// Send GestureFlingCancel.
tap_suppression_controller_->SendGestureFlingCancel();
EXPECT_EQ(MockTapSuppressionController::NONE,
@@ -497,9 +461,6 @@ TEST_F(TapSuppressionControllerTest, GFCAckAfterTapInsufficientlyLateTapUp) {
// Test TapSuppressionController for when GestureFlingCancel Ack comes after
// TapDown and there is a long delay between the Ack and TapUp.
TEST_F(TapSuppressionControllerTest, GFCAckAfterTapSufficientlyLateTapUp) {
- tap_suppression_controller_->set_max_cancel_to_down_time_in_ms(10);
- tap_suppression_controller_->set_max_tap_gap_time_in_ms(10);
-
// Send GestureFlingCancel.
tap_suppression_controller_->SendGestureFlingCancel();
EXPECT_EQ(MockTapSuppressionController::NONE,
@@ -537,4 +498,40 @@ TEST_F(TapSuppressionControllerTest, GFCAckAfterTapSufficientlyLateTapUp) {
tap_suppression_controller_->state());
}
+// Test that no suppression occurs if the TapSuppressionController is disabled.
+TEST_F(TapSuppressionControllerTest, NoSuppressionIfDisabled) {
+ TapSuppressionController::Config disabled_config;
+ disabled_config.enabled = false;
+ tap_suppression_controller_.reset(
+ new MockTapSuppressionController(disabled_config));
+
+ // Send GestureFlingCancel.
+ tap_suppression_controller_->SendGestureFlingCancel();
+ EXPECT_EQ(MockTapSuppressionController::NONE,
+ tap_suppression_controller_->last_actions());
+ EXPECT_EQ(MockTapSuppressionController::DISABLED,
+ tap_suppression_controller_->state());
+
+ // Send GestureFlingCancel Ack.
+ tap_suppression_controller_->SendGestureFlingCancelAck(true);
+ EXPECT_EQ(MockTapSuppressionController::NONE,
+ tap_suppression_controller_->last_actions());
+ EXPECT_EQ(MockTapSuppressionController::DISABLED,
+ tap_suppression_controller_->state());
+
+ // Send TapDown. This TapDown should not be suppressed.
+ tap_suppression_controller_->SendTapDown();
+ EXPECT_EQ(MockTapSuppressionController::TAP_DOWN_FORWARDED,
+ tap_suppression_controller_->last_actions());
+ EXPECT_EQ(MockTapSuppressionController::DISABLED,
+ tap_suppression_controller_->state());
+
+ // Send TapUp. This TapUp should not be suppressed.
+ tap_suppression_controller_->SendTapUp();
+ EXPECT_EQ(MockTapSuppressionController::TAP_UP_FORWARDED,
+ tap_suppression_controller_->last_actions());
+ EXPECT_EQ(MockTapSuppressionController::DISABLED,
+ tap_suppression_controller_->state());
+}
+
} // namespace content
diff --git a/content/browser/renderer_host/input/touch_event_queue.cc b/content/browser/renderer_host/input/touch_event_queue.cc
index 16d9e11..1877281 100644
--- a/content/browser/renderer_host/input/touch_event_queue.cc
+++ b/content/browser/renderer_host/input/touch_event_queue.cc
@@ -5,12 +5,10 @@
#include "content/browser/renderer_host/input/touch_event_queue.h"
#include "base/auto_reset.h"
-#include "base/command_line.h"
#include "base/debug/trace_event.h"
#include "base/stl_util.h"
#include "content/browser/renderer_host/input/timeout_monitor.h"
#include "content/common/input/web_touch_event_traits.h"
-#include "content/public/common/content_switches.h"
#include "ui/gfx/geometry/point_f.h"
using blink::WebInputEvent;
@@ -35,8 +33,6 @@ const double kApplicationSlopRegionLengthDipsSqared = 15. * 15.;
// region and DPI scale are reasonably proportioned).
const float kSlopEpsilon = .05f;
-typedef std::vector<TouchEventWithLatencyInfo> WebTouchEventWithLatencyList;
-
TouchEventWithLatencyInfo ObtainCancelEventForTouchEvent(
const TouchEventWithLatencyInfo& event_to_cancel) {
TouchEventWithLatencyInfo event = event_to_cancel;
@@ -73,7 +69,9 @@ class TouchEventQueue::TouchTimeoutHandler {
timeout_delay_(timeout_delay),
pending_ack_state_(PENDING_ACK_NONE),
timeout_monitor_(base::Bind(&TouchTimeoutHandler::OnTimeOut,
- base::Unretained(this))) {}
+ base::Unretained(this))) {
+ DCHECK(timeout_delay != base::TimeDelta());
+ }
~TouchTimeoutHandler() {}
@@ -197,42 +195,42 @@ class TouchEventQueue::TouchMoveSlopSuppressor {
TouchMoveSlopSuppressor(double slop_suppression_length_dips)
: slop_suppression_length_dips_squared_(slop_suppression_length_dips *
slop_suppression_length_dips),
- suppressing_touch_moves_(false) {}
+ suppressing_touchmoves_(false) {}
bool FilterEvent(const WebTouchEvent& event) {
if (WebTouchEventTraits::IsTouchSequenceStart(event)) {
touch_sequence_start_position_ =
gfx::PointF(event.touches[0].position);
- suppressing_touch_moves_ = slop_suppression_length_dips_squared_ != 0;
+ suppressing_touchmoves_ = slop_suppression_length_dips_squared_ != 0;
}
if (event.type != WebInputEvent::TouchMove)
return false;
- if (suppressing_touch_moves_) {
+ if (suppressing_touchmoves_) {
// Movement with a secondary pointer should terminate suppression.
if (event.touchesLength > 1) {
- suppressing_touch_moves_ = false;
+ suppressing_touchmoves_ = false;
} else if (event.touchesLength == 1) {
// Movement outside of the slop region should terminate suppression.
gfx::PointF position(event.touches[0].position);
if ((position - touch_sequence_start_position_).LengthSquared() >
slop_suppression_length_dips_squared_)
- suppressing_touch_moves_ = false;
+ suppressing_touchmoves_ = false;
}
}
- return suppressing_touch_moves_;
+ return suppressing_touchmoves_;
}
void ConfirmTouchEvent(InputEventAckState ack_result) {
if (ack_result == INPUT_EVENT_ACK_STATE_CONSUMED)
- suppressing_touch_moves_ = false;
+ suppressing_touchmoves_ = false;
}
private:
double slop_suppression_length_dips_squared_;
gfx::PointF touch_sequence_start_position_;
- bool suppressing_touch_moves_;
+ bool suppressing_touchmoves_;
DISALLOW_COPY_AND_ASSIGN(TouchMoveSlopSuppressor);
};
@@ -316,26 +314,37 @@ class CoalescedWebTouchEvent {
// This is the list of the original events that were coalesced, each requiring
// future ack dispatch to the client.
+ typedef std::vector<TouchEventWithLatencyInfo> WebTouchEventWithLatencyList;
WebTouchEventWithLatencyList events_to_ack_;
DISALLOW_COPY_AND_ASSIGN(CoalescedWebTouchEvent);
};
+TouchEventQueue::Config::Config()
+ : touchmove_slop_suppression_length_dips(0),
+ touch_scrolling_mode(TOUCH_SCROLLING_MODE_DEFAULT),
+ touch_ack_timeout_delay(base::TimeDelta::FromMilliseconds(200)),
+ touch_ack_timeout_supported(false) {
+}
+
TouchEventQueue::TouchEventQueue(TouchEventQueueClient* client,
- TouchScrollingMode mode,
- double touchmove_suppression_length_dips)
+ const Config& config)
: client_(client),
dispatching_touch_ack_(NULL),
dispatching_touch_(false),
touch_filtering_state_(TOUCH_FILTERING_STATE_DEFAULT),
- ack_timeout_enabled_(false),
+ ack_timeout_enabled_(config.touch_ack_timeout_supported),
touchmove_slop_suppressor_(new TouchMoveSlopSuppressor(
- touchmove_suppression_length_dips + kSlopEpsilon)),
+ config.touchmove_slop_suppression_length_dips + kSlopEpsilon)),
send_touch_events_async_(false),
- needs_async_touch_move_for_outer_slop_region_(false),
+ needs_async_touchmove_for_outer_slop_region_(false),
last_sent_touch_timestamp_sec_(0),
- touch_scrolling_mode_(mode) {
+ touch_scrolling_mode_(config.touch_scrolling_mode) {
DCHECK(client);
+ if (ack_timeout_enabled_) {
+ timeout_handler_.reset(
+ new TouchTimeoutHandler(this, config.touch_ack_timeout_delay));
+ }
}
TouchEventQueue::~TouchEventQueue() {
@@ -447,22 +456,22 @@ void TouchEventQueue::ForwardNextEventToRenderer() {
// application be sent touches at key points in the gesture stream,
// e.g., when the application slop region is exceeded or touchmove
// coalescing fails because of different modifiers.
- const bool send_touch_move_now =
+ const bool send_touchmove_now =
size() > 1 ||
(touch.event.timeStampSeconds >=
last_sent_touch_timestamp_sec_ + kAsyncTouchMoveIntervalSec) ||
- (needs_async_touch_move_for_outer_slop_region_ &&
+ (needs_async_touchmove_for_outer_slop_region_ &&
OutsideApplicationSlopRegion(touch.event,
touch_sequence_start_position_)) ||
- (pending_async_touch_move_ &&
- !pending_async_touch_move_->CanCoalesceWith(touch));
+ (pending_async_touchmove_ &&
+ !pending_async_touchmove_->CanCoalesceWith(touch));
- if (!send_touch_move_now) {
- if (!pending_async_touch_move_) {
- pending_async_touch_move_.reset(new TouchEventWithLatencyInfo(touch));
+ if (!send_touchmove_now) {
+ if (!pending_async_touchmove_) {
+ pending_async_touchmove_.reset(new TouchEventWithLatencyInfo(touch));
} else {
- DCHECK(pending_async_touch_move_->CanCoalesceWith(touch));
- pending_async_touch_move_->CoalesceWith(touch);
+ DCHECK(pending_async_touchmove_->CanCoalesceWith(touch));
+ pending_async_touchmove_->CoalesceWith(touch);
}
DCHECK_EQ(1U, size());
PopTouchEventToClient(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
@@ -480,14 +489,14 @@ void TouchEventQueue::ForwardNextEventToRenderer() {
// Flush any pending async touch move. If it can be combined with the current
// (touchmove) event, great, otherwise send it immediately but separately. Its
// ack will trigger forwarding of the original |touch| event.
- if (pending_async_touch_move_) {
- if (pending_async_touch_move_->CanCoalesceWith(touch)) {
- pending_async_touch_move_->CoalesceWith(touch);
- pending_async_touch_move_->event.cancelable = !send_touch_events_async_;
- touch = *pending_async_touch_move_.Pass();
+ if (pending_async_touchmove_) {
+ if (pending_async_touchmove_->CanCoalesceWith(touch)) {
+ pending_async_touchmove_->CoalesceWith(touch);
+ pending_async_touchmove_->event.cancelable = !send_touch_events_async_;
+ touch = *pending_async_touchmove_.Pass();
} else {
scoped_ptr<TouchEventWithLatencyInfo> async_move =
- pending_async_touch_move_.Pass();
+ pending_async_touchmove_.Pass();
async_move->event.cancelable = false;
touch_queue_.push_front(new CoalescedWebTouchEvent(*async_move, true));
SendTouchEventImmediately(*async_move);
@@ -534,9 +543,9 @@ void TouchEventQueue::OnGestureScrollEvent(
}
}
- pending_async_touch_move_.reset();
+ pending_async_touchmove_.reset();
send_touch_events_async_ = true;
- needs_async_touch_move_for_outer_slop_region_ = true;
+ needs_async_touchmove_for_outer_slop_region_ = true;
return;
}
@@ -579,11 +588,11 @@ void TouchEventQueue::OnGestureEventAck(
// Note that there's no guarantee that this ACK is for the most recent
// gesture event (or even part of the current sequence). Worst case, the
// delay in updating the absorption state will result in minor UI glitches.
- // A valid |pending_async_touch_move_| will be flushed when the next event is
+ // A valid |pending_async_touchmove_| will be flushed when the next event is
// forwarded.
send_touch_events_async_ = (ack_result == INPUT_EVENT_ACK_STATE_CONSUMED);
if (!send_touch_events_async_)
- needs_async_touch_move_for_outer_slop_region_ = false;
+ needs_async_touchmove_for_outer_slop_region_ = false;
}
void TouchEventQueue::OnHasTouchEventHandlers(bool has_handlers) {
@@ -601,7 +610,7 @@ void TouchEventQueue::OnHasTouchEventHandlers(bool has_handlers) {
// TODO(jdduke): Synthesize a TouchCancel if necessary to update Blink touch
// state tracking (e.g., if the touch handler was removed mid-sequence).
touch_filtering_state_ = DROP_ALL_TOUCHES;
- pending_async_touch_move_.reset();
+ pending_async_touchmove_.reset();
if (timeout_handler_)
timeout_handler_->Reset();
if (!touch_queue_.empty())
@@ -621,29 +630,30 @@ bool TouchEventQueue::IsPendingAckTouchStart() const {
return (event.type == WebInputEvent::TouchStart);
}
-void TouchEventQueue::SetAckTimeoutEnabled(bool enabled,
- base::TimeDelta ack_timeout_delay) {
- if (!enabled) {
- ack_timeout_enabled_ = false;
- if (touch_filtering_state_ == FORWARD_TOUCHES_UNTIL_TIMEOUT)
- touch_filtering_state_ = FORWARD_ALL_TOUCHES;
- // Only reset the |timeout_handler_| if the timer is running and has not yet
- // timed out. This ensures that an already timed out sequence is properly
- // flushed by the handler.
- if (timeout_handler_ && timeout_handler_->IsTimeoutTimerRunning())
- timeout_handler_->Reset();
+void TouchEventQueue::SetAckTimeoutEnabled(bool enabled) {
+ // The timeout handler is valid only if explicitly supported in the config.
+ if (!timeout_handler_)
return;
- }
- ack_timeout_enabled_ = true;
- if (!timeout_handler_)
- timeout_handler_.reset(new TouchTimeoutHandler(this, ack_timeout_delay));
- else
- timeout_handler_->set_timeout_delay(ack_timeout_delay);
+ if (ack_timeout_enabled_ == enabled)
+ return;
+
+ ack_timeout_enabled_ = enabled;
+
+ if (enabled)
+ return;
+
+ if (touch_filtering_state_ == FORWARD_TOUCHES_UNTIL_TIMEOUT)
+ touch_filtering_state_ = FORWARD_ALL_TOUCHES;
+ // Only reset the |timeout_handler_| if the timer is running and has not yet
+ // timed out. This ensures that an already timed out sequence is properly
+ // flushed by the handler.
+ if (timeout_handler_ && timeout_handler_->IsTimeoutTimerRunning())
+ timeout_handler_->Reset();
}
bool TouchEventQueue::HasPendingAsyncTouchMoveForTesting() const {
- return pending_async_touch_move_;
+ return pending_async_touchmove_;
}
bool TouchEventQueue::IsTimeoutRunningForTesting() const {
@@ -658,7 +668,7 @@ TouchEventQueue::GetLatestEventForTesting() const {
void TouchEventQueue::FlushQueue() {
DCHECK(!dispatching_touch_ack_);
DCHECK(!dispatching_touch_);
- pending_async_touch_move_.reset();
+ pending_async_touchmove_.reset();
if (touch_filtering_state_ != DROP_ALL_TOUCHES)
touch_filtering_state_ = DROP_TOUCHES_IN_SEQUENCE;
while (!touch_queue_.empty())
@@ -700,14 +710,14 @@ scoped_ptr<CoalescedWebTouchEvent> TouchEventQueue::PopTouchEvent() {
void TouchEventQueue::SendTouchEventImmediately(
const TouchEventWithLatencyInfo& touch) {
- if (needs_async_touch_move_for_outer_slop_region_) {
+ if (needs_async_touchmove_for_outer_slop_region_) {
// Any event other than a touchmove (e.g., touchcancel or secondary
// touchstart) after a scroll has started will interrupt the need to send a
// an outer slop-region exceeding touchmove.
if (touch.event.type != WebInputEvent::TouchMove ||
OutsideApplicationSlopRegion(touch.event,
touch_sequence_start_position_))
- needs_async_touch_move_for_outer_slop_region_ = false;
+ needs_async_touchmove_for_outer_slop_region_ = false;
}
client_->SendTouchEventImmediately(touch);
diff --git a/content/browser/renderer_host/input/touch_event_queue.h b/content/browser/renderer_host/input/touch_event_queue.h
index 9290d40..e491a62 100644
--- a/content/browser/renderer_host/input/touch_event_queue.h
+++ b/content/browser/renderer_host/input/touch_event_queue.h
@@ -55,12 +55,29 @@ class CONTENT_EXPORT TouchEventQueue {
TOUCH_SCROLLING_MODE_DEFAULT = TOUCH_SCROLLING_MODE_ASYNC_TOUCHMOVE
};
- // The |client| must outlive the TouchEventQueue. If
- // |touchmove_suppression_length_dips| <= 0, touch move suppression is
- // disabled.
- TouchEventQueue(TouchEventQueueClient* client,
- TouchScrollingMode mode,
- double touchmove_suppression_length_dips);
+ struct CONTENT_EXPORT Config {
+ Config();
+
+ // Determines the bounds of the (square) touchmove slop suppression region.
+ // Defaults to 0 (disabled).
+ double touchmove_slop_suppression_length_dips;
+
+ // Determines the type of touch scrolling.
+ // Defaults to TouchEventQueue:::TOUCH_SCROLLING_MODE_DEFAULT.
+ TouchEventQueue::TouchScrollingMode touch_scrolling_mode;
+
+ // Controls whether touch ack timeouts will trigger touch cancellation.
+ // Defaults to 200ms.
+ base::TimeDelta touch_ack_timeout_delay;
+
+ // Whether the platform supports touch ack timeout behavior.
+ // Defaults to false (disabled).
+ bool touch_ack_timeout_supported;
+ };
+
+ // The |client| must outlive the TouchEventQueue.
+ TouchEventQueue(TouchEventQueueClient* client, const Config& config);
+
~TouchEventQueue();
// Adds an event to the queue. The event may be coalesced with previously
@@ -95,7 +112,7 @@ class CONTENT_EXPORT TouchEventQueue {
// Sets whether a delayed touch ack will cancel and flush the current
// touch sequence. Note that, if the timeout was previously disabled, enabling
// it will take effect only for the following touch sequence.
- void SetAckTimeoutEnabled(bool enabled, base::TimeDelta ack_timeout_delay);
+ void SetAckTimeoutEnabled(bool enabled);
bool empty() const WARN_UNUSED_RESULT {
return touch_queue_.empty();
@@ -200,7 +217,7 @@ class CONTENT_EXPORT TouchEventQueue {
};
TouchFilteringState touch_filtering_state_;
- // Optional handler for timed-out touch event acks, disabled by default.
+ // Optional handler for timed-out touch event acks.
bool ack_timeout_enabled_;
scoped_ptr<TouchTimeoutHandler> timeout_handler_;
@@ -210,12 +227,12 @@ class CONTENT_EXPORT TouchEventQueue {
// Whether touch events should remain buffered and dispatched asynchronously
// while a scroll sequence is active. In this mode, touchmove's are throttled
- // and ack'ed immediately, but remain buffered in |pending_async_touch_move_|
+ // and ack'ed immediately, but remain buffered in |pending_async_touchmove_|
// until a sufficient time period has elapsed since the last sent touch event.
// For details see the design doc at http://goo.gl/lVyJAa.
bool send_touch_events_async_;
- bool needs_async_touch_move_for_outer_slop_region_;
- scoped_ptr<TouchEventWithLatencyInfo> pending_async_touch_move_;
+ bool needs_async_touchmove_for_outer_slop_region_;
+ scoped_ptr<TouchEventWithLatencyInfo> pending_async_touchmove_;
double last_sent_touch_timestamp_sec_;
// How touch events are handled during scrolling. For now this is a global
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 779cf25..6c23e98 100644
--- a/content/browser/renderer_host/input/touch_event_queue_unittest.cc
+++ b/content/browser/renderer_host/input/touch_event_queue_unittest.cc
@@ -40,14 +40,7 @@ class TouchEventQueueTest : public testing::Test,
virtual ~TouchEventQueueTest() {}
// testing::Test
- virtual void SetUp() OVERRIDE {
- ResetQueueWithParameters(touch_scrolling_mode_, slop_length_dips_);
- }
-
- virtual void SetTouchScrollingMode(TouchEventQueue::TouchScrollingMode mode) {
- touch_scrolling_mode_ = mode;
- ResetQueueWithParameters(touch_scrolling_mode_, slop_length_dips_);
- }
+ virtual void SetUp() OVERRIDE { ResetQueueWithConfig(CreateConfig()); }
virtual void TearDown() OVERRIDE {
queue_.reset();
@@ -83,14 +76,28 @@ class TouchEventQueueTest : public testing::Test,
}
protected:
+ TouchEventQueue::Config CreateConfig() {
+ TouchEventQueue::Config config;
+ config.touch_scrolling_mode = touch_scrolling_mode_;
+ config.touchmove_slop_suppression_length_dips = slop_length_dips_;
+ return config;
+ }
- void SetUpForTimeoutTesting(base::TimeDelta timeout_delay) {
- queue_->SetAckTimeoutEnabled(true, timeout_delay);
+ void SetTouchScrollingMode(TouchEventQueue::TouchScrollingMode mode) {
+ touch_scrolling_mode_ = mode;
+ ResetQueueWithConfig(CreateConfig());
}
void SetUpForTouchMoveSlopTesting(double slop_length_dips) {
slop_length_dips_ = slop_length_dips;
- ResetQueueWithParameters(touch_scrolling_mode_, slop_length_dips_);
+ ResetQueueWithConfig(CreateConfig());
+ }
+
+ void SetUpForTimeoutTesting(base::TimeDelta timeout_delay) {
+ TouchEventQueue::Config config = CreateConfig();
+ config.touch_ack_timeout_delay = timeout_delay;
+ config.touch_ack_timeout_supported = true;
+ ResetQueueWithConfig(config);
}
void SendTouchEvent(const WebTouchEvent& event) {
@@ -183,9 +190,7 @@ class TouchEventQueueTest : public testing::Test,
queue_->OnHasTouchEventHandlers(has_handlers);
}
- void SetAckTimeoutDisabled() {
- queue_->SetAckTimeoutEnabled(false, base::TimeDelta());
- }
+ void SetAckTimeoutDisabled() { queue_->SetAckTimeoutEnabled(false); }
bool IsTimeoutEnabled() const { return queue_->ack_timeout_enabled(); }
@@ -227,9 +232,8 @@ class TouchEventQueueTest : public testing::Test,
touch_event_.ResetPoints();
}
- void ResetQueueWithParameters(TouchEventQueue::TouchScrollingMode mode,
- double slop_length_dips) {
- queue_.reset(new TouchEventQueue(this, mode, slop_length_dips));
+ void ResetQueueWithConfig(const TouchEventQueue::Config& config) {
+ queue_.reset(new TouchEventQueue(this, config));
queue_->OnHasTouchEventHandlers(true);
}
diff --git a/content/browser/renderer_host/input/touchpad_tap_suppression_controller.cc b/content/browser/renderer_host/input/touchpad_tap_suppression_controller.cc
index d920779..d309742 100644
--- a/content/browser/renderer_host/input/touchpad_tap_suppression_controller.cc
+++ b/content/browser/renderer_host/input/touchpad_tap_suppression_controller.cc
@@ -4,45 +4,43 @@
#include "content/browser/renderer_host/input/touchpad_tap_suppression_controller.h"
-#include "content/browser/renderer_host/input/tap_suppression_controller.h"
-#include "content/browser/renderer_host/input/tap_suppression_controller_client.h"
-
-// The default implementation of the TouchpadTapSuppressionController does not
-// suppress taps. Touchpad tap suppression is needed only on CrOS.
-
namespace content {
TouchpadTapSuppressionController::TouchpadTapSuppressionController(
- TouchpadTapSuppressionControllerClient* /* client */)
- : client_(NULL) {}
+ TouchpadTapSuppressionControllerClient* client,
+ const TapSuppressionController::Config& config)
+ : client_(client), controller_(this, config) {
+}
TouchpadTapSuppressionController::~TouchpadTapSuppressionController() {}
-void TouchpadTapSuppressionController::GestureFlingCancel() {}
-
-void TouchpadTapSuppressionController::GestureFlingCancelAck(
- bool /*processed*/) {
+void TouchpadTapSuppressionController::GestureFlingCancel() {
+ controller_.GestureFlingCancel();
}
-bool TouchpadTapSuppressionController::ShouldDeferMouseDown(
- const MouseEventWithLatencyInfo& /*event*/) {
- return false;
+void TouchpadTapSuppressionController::GestureFlingCancelAck(bool processed) {
+ controller_.GestureFlingCancelAck(processed);
}
-bool TouchpadTapSuppressionController::ShouldSuppressMouseUp() { return false; }
-
-int TouchpadTapSuppressionController::MaxCancelToDownTimeInMs() {
- return 0;
+bool TouchpadTapSuppressionController::ShouldDeferMouseDown(
+ const MouseEventWithLatencyInfo& event) {
+ bool should_defer = controller_.ShouldDeferTapDown();
+ if (should_defer)
+ stashed_mouse_down_ = event;
+ return should_defer;
}
-int TouchpadTapSuppressionController::MaxTapGapTimeInMs() {
- return 0;
+bool TouchpadTapSuppressionController::ShouldSuppressMouseUp() {
+ return controller_.ShouldSuppressTapEnd();
}
void TouchpadTapSuppressionController::DropStashedTapDown() {
}
void TouchpadTapSuppressionController::ForwardStashedTapDown() {
+ // Mouse downs are not handled by gesture event filter; so, they are
+ // immediately forwarded to the renderer.
+ client_->SendMouseEventImmediately(stashed_mouse_down_);
}
} // namespace content
diff --git a/content/browser/renderer_host/input/touchpad_tap_suppression_controller.h b/content/browser/renderer_host/input/touchpad_tap_suppression_controller.h
index 64b2ed4..23e3ee4 100644
--- a/content/browser/renderer_host/input/touchpad_tap_suppression_controller.h
+++ b/content/browser/renderer_host/input/touchpad_tap_suppression_controller.h
@@ -5,7 +5,7 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_INPUT_TOUCHPAD_TAP_SUPPRESSION_CONTROLLER_H_
#define CONTENT_BROWSER_RENDERER_HOST_INPUT_TOUCHPAD_TAP_SUPPRESSION_CONTROLLER_H_
-#include "base/memory/scoped_ptr.h"
+#include "content/browser/renderer_host/input/tap_suppression_controller.h"
#include "content/browser/renderer_host/input/tap_suppression_controller_client.h"
#include "content/common/content_export.h"
#include "content/port/browser/event_with_latency_info.h"
@@ -27,8 +27,9 @@ class CONTENT_EXPORT TouchpadTapSuppressionControllerClient {
class TouchpadTapSuppressionController : public TapSuppressionControllerClient {
public:
// The |client| must outlive the TouchpadTapSupressionController.
- explicit TouchpadTapSuppressionController(
- TouchpadTapSuppressionControllerClient* client);
+ TouchpadTapSuppressionController(
+ TouchpadTapSuppressionControllerClient* client,
+ const TapSuppressionController::Config& config);
virtual ~TouchpadTapSuppressionController();
// Should be called on arrival of GestureFlingCancel events.
@@ -51,8 +52,6 @@ class TouchpadTapSuppressionController : public TapSuppressionControllerClient {
friend class MockRenderWidgetHost;
// TapSuppressionControllerClient implementation.
- virtual int MaxCancelToDownTimeInMs() OVERRIDE;
- virtual int MaxTapGapTimeInMs() OVERRIDE;
virtual void DropStashedTapDown() OVERRIDE;
virtual void ForwardStashedTapDown() OVERRIDE;
@@ -60,7 +59,7 @@ class TouchpadTapSuppressionController : public TapSuppressionControllerClient {
MouseEventWithLatencyInfo stashed_mouse_down_;
// The core controller of tap suppression.
- scoped_ptr<TapSuppressionController> controller_;
+ TapSuppressionController controller_;
DISALLOW_COPY_AND_ASSIGN(TouchpadTapSuppressionController);
};
diff --git a/content/browser/renderer_host/input/touchpad_tap_suppression_controller_aura.cc b/content/browser/renderer_host/input/touchpad_tap_suppression_controller_aura.cc
deleted file mode 100644
index b2176ac..0000000
--- a/content/browser/renderer_host/input/touchpad_tap_suppression_controller_aura.cc
+++ /dev/null
@@ -1,58 +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/touchpad_tap_suppression_controller.h"
-
-#include "content/browser/renderer_host/input/tap_suppression_controller.h"
-#include "content/browser/renderer_host/input/tap_suppression_controller_client.h"
-#include "ui/events/gestures/gesture_configuration.h"
-
-namespace content {
-
-TouchpadTapSuppressionController::TouchpadTapSuppressionController(
- TouchpadTapSuppressionControllerClient* client)
- : client_(client),
- controller_(new TapSuppressionController(this)) {
-}
-
-TouchpadTapSuppressionController::~TouchpadTapSuppressionController() {}
-
-void TouchpadTapSuppressionController::GestureFlingCancel() {
- controller_->GestureFlingCancel();
-}
-
-void TouchpadTapSuppressionController::GestureFlingCancelAck(bool processed) {
- controller_->GestureFlingCancelAck(processed);
-}
-
-bool TouchpadTapSuppressionController::ShouldDeferMouseDown(
- const MouseEventWithLatencyInfo& event) {
- bool should_defer = controller_->ShouldDeferTapDown();
- if (should_defer)
- stashed_mouse_down_ = event;
- return should_defer;
-}
-
-bool TouchpadTapSuppressionController::ShouldSuppressMouseUp() {
- return controller_->ShouldSuppressTapEnd();
-}
-
-int TouchpadTapSuppressionController::MaxCancelToDownTimeInMs() {
- return ui::GestureConfiguration::fling_max_cancel_to_down_time_in_ms();
-}
-
-int TouchpadTapSuppressionController::MaxTapGapTimeInMs() {
- return ui::GestureConfiguration::fling_max_tap_gap_time_in_ms();
-}
-
-void TouchpadTapSuppressionController::DropStashedTapDown() {
-}
-
-void TouchpadTapSuppressionController::ForwardStashedTapDown() {
- // Mouse downs are not handled by gesture event filter; so, they are
- // immediately forwarded to the renderer.
- client_->SendMouseEventImmediately(stashed_mouse_down_);
-}
-
-} // namespace content
diff --git a/content/browser/renderer_host/input/touchscreen_tap_suppression_controller.cc b/content/browser/renderer_host/input/touchscreen_tap_suppression_controller.cc
index 7f024b3..872cfb0 100644
--- a/content/browser/renderer_host/input/touchscreen_tap_suppression_controller.cc
+++ b/content/browser/renderer_host/input/touchscreen_tap_suppression_controller.cc
@@ -5,39 +5,33 @@
#include "content/browser/renderer_host/input/touchscreen_tap_suppression_controller.h"
#include "content/browser/renderer_host/input/gesture_event_queue.h"
-#include "content/browser/renderer_host/input/tap_suppression_controller.h"
-#include "ui/events/gestures/gesture_configuration.h"
-
-#if defined(OS_ANDROID)
-#include "ui/gfx/android/view_configuration.h"
-#endif
using blink::WebInputEvent;
namespace content {
TouchscreenTapSuppressionController::TouchscreenTapSuppressionController(
- GestureEventQueue* geq)
- : gesture_event_queue_(geq),
- controller_(new TapSuppressionController(this)) {
+ GestureEventQueue* geq,
+ const TapSuppressionController::Config& config)
+ : gesture_event_queue_(geq), controller_(this, config) {
}
TouchscreenTapSuppressionController::~TouchscreenTapSuppressionController() {}
void TouchscreenTapSuppressionController::GestureFlingCancel() {
- controller_->GestureFlingCancel();
+ controller_.GestureFlingCancel();
}
void TouchscreenTapSuppressionController::GestureFlingCancelAck(
bool processed) {
- controller_->GestureFlingCancelAck(processed);
+ controller_.GestureFlingCancelAck(processed);
}
bool TouchscreenTapSuppressionController::FilterTapEvent(
const GestureEventWithLatencyInfo& event) {
switch (event.event.type) {
case WebInputEvent::GestureTapDown:
- if (!controller_->ShouldDeferTapDown())
+ if (!controller_.ShouldDeferTapDown())
return false;
stashed_tap_down_.reset(new GestureEventWithLatencyInfo(event));
return true;
@@ -54,7 +48,7 @@ bool TouchscreenTapSuppressionController::FilterTapEvent(
case WebInputEvent::GestureTapCancel:
case WebInputEvent::GestureTap:
case WebInputEvent::GestureDoubleTap:
- return controller_->ShouldSuppressTapEnd();
+ return controller_.ShouldSuppressTapEnd();
default:
break;
@@ -62,27 +56,6 @@ bool TouchscreenTapSuppressionController::FilterTapEvent(
return false;
}
-#if defined(OS_ANDROID)
-// TODO(jdduke): Enable ui::GestureConfiguration on Android and initialize
-// with parameters from ViewConfiguration.
-int TouchscreenTapSuppressionController::MaxCancelToDownTimeInMs() {
- return gfx::ViewConfiguration::GetTapTimeoutInMs();
-}
-
-int TouchscreenTapSuppressionController::MaxTapGapTimeInMs() {
- return gfx::ViewConfiguration::GetLongPressTimeoutInMs();
-}
-#else
-int TouchscreenTapSuppressionController::MaxCancelToDownTimeInMs() {
- return ui::GestureConfiguration::fling_max_cancel_to_down_time_in_ms();
-}
-
-int TouchscreenTapSuppressionController::MaxTapGapTimeInMs() {
- return static_cast<int>(
- ui::GestureConfiguration::semi_long_press_time_in_seconds() * 1000);
-}
-#endif
-
void TouchscreenTapSuppressionController::DropStashedTapDown() {
stashed_tap_down_.reset();
stashed_show_press_.reset();
diff --git a/content/browser/renderer_host/input/touchscreen_tap_suppression_controller.h b/content/browser/renderer_host/input/touchscreen_tap_suppression_controller.h
index 02b5b06..a9e09f4 100644
--- a/content/browser/renderer_host/input/touchscreen_tap_suppression_controller.h
+++ b/content/browser/renderer_host/input/touchscreen_tap_suppression_controller.h
@@ -6,20 +6,22 @@
#define CONTENT_BROWSER_RENDERER_HOST_INPUT_TOUCHSCREEN_TAP_SUPPRESSION_CONTROLLER_H_
#include "base/memory/scoped_ptr.h"
-#include "content/browser/renderer_host/input/gesture_event_queue.h"
+#include "content/browser/renderer_host/input/tap_suppression_controller.h"
#include "content/browser/renderer_host/input/tap_suppression_controller_client.h"
+#include "content/port/browser/event_with_latency_info.h"
namespace content {
class GestureEventQueue;
-class TapSuppressionController;
// Controls the suppression of touchscreen taps immediately following the
// dispatch of a GestureFlingCancel event.
class TouchscreenTapSuppressionController
: public TapSuppressionControllerClient {
public:
- explicit TouchscreenTapSuppressionController(GestureEventQueue* geq);
+ TouchscreenTapSuppressionController(
+ GestureEventQueue* geq,
+ const TapSuppressionController::Config& config);
virtual ~TouchscreenTapSuppressionController();
// Should be called on arrival of GestureFlingCancel events.
@@ -35,8 +37,6 @@ class TouchscreenTapSuppressionController
private:
// TapSuppressionControllerClient implementation.
- virtual int MaxCancelToDownTimeInMs() OVERRIDE;
- virtual int MaxTapGapTimeInMs() OVERRIDE;
virtual void DropStashedTapDown() OVERRIDE;
virtual void ForwardStashedTapDown() OVERRIDE;
@@ -47,7 +47,7 @@ class TouchscreenTapSuppressionController
ScopedGestureEvent stashed_show_press_;
// The core controller of tap suppression.
- scoped_ptr<TapSuppressionController> controller_;
+ TapSuppressionController controller_;
DISALLOW_COPY_AND_ASSIGN(TouchscreenTapSuppressionController);
};
diff --git a/content/browser/renderer_host/input/touchscreen_tap_suppression_controller_stub.cc b/content/browser/renderer_host/input/touchscreen_tap_suppression_controller_stub.cc
deleted file mode 100644
index b3a136b..0000000
--- a/content/browser/renderer_host/input/touchscreen_tap_suppression_controller_stub.cc
+++ /dev/null
@@ -1,43 +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/touchscreen_tap_suppression_controller.h"
-
-#include "content/browser/renderer_host/input/tap_suppression_controller.h"
-
-// This is the stub implementation of TouchscreenTapSuppressionController which
-// is used on platforms that do not need tap suppression for touchscreen.
-
-namespace content {
-
-TouchscreenTapSuppressionController::TouchscreenTapSuppressionController(
- GestureEventQueue* /*geq*/)
- : gesture_event_queue_(NULL) {}
-
-TouchscreenTapSuppressionController::~TouchscreenTapSuppressionController() {}
-
-void TouchscreenTapSuppressionController::GestureFlingCancel() {}
-
-void TouchscreenTapSuppressionController::GestureFlingCancelAck(
- bool /*processed*/) {
-}
-
-bool TouchscreenTapSuppressionController::FilterTapEvent(
- const GestureEventWithLatencyInfo& /*event*/) {
- return false;
-}
-
-int TouchscreenTapSuppressionController::MaxCancelToDownTimeInMs() {
- return 0;
-}
-
-int TouchscreenTapSuppressionController::MaxTapGapTimeInMs() {
- return 0;
-}
-
-void TouchscreenTapSuppressionController::DropStashedTapDown() {}
-
-void TouchscreenTapSuppressionController::ForwardStashedTapDown() {}
-
-} // namespace content
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc
index c464a51..f01a2e7 100644
--- a/content/browser/renderer_host/render_widget_host_impl.cc
+++ b/content/browser/renderer_host/render_widget_host_impl.cc
@@ -31,6 +31,7 @@
#include "content/browser/gpu/gpu_process_host_ui_shim.h"
#include "content/browser/gpu/gpu_surface_tracker.h"
#include "content/browser/renderer_host/dip_util.h"
+#include "content/browser/renderer_host/input/input_router_config_helper.h"
#include "content/browser/renderer_host/input/input_router_impl.h"
#include "content/browser/renderer_host/input/synthetic_gesture.h"
#include "content/browser/renderer_host/input/synthetic_gesture_controller.h"
@@ -229,7 +230,8 @@ RenderWidgetHostImpl::RenderWidgetHostImpl(RenderWidgetHostDelegate* delegate,
accessibility_mode_ =
BrowserAccessibilityStateImpl::GetInstance()->accessibility_mode();
- input_router_.reset(new InputRouterImpl(process_, this, this, routing_id_));
+ input_router_.reset(new InputRouterImpl(
+ process_, this, this, routing_id_, GetInputRouterConfigForPlatform()));
touch_emulator_.reset();
@@ -1218,7 +1220,8 @@ void RenderWidgetHostImpl::RendererExited(base::TerminationStatus status,
waiting_for_screen_rects_ack_ = false;
// Reset to ensure that input routing works with a new renderer.
- input_router_.reset(new InputRouterImpl(process_, this, this, routing_id_));
+ input_router_.reset(new InputRouterImpl(
+ process_, this, this, routing_id_, GetInputRouterConfigForPlatform()));
if (overscroll_controller_)
overscroll_controller_->Reset();
diff --git a/content/browser/renderer_host/render_widget_host_unittest.cc b/content/browser/renderer_host/render_widget_host_unittest.cc
index 7c175fa..0370c9d 100644
--- a/content/browser/renderer_host/render_widget_host_unittest.cc
+++ b/content/browser/renderer_host/render_widget_host_unittest.cc
@@ -11,8 +11,6 @@
#include "content/browser/browser_thread_impl.h"
#include "content/browser/renderer_host/input/gesture_event_queue.h"
#include "content/browser/renderer_host/input/input_router_impl.h"
-#include "content/browser/renderer_host/input/tap_suppression_controller.h"
-#include "content/browser/renderer_host/input/tap_suppression_controller_client.h"
#include "content/browser/renderer_host/input/touch_event_queue.h"
#include "content/browser/renderer_host/overscroll_controller.h"
#include "content/browser/renderer_host/overscroll_controller_delegate.h"
@@ -199,7 +197,6 @@ class MockRenderWidgetHost : public RenderWidgetHostImpl {
int routing_id)
: RenderWidgetHostImpl(delegate, process, routing_id, false),
unresponsive_timer_fired_(false) {
- input_router_impl_ = static_cast<InputRouterImpl*>(input_router_.get());
acked_touch_event_type_ = blink::WebInputEvent::Undefined;
}
@@ -250,13 +247,10 @@ class MockRenderWidgetHost : public RenderWidgetHostImpl {
overscroll_controller_->set_delegate(overscroll_delegate_.get());
}
- void DisableGestureDebounce() {
- gesture_event_queue().set_debounce_enabled_for_testing(false);
- }
+ void DisableGestureDebounce() { set_debounce_interval_time_ms(0); }
void set_debounce_interval_time_ms(int delay_ms) {
- gesture_event_queue().
- set_debounce_interval_time_ms_for_testing(delay_ms);
+ gesture_event_queue().set_debounce_interval_time_ms_for_testing(delay_ms);
}
bool TouchEventQueueEmpty() const {
@@ -308,12 +302,11 @@ class MockRenderWidgetHost : public RenderWidgetHostImpl {
}
void SetupForInputRouterTest() {
- mock_input_router_ = new MockInputRouter(this);
- input_router_.reset(mock_input_router_);
+ input_router_.reset(new MockInputRouter(this));
}
MockInputRouter* mock_input_router() {
- return mock_input_router_;
+ return static_cast<MockInputRouter*>(input_router_.get());
}
protected:
@@ -322,27 +315,29 @@ class MockRenderWidgetHost : public RenderWidgetHostImpl {
}
const TouchEventQueue& touch_event_queue() const {
- return input_router_impl_->touch_event_queue_;
+ return input_router_impl()->touch_event_queue_;
}
const GestureEventQueue& gesture_event_queue() const {
- return input_router_impl_->gesture_event_queue_;
+ return input_router_impl()->gesture_event_queue_;
}
GestureEventQueue& gesture_event_queue() {
- return input_router_impl_->gesture_event_queue_;
+ return input_router_impl()->gesture_event_queue_;
}
private:
+ const InputRouterImpl* input_router_impl() const {
+ return static_cast<InputRouterImpl*>(input_router_.get());
+ }
+
+ InputRouterImpl* input_router_impl() {
+ return static_cast<InputRouterImpl*>(input_router_.get());
+ }
+
bool unresponsive_timer_fired_;
WebInputEvent::Type acked_touch_event_type_;
- // |input_router_impl_| and |mock_input_router_| are owned by
- // RenderWidgetHostImpl. The handles below are provided for convenience so
- // that we don't have to reinterpret_cast it all the time.
- InputRouterImpl* input_router_impl_;
- MockInputRouter* mock_input_router_;
-
scoped_ptr<TestOverscrollDelegate> overscroll_delegate_;
DISALLOW_COPY_AND_ASSIGN(MockRenderWidgetHost);
@@ -616,6 +611,9 @@ class RenderWidgetHostTest : public testing::Test {
view_.reset(new TestView(host_.get()));
host_->SetView(view_.get());
host_->Init();
+
+ // Tests for debounce-related behavior will explicitly enable debouncing.
+ host_->DisableGestureDebounce();
}
virtual void TearDown() {
view_.reset();
@@ -1518,7 +1516,6 @@ TEST_F(RenderWidgetHostTest, ScrollEventsOverscrollWithZeroFling) {
// overscroll nav instead of completing it.
TEST_F(RenderWidgetHostTest, ReverseFlingCancelsOverscroll) {
host_->SetupForOverscrollControllerTest();
- host_->DisableGestureDebounce();
process_->sink().ClearMessages();
view_->set_bounds(gfx::Rect(0, 0, 400, 200));
view_->Show();
@@ -1571,7 +1568,6 @@ TEST_F(RenderWidgetHostTest, ReverseFlingCancelsOverscroll) {
TEST_F(RenderWidgetHostTest, GestureScrollOverscrolls) {
// Turn off debounce handling for test isolation.
host_->SetupForOverscrollControllerTest();
- host_->DisableGestureDebounce();
process_->sink().ClearMessages();
SimulateGestureEvent(WebInputEvent::GestureScrollBegin,
@@ -1625,7 +1621,6 @@ TEST_F(RenderWidgetHostTest, GestureScrollOverscrolls) {
TEST_F(RenderWidgetHostTest, GestureScrollConsumedHorizontal) {
// Turn off debounce handling for test isolation.
host_->SetupForOverscrollControllerTest();
- host_->DisableGestureDebounce();
process_->sink().ClearMessages();
SimulateGestureEvent(WebInputEvent::GestureScrollBegin,
@@ -2080,7 +2075,6 @@ TEST_F(RenderWidgetHostTest, OverscrollDirectionChange) {
// move events do reach the renderer.
TEST_F(RenderWidgetHostTest, OverscrollMouseMoveCompletion) {
host_->SetupForOverscrollControllerTest();
- host_->DisableGestureDebounce();
process_->sink().ClearMessages();
view_->set_bounds(gfx::Rect(0, 0, 400, 200));
view_->Show();
@@ -2171,7 +2165,6 @@ TEST_F(RenderWidgetHostTest, OverscrollMouseMoveCompletion) {
// reset after the end of the scroll.
TEST_F(RenderWidgetHostTest, OverscrollStateResetsAfterScroll) {
host_->SetupForOverscrollControllerTest();
- host_->DisableGestureDebounce();
process_->sink().ClearMessages();
view_->set_bounds(gfx::Rect(0, 0, 400, 200));
view_->Show();
@@ -2246,6 +2239,7 @@ TEST_F(RenderWidgetHostTest, OverscrollResetsOnBlur) {
INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_EQ(OVERSCROLL_EAST, host_->overscroll_mode());
EXPECT_EQ(OVERSCROLL_EAST, host_->overscroll_delegate()->current_mode());
+ EXPECT_EQ(2U, process_->sink().message_count());
host_->Blur();
EXPECT_EQ(OVERSCROLL_NONE, host_->overscroll_mode());
@@ -2257,7 +2251,8 @@ TEST_F(RenderWidgetHostTest, OverscrollResetsOnBlur) {
SimulateGestureEvent(WebInputEvent::GestureScrollEnd,
WebGestureEvent::Touchscreen);
- EXPECT_EQ(0U, process_->sink().message_count());
+ EXPECT_EQ(1U, process_->sink().message_count());
+ process_->sink().ClearMessages();
// Start a scroll gesture again. This should correctly start the overscroll
// after the threshold.
@@ -2274,7 +2269,7 @@ TEST_F(RenderWidgetHostTest, OverscrollResetsOnBlur) {
WebGestureEvent::Touchscreen);
EXPECT_EQ(OVERSCROLL_NONE, host_->overscroll_delegate()->current_mode());
EXPECT_EQ(OVERSCROLL_EAST, host_->overscroll_delegate()->completed_mode());
- process_->sink().ClearMessages();
+ EXPECT_EQ(3U, process_->sink().message_count());
}
std::string GetInputMessageTypes(RenderWidgetHostProcess* process) {
@@ -2297,7 +2292,6 @@ std::string GetInputMessageTypes(RenderWidgetHostProcess* process) {
TEST_F(RenderWidgetHostTest, TouchEmulator) {
simulated_event_time_delta_seconds_ = 0.1;
- host_->DisableGestureDebounce();
// Immediately ack all touches instead of sending them to the renderer.
host_->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, false));
host_->OnMessageReceived(