diff options
author | tdresser@chromium.org <tdresser@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-08-08 06:46:34 +0000 |
---|---|---|
committer | tdresser@chromium.org <tdresser@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-08-08 06:47:59 +0000 |
commit | 709c57ee1041c59a902e0b35afd740c8c79a0433 (patch) | |
tree | 1bdd96726725abc30e2c3913e9e4537c2b7761f9 /ui/events/gestures | |
parent | d58d5b98abc2a4062861a130599624b5d60bbbdf (diff) | |
download | chromium_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.cc | 12 | ||||
-rw-r--r-- | ui/events/gestures/gesture_provider_aura_unittest.cc | 152 | ||||
-rw-r--r-- | ui/events/gestures/gesture_recognizer.h | 19 | ||||
-rw-r--r-- | ui/events/gestures/gesture_recognizer_impl.cc | 60 | ||||
-rw-r--r-- | ui/events/gestures/gesture_recognizer_impl.h | 13 | ||||
-rw-r--r-- | ui/events/gestures/gesture_recognizer_impl_mac.cc | 14 |
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; } |