summaryrefslogtreecommitdiffstats
path: root/ui/events/gestures
diff options
context:
space:
mode:
authortdresser@chromium.org <tdresser@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-08-08 06:46:34 +0000
committertdresser@chromium.org <tdresser@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-08-08 06:47:59 +0000
commit709c57ee1041c59a902e0b35afd740c8c79a0433 (patch)
tree1bdd96726725abc30e2c3913e9e4537c2b7761f9 /ui/events/gestures
parentd58d5b98abc2a4062861a130599624b5d60bbbdf (diff)
downloadchromium_src-709c57ee1041c59a902e0b35afd740c8c79a0433.zip
chromium_src-709c57ee1041c59a902e0b35afd740c8c79a0433.tar.gz
chromium_src-709c57ee1041c59a902e0b35afd740c8c79a0433.tar.bz2
Eager Gesture Recognition on Aura
This enables eager gesture recognition on Aura for the unified gesture detector. BUG=332418 TEST=GestureRecognizer/GestureRecognizerTest Review URL: https://codereview.chromium.org/393953012 Cr-Commit-Position: refs/heads/master@{#288236} git-svn-id: svn://svn.chromium.org/chrome/trunk/src@288236 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui/events/gestures')
-rw-r--r--ui/events/gestures/gesture_provider_aura.cc12
-rw-r--r--ui/events/gestures/gesture_provider_aura_unittest.cc152
-rw-r--r--ui/events/gestures/gesture_recognizer.h19
-rw-r--r--ui/events/gestures/gesture_recognizer_impl.cc60
-rw-r--r--ui/events/gestures/gesture_recognizer_impl.h13
-rw-r--r--ui/events/gestures/gesture_recognizer_impl_mac.cc14
6 files changed, 244 insertions, 26 deletions
diff --git a/ui/events/gestures/gesture_provider_aura.cc b/ui/events/gestures/gesture_provider_aura.cc
index 079884e..30200f9 100644
--- a/ui/events/gestures/gesture_provider_aura.cc
+++ b/ui/events/gestures/gesture_provider_aura.cc
@@ -23,8 +23,8 @@ GestureProviderAura::GestureProviderAura(GestureProviderAuraClient* client)
GestureProviderAura::~GestureProviderAura() {}
bool GestureProviderAura::OnTouchEvent(const TouchEvent& event) {
- bool pointer_id_is_active =
- pointer_state_.FindPointerIndexOfId(event.touch_id()) != -1;
+ int index = pointer_state_.FindPointerIndexOfId(event.touch_id());
+ bool pointer_id_is_active = index != -1;
if (event.type() == ET_TOUCH_PRESSED && pointer_id_is_active) {
// Ignore touch press events if we already believe the pointer is down.
@@ -36,6 +36,14 @@ bool GestureProviderAura::OnTouchEvent(const TouchEvent& event) {
return false;
}
+ // If this is a touchmove event, and it isn't different from the last
+ // event, ignore it.
+ if (event.type() == ET_TOUCH_MOVED &&
+ event.x() == pointer_state_.GetX(index) &&
+ event.y() == pointer_state_.GetY(index)) {
+ return false;
+ }
+
last_touch_event_flags_ = event.flags();
last_touch_event_latency_info_ = *event.latency();
pointer_state_.OnTouch(event);
diff --git a/ui/events/gestures/gesture_provider_aura_unittest.cc b/ui/events/gestures/gesture_provider_aura_unittest.cc
new file mode 100644
index 0000000..b51ca61
--- /dev/null
+++ b/ui/events/gestures/gesture_provider_aura_unittest.cc
@@ -0,0 +1,152 @@
+// 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 "base/memory/scoped_ptr.h"
+#include "base/message_loop/message_loop.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/events/event_utils.h"
+#include "ui/events/gestures/gesture_provider_aura.h"
+
+namespace ui {
+
+class GestureProviderAuraTest : public testing::Test,
+ public GestureProviderAuraClient {
+ public:
+ GestureProviderAuraTest() {}
+
+ virtual ~GestureProviderAuraTest() {}
+
+ virtual void OnGestureEvent(GestureEvent* event) OVERRIDE {}
+
+ virtual void SetUp() OVERRIDE {
+ provider_.reset(new GestureProviderAura(this));
+ }
+
+ virtual void TearDown() OVERRIDE { provider_.reset(); }
+
+ GestureProviderAura* provider() { return provider_.get(); }
+
+ private:
+ scoped_ptr<GestureProviderAura> provider_;
+ base::MessageLoopForUI message_loop_;
+};
+
+TEST_F(GestureProviderAuraTest, IgnoresExtraPressEvents) {
+ base::TimeDelta time = ui::EventTimeForNow();
+ TouchEvent press1(ET_TOUCH_PRESSED, gfx::PointF(10, 10), 0, time);
+ EXPECT_TRUE(provider()->OnTouchEvent(press1));
+
+ time += base::TimeDelta::FromMilliseconds(10);
+ TouchEvent press2(ET_TOUCH_PRESSED, gfx::PointF(30, 40), 0, time);
+ // Redundant press with same id is ignored.
+ EXPECT_FALSE(provider()->OnTouchEvent(press2));
+}
+
+TEST_F(GestureProviderAuraTest, IgnoresExtraMoveOrReleaseEvents) {
+ base::TimeDelta time = ui::EventTimeForNow();
+ TouchEvent press1(ET_TOUCH_PRESSED, gfx::PointF(10, 10), 0, time);
+ EXPECT_TRUE(provider()->OnTouchEvent(press1));
+
+ time += base::TimeDelta::FromMilliseconds(10);
+ TouchEvent release1(ET_TOUCH_RELEASED, gfx::PointF(30, 40), 0, time);
+ EXPECT_TRUE(provider()->OnTouchEvent(release1));
+
+ time += base::TimeDelta::FromMilliseconds(10);
+ TouchEvent release2(ET_TOUCH_RELEASED, gfx::PointF(30, 45), 0, time);
+ EXPECT_FALSE(provider()->OnTouchEvent(release1));
+
+ time += base::TimeDelta::FromMilliseconds(10);
+ TouchEvent move1(ET_TOUCH_MOVED, gfx::PointF(70, 75), 0, time);
+ EXPECT_FALSE(provider()->OnTouchEvent(move1));
+}
+
+TEST_F(GestureProviderAuraTest, IgnoresIdenticalMoveEvents) {
+ const float kRadiusX = 20;
+ const float kRadiusY = 30;
+ const float kAngle = 120;
+ const float kForce = 40;
+ const int kTouchId0 = 5;
+ const int kTouchId1 = 3;
+
+ base::TimeDelta time = ui::EventTimeForNow();
+ TouchEvent press0_1(ET_TOUCH_PRESSED, gfx::PointF(9, 10), kTouchId0, time);
+ EXPECT_TRUE(provider()->OnTouchEvent(press0_1));
+
+ TouchEvent press1_1(ET_TOUCH_PRESSED, gfx::PointF(40, 40), kTouchId1, time);
+ EXPECT_TRUE(provider()->OnTouchEvent(press1_1));
+
+ time += base::TimeDelta::FromMilliseconds(10);
+ TouchEvent move0_1(ET_TOUCH_MOVED,
+ gfx::PointF(10, 10),
+ 0,
+ kTouchId0,
+ time,
+ kRadiusX,
+ kRadiusY,
+ kAngle,
+ kForce);
+ EXPECT_TRUE(provider()->OnTouchEvent(move0_1));
+
+ TouchEvent move1_1(ET_TOUCH_MOVED,
+ gfx::PointF(100, 200),
+ 0,
+ kTouchId1,
+ time,
+ kRadiusX,
+ kRadiusY,
+ kAngle,
+ kForce);
+ EXPECT_TRUE(provider()->OnTouchEvent(move1_1));
+
+ time += base::TimeDelta::FromMilliseconds(10);
+ TouchEvent move0_2(ET_TOUCH_MOVED,
+ gfx::PointF(10, 10),
+ 0,
+ kTouchId0,
+ time,
+ kRadiusX,
+ kRadiusY,
+ kAngle,
+ kForce);
+ // Nothing has changed, so ignore the move.
+ EXPECT_FALSE(provider()->OnTouchEvent(move0_2));
+
+ TouchEvent move1_2(ET_TOUCH_MOVED,
+ gfx::PointF(100, 200),
+ 0,
+ kTouchId1,
+ time,
+ kRadiusX,
+ kRadiusY,
+ kAngle,
+ kForce);
+ // Nothing has changed, so ignore the move.
+ EXPECT_FALSE(provider()->OnTouchEvent(move1_2));
+
+ time += base::TimeDelta::FromMilliseconds(10);
+ TouchEvent move0_3(ET_TOUCH_MOVED,
+ gfx::PointF(70, 75.1f),
+ 0,
+ kTouchId0,
+ time,
+ kRadiusX,
+ kRadiusY,
+ kAngle,
+ kForce);
+ // Position has changed, so don't ignore the move.
+ EXPECT_TRUE(provider()->OnTouchEvent(move0_3));
+
+ time += base::TimeDelta::FromMilliseconds(10);
+ TouchEvent move0_4(ET_TOUCH_MOVED,
+ gfx::PointF(70, 75.1f),
+ 0,
+ kTouchId0,
+ time,
+ kRadiusX,
+ kRadiusY + 1,
+ kAngle,
+ kForce);
+}
+
+} // namespace ui
diff --git a/ui/events/gestures/gesture_recognizer.h b/ui/events/gestures/gesture_recognizer.h
index 4b31e57..5dc5834 100644
--- a/ui/events/gestures/gesture_recognizer.h
+++ b/ui/events/gestures/gesture_recognizer.h
@@ -27,11 +27,20 @@ class EVENTS_EXPORT GestureRecognizer {
virtual ~GestureRecognizer() {}
- // Invoked for each touch event that could contribute to the current gesture.
- // Returns list of zero or more GestureEvents identified after processing
- // TouchEvent.
- // Caller would be responsible for freeing up Gestures.
- virtual Gestures* ProcessTouchEventForGesture(const TouchEvent& event,
+ // Invoked before event dispatch. If the event is invalid given the current
+ // touch sequence, marks it as handled.
+ virtual bool ProcessTouchEventPreDispatch(const TouchEvent& event,
+ GestureConsumer* consumer) = 0;
+ // Returns a list of zero or more GestureEvents. The caller is responsible for
+ // freeing the returned events. Called synchronously after event dispatch.
+ virtual Gestures* ProcessTouchEventPostDispatch(
+ const TouchEvent& event,
+ ui::EventResult result,
+ GestureConsumer* consumer) = 0;
+ // Returns a list of zero or more GestureEvents. The caller is responsible for
+ // freeing the returned events. Called when a touch event receives an
+ // asynchronous ack.
+ virtual Gestures* ProcessTouchEventOnAsyncAck(const TouchEvent& event,
ui::EventResult result,
GestureConsumer* consumer) = 0;
diff --git a/ui/events/gestures/gesture_recognizer_impl.cc b/ui/events/gestures/gesture_recognizer_impl.cc
index 38c07f8e..099d29f 100644
--- a/ui/events/gestures/gesture_recognizer_impl.cc
+++ b/ui/events/gestures/gesture_recognizer_impl.cc
@@ -288,26 +288,54 @@ void GestureRecognizerImpl::DispatchGestureEvent(GestureEvent* event) {
}
}
-ScopedVector<GestureEvent>* GestureRecognizerImpl::ProcessTouchEventForGesture(
+bool GestureRecognizerImpl::ProcessTouchEventPreDispatch(
const TouchEvent& event,
- ui::EventResult result,
- GestureConsumer* target) {
- SetupTargets(event, target);
+ GestureConsumer* consumer) {
+ SetupTargets(event, consumer);
- if (!use_unified_gesture_detector_) {
- GestureSequence* gesture_sequence = GetGestureSequenceForConsumer(target);
- return gesture_sequence->ProcessTouchEventForGesture(event, result);
+ // If we aren't using the unified GR, we definitely want to dispatch the
+ // event.
+ if (!ui::IsUnifiedGestureDetectorEnabled())
+ return true;
+
+ if (event.result() & ER_CONSUMED)
+ return false;
+
+ GestureProviderAura* gesture_provider =
+ GetGestureProviderForConsumer(consumer);
+ return gesture_provider->OnTouchEvent(event);
+}
+
+GestureRecognizer::Gestures*
+GestureRecognizerImpl::ProcessTouchEventPostDispatch(
+ const TouchEvent& event,
+ ui::EventResult result,
+ GestureConsumer* consumer) {
+ if (ui::IsUnifiedGestureDetectorEnabled()) {
+ GestureProviderAura* gesture_provider =
+ GetGestureProviderForConsumer(consumer);
+ gesture_provider->OnTouchEventAck(result != ER_UNHANDLED);
+ return gesture_provider->GetAndResetPendingGestures();
} else {
+ GestureSequence* gesture_sequence = GetGestureSequenceForConsumer(consumer);
+ return gesture_sequence->ProcessTouchEventForGesture(event, result);
+ }
+}
+
+GestureRecognizer::Gestures* GestureRecognizerImpl::ProcessTouchEventOnAsyncAck(
+ const TouchEvent& event,
+ ui::EventResult result,
+ GestureConsumer* consumer) {
+ if (ui::IsUnifiedGestureDetectorEnabled()) {
+ if (result & ui::ER_CONSUMED)
+ return NULL;
GestureProviderAura* gesture_provider =
- GetGestureProviderForConsumer(target);
- // TODO(tdresser) - detect gestures eagerly.
- if (!(result & ER_CONSUMED)) {
- if (gesture_provider->OnTouchEvent(event)) {
- gesture_provider->OnTouchEventAck(result != ER_UNHANDLED);
- return gesture_provider->GetAndResetPendingGestures();
- }
- }
- return NULL;
+ GetGestureProviderForConsumer(consumer);
+ gesture_provider->OnTouchEventAck(result != ER_UNHANDLED);
+ return gesture_provider->GetAndResetPendingGestures();
+ } else {
+ GestureSequence* gesture_sequence = GetGestureSequenceForConsumer(consumer);
+ return gesture_sequence->ProcessTouchEventForGesture(event, result);
}
}
diff --git a/ui/events/gestures/gesture_recognizer_impl.h b/ui/events/gestures/gesture_recognizer_impl.h
index 80a3007..b2e8106 100644
--- a/ui/events/gestures/gesture_recognizer_impl.h
+++ b/ui/events/gestures/gesture_recognizer_impl.h
@@ -66,10 +66,19 @@ class EVENTS_EXPORT GestureRecognizerImpl : public GestureRecognizer,
void DispatchGestureEvent(GestureEvent* event);
// Overridden from GestureRecognizer
- virtual Gestures* ProcessTouchEventForGesture(
+ virtual bool ProcessTouchEventPreDispatch(const TouchEvent& event,
+ GestureConsumer* consumer) OVERRIDE;
+
+ virtual Gestures* ProcessTouchEventPostDispatch(
const TouchEvent& event,
ui::EventResult result,
- GestureConsumer* target) OVERRIDE;
+ GestureConsumer* consumer) OVERRIDE;
+
+ virtual Gestures* ProcessTouchEventOnAsyncAck(
+ const TouchEvent& event,
+ ui::EventResult result,
+ GestureConsumer* consumer) OVERRIDE;
+
virtual bool CleanupStateForConsumer(GestureConsumer* consumer)
OVERRIDE;
virtual void AddGestureEventHelper(GestureEventHelper* helper) OVERRIDE;
diff --git a/ui/events/gestures/gesture_recognizer_impl_mac.cc b/ui/events/gestures/gesture_recognizer_impl_mac.cc
index 46dde02..4dfa311 100644
--- a/ui/events/gestures/gesture_recognizer_impl_mac.cc
+++ b/ui/events/gestures/gesture_recognizer_impl_mac.cc
@@ -17,12 +17,24 @@ class GestureRecognizerImplMac : public GestureRecognizer {
virtual ~GestureRecognizerImplMac() {}
private:
- virtual Gestures* ProcessTouchEventForGesture(
+ virtual bool ProcessTouchEventPreDispatch(
+ const TouchEvent& event,
+ GestureConsumer* consumer) OVERRIDE {
+ return false;
+ }
+
+ virtual Gestures* ProcessTouchEventPostDispatch(
const TouchEvent& event,
ui::EventResult result,
GestureConsumer* consumer) OVERRIDE {
return NULL;
}
+ virtual Gestures* ProcessTouchEventOnAsyncAck(
+ const TouchEvent& event,
+ ui::EventResult result,
+ GestureConsumer* consumer) OVERRIDE {
+ return NULL;
+ };
virtual bool CleanupStateForConsumer(GestureConsumer* consumer) OVERRIDE {
return false;
}