Commit 0143ff42 authored by tdresser@chromium.org's avatar tdresser@chromium.org

Currently, destroying a ui::TouchEvent removes its tracking id from the slot...

Currently, destroying a ui::TouchEvent removes its tracking id from the slot mapping. Because MenuEventDispatcher::DispatchEvent was creating
(and destroying) a touch event, the tracking id was being
removed too early.

This patch refcounts the tracking ids, so the tracking id won't be removed until it should be.

BUG=394437

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

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@285580 0039d316-1c4b-4281-b951-d872f2087c98
parent 3580f4f0
......@@ -148,6 +148,10 @@ void ReleaseCopiedNativeEvent(const base::NativeEvent& event) {
[event release];
}
void IncrementTouchIdRefCount(const base::NativeEvent& native_event) {
NOTIMPLEMENTED();
}
void ClearTouchIdIfReleased(const base::NativeEvent& native_event) {
NOTIMPLEMENTED();
}
......
......@@ -481,6 +481,9 @@ TouchEvent::TouchEvent(const base::NativeEvent& native_event)
1);
latency()->AddLatencyNumber(INPUT_EVENT_LATENCY_UI_COMPONENT, 0, 0);
if (type() == ET_TOUCH_PRESSED)
IncrementTouchIdRefCount(native_event);
}
TouchEvent::TouchEvent(EventType type,
......
......@@ -106,6 +106,11 @@ void ReleaseCopiedNativeEvent(
// Gets the touch id from a native event.
EVENTS_EXPORT int GetTouchId(const base::NativeEvent& native_event);
// Increases the number of times |ClearTouchIdIfReleased| needs to be called on
// an event with a given touch id before it will actually be cleared.
EVENTS_EXPORT void IncrementTouchIdRefCount(
const base::NativeEvent& native_event);
// Clear the touch id from bookkeeping if it is a release/cancel event.
EVENTS_EXPORT void ClearTouchIdIfReleased(
const base::NativeEvent& native_event);
......
......@@ -12,7 +12,7 @@
namespace ui {
// Stub implementations of platform-specific methods in events_util.h, built
// on platform sthat currently do not have a complete implementation of events.
// on platforms that currently do not have a complete implementation of events.
void UpdateDeviceList() {
NOTIMPLEMENTED();
......@@ -69,6 +69,10 @@ base::NativeEvent CopyNativeEvent(const base::NativeEvent& event) {
void ReleaseCopiedNativeEvent(const base::NativeEvent& event) {
}
void IncrementTouchIdRefCount(const base::NativeEvent& native_event) {
NOTIMPLEMENTED();
}
void ClearTouchIdIfReleased(const base::NativeEvent& native_event) {
NOTIMPLEMENTED();
}
......
......@@ -78,6 +78,9 @@ base::NativeEvent CopyNativeEvent(const base::NativeEvent& event) {
void ReleaseCopiedNativeEvent(const base::NativeEvent& event) {
}
void IncrementTouchIdRefCount(const base::NativeEvent& event) {
}
void ClearTouchIdIfReleased(const base::NativeEvent& xev) {
}
......
......@@ -290,6 +290,10 @@ base::NativeEvent CopyNativeEvent(const base::NativeEvent& event) {
void ReleaseCopiedNativeEvent(const base::NativeEvent& event) {
}
void IncrementTouchIdRefCount(const base::NativeEvent& event) {
NOTIMPLEMENTED();
}
void ClearTouchIdIfReleased(const base::NativeEvent& xev) {
NOTIMPLEMENTED();
}
......
......@@ -682,6 +682,18 @@ void ReleaseCopiedNativeEvent(const base::NativeEvent& event) {
delete event;
}
void IncrementTouchIdRefCount(const base::NativeEvent& xev) {
ui::DeviceDataManagerX11* manager = ui::DeviceDataManagerX11::GetInstance();
double tracking_id;
if (!manager->GetEventData(
*xev, ui::DeviceDataManagerX11::DT_TOUCH_TRACKING_ID, &tracking_id)) {
return;
}
ui::TouchFactory* factory = ui::TouchFactory::GetInstance();
factory->AcquireSlotForTrackingID(tracking_id);
}
void ClearTouchIdIfReleased(const base::NativeEvent& xev) {
ui::EventType type = ui::EventTypeFromNative(xev);
if (type == ui::ET_TOUCH_CANCELLED ||
......
......@@ -289,6 +289,65 @@ TEST_F(EventsXTest, TouchEventBasic) {
EXPECT_FLOAT_EQ(GetTouchAngle(scoped_xevent), 0.45f);
EXPECT_FLOAT_EQ(GetTouchForce(scoped_xevent), 0.5f);
}
int GetTouchIdForTrackingId(uint32 tracking_id) {
int slot = 0;
bool success =
TouchFactory::GetInstance()->QuerySlotForTrackingID(tracking_id, &slot);
if (success)
return slot;
return -1;
}
TEST_F(EventsXTest, TouchEventIdRefcounting) {
std::vector<unsigned int> devices;
devices.push_back(0);
ui::SetUpTouchDevicesForTest(devices);
std::vector<Valuator> valuators;
const int kTrackingId0 = 5;
const int kTrackingId1 = 7;
// Increment ref count once for first touch.
ui::ScopedXI2Event xpress0;
xpress0.InitTouchEvent(
0, XI_TouchBegin, kTrackingId0, gfx::Point(10, 10), valuators);
scoped_ptr<ui::TouchEvent> upress0(new ui::TouchEvent(xpress0));
EXPECT_EQ(0, GetTouchIdForTrackingId(kTrackingId0));
// Increment ref count 4 times for second touch.
ui::ScopedXI2Event xpress1;
xpress1.InitTouchEvent(
0, XI_TouchBegin, kTrackingId1, gfx::Point(20, 20), valuators);
for (int i = 0; i < 4; ++i) {
ui::TouchEvent upress1(xpress1);
EXPECT_EQ(1, GetTouchIdForTrackingId(kTrackingId1));
}
ui::ScopedXI2Event xrelease1;
xrelease1.InitTouchEvent(
0, XI_TouchEnd, kTrackingId1, gfx::Point(10, 10), valuators);
// Decrement ref count 3 times for second touch.
for (int i = 0; i < 3; ++i) {
ui::TouchEvent urelease1(xrelease1);
EXPECT_EQ(1, GetTouchIdForTrackingId(kTrackingId1));
}
// This should clear the touch id of the second touch.
scoped_ptr<ui::TouchEvent> urelease1(new ui::TouchEvent(xrelease1));
urelease1.reset();
EXPECT_EQ(-1, GetTouchIdForTrackingId(kTrackingId1));
// This should clear the touch id of the first touch.
ui::ScopedXI2Event xrelease0;
xrelease0.InitTouchEvent(
0, XI_TouchEnd, kTrackingId0, gfx::Point(10, 10), valuators);
scoped_ptr<ui::TouchEvent> urelease0(new ui::TouchEvent(xrelease0));
urelease0.reset();
EXPECT_EQ(-1, GetTouchIdForTrackingId(kTrackingId0));
}
#endif
TEST_F(EventsXTest, NumpadKeyEvents) {
......
......@@ -254,8 +254,14 @@ int TouchFactory::GetSlotForTrackingID(uint32 tracking_id) {
return id_generator_.GetGeneratedID(tracking_id);
}
void TouchFactory::AcquireSlotForTrackingID(uint32 tracking_id) {
tracking_id_refcounts_[tracking_id]++;
}
void TouchFactory::ReleaseSlotForTrackingID(uint32 tracking_id) {
id_generator_.ReleaseNumber(tracking_id);
tracking_id_refcounts_[tracking_id]--;
if (tracking_id_refcounts_[tracking_id] == 0)
id_generator_.ReleaseNumber(tracking_id);
}
bool TouchFactory::IsTouchDevicePresent() {
......
......@@ -68,6 +68,10 @@ class EVENTS_BASE_EXPORT TouchFactory {
// isn't one already, allocates a new slot ID and sets up the mapping.
int GetSlotForTrackingID(uint32 tracking_id);
// Increases the number of times |ReleaseSlotForTrackingID| needs to be called
// on a given tracking id before it will actually be released.
void AcquireSlotForTrackingID(uint32 tracking_id);
// Releases the slot ID mapping to tracking ID.
void ReleaseSlotForTrackingID(uint32 tracking_id);
......@@ -130,6 +134,10 @@ class EVENTS_BASE_EXPORT TouchFactory {
// Touch screen <vid, pid>s.
std::set<std::pair<int, int> > touchscreen_ids_;
// Maps from a tracking id to the number of times |ReleaseSlotForTrackingID|
// must be called before the tracking id is released.
std::map<uint32, int> tracking_id_refcounts_;
// Maximum simultaneous touch points supported by device. In the case of
// devices with multiple digitizers (e.g. multiple touchscreens), the value
// is the maximum of the set of maximum supported contacts by each individual
......
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