Commit b5a33976 authored by jdduke's avatar jdduke Committed by Commit bot

Remove abstract Clone and Cancel methods from MotionEvent

Create a single implementation of MotionEvent's |Clone()| and
|Cancel()| methods using MotionEventGeneric. Expand
MotionEventGeneric to support historical events, also removing
CompoundMotionEvent from the MotionEventBuffer implementation.

By avoiding JNI and garbage creation, this reduces the cost of both
methods by ~10x on Android, from ~25us call to ~2us.

BUG=501503003

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

Cr-Commit-Position: refs/heads/master@{#301136}
parent 45eeb4a8
......@@ -866,6 +866,20 @@ jboolean ContentViewCoreImpl::OnTouchEvent(JNIEnv* env,
if (!rwhv)
return false;
MotionEventAndroid::Pointer pointer0(pointer_id_0,
pos_x_0,
pos_y_0,
touch_major_0,
touch_minor_0,
orientation_0,
android_tool_type_0);
MotionEventAndroid::Pointer pointer1(pointer_id_1,
pos_x_1,
pos_y_1,
touch_major_1,
touch_minor_1,
orientation_1,
android_tool_type_1);
MotionEventAndroid event(1.f / dpi_scale(),
env,
motion_event,
......@@ -874,24 +888,12 @@ jboolean ContentViewCoreImpl::OnTouchEvent(JNIEnv* env,
pointer_count,
history_size,
action_index,
pos_x_0,
pos_y_0,
pos_x_1,
pos_y_1,
pointer_id_0,
pointer_id_1,
touch_major_0,
touch_major_1,
touch_minor_0,
touch_minor_1,
orientation_0,
orientation_1,
raw_pos_x,
raw_pos_y,
android_tool_type_0,
android_tool_type_1,
android_button_state,
android_meta_state);
android_meta_state,
raw_pos_x - pos_x_0,
raw_pos_y - pos_y_0,
pointer0,
pointer1);
return is_touch_handle_event ? rwhv->OnTouchHandleEvent(event)
: rwhv->OnTouchEvent(event);
......
......@@ -11,7 +11,7 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/events/event_constants.h"
#include "ui/events/gesture_detection/motion_event.h"
#include "ui/events/test/mock_motion_event.h"
#include "ui/events/test/motion_event_test_utils.h"
#include "ui/gfx/geometry/rect_f.h"
using ui::MotionEvent;
......
// 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.
......@@ -21,6 +22,23 @@ namespace content {
// while all *output* coordinates are in DIPs (as with WebTouchEvent).
class CONTENT_EXPORT MotionEventAndroid : public ui::MotionEvent {
public:
struct Pointer {
Pointer(jint id,
jfloat pos_x_pixels,
jfloat pos_y_pixels,
jfloat touch_major_pixels,
jfloat touch_minor_pixels,
jfloat orientation_rad,
jint tool_type);
jint id;
jfloat pos_x_pixels;
jfloat pos_y_pixels;
jfloat touch_major_pixels;
jfloat touch_minor_pixels;
jfloat orientation_rad;
jint tool_type;
};
// Forcing the caller to provide all cached values upon construction
// eliminates the need to perform a JNI call to retrieve values individually.
MotionEventAndroid(float pix_to_dip,
......@@ -31,24 +49,12 @@ class CONTENT_EXPORT MotionEventAndroid : public ui::MotionEvent {
jint pointer_count,
jint history_size,
jint action_index,
jfloat pos_x_0_pixels,
jfloat pos_y_0_pixels,
jfloat pos_x_1_pixels,
jfloat pos_y_1_pixels,
jint pointer_id_0,
jint pointer_id_1,
jfloat touch_major_0_pixels,
jfloat touch_major_1_pixels,
jfloat touch_minor_0_pixels,
jfloat touch_minor_1_pixels,
jfloat orientation_0_rad,
jfloat orientation_1_rad,
jfloat raw_pos_x_pixels,
jfloat raw_pos_y_pixels,
jint android_tool_type_0,
jint android_tool_type_1,
jint android_button_state,
jint meta_state);
jint meta_state,
jfloat raw_offset_x_pixels,
jfloat raw_offset_y_pixels,
const Pointer& pointer0,
const Pointer& pointer1);
virtual ~MotionEventAndroid();
// ui::MotionEvent methods.
......@@ -78,31 +84,14 @@ class CONTENT_EXPORT MotionEventAndroid : public ui::MotionEvent {
virtual ToolType GetToolType(size_t pointer_index) const override;
virtual int GetButtonState() const override;
virtual int GetFlags() const override;
virtual scoped_ptr<MotionEvent> Clone() const override;
virtual scoped_ptr<MotionEvent> Cancel() const override;
// Additional Android MotionEvent methods.
base::TimeTicks GetDownTime() const;
static bool RegisterMotionEventAndroid(JNIEnv* env);
static base::android::ScopedJavaLocalRef<jobject> Obtain(
const MotionEventAndroid& event);
static base::android::ScopedJavaLocalRef<jobject> Obtain(
base::TimeTicks down_time,
base::TimeTicks event_time,
Action action,
float x_pixels,
float y_pixels);
private:
MotionEventAndroid();
MotionEventAndroid(float pix_to_dip, JNIEnv* env, jobject event);
MotionEventAndroid(const MotionEventAndroid&);
MotionEventAndroid& operator=(const MotionEventAndroid&);
struct CachedPointer;
float ToDips(float pixels) const;
gfx::PointF ToDips(const gfx::PointF& pixels) const;
CachedPointer FromAndroidPointer(const Pointer& pointer) const;
// Cache pointer coords, id's and major lengths for the most common
// touch-related scenarios, i.e., scrolling and pinching. This prevents
......@@ -112,28 +101,29 @@ class CONTENT_EXPORT MotionEventAndroid : public ui::MotionEvent {
// The Java reference to the underlying MotionEvent.
base::android::ScopedJavaGlobalRef<jobject> event_;
base::TimeTicks cached_time_;
Action cached_action_;
size_t cached_pointer_count_;
size_t cached_history_size_;
int cached_action_index_;
gfx::PointF cached_positions_[MAX_POINTERS_TO_CACHE];
int cached_pointer_ids_[MAX_POINTERS_TO_CACHE];
float cached_touch_majors_[MAX_POINTERS_TO_CACHE];
float cached_touch_minors_[MAX_POINTERS_TO_CACHE];
float cached_orientations_[MAX_POINTERS_TO_CACHE];
gfx::Vector2dF cached_raw_position_offset_;
ToolType cached_tool_types_[MAX_POINTERS_TO_CACHE];
int cached_button_state_;
int cached_flags_;
// Used to convert pixel coordinates from the Java-backed MotionEvent to
// DIP coordinates cached/returned by the MotionEventAndroid.
const float pix_to_dip_;
// Whether |event_| should be recycled on destruction. This will only be true
// for those events generated via |Obtain(...)|.
bool should_recycle_;
const base::TimeTicks cached_time_;
const Action cached_action_;
const size_t cached_pointer_count_;
const size_t cached_history_size_;
const int cached_action_index_;
const int cached_button_state_;
const int cached_flags_;
const gfx::Vector2dF cached_raw_position_offset_;
struct CachedPointer {
CachedPointer();
int id;
gfx::PointF position;
float touch_major;
float touch_minor;
float orientation;
ToolType tool_type;
} cached_pointers_[MAX_POINTERS_TO_CACHE];
DISALLOW_COPY_AND_ASSIGN(MotionEventAndroid);
};
} // namespace content
......
......@@ -155,7 +155,6 @@ ui::MotionEvent::ToolType MotionEventWeb::GetToolType(
}
int MotionEventWeb::GetButtonState() const {
NOTIMPLEMENTED();
return 0;
}
......@@ -163,18 +162,4 @@ int MotionEventWeb::GetFlags() const {
return WebEventModifiersToEventFlags(event_.modifiers);
}
scoped_ptr<ui::MotionEvent> MotionEventWeb::Clone() const {
return scoped_ptr<MotionEvent>(new MotionEventWeb(event_));
}
scoped_ptr<ui::MotionEvent> MotionEventWeb::Cancel() const {
WebTouchEvent cancel_event(event_);
WebTouchEventTraits::ResetTypeAndTouchStates(
blink::WebInputEvent::TouchCancel,
// TODO(rbyers): Shouldn't we use a fresh timestamp?
event_.timeStampSeconds,
&cancel_event);
return scoped_ptr<MotionEvent>(new MotionEventWeb(cancel_event));
}
} // namespace content
......@@ -34,8 +34,6 @@ class MotionEventWeb : public ui::MotionEvent {
ToolType GetToolType(size_t pointer_index) const override;
int GetButtonState() const override;
int GetFlags() const override;
scoped_ptr<MotionEvent> Clone() const override;
scoped_ptr<MotionEvent> Cancel() const override;
private:
blink::WebTouchEvent event_;
......
......@@ -5,7 +5,7 @@
#include "content/browser/renderer_host/input/touch_handle.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/events/test/mock_motion_event.h"
#include "ui/events/test/motion_event_test_utils.h"
#include "ui/gfx/geometry/rect_f.h"
using ui::test::MockMotionEvent;
......
......@@ -5,7 +5,7 @@
#include "content/browser/renderer_host/input/touch_selection_controller.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/events/test/mock_motion_event.h"
#include "ui/events/test/motion_event_test_utils.h"
using ui::test::MockMotionEvent;
......
......@@ -24,13 +24,12 @@ using ui::MotionEventGeneric;
namespace content {
TEST(WebInputEventUtilTest, MotionEventConversion) {
ui::PointerProperties pointer(5, 10);
ui::PointerProperties pointer(5, 10, 40);
pointer.id = 15;
pointer.raw_x = 20;
pointer.raw_y = 25;
pointer.pressure = 30;
pointer.touch_minor = 35;
pointer.touch_major = 40;
pointer.orientation = static_cast<float>(-M_PI / 2);
MotionEventGeneric event(
MotionEvent::ACTION_DOWN, base::TimeTicks::Now(), pointer);
......
......@@ -238,8 +238,8 @@ source_set("test_support") {
"test/event_generator.h",
"test/events_test_utils.cc",
"test/events_test_utils.h",
"test/mock_motion_event.cc",
"test/mock_motion_event.h",
"test/motion_event_test_utils.cc",
"test/motion_event_test_utils.h",
"test/platform_event_waiter.cc",
"test/platform_event_waiter.h",
"test/test_event_handler.cc",
......
......@@ -4,3 +4,4 @@ per-file latency_info*=miletus@chromium.org
# If you're doing structural changes get a review from one of the OWNERS.
per-file *.gyp*=*
per-file BUILD.gn=*
......@@ -274,8 +274,8 @@
'test/events_test_utils.h',
'test/events_test_utils_x11.cc',
'test/events_test_utils_x11.h',
'test/mock_motion_event.cc',
'test/mock_motion_event.h',
'test/motion_event_test_utils.cc',
'test/motion_event_test_utils.h',
'test/platform_event_waiter.cc',
'test/platform_event_waiter.h',
'test/test_event_handler.cc',
......
......@@ -87,7 +87,7 @@ struct BitSet32 {
return n;
}
// Gets the inde of the specified bit in the set, which is the number of
// Gets the index of the specified bit in the set, which is the number of
// marked bits that appear before the specified bit.
inline uint32_t get_index_of_bit(uint32_t n) const {
DCHECK_LE(n, 31U);
......
......@@ -5,7 +5,7 @@
#include "base/basictypes.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/events/gesture_detection/gesture_event_data_packet.h"
#include "ui/events/test/mock_motion_event.h"
#include "ui/events/test/motion_event_test_utils.h"
using ui::test::MockMotionEvent;
......
......@@ -12,7 +12,7 @@
#include "ui/events/gesture_detection/gesture_event_data.h"
#include "ui/events/gesture_detection/gesture_provider.h"
#include "ui/events/gesture_detection/motion_event.h"
#include "ui/events/test/mock_motion_event.h"
#include "ui/events/test/motion_event_test_utils.h"
#include "ui/gfx/geometry/point_f.h"
using base::TimeDelta;
......
......@@ -5,6 +5,7 @@
#include "ui/events/gesture_detection/motion_event.h"
#include "base/logging.h"
#include "ui/events/gesture_detection/motion_event_generic.h"
namespace ui {
......@@ -45,49 +46,12 @@ int MotionEvent::FindPointerIndexOfId(int id) const {
return -1;
}
bool operator==(const MotionEvent& lhs, const MotionEvent& rhs) {
if (lhs.GetId() != rhs.GetId() || lhs.GetAction() != rhs.GetAction() ||
lhs.GetActionIndex() != rhs.GetActionIndex() ||
lhs.GetPointerCount() != rhs.GetPointerCount() ||
lhs.GetButtonState() != rhs.GetButtonState() ||
lhs.GetEventTime() != rhs.GetEventTime() ||
lhs.GetHistorySize() != rhs.GetHistorySize())
return false;
for (size_t i = 0; i < lhs.GetPointerCount(); ++i) {
int rhsi = rhs.FindPointerIndexOfId(lhs.GetPointerId(i));
if (rhsi == -1)
return false;
if (lhs.GetX(i) != rhs.GetX(rhsi) || lhs.GetY(i) != rhs.GetY(rhsi) ||
lhs.GetRawX(i) != rhs.GetRawX(rhsi) ||
lhs.GetRawY(i) != rhs.GetRawY(rhsi) ||
lhs.GetTouchMajor(i) != rhs.GetTouchMajor(rhsi) ||
lhs.GetTouchMinor(i) != rhs.GetTouchMinor(rhsi) ||
lhs.GetOrientation(i) != rhs.GetOrientation(rhsi) ||
lhs.GetPressure(i) != rhs.GetPressure(rhsi) ||
lhs.GetToolType(i) != rhs.GetToolType(rhsi))
return false;
for (size_t h = 0; h < lhs.GetHistorySize(); ++h) {
if (lhs.GetHistoricalX(i, h) != rhs.GetHistoricalX(rhsi, h) ||
lhs.GetHistoricalY(i, h) != rhs.GetHistoricalY(rhsi, h) ||
lhs.GetHistoricalTouchMajor(i, h) !=
rhs.GetHistoricalTouchMajor(rhsi, h))
return false;
}
}
for (size_t h = 0; h < lhs.GetHistorySize(); ++h) {
if (lhs.GetHistoricalEventTime(h) != rhs.GetHistoricalEventTime(h))
return false;
}
return true;
scoped_ptr<MotionEvent> MotionEvent::Clone() const {
return MotionEventGeneric::CloneEvent(*this);
}
bool operator!=(const MotionEvent& lhs, const MotionEvent& rhs) {
return !(lhs == rhs);
scoped_ptr<MotionEvent> MotionEvent::Cancel() const {
return MotionEventGeneric::CancelEvent(*this);
}
} // namespace ui
......@@ -76,9 +76,7 @@ class GESTURE_DETECTION_EXPORT MotionEvent {
virtual float GetHistoricalY(size_t pointer_index,
size_t historical_index) const;
virtual scoped_ptr<MotionEvent> Clone() const = 0;
virtual scoped_ptr<MotionEvent> Cancel() const = 0;
// Utility accessor methods for convenience.
float GetX() const { return GetX(0); }
float GetY() const { return GetY(0); }
float GetRawX() const { return GetRawX(0); }
......@@ -98,12 +96,14 @@ class GESTURE_DETECTION_EXPORT MotionEvent {
// O(N) search of pointers (use sparingly!). Returns -1 if |id| nonexistent.
int FindPointerIndexOfId(int id) const;
};
GESTURE_DETECTION_EXPORT bool operator==(const MotionEvent& lhs,
const MotionEvent& rhs);
GESTURE_DETECTION_EXPORT bool operator!=(const MotionEvent& lhs,
const MotionEvent& rhs);
// Note that these methods perform shallow copies of the originating events.
// They guarantee only that the returned type will reflect the same
// data exposed by the MotionEvent interface; no guarantees are made that the
// underlying implementation is identical to the source implementation.
scoped_ptr<MotionEvent> Clone() const;
scoped_ptr<MotionEvent> Cancel() const;
};
} // namespace ui
......
......@@ -13,6 +13,7 @@
namespace ui {
class MotionEvent;
class MotionEventGeneric;
// Allows event forwarding and flush requests from a |MotionEventBuffer|.
class MotionEventBufferClient {
......@@ -52,8 +53,10 @@ class GESTURE_DETECTION_EXPORT MotionEventBuffer {
void Flush(base::TimeTicks frame_time);
private:
typedef ScopedVector<MotionEvent> MotionEventVector;
typedef ScopedVector<MotionEventGeneric> MotionEventVector;
void FlushWithResampling(MotionEventVector events,
base::TimeTicks resample_time);
void FlushWithoutResampling(MotionEventVector events);
MotionEventBufferClient* const client_;
......@@ -61,7 +64,7 @@ class GESTURE_DETECTION_EXPORT MotionEventBuffer {
// Time of the most recently extrapolated event. This will be 0 if the
// last sent event was not extrapolated. Used internally to guard against
// conflicts between events received from the platfrom that may have an
// conflicts between events received from the platform that may have an
// earlier timestamp than that synthesized at the latest resample.
base::TimeTicks last_extrapolated_event_time_;
......
......@@ -7,7 +7,7 @@
#include "base/time/time.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/events/gesture_detection/motion_event_buffer.h"
#include "ui/events/test/mock_motion_event.h"
#include "ui/events/test/motion_event_test_utils.h"
using base::TimeDelta;
using base::TimeTicks;
......@@ -41,14 +41,14 @@ class MotionEventBufferTest : public testing::Test,
public MotionEventBufferClient {
public:
MotionEventBufferTest() : needs_flush_(false) {}
virtual ~MotionEventBufferTest() {}
~MotionEventBufferTest() override {}
// MotionEventBufferClient implementation.
virtual void ForwardMotionEvent(const MotionEvent& event) override {
void ForwardMotionEvent(const MotionEvent& event) override {
forwarded_events_.push_back(event.Clone().release());
}
virtual void SetNeedsFlush() override { needs_flush_ = true; }
void SetNeedsFlush() override { needs_flush_ = true; }
bool GetAndResetNeedsFlush() {
bool needs_flush = needs_flush_;
......@@ -344,9 +344,9 @@ TEST_F(MotionEventBufferTest, BufferFlushedOnIncompatibleActionMove) {
event_time += base::TimeDelta::FromMilliseconds(5);
// Events with different pointer ids should not combine.
PointerProperties pointer0(5.f, 5.f);
PointerProperties pointer0(5.f, 5.f, 1.f);
pointer0.id = 1;
PointerProperties pointer1(10.f, 10.f);
PointerProperties pointer1(10.f, 10.f, 2.f);
pointer1.id = 2;
MotionEventGeneric move3(MotionEvent::ACTION_MOVE, event_time, pointer0);
move3.PushPointer(pointer1);
......@@ -407,9 +407,9 @@ TEST_F(MotionEventBufferTest, OutOfOrderPointersBuffered) {
base::TimeTicks event_time = base::TimeTicks::Now();
MotionEventBuffer buffer(this, true);
PointerProperties p0(1.f, 2.f);
PointerProperties p0(1.f, 2.f, 3.f);
p0.id = 1;
PointerProperties p1(2.f, 1.f);
PointerProperties p1(2.f, 1.f, 0.5f);
p1.id = 2;
MotionEventGeneric move0(MotionEvent::ACTION_MOVE, event_time, p0);
......
......@@ -21,7 +21,7 @@ PointerProperties::PointerProperties()
orientation(0) {
}
PointerProperties::PointerProperties(float x, float y)
PointerProperties::PointerProperties(float x, float y, float touch_major)
: id(0),
tool_type(MotionEvent::TOOL_TYPE_UNKNOWN),
x(x),
......@@ -29,17 +29,23 @@ PointerProperties::PointerProperties(float x, float y)
raw_x(x),
raw_y(y),
pressure(0),
touch_major(0),
touch_major(touch_major),
touch_minor(0),
orientation(0) {
}
MotionEventGeneric::MotionEventGeneric()
: action_(ACTION_CANCEL),
id_(0),
action_index_(0),
button_state_(0),
flags_(0) {
PointerProperties::PointerProperties(const MotionEvent& event,
size_t pointer_index)
: id(event.GetPointerId(pointer_index)),
tool_type(event.GetToolType(pointer_index)),
x(event.GetX(pointer_index)),
y(event.GetY(pointer_index)),
raw_x(event.GetRawX(pointer_index)),
raw_y(event.GetRawY(pointer_index)),
pressure(event.GetPressure(pointer_index)),
touch_major(event.GetTouchMajor(pointer_index)),
touch_minor(event.GetTouchMinor(pointer_index)),
orientation(event.GetOrientation(pointer_index)) {
}
MotionEventGeneric::MotionEventGeneric(Action action,
......@@ -62,6 +68,9 @@ MotionEventGeneric::MotionEventGeneric(const MotionEventGeneric& other)
button_state_(other.button_state_),
flags_(other.flags_),
pointers_(other.pointers_) {
const size_t history_size = other.GetHistorySize();
for (size_t h = 0; h < history_size; ++h)
PushHistoricalEvent(other.historical_events_[h]->Clone());
}
MotionEventGeneric::~MotionEventGeneric() {
......@@ -146,20 +155,119 @@ base::TimeTicks MotionEventGeneric::GetEventTime() const {
return event_time_;
}
scoped_ptr<MotionEvent> MotionEventGeneric::Clone() const {
return scoped_ptr<MotionEvent>(new MotionEventGeneric(*this));
size_t MotionEventGeneric::GetHistorySize() const {
return historical_events_.size();
}
base::TimeTicks MotionEventGeneric::GetHistoricalEventTime(
size_t historical_index) const {
DCHECK_LT(historical_index, historical_events_.size());
return historical_events_[historical_index]->GetEventTime();
}
float MotionEventGeneric::GetHistoricalTouchMajor(
size_t pointer_index,
size_t historical_index) const {
DCHECK_LT(historical_index, historical_events_.size());
return historical_events_[historical_index]->GetTouchMajor(pointer_index);
}
float MotionEventGeneric::GetHistoricalX(size_t pointer_index,
size_t historical_index) const {
DCHECK_LT(historical_index, historical_events_.size());
return historical_events_[historical_index]->GetX(pointer_index);
}
float MotionEventGeneric::GetHistoricalY(size_t pointer_index,
size_t historical_index) const {
DCHECK_LT(historical_index, historical_events_.size());
return historical_events_[historical_index]->GetY(pointer_index);
}
scoped_ptr<MotionEvent> MotionEventGeneric::Cancel() const {
scoped_ptr<MotionEventGeneric> event(new MotionEventGeneric(*this));
event->set_action(ACTION_CANCEL);
return event.Pass();
// static
scoped_ptr<MotionEventGeneric> MotionEventGeneric::CloneEvent(
const MotionEvent& event) {
bool with_history = true;
return make_scoped_ptr(new MotionEventGeneric(event, with_history));
}
// static
scoped_ptr<MotionEventGeneric> MotionEventGeneric::CancelEvent(
const MotionEvent& event) {
bool with_history = false;
scoped_ptr<MotionEventGeneric> cancel_event(
new MotionEventGeneric(event, with_history));
cancel_event->set_action(ACTION_CANCEL);
return cancel_event.Pass();
}
void MotionEventGeneric::PushPointer(const PointerProperties& pointer) {
DCHECK_EQ(0U, GetHistorySize());
pointers_->push_back(pointer);
}
void MotionEventGeneric::PushHistoricalEvent(scoped_ptr<MotionEvent> event) {
DCHECK(event);
DCHECK_EQ(event->GetAction(), ACTION_MOVE);
DCHECK_EQ(event->GetPointerCount(), GetPointerCount());
DCHECK_EQ(event->GetAction(), GetAction());
DCHECK_LE(event->GetEventTime().ToInternalValue(),
GetEventTime().ToInternalValue());
historical_events_.push_back(event.release());
}
MotionEventGeneric::MotionEventGeneric()
: action_(ACTION_CANCEL), id_(0), action_index_(0), button_state_(0) {
}
MotionEventGeneric::MotionEventGeneric(const MotionEvent& event,
bool with_history)
: action_(event.GetAction()),
event_time_(event.GetEventTime()),
id_(event.GetId()),
action_index_(
(action_ == ACTION_POINTER_UP || action_ == ACTION_POINTER_DOWN)
? event.GetActionIndex()
: 0),
button_state_(event.GetButtonState()),
flags_(event.GetFlags()) {
const size_t pointer_count = event.GetPointerCount();
for (size_t i = 0; i < pointer_count; ++i)
PushPointer(PointerProperties(event, i));
if (!with_history)
return;
const size_t history_size = event.GetHistorySize();
for (size_t h = 0; h < history_size; ++h) {
scoped_ptr<MotionEventGeneric> historical_event(new MotionEventGeneric());
historical_event->set_action(ACTION_MOVE);
historical_event->set_event_time(event.GetHistoricalEventTime(h));
for (size_t i = 0; i < pointer_count; ++i) {
historical_event->PushPointer(
PointerProperties(event.GetHistoricalX(i, h),
event.GetHistoricalY(i, h),
event.GetHistoricalTouchMajor(i, h)));
}
PushHistoricalEvent(historical_event.Pass());
}
}
MotionEventGeneric& MotionEventGeneric::operator=(
const MotionEventGeneric& other) {
action_ = other.action_;
event_time_ = other.event_time_;
id_ = other.id_;
action_index_ = other.action_index_;
button_state_ = other.button_state_;
flags_ = other.flags_;
pointers_ = other.pointers_;
const size_t history_size = other.GetHistorySize();
for (size_t h = 0; h < history_size; ++h)
PushHistoricalEvent(other.historical_events_[h]->Clone());
return *this;
}
void MotionEventGeneric::PopPointer() {
DCHECK_GT(pointers_->size(), 0U);
pointers_->pop_back();
......
......@@ -7,6 +7,7 @@
#include "base/basictypes.h"
#include "base/containers/stack_container.h"
#include "base/memory/scoped_vector.h"
#include "ui/events/gesture_detection/gesture_detection_export.h"
#include "ui/events/gesture_detection/motion_event.h"
......@@ -14,7 +15,8 @@ namespace ui {
struct GESTURE_DETECTION_EXPORT PointerProperties {
PointerProperties();
PointerProperties(float x, float y);
PointerProperties(float x, float y, float touch_major);
PointerProperties(const MotionEvent& event, size_t pointer_index);
int id;
MotionEvent::ToolType tool_type;
......@@ -56,11 +58,22 @@ class GESTURE_DETECTION_EXPORT MotionEventGeneric : public MotionEvent {
int GetButtonState() const override;
int GetFlags() const override;
base::TimeTicks GetEventTime() const override;
scoped_ptr<MotionEvent> Clone() const override;
scoped_ptr<MotionEvent> Cancel() const override;
size_t GetHistorySize() const override;
base::TimeTicks GetHistoricalEventTime(
size_t historical_index) const override;
float GetHistoricalTouchMajor(size_t pointer_index,
size_t historical_index) const override;
float GetHistoricalX(size_t pointer_index,
size_t historical_index) const override;
float GetHistoricalY(size_t pointer_index,
size_t historical_index) const override;
void PushPointer(const PointerProperties& pointer);
// Add an event to the history. |this| and |event| must have the same pointer
// count and must both have an action of ACTION_MOVE.
void PushHistoricalEvent(scoped_ptr<MotionEvent> event);
void set_action(Action action) { action_ = action; }
void set_event_time(base::TimeTicks event_time) { event_time_ = event_time; }
void set_id(int id) { id_ = id; }
......@@ -68,8 +81,13 @@ class GESTURE_DETECTION_EXPORT MotionEventGeneric : public MotionEvent {
void set_button_state(int button_state) { button_state_ = button_state; }
void set_flags(int flags) { flags_ = flags; }
static scoped_ptr<MotionEventGeneric> CloneEvent(const MotionEvent& event);
static scoped_ptr<MotionEventGeneric> CancelEvent(const MotionEvent& event);
protected:
MotionEventGeneric();
MotionEventGeneric(const MotionEvent& event, bool with_history);
MotionEventGeneric& operator=(const MotionEventGeneric& other);
void PopPointer();
......@@ -88,6 +106,7 @@ class GESTURE_DETECTION_EXPORT MotionEventGeneric : public MotionEvent {
int button_state_;
int flags_;
base::StackVector<PointerProperties, kTypicalMaxPointerCount> pointers_;
ScopedVector<MotionEvent> historical_events_;
};
} // namespace ui
......
......@@ -5,6 +5,7 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/events/event_constants.h"
#include "ui/events/gesture_detection/motion_event_generic.h"
#include "ui/events/test/motion_event_test_utils.h"
namespace ui {
......@@ -16,12 +17,12 @@ TEST(MotionEventGenericTest, Basic) {
EXPECT_EQ(0U, event.GetHistorySize());
EXPECT_EQ(event_time, event.GetEventTime());
event.PushPointer(PointerProperties(8.3f, 4.7f));
event.PushPointer(PointerProperties(8.3f, 4.7f, 0.9f));
ASSERT_EQ(2U, event.GetPointerCount());
EXPECT_EQ(8.3f, event.GetX(1));
EXPECT_EQ(4.7f, event.GetY(1));
event.PushPointer(PointerProperties(2.3f, -3.7f));
event.PushPointer(PointerProperties(2.3f, -3.7f, 5.8f));
ASSERT_EQ(3U, event.GetPointerCount());
EXPECT_EQ(2.3f, event.GetX(2));
EXPECT_EQ(-3.7f, event.GetY(2));
......@@ -44,31 +45,78 @@ TEST(MotionEventGenericTest, Basic) {
event.set_action_index(1);
EXPECT_EQ(1, event.GetActionIndex());
event.set_action(MotionEvent::ACTION_MOVE);
EXPECT_EQ(MotionEvent::ACTION_MOVE, event.GetAction());
PointerProperties historical_pointer0(1.2f, 2.4f, 1.f);
PointerProperties historical_pointer1(2.4f, 4.8f, 2.f);
PointerProperties historical_pointer2(4.8f, 9.6f, 3.f);
MotionEventGeneric historical_event(
MotionEvent::ACTION_MOVE,
event_time - base::TimeDelta::FromMilliseconds(5),
historical_pointer0);
historical_event.PushPointer(historical_pointer1);
historical_event.PushPointer(historical_pointer2);
event.PushHistoricalEvent(historical_event.Clone());
EXPECT_EQ(1U, event.GetHistorySize());
EXPECT_EQ(event_time - base::TimeDelta::FromMilliseconds(5),
event.GetHistoricalEventTime(0));
EXPECT_EQ(1.2f, event.GetHistoricalX(0, 0));
EXPECT_EQ(2.4f, event.GetHistoricalY(0, 0));
EXPECT_EQ(1.f, event.GetHistoricalTouchMajor(0, 0));
EXPECT_EQ(2.4f, event.GetHistoricalX(1, 0));
EXPECT_EQ(4.8f, event.GetHistoricalY(1, 0));
EXPECT_EQ(2.f, event.GetHistoricalTouchMajor(1, 0));
EXPECT_EQ(4.8f, event.GetHistoricalX(2, 0));
EXPECT_EQ(9.6f, event.GetHistoricalY(2, 0));
EXPECT_EQ(3.f, event.GetHistoricalTouchMajor(2, 0));
}
TEST(MotionEventGenericTest, Clone) {
MotionEventGeneric event(MotionEvent::ACTION_DOWN,
base::TimeTicks::Now(),
PointerProperties(8.3f, 4.7f));
PointerProperties(8.3f, 4.7f, 2.f));
event.set_id(1);
event.set_button_state(MotionEvent::BUTTON_PRIMARY);
scoped_ptr<MotionEvent> clone = event.Clone();
ASSERT_TRUE(clone);
EXPECT_EQ(event, *clone);
EXPECT_EQ(test::ToString(event), test::ToString(*clone));
}
TEST(MotionEventGenericTest, CloneWithHistory) {
base::TimeTicks event_time = base::TimeTicks::Now();
base::TimeTicks historical_event_time =
event_time - base::TimeDelta::FromMilliseconds(5);
PointerProperties pointer(8.3f, 4.7f, 10.1f);
MotionEventGeneric event(MotionEvent::ACTION_MOVE, event_time, pointer);
PointerProperties historical_pointer(3.4f, -4.3f, 11.5);
scoped_ptr<MotionEvent> historical_event(new MotionEventGeneric(
MotionEvent::ACTION_MOVE, historical_event_time, historical_pointer));
event.PushHistoricalEvent(historical_event.Pass());
EXPECT_EQ(1U, event.GetHistorySize());
scoped_ptr<MotionEvent> clone = event.Clone();
ASSERT_TRUE(clone);
EXPECT_EQ(test::ToString(event), test::ToString(*clone));
}
TEST(MotionEventGenericTest, Cancel) {
MotionEventGeneric event(MotionEvent::ACTION_UP,
base::TimeTicks::Now(),
PointerProperties(8.7f, 4.3f));
PointerProperties(8.7f, 4.3f, 1.f));
event.set_id(2);
event.set_button_state(MotionEvent::BUTTON_SECONDARY);
scoped_ptr<MotionEvent> cancel = event.Cancel();
event.set_action(MotionEvent::ACTION_CANCEL);
ASSERT_TRUE(cancel);
EXPECT_EQ(event, *cancel);
EXPECT_EQ(test::ToString(event), test::ToString(*cancel));
}
TEST(MotionEventGenericTest, FindPointerIndexOfId) {
......@@ -98,4 +146,51 @@ TEST(MotionEventGenericTest, FindPointerIndexOfId) {
EXPECT_EQ(-1, event2.FindPointerIndexOfId(2));
}
TEST(MotionEventGenericTest, ToString) {
base::TimeTicks event_time = base::TimeTicks::Now();
base::TimeTicks historical_event_time0 =
event_time - base::TimeDelta::FromMilliseconds(10);
base::TimeTicks historical_event_time1 =
event_time - base::TimeDelta::FromMilliseconds(5);
PointerProperties pointer0(1, 2, 3);
pointer0.id = 7;
pointer0.pressure = 10;
pointer0.touch_minor = 15;
pointer0.touch_major = 20;
pointer0.orientation = 1;
PointerProperties pointer1(4, 5, 6);
pointer1.id = 3;
pointer0.pressure = 25;
pointer0.touch_minor = 30;
pointer0.touch_major = 35;
pointer0.orientation = -1;
MotionEventGeneric event(MotionEvent::ACTION_MOVE, event_time, pointer0);
event.PushPointer(pointer1);
pointer0.x += 50;
pointer1.x -= 50;
scoped_ptr<MotionEventGeneric> historical_event0(new MotionEventGeneric(
MotionEvent::ACTION_MOVE, historical_event_time0, pointer0));
historical_event0->PushPointer(pointer1);
pointer0.x += 100;
pointer1.x -= 100;
scoped_ptr<MotionEventGeneric> historical_event1(new MotionEventGeneric(
MotionEvent::ACTION_MOVE, historical_event_time1, pointer0));
historical_event1->PushPointer(pointer1);
event.PushHistoricalEvent(historical_event0.Pass());
event.PushHistoricalEvent(historical_event1.Pass());
ASSERT_EQ(2U, event.GetHistorySize());
ASSERT_EQ(2U, event.GetPointerCount());
// Do a basic smoke exercise of event stringification to ensure things don't
// explode in the process.
std::string event_string = test::ToString(event);
EXPECT_FALSE(event_string.empty());
}
} // namespace ui
......@@ -6,7 +6,7 @@
#include "base/memory/scoped_ptr.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/events/gesture_detection/touch_disposition_gesture_filter.h"
#include "ui/events/test/mock_motion_event.h"
#include "ui/events/test/motion_event_test_utils.h"
using ui::test::MockMotionEvent;
......
......@@ -8,7 +8,7 @@
#include "base/time/time.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/events/gesture_detection/velocity_tracker_state.h"
#include "ui/events/test/mock_motion_event.h"
#include "ui/events/test/motion_event_test_utils.h"
#include "ui/gfx/geometry/point_f.h"
#include "ui/gfx/geometry/vector2d_f.h"
......
......@@ -173,7 +173,6 @@ MotionEvent::ToolType MotionEventAura::GetToolType(size_t pointer_index) const {
}
int MotionEventAura::GetButtonState() const {
NOTIMPLEMENTED();
return 0;
}
......@@ -185,26 +184,15 @@ base::TimeTicks MotionEventAura::GetEventTime() const {
return last_touch_time_;
}
scoped_ptr<MotionEvent> MotionEventAura::Clone() const {
return scoped_ptr<MotionEvent>(new MotionEventAura(pointer_count_,
last_touch_time_,
cached_action_,
cached_action_index_,
flags_,
active_touches_));
}
scoped_ptr<MotionEvent> MotionEventAura::Cancel() const {
return scoped_ptr<MotionEvent>(new MotionEventAura(
pointer_count_, last_touch_time_, ACTION_CANCEL, -1, 0, active_touches_));
}
void MotionEventAura::CleanupRemovedTouchPoints(const TouchEvent& event) {
if (event.type() != ET_TOUCH_RELEASED &&
event.type() != ET_TOUCH_CANCELLED) {
return;
}
int index_to_delete = static_cast<int>(GetIndexFromId(event.touch_id()));
DCHECK(pointer_count_);
int index_to_delete = GetIndexFromId(event.touch_id());
cached_action_index_ = 0;
pointer_count_--;
active_touches_[index_to_delete] = active_touches_[pointer_count_];
}
......@@ -249,8 +237,7 @@ void MotionEventAura::UpdateCachedAction(const TouchEvent& touch) {
cached_action_ = ACTION_DOWN;
} else {
cached_action_ = ACTION_POINTER_DOWN;
cached_action_index_ =
static_cast<int>(GetIndexFromId(touch.touch_id()));
cached_action_index_ = GetIndexFromId(touch.touch_id());
}
break;
case ET_TOUCH_RELEASED:
......@@ -258,9 +245,7 @@ void MotionEventAura::UpdateCachedAction(const TouchEvent& touch) {
cached_action_ = ACTION_UP;
} else {
cached_action_ = ACTION_POINTER_UP;
cached_action_index_ =
static_cast<int>(GetIndexFromId(touch.touch_id()));
DCHECK_LT(cached_action_index_, static_cast<int>(pointer_count_));
cached_action_index_ = GetIndexFromId(touch.touch_id());
}
break;
case ET_TOUCH_CANCELLED:
......@@ -275,13 +260,11 @@ void MotionEventAura::UpdateCachedAction(const TouchEvent& touch) {
}
}
size_t MotionEventAura::GetIndexFromId(int id) const {
for (size_t i = 0; i < pointer_count_; ++i) {
if (active_touches_[i].touch_id == id)
return i;
}
NOTREACHED();
return 0;
int MotionEventAura::GetIndexFromId(int id) const {
int index = FindPointerIndexOfId(id);
DCHECK_GE(index, 0);
DCHECK_LT(index, static_cast<int>(pointer_count_));
return index;
}
} // namespace ui
......@@ -42,9 +42,6 @@ class EVENTS_EXPORT MotionEventAura : public MotionEvent {
virtual int GetFlags() const override;
virtual base::TimeTicks GetEventTime() const override;
virtual scoped_ptr<MotionEvent> Clone() const override;
virtual scoped_ptr<MotionEvent> Cancel() const override;
int GetSourceDeviceId(size_t pointer_index) const;
// We can't cleanup removed touch points immediately upon receipt of a
......@@ -81,7 +78,7 @@ class EVENTS_EXPORT MotionEventAura : public MotionEvent {
void AddTouch(const TouchEvent& touch);
void UpdateTouch(const TouchEvent& touch);
void UpdateCachedAction(const TouchEvent& touch);
size_t GetIndexFromId(int id) const;
int GetIndexFromId(int id) const;
size_t pointer_count_;
base::TimeTicks last_touch_time_;
......
......@@ -10,6 +10,7 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/events/event.h"
#include "ui/events/gestures/motion_event_aura.h"
#include "ui/events/test/motion_event_test_utils.h"
namespace {
......@@ -112,6 +113,7 @@ TEST(MotionEventAuraTest, PointerCountAndIds) {
EXPECT_EQ(2U, clone->GetPointerCount());
EXPECT_EQ(ids[0], clone->GetPointerId(0));
EXPECT_EQ(ids[2], clone->GetPointerId(1));
EXPECT_EQ(test::ToString(event), test::ToString(*clone));
TouchEvent release0 = TouchWithType(ET_TOUCH_RELEASED, ids[0]);
event.OnTouch(release0);
......@@ -138,20 +140,22 @@ TEST(MotionEventAuraTest, GetActionIndexAfterRemoval) {
event.OnTouch(press0);
TouchEvent press1 = TouchWithType(ET_TOUCH_PRESSED, ids[1]);
event.OnTouch(press1);
EXPECT_EQ(1, event.GetActionIndex());
TouchEvent press2 = TouchWithType(ET_TOUCH_PRESSED, ids[2]);
event.OnTouch(press2);
EXPECT_EQ(2, event.GetActionIndex());
EXPECT_EQ(3U, event.GetPointerCount());
TouchEvent release1 = TouchWithType(ET_TOUCH_RELEASED, ids[1]);
event.OnTouch(release1);
event.CleanupRemovedTouchPoints(release1);
EXPECT_EQ(1, event.GetActionIndex());
event.CleanupRemovedTouchPoints(release1);
EXPECT_EQ(2U, event.GetPointerCount());
TouchEvent release2 = TouchWithType(ET_TOUCH_RELEASED, ids[0]);
event.OnTouch(release2);
event.CleanupRemovedTouchPoints(release2);
EXPECT_EQ(0, event.GetActionIndex());
event.CleanupRemovedTouchPoints(release2);
EXPECT_EQ(1U, event.GetPointerCount());
TouchEvent release0 = TouchWithType(ET_TOUCH_RELEASED, ids[2]);
......@@ -204,13 +208,12 @@ TEST(MotionEventAuraTest, PointerLocations) {
// Test cloning of pointer location information.
scoped_ptr<MotionEvent> clone = event.Clone();
{
const MotionEventAura* raw_clone_aura =
static_cast<MotionEventAura*>(clone.get());
EXPECT_EQ(2U, raw_clone_aura->GetPointerCount());
EXPECT_FLOAT_EQ(x, raw_clone_aura->GetX(1));
EXPECT_FLOAT_EQ(y, raw_clone_aura->GetY(1));
EXPECT_FLOAT_EQ(raw_x, raw_clone_aura->GetRawX(1));
EXPECT_FLOAT_EQ(raw_y, raw_clone_aura->GetRawY(1));
EXPECT_EQ(test::ToString(event), test::ToString(*clone));
EXPECT_EQ(2U, clone->GetPointerCount());
EXPECT_FLOAT_EQ(x, clone->GetX(1));
EXPECT_FLOAT_EQ(y, clone->GetY(1));
EXPECT_FLOAT_EQ(raw_x, clone->GetRawX(1));
EXPECT_FLOAT_EQ(raw_y, clone->GetRawY(1));
}
x = 27.9f;
......@@ -282,14 +285,12 @@ TEST(MotionEventAuraTest, TapParams) {
// Test cloning of tap params
scoped_ptr<MotionEvent> clone = event.Clone();
{
const MotionEventAura* raw_clone_aura =
static_cast<MotionEventAura*>(clone.get());
EXPECT_EQ(2U, raw_clone_aura->GetPointerCount());
EXPECT_FLOAT_EQ(radius_y, raw_clone_aura->GetTouchMajor(1) / 2);
EXPECT_FLOAT_EQ(radius_x, raw_clone_aura->GetTouchMinor(1) / 2);
EXPECT_FLOAT_EQ(
rotation_angle, raw_clone_aura->GetOrientation(1) * 180 / M_PI);
EXPECT_FLOAT_EQ(pressure, raw_clone_aura->GetPressure(1));
EXPECT_EQ(test::ToString(event), test::ToString(*clone));
EXPECT_EQ(2U, clone->GetPointerCount());
EXPECT_FLOAT_EQ(radius_y, clone->GetTouchMajor(1) / 2);
EXPECT_FLOAT_EQ(radius_x, clone->GetTouchMinor(1) / 2);
EXPECT_FLOAT_EQ(rotation_angle, clone->GetOrientation(1) * 180 / M_PI);
EXPECT_FLOAT_EQ(pressure, clone->GetPressure(1));
}
radius_x = 76.98f;
......@@ -391,7 +392,7 @@ TEST(MotionEventAuraTest, Cancel) {
scoped_ptr<MotionEvent> cancel = event.Cancel();
EXPECT_EQ(MotionEvent::ACTION_CANCEL, cancel->GetAction());
EXPECT_EQ(2U, static_cast<MotionEventAura*>(cancel.get())->GetPointerCount());
EXPECT_EQ(2U, cancel->GetPointerCount());
}
TEST(MotionEventAuraTest, ToolType) {
......
......@@ -2,9 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ui/events/test/mock_motion_event.h"
#include "ui/events/test/motion_event_test_utils.h"
#include <sstream>
#include "base/logging.h"
#include "ui/events/gesture_detection/bitset_32.h"
#include "ui/events/gesture_detection/motion_event.h"
using base::TimeTicks;
......@@ -19,13 +23,11 @@ PointerProperties CreatePointer() {
}
PointerProperties CreatePointer(float x, float y, int id) {
PointerProperties pointer(x, y);
pointer.touch_major = MockMotionEvent::TOUCH_MAJOR;
PointerProperties pointer(x, y, MockMotionEvent::TOUCH_MAJOR);
pointer.id = id;
return pointer;
}
} // namespace
MockMotionEvent::MockMotionEvent()
......@@ -85,16 +87,7 @@ MockMotionEvent::MockMotionEvent(const MockMotionEvent& other)
: MotionEventGeneric(other) {
}
MockMotionEvent::~MockMotionEvent() {}
scoped_ptr<MotionEvent> MockMotionEvent::Clone() const {
return scoped_ptr<MotionEvent>(new MockMotionEvent(*this));
}
scoped_ptr<MotionEvent> MockMotionEvent::Cancel() const {
scoped_ptr<MockMotionEvent> event(new MockMotionEvent(*this));
event->set_action(MotionEvent::ACTION_CANCEL);
return event.Pass();
MockMotionEvent::~MockMotionEvent() {
}
void MockMotionEvent::PressPoint(float x, float y) {
......@@ -173,5 +166,54 @@ void MockMotionEvent::ResolvePointers() {
}
}
std::string ToString(const MotionEvent& event) {
std::stringstream ss;
ss << "MotionEvent {"
<< "\n ID: " << event.GetId() << "\n Action: " << event.GetAction()
<< "\n ActionIndex: " << event.GetActionIndex()
<< "\n Flags: " << event.GetFlags()
<< "\n ButtonState: " << event.GetButtonState() << "\n Pointers: [";
const size_t pointer_count = event.GetPointerCount();
const size_t history_size = event.GetHistorySize();
BitSet32 pointer_ids;
for (size_t i = 0; i < pointer_count; ++i) {
pointer_ids.mark_bit(event.GetPointerId(i));
// Print the pointers sorted by id.
while (!pointer_ids.is_empty()) {
int pi = event.FindPointerIndexOfId(pointer_ids.first_marked_bit());
DCHECK_GE(pi, 0);
pointer_ids.clear_first_marked_bit();
ss << "{"
<< "\n Pos: (" << event.GetX(pi) << ", " << event.GetY(pi) << ")"
<< "\n RawPos: (" << event.GetX(pi) << ", " << event.GetY(pi) << ")"
<< "\n Size: (" << event.GetTouchMajor(pi) << ", "
<< event.GetTouchMinor(pi) << ")"
<< "\n Orientation: " << event.GetOrientation(pi)
<< "\n Pressure: " << event.GetOrientation(pi)
<< "\n Tool: " << event.GetToolType(pi);
if (history_size) {
ss << "\n History: [";
for (size_t h = 0; h < history_size; ++h) {
ss << "\n { " << event.GetHistoricalX(pi, h) << ", "
<< event.GetHistoricalY(pi, h) << ", "
<< event.GetHistoricalTouchMajor(pi, h) << ", "
<< event.GetHistoricalEventTime(pi).ToInternalValue() << " }";
if (h + 1 < history_size)
ss << ",";
}
ss << "\n ]";
}
ss << "\n }";
if (i + 1 < pointer_count)
ss << ", ";
}
ss << "]\n}";
}
return ss.str();
}
} // namespace test
} // namespace ui
......@@ -2,6 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef UI_EVENTS_TEST_MOTION_EVENT_TEST_UTILS_H_
#define UI_EVENTS_TEST_MOTION_EVENT_TEST_UTILS_H_
#include <string>
#include <vector>
#include "base/basictypes.h"
......@@ -39,10 +43,6 @@ struct MockMotionEvent : public MotionEventGeneric {
~MockMotionEvent() override;
// MotionEvent methods.
scoped_ptr<MotionEvent> Clone() const override;
scoped_ptr<MotionEvent> Cancel() const override;
// Utility methods.
void PressPoint(float x, float y);
void MovePoint(size_t index, float x, float y);
......@@ -57,5 +57,9 @@ struct MockMotionEvent : public MotionEventGeneric {
void ResolvePointers();
};
std::string ToString(const MotionEvent& event);
} // namespace test
} // namespace ui
#endif // UI_EVENTS_TEST_MOTION_EVENT_TEST_UTILS_H_
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