Commit 32a40c21 authored by jdduke@chromium.org's avatar jdduke@chromium.org

Ignore min/max gesture bounds for mouse or stylus-derived gestures

The min/max gesture bounds are a semi-hacky workaround for unpredictable touch
devices. For mouse and stylus inputs, we should avoid applying these bounds,
preventing undesirable side-effects like tap disambiguation for mouse clicks.

BUG=403368

Review URL: https://codereview.chromium.org/468043003

Cr-Commit-Position: refs/heads/master@{#289477}
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@289477 0039d316-1c4b-4281-b951-d872f2087c98
parent 4c728d7d
......@@ -57,6 +57,22 @@ class GestureTextSelectorTest : public testing::Test,
}
protected:
static GestureEventData CreateGesture(ui::EventType type,
base::TimeTicks event_time,
float x,
float y) {
return GestureEventData(GestureEventDetails(type, 0, 0),
0,
MotionEvent::TOOL_TYPE_FINGER,
event_time,
x,
y,
x,
y,
1,
gfx::RectF(0, 0, 0, 0));
}
scoped_ptr<GestureTextSelector> selector_;
std::vector<std::string> event_log_;
};
......@@ -130,25 +146,22 @@ TEST_F(GestureTextSelectorTest, PenDragging) {
// 3. DOUBLE TAP
// Suppress most gesture events when in text selection mode.
event_time += base::TimeDelta::FromMilliseconds(10);
const GestureEventData double_tap(
GestureEventDetails(ui::ET_GESTURE_DOUBLE_TAP, 0, 0), 0, event_time,
x2, y2, x2, y2, 1, gfx::RectF(0, 0, 0, 0));
const GestureEventData double_tap =
CreateGesture(ui::ET_GESTURE_DOUBLE_TAP, event_time, x2, y2);
EXPECT_TRUE(selector_->OnGestureEvent(double_tap));
EXPECT_TRUE(event_log_.empty());
// 4. ET_GESTURE_SCROLL_BEGIN
event_time += base::TimeDelta::FromMilliseconds(10);
const GestureEventData scroll_begin(
GestureEventDetails(ui::ET_GESTURE_SCROLL_BEGIN, 0, 0), 0, event_time,
x1, y1, x1, y1, 1, gfx::RectF(0, 0, 0, 0));
const GestureEventData scroll_begin =
CreateGesture(ui::ET_GESTURE_SCROLL_BEGIN, event_time, x1, y1);
EXPECT_TRUE(selector_->OnGestureEvent(scroll_begin));
EXPECT_EQ(1u, event_log_.size()); // Unselect
// 5. ET_GESTURE_SCROLL_UPDATE
event_time += base::TimeDelta::FromMilliseconds(10);
const GestureEventData scroll_update(
GestureEventDetails(ui::ET_GESTURE_SCROLL_UPDATE, 0, 0), 0, event_time,
x2, y2, x2, y2, 1, gfx::RectF(0, 0, 0, 0));
const GestureEventData scroll_update =
CreateGesture(ui::ET_GESTURE_SCROLL_UPDATE, event_time, x2, y2);
EXPECT_TRUE(selector_->OnGestureEvent(scroll_update));
EXPECT_EQ(3u, event_log_.size()); // Unselect, Show, SelectRange
EXPECT_STREQ("SelectRange", event_log_.back().c_str());
......@@ -163,9 +176,8 @@ TEST_F(GestureTextSelectorTest, PenDragging) {
// 7. ET_GESTURE_SCROLL_END
event_time += base::TimeDelta::FromMilliseconds(10);
const GestureEventData scroll_end(
GestureEventDetails(ui::ET_GESTURE_SCROLL_END, 0, 0), 0, event_time,
x2, y2, x2, y2, 1, gfx::RectF(0, 0, 0, 0));
const GestureEventData scroll_end =
CreateGesture(ui::ET_GESTURE_SCROLL_END, event_time, x2, y2);
EXPECT_TRUE(selector_->OnGestureEvent(scroll_end));
EXPECT_EQ(3u, event_log_.size()); // NO CHANGE
}
......@@ -186,9 +198,8 @@ TEST_F(GestureTextSelectorTest, TapToSelectWord) {
// 5. TAP_DOWN
event_time += base::TimeDelta::FromMilliseconds(10);
const GestureEventData tap_down(
GestureEventDetails(ui::ET_GESTURE_TAP_DOWN, 0, 0), 0, event_time,
x2, y2, x2, y2, 1, gfx::RectF(0, 0, 0, 0));
const GestureEventData tap_down =
CreateGesture(ui::ET_GESTURE_TAP_DOWN, event_time, x2, y2);
EXPECT_TRUE(selector_->OnGestureEvent(tap_down));
EXPECT_TRUE(event_log_.empty());
......@@ -210,9 +221,8 @@ TEST_F(GestureTextSelectorTest, TapToSelectWord) {
// 4. TAP
event_time += base::TimeDelta::FromMilliseconds(10);
const GestureEventData tap(
GestureEventDetails(ui::ET_GESTURE_TAP, 0, 0), 0, event_time,
x1, y1, x1, y1, 1, gfx::RectF(0, 0, 0, 0));
const GestureEventData tap =
CreateGesture(ui::ET_GESTURE_TAP, event_time, x1, y1);
EXPECT_TRUE(selector_->OnGestureEvent(tap));
EXPECT_EQ(1u, event_log_.size()); // LongPress
EXPECT_STREQ("LongPress", event_log_.back().c_str());
......
......@@ -64,6 +64,8 @@ MotionEventAndroid::ToolType FromAndroidToolType(int android_tool_type) {
return MotionEventAndroid::TOOL_TYPE_STYLUS;
case TOOL_TYPE_MOUSE:
return MotionEventAndroid::TOOL_TYPE_MOUSE;
case TOOL_TYPE_ERASER:
return MotionEventAndroid::TOOL_TYPE_ERASER;
default:
NOTREACHED() << "Invalid Android MotionEvent tool type: "
<< android_tool_type;
......
......@@ -10,6 +10,7 @@ namespace ui {
GestureEventData::GestureEventData(const GestureEventDetails& details,
int motion_event_id,
MotionEvent::ToolType primary_tool_type,
base::TimeTicks time,
float x,
float y,
......@@ -19,6 +20,7 @@ GestureEventData::GestureEventData(const GestureEventDetails& details,
const gfx::RectF& bounding_box)
: details(details),
motion_event_id(motion_event_id),
primary_tool_type(primary_tool_type),
time(time),
x(x),
y(y),
......@@ -34,6 +36,7 @@ GestureEventData::GestureEventData(EventType type,
const GestureEventData& other)
: details(type, 0, 0),
motion_event_id(other.motion_event_id),
primary_tool_type(other.primary_tool_type),
time(other.time),
x(other.x),
y(other.y),
......@@ -44,7 +47,12 @@ GestureEventData::GestureEventData(EventType type,
}
GestureEventData::GestureEventData()
: motion_event_id(0), x(0), y(0), raw_x(0), raw_y(0) {
: motion_event_id(0),
primary_tool_type(MotionEvent::TOOL_TYPE_UNKNOWN),
x(0),
y(0),
raw_x(0),
raw_y(0) {
}
} // namespace ui
......@@ -8,6 +8,7 @@
#include "base/time/time.h"
#include "ui/events/event_constants.h"
#include "ui/events/gesture_detection/gesture_detection_export.h"
#include "ui/events/gesture_detection/motion_event.h"
#include "ui/events/gesture_event_details.h"
namespace ui {
......@@ -17,6 +18,7 @@ class GestureEventDataPacket;
struct GESTURE_DETECTION_EXPORT GestureEventData {
GestureEventData(const GestureEventDetails&,
int motion_event_id,
MotionEvent::ToolType primary_tool_type,
base::TimeTicks time,
float x,
float y,
......@@ -30,6 +32,7 @@ struct GESTURE_DETECTION_EXPORT GestureEventData {
GestureEventDetails details;
int motion_event_id;
MotionEvent::ToolType primary_tool_type;
base::TimeTicks time;
float x;
float y;
......
......@@ -18,6 +18,7 @@ const float kTouchY = 14.2f;
GestureEventData CreateGesture(EventType type) {
return GestureEventData(GestureEventDetails(type, 0, 0),
0,
MotionEvent::TOOL_TYPE_FINGER,
base::TimeTicks(),
kTouchX,
kTouchY,
......@@ -31,9 +32,10 @@ GestureEventData CreateGesture(EventType type) {
bool GestureEquals(const GestureEventData& lhs, const GestureEventData& rhs) {
return lhs.type() == rhs.type() &&
lhs.motion_event_id == rhs.motion_event_id && lhs.time == rhs.time &&
lhs.x == rhs.x && lhs.y == rhs.y && lhs.raw_x == rhs.raw_x &&
lhs.raw_y == rhs.raw_y;
lhs.motion_event_id == rhs.motion_event_id &&
lhs.primary_tool_type == rhs.primary_tool_type &&
lhs.time == rhs.time && lhs.x == rhs.x && lhs.y == rhs.y &&
lhs.raw_x == rhs.raw_x && lhs.raw_y == rhs.raw_y;
}
bool PacketEquals(const GestureEventDataPacket& lhs,
......
......@@ -50,6 +50,7 @@ gfx::RectF GetBoundingBox(const MotionEvent& event) {
GestureEventData CreateGesture(const GestureEventDetails& details,
int motion_event_id,
MotionEvent::ToolType primary_tool_type,
base::TimeTicks time,
float x,
float y,
......@@ -59,6 +60,7 @@ GestureEventData CreateGesture(const GestureEventDetails& details,
const gfx::RectF& bounding_box) {
return GestureEventData(details,
motion_event_id,
primary_tool_type,
time,
x,
y,
......@@ -70,6 +72,7 @@ GestureEventData CreateGesture(const GestureEventDetails& details,
GestureEventData CreateGesture(EventType type,
int motion_event_id,
MotionEvent::ToolType primary_tool_type,
base::TimeTicks time,
float x,
float y,
......@@ -79,6 +82,7 @@ GestureEventData CreateGesture(EventType type,
const gfx::RectF& bounding_box) {
return GestureEventData(GestureEventDetails(type, 0, 0),
motion_event_id,
primary_tool_type,
time,
x,
y,
......@@ -92,6 +96,7 @@ GestureEventData CreateGesture(const GestureEventDetails& details,
const MotionEvent& event) {
return GestureEventData(details,
event.GetId(),
event.GetToolType(),
event.GetEventTime(),
event.GetX(),
event.GetY(),
......@@ -194,6 +199,7 @@ class GestureProvider::ScaleGestureListenerImpl
pinch_event_sent_ = true;
provider_->Send(CreateGesture(ET_GESTURE_PINCH_BEGIN,
e.GetId(),
e.GetToolType(),
detector.GetEventTime(),
detector.GetFocusX(),
detector.GetFocusY(),
......@@ -227,6 +233,7 @@ class GestureProvider::ScaleGestureListenerImpl
GestureEventDetails pinch_details(ET_GESTURE_PINCH_UPDATE, scale, 0);
provider_->Send(CreateGesture(pinch_details,
e.GetId(),
e.GetToolType(),
detector.GetEventTime(),
detector.GetFocusX(),
detector.GetFocusY(),
......@@ -368,6 +375,7 @@ class GestureProvider::GestureListenerImpl
// used to determine which layer the scroll should affect.
provider_->Send(CreateGesture(scroll_details,
e2.GetId(),
e2.GetToolType(),
e2.GetEventTime(),
e1.GetX(),
e1.GetY(),
......@@ -386,6 +394,7 @@ class GestureProvider::GestureListenerImpl
ET_GESTURE_SCROLL_UPDATE, -distance_x, -distance_y);
provider_->Send(CreateGesture(scroll_details,
e2.GetId(),
e2.GetToolType(),
e2.GetEventTime(),
center.x(),
center.y(),
......@@ -432,6 +441,7 @@ class GestureProvider::GestureListenerImpl
e1.GetTouchMajor());
provider_->Send(CreateGesture(two_finger_tap_details,
e2.GetId(),
e2.GetToolType(),
e2.GetEventTime(),
e1.GetX(),
e1.GetY(),
......@@ -685,12 +695,13 @@ void GestureProvider::Send(GestureEventData gesture) {
gesture.type() == ET_GESTURE_SHOW_PRESS ||
gesture.type() == ET_GESTURE_END);
// TODO(jdduke): Provide a way of skipping this clamping for stylus and/or
// mouse-based input, perhaps by exposing the source type on MotionEvent.
gesture.details.set_bounding_box(
ClampBoundingBox(gesture.details.bounding_box_f(),
min_gesture_bounds_length_,
max_gesture_bounds_length_));
if (gesture.primary_tool_type == MotionEvent::TOOL_TYPE_UNKNOWN ||
gesture.primary_tool_type == MotionEvent::TOOL_TYPE_FINGER) {
gesture.details.set_bounding_box(
ClampBoundingBox(gesture.details.bounding_box_f(),
min_gesture_bounds_length_,
max_gesture_bounds_length_));
}
switch (gesture.type()) {
case ET_GESTURE_LONG_PRESS:
......@@ -768,6 +779,7 @@ void GestureProvider::OnTouchEventHandlingBegin(const MotionEvent& event) {
const int action_index = event.GetActionIndex();
Send(CreateGesture(ET_GESTURE_BEGIN,
event.GetId(),
event.GetToolType(),
event.GetEventTime(),
event.GetX(action_index),
event.GetY(action_index),
......
......@@ -49,6 +49,8 @@ class GESTURE_DETECTION_EXPORT GestureProvider {
// The min and max size (both length and width, in dips) of the generated
// bounding box for all gesture types. This is useful for touch streams
// that may report zero or unreasonably small or large touch sizes.
// Note that these bounds are only applied for touch or unknown tool types;
// mouse and stylus-derived gestures will not be affected.
// Both values default to 0 (disabled).
float min_gesture_bounds_length;
float max_gesture_bounds_length;
......
......@@ -252,14 +252,10 @@ class GestureProviderTest : public testing::Test, public GestureProviderClient {
SetUpWithConfig(config);
}
void SetMinGestureBoundsLength(float min_gesture_bound_length) {
void SetMinMaxGestureBoundsLength(float min_gesture_bound_length,
float max_gesture_bound_length) {
GestureProvider::Config config = GetDefaultConfig();
config.min_gesture_bounds_length = min_gesture_bound_length;
SetUpWithConfig(config);
}
void SetMaxGestureBoundsLength(float max_gesture_bound_length) {
GestureProvider::Config config = GetDefaultConfig();
config.max_gesture_bounds_length = max_gesture_bound_length;
SetUpWithConfig(config);
}
......@@ -284,12 +280,15 @@ class GestureProviderTest : public testing::Test, public GestureProviderClient {
MotionEvent::ACTION_MOVE,
scroll_to_x,
scroll_to_y);
event.SetToolType(0, MotionEvent::TOOL_TYPE_FINGER);
event.set_id(++motion_event_id);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_TRUE(gesture_provider_->IsScrollInProgress());
EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN));
EXPECT_EQ(motion_event_id, GetMostRecentGestureEvent().motion_event_id);
EXPECT_EQ(event.GetToolType(0),
GetMostRecentGestureEvent().primary_tool_type);
EXPECT_EQ(ET_GESTURE_SCROLL_UPDATE, GetMostRecentGestureEventType());
EXPECT_EQ(BoundsForSingleMockTouchAtLocation(scroll_to_x, scroll_to_y),
GetMostRecentGestureEvent().details.bounding_box());
......@@ -304,6 +303,7 @@ class GestureProviderTest : public testing::Test, public GestureProviderClient {
event = ObtainMotionEvent(
event_time + kOneSecond, end_action_type, scroll_to_x, scroll_to_y);
event.SetToolType(0, MotionEvent::TOOL_TYPE_FINGER);
event.set_id(++motion_event_id);
gesture_provider_->OnTouchEvent(event);
......@@ -311,6 +311,8 @@ class GestureProviderTest : public testing::Test, public GestureProviderClient {
EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_END));
EXPECT_EQ(ET_GESTURE_SCROLL_END, GetMostRecentGestureEventType());
EXPECT_EQ(motion_event_id, GetMostRecentGestureEvent().motion_event_id);
EXPECT_EQ(event.GetToolType(0),
GetMostRecentGestureEvent().primary_tool_type);
EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
EXPECT_EQ(BoundsForSingleMockTouchAtLocation(scroll_to_x, scroll_to_y),
GetMostRecentGestureEvent().details.bounding_box());
......@@ -409,22 +411,28 @@ TEST_F(GestureProviderTest, GestureTap) {
MockMotionEvent event =
ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
event.SetToolType(0, MotionEvent::TOOL_TYPE_FINGER);
event.set_id(++motion_event_id);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
EXPECT_EQ(event.GetToolType(0),
GetMostRecentGestureEvent().primary_tool_type);
EXPECT_EQ(BoundsForSingleMockTouchAtLocation(kFakeCoordX, kFakeCoordY),
GetMostRecentGestureEvent().details.bounding_box());
event = ObtainMotionEvent(event_time + kOneMicrosecond,
MotionEvent::ACTION_UP);
event.SetToolType(0, MotionEvent::TOOL_TYPE_FINGER);
event.set_id(++motion_event_id);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(ET_GESTURE_TAP, GetMostRecentGestureEventType());
// Ensure tap details have been set.
EXPECT_EQ(1, GetMostRecentGestureEvent().details.tap_count());
EXPECT_EQ(event.GetToolType(0),
GetMostRecentGestureEvent().primary_tool_type);
EXPECT_EQ(motion_event_id, GetMostRecentGestureEvent().motion_event_id);
EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
EXPECT_EQ(BoundsForSingleMockTouchAtLocation(kFakeCoordX, kFakeCoordY),
......@@ -2290,7 +2298,7 @@ TEST_F(GestureProviderTest, PinchZoomWithThreshold) {
// Verify that the min gesture bound setting is honored.
TEST_F(GestureProviderTest, MinGestureBoundsLength) {
const float kMinGestureBoundsLength = 10.f * kMockTouchRadius;
SetMinGestureBoundsLength(kMinGestureBoundsLength);
SetMinMaxGestureBoundsLength(kMinGestureBoundsLength, 0.f);
gesture_provider_->SetDoubleTapSupportForPlatformEnabled(false);
base::TimeTicks event_time = base::TimeTicks::Now();
......@@ -2316,7 +2324,7 @@ TEST_F(GestureProviderTest, MinGestureBoundsLength) {
TEST_F(GestureProviderTest, MaxGestureBoundsLength) {
const float kMaxGestureBoundsLength = kMockTouchRadius / 10.f;
SetMaxGestureBoundsLength(kMaxGestureBoundsLength);
SetMinMaxGestureBoundsLength(0.f, kMaxGestureBoundsLength);
gesture_provider_->SetDoubleTapSupportForPlatformEnabled(false);
base::TimeTicks event_time = base::TimeTicks::Now();
......@@ -2363,4 +2371,63 @@ TEST_F(GestureProviderTest, ZeroRadiusBoundingBox) {
GetMostRecentGestureEvent().details.bounding_box());
}
// Verify that the min/max gesture bound settings are not applied to stylus
// or mouse-derived MotionEvents.
TEST_F(GestureProviderTest, NoMinOrMaxGestureBoundsLengthWithStylusOrMouse) {
const float kMinGestureBoundsLength = 5.f * kMockTouchRadius;
const float kMaxGestureBoundsLength = 10.f * kMockTouchRadius;
SetMinMaxGestureBoundsLength(kMinGestureBoundsLength,
kMaxGestureBoundsLength);
gesture_provider_->SetDoubleTapSupportForPlatformEnabled(false);
base::TimeTicks event_time = base::TimeTicks::Now();
MockMotionEvent event =
ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
event.SetTouchMajor(0);
event.SetToolType(0, MotionEvent::TOOL_TYPE_MOUSE);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
EXPECT_EQ(MotionEvent::TOOL_TYPE_MOUSE,
GetMostRecentGestureEvent().primary_tool_type);
EXPECT_EQ(0.f, GetMostRecentGestureEvent().details.bounding_box_f().width());
EXPECT_EQ(0.f, GetMostRecentGestureEvent().details.bounding_box_f().height());
event =
ObtainMotionEvent(event_time + kOneMicrosecond, MotionEvent::ACTION_UP);
event.SetTouchMajor(1);
event.SetToolType(0, MotionEvent::TOOL_TYPE_STYLUS);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(ET_GESTURE_TAP, GetMostRecentGestureEventType());
EXPECT_EQ(MotionEvent::TOOL_TYPE_STYLUS,
GetMostRecentGestureEvent().primary_tool_type);
EXPECT_EQ(1.f, GetMostRecentGestureEvent().details.bounding_box_f().width());
EXPECT_EQ(1.f, GetMostRecentGestureEvent().details.bounding_box_f().height());
event = ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
event.SetTouchMajor(2.f * kMaxGestureBoundsLength);
event.SetToolType(0, MotionEvent::TOOL_TYPE_MOUSE);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(MotionEvent::TOOL_TYPE_MOUSE,
GetMostRecentGestureEvent().primary_tool_type);
EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
EXPECT_EQ(2.f * kMaxGestureBoundsLength,
GetMostRecentGestureEvent().details.bounding_box_f().width());
EXPECT_EQ(2.f * kMaxGestureBoundsLength,
GetMostRecentGestureEvent().details.bounding_box_f().height());
event =
ObtainMotionEvent(event_time + kOneMicrosecond, MotionEvent::ACTION_UP);
event.SetTouchMajor(2.f * kMaxGestureBoundsLength);
event.SetToolType(0, MotionEvent::TOOL_TYPE_ERASER);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(ET_GESTURE_TAP, GetMostRecentGestureEventType());
EXPECT_EQ(MotionEvent::TOOL_TYPE_ERASER,
GetMostRecentGestureEvent().primary_tool_type);
EXPECT_EQ(2.f * kMaxGestureBoundsLength,
GetMostRecentGestureEvent().details.bounding_box_f().width());
EXPECT_EQ(2.f * kMaxGestureBoundsLength,
GetMostRecentGestureEvent().details.bounding_box_f().height());
}
} // namespace ui
......@@ -29,6 +29,7 @@ class GESTURE_DETECTION_EXPORT MotionEvent {
TOOL_TYPE_FINGER,
TOOL_TYPE_STYLUS,
TOOL_TYPE_MOUSE,
TOOL_TYPE_ERASER
};
enum ButtonType {
......@@ -83,6 +84,7 @@ class GESTURE_DETECTION_EXPORT MotionEvent {
float GetRawOffsetY() const { return GetRawY() - GetY(); }
float GetTouchMajor() const { return GetTouchMajor(0); }
float GetPressure() const { return GetPressure(0); }
ToolType GetToolType() const { return GetToolType(0); }
// O(N) search of pointers (use sparingly!). Returns -1 if |id| nonexistent.
int FindPointerIndexOfId(int id) const;
......
......@@ -17,9 +17,11 @@ COMPILE_ASSERT(ET_GESTURE_TYPE_END - ET_GESTURE_TYPE_START < 32,
GestureEventData CreateGesture(EventType type,
int motion_event_id,
MotionEvent::ToolType primary_tool_type,
const GestureEventDataPacket& packet) {
return GestureEventData(GestureEventDetails(type, 0, 0),
motion_event_id,
primary_tool_type,
packet.timestamp(),
packet.touch_location().x(),
packet.touch_location().y(),
......@@ -128,6 +130,8 @@ bool IsTouchStartEvent(GestureEventDataPacket::GestureSource gesture_source) {
TouchDispositionGestureFilter::TouchDispositionGestureFilter(
TouchDispositionGestureFilterClient* client)
: client_(client),
ending_event_motion_event_id_(0),
ending_event_primary_tool_type_(MotionEvent::TOOL_TYPE_UNKNOWN),
needs_tap_ending_event_(false),
needs_show_press_event_(false),
needs_fling_ending_event_(false),
......@@ -259,6 +263,7 @@ void TouchDispositionGestureFilter::SendGesture(
case ET_GESTURE_TAP_DOWN:
DCHECK(!needs_tap_ending_event_);
ending_event_motion_event_id_ = event.motion_event_id;
ending_event_primary_tool_type_ = event.primary_tool_type;
needs_show_press_event_ = true;
needs_tap_ending_event_ = true;
break;
......@@ -289,6 +294,7 @@ void TouchDispositionGestureFilter::SendGesture(
CancelFlingIfNecessary(packet_being_sent);
EndScrollIfNecessary(packet_being_sent);
ending_event_motion_event_id_ = event.motion_event_id;
ending_event_primary_tool_type_ = event.primary_tool_type;
needs_scroll_ending_event_ = true;
break;
case ET_GESTURE_SCROLL_END:
......@@ -297,6 +303,7 @@ void TouchDispositionGestureFilter::SendGesture(
case ET_SCROLL_FLING_START:
CancelFlingIfNecessary(packet_being_sent);
ending_event_motion_event_id_ = event.motion_event_id;
ending_event_primary_tool_type_ = event.primary_tool_type;
needs_fling_ending_event_ = true;
needs_scroll_ending_event_ = false;
break;
......@@ -316,6 +323,7 @@ void TouchDispositionGestureFilter::CancelTapIfNecessary(
SendGesture(CreateGesture(ET_GESTURE_TAP_CANCEL,
ending_event_motion_event_id_,
ending_event_primary_tool_type_,
packet_being_sent),
packet_being_sent);
DCHECK(!needs_tap_ending_event_);
......@@ -328,6 +336,7 @@ void TouchDispositionGestureFilter::CancelFlingIfNecessary(
SendGesture(CreateGesture(ET_SCROLL_FLING_CANCEL,
ending_event_motion_event_id_,
ending_event_primary_tool_type_,
packet_being_sent),
packet_being_sent);
DCHECK(!needs_fling_ending_event_);
......@@ -340,6 +349,7 @@ void TouchDispositionGestureFilter::EndScrollIfNecessary(
SendGesture(CreateGesture(ET_GESTURE_SCROLL_END,
ending_event_motion_event_id_,
ending_event_primary_tool_type_,
packet_being_sent),
packet_being_sent);
DCHECK(!needs_scroll_ending_event_);
......
......@@ -95,6 +95,7 @@ class GESTURE_DETECTION_EXPORT TouchDispositionGestureFilter {
// when necessary, e.g., GestureTapCancel when scrolling begins, or
// GestureFlingCancel when a user taps following a GestureFlingStart.
int ending_event_motion_event_id_;
MotionEvent::ToolType ending_event_primary_tool_type_;
bool needs_tap_ending_event_;
bool needs_show_press_event_;
bool needs_fling_ending_event_;
......
......@@ -202,6 +202,7 @@ class TouchDispositionGestureFilterTest
GestureEventData CreateGesture(EventType type) {
return GestureEventData(GestureEventDetails(type, 0, 0),
0,
MotionEvent::TOOL_TYPE_FINGER,
base::TimeTicks(),
touch_event_.GetX(0),
touch_event_.GetY(0),
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment