Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(396)

Side by Side Diff: ui/events/ozone/evdev/touch_event_converter_evdev.cc

Issue 1033933004: Revert of Port Chromium OS touch noise filtering to Chromium (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/events/ozone/evdev/touch_event_converter_evdev.h" 5 #include "ui/events/ozone/evdev/touch_event_converter_evdev.h"
6 6
7 #include <errno.h> 7 #include <errno.h>
8 #include <fcntl.h> 8 #include <fcntl.h>
9 #include <linux/input.h> 9 #include <linux/input.h>
10 #include <poll.h> 10 #include <poll.h>
(...skipping 11 matching lines...) Expand all
22 #include "base/message_loop/message_loop.h" 22 #include "base/message_loop/message_loop.h"
23 #include "base/strings/string_number_conversions.h" 23 #include "base/strings/string_number_conversions.h"
24 #include "base/strings/string_util.h" 24 #include "base/strings/string_util.h"
25 #include "base/strings/stringprintf.h" 25 #include "base/strings/stringprintf.h"
26 #include "ui/events/devices/device_data_manager.h" 26 #include "ui/events/devices/device_data_manager.h"
27 #include "ui/events/devices/device_util_linux.h" 27 #include "ui/events/devices/device_util_linux.h"
28 #include "ui/events/event.h" 28 #include "ui/events/event.h"
29 #include "ui/events/event_constants.h" 29 #include "ui/events/event_constants.h"
30 #include "ui/events/event_switches.h" 30 #include "ui/events/event_switches.h"
31 #include "ui/events/ozone/evdev/device_event_dispatcher_evdev.h" 31 #include "ui/events/ozone/evdev/device_event_dispatcher_evdev.h"
32 #include "ui/events/ozone/evdev/touch_evdev_types.h"
33 #include "ui/events/ozone/evdev/touch_noise/touch_noise_finder.h"
34 32
35 namespace { 33 namespace {
36 34
37 struct TouchCalibration { 35 struct TouchCalibration {
38 int bezel_left; 36 int bezel_left;
39 int bezel_right; 37 int bezel_right;
40 int bezel_top; 38 int bezel_top;
41 int bezel_bottom; 39 int bezel_bottom;
42 }; 40 };
43 41
(...skipping 10 matching lines...) Expand all
54 DLOG(ERROR) << "Incorrect top border calibration value passed."; 52 DLOG(ERROR) << "Incorrect top border calibration value passed.";
55 if (!base::StringToInt(parts[3], &cal->bezel_bottom)) 53 if (!base::StringToInt(parts[3], &cal->bezel_bottom))
56 DLOG(ERROR) << "Incorrect bottom border calibration value passed."; 54 DLOG(ERROR) << "Incorrect bottom border calibration value passed.";
57 } 55 }
58 } 56 }
59 57
60 } // namespace 58 } // namespace
61 59
62 namespace ui { 60 namespace ui {
63 61
62 TouchEventConverterEvdev::InProgressEvents::InProgressEvents()
63 : altered_(false),
64 x_(0),
65 y_(0),
66 id_(-1),
67 finger_(-1),
68 type_(ET_UNKNOWN),
69 radius_x_(0),
70 radius_y_(0),
71 pressure_(0) {
72 }
73
64 TouchEventConverterEvdev::TouchEventConverterEvdev( 74 TouchEventConverterEvdev::TouchEventConverterEvdev(
65 int fd, 75 int fd,
66 base::FilePath path, 76 base::FilePath path,
67 int id, 77 int id,
68 InputDeviceType type, 78 InputDeviceType type,
69 DeviceEventDispatcherEvdev* dispatcher) 79 DeviceEventDispatcherEvdev* dispatcher)
70 : EventConverterEvdev(fd, path, id, type), 80 : EventConverterEvdev(fd, path, id, type),
71 dispatcher_(dispatcher), 81 dispatcher_(dispatcher),
72 syn_dropped_(false), 82 syn_dropped_(false),
83 is_type_a_(false),
73 touch_points_(0), 84 touch_points_(0),
74 current_slot_(0) { 85 current_slot_(0) {
75 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
76 switches::kExtraTouchNoiseFiltering)) {
77 touch_noise_finder_.reset(new TouchNoiseFinder);
78 }
79 } 86 }
80 87
81 TouchEventConverterEvdev::~TouchEventConverterEvdev() { 88 TouchEventConverterEvdev::~TouchEventConverterEvdev() {
82 Stop(); 89 Stop();
83 close(fd_); 90 close(fd_);
84 } 91 }
85 92
86 void TouchEventConverterEvdev::Initialize(const EventDeviceInfo& info) { 93 void TouchEventConverterEvdev::Initialize(const EventDeviceInfo& info) {
87 pressure_min_ = info.GetAbsMinimum(ABS_MT_PRESSURE); 94 pressure_min_ = info.GetAbsMinimum(ABS_MT_PRESSURE);
88 pressure_max_ = info.GetAbsMaximum(ABS_MT_PRESSURE); 95 pressure_max_ = info.GetAbsMaximum(ABS_MT_PRESSURE);
89 x_min_tuxels_ = info.GetAbsMinimum(ABS_MT_POSITION_X); 96 x_min_tuxels_ = info.GetAbsMinimum(ABS_MT_POSITION_X);
90 x_num_tuxels_ = info.GetAbsMaximum(ABS_MT_POSITION_X) - x_min_tuxels_ + 1; 97 x_num_tuxels_ = info.GetAbsMaximum(ABS_MT_POSITION_X) - x_min_tuxels_ + 1;
91 y_min_tuxels_ = info.GetAbsMinimum(ABS_MT_POSITION_Y); 98 y_min_tuxels_ = info.GetAbsMinimum(ABS_MT_POSITION_Y);
92 y_num_tuxels_ = info.GetAbsMaximum(ABS_MT_POSITION_Y) - y_min_tuxels_ + 1; 99 y_num_tuxels_ = info.GetAbsMaximum(ABS_MT_POSITION_Y) - y_min_tuxels_ + 1;
93 touch_points_ = 100 touch_points_ =
94 std::min<int>(info.GetAbsMaximum(ABS_MT_SLOT) + 1, kNumTouchEvdevSlots); 101 std::min<int>(info.GetAbsMaximum(ABS_MT_SLOT) + 1, MAX_FINGERS);
95 102
96 // Apply --touch-calibration. 103 // Apply --touch-calibration.
97 if (type() == INPUT_DEVICE_INTERNAL) { 104 if (type() == INPUT_DEVICE_INTERNAL) {
98 TouchCalibration cal = {}; 105 TouchCalibration cal = {};
99 GetTouchCalibration(&cal); 106 GetTouchCalibration(&cal);
100 x_min_tuxels_ += cal.bezel_left; 107 x_min_tuxels_ += cal.bezel_left;
101 x_num_tuxels_ -= cal.bezel_left + cal.bezel_right; 108 x_num_tuxels_ -= cal.bezel_left + cal.bezel_right;
102 y_min_tuxels_ += cal.bezel_top; 109 y_min_tuxels_ += cal.bezel_top;
103 y_num_tuxels_ -= cal.bezel_top + cal.bezel_bottom; 110 y_num_tuxels_ -= cal.bezel_top + cal.bezel_bottom;
104 111
105 VLOG(1) << "applying touch calibration: " 112 VLOG(1) << "applying touch calibration: "
106 << base::StringPrintf("[%d, %d, %d, %d]", cal.bezel_left, 113 << base::StringPrintf("[%d, %d, %d, %d]", cal.bezel_left,
107 cal.bezel_right, cal.bezel_top, 114 cal.bezel_right, cal.bezel_top,
108 cal.bezel_bottom); 115 cal.bezel_bottom);
109 } 116 }
110 117
111 native_size_ = gfx::Size(x_num_tuxels_, y_num_tuxels_); 118 native_size_ = gfx::Size(x_num_tuxels_, y_num_tuxels_);
112 119
113 events_.resize(touch_points_); 120 events_.resize(touch_points_);
114 for (size_t i = 0; i < events_.size(); ++i) { 121 for (size_t i = 0; i < events_.size(); ++i) {
115 events_[i].x = info.GetSlotValue(ABS_MT_POSITION_X, i); 122 events_[i].finger_ = info.GetSlotValue(ABS_MT_TRACKING_ID, i);
116 events_[i].y = info.GetSlotValue(ABS_MT_POSITION_Y, i); 123 events_[i].type_ =
117 events_[i].tracking_id = info.GetSlotValue(ABS_MT_TRACKING_ID, i); 124 events_[i].finger_ < 0 ? ET_TOUCH_RELEASED : ET_TOUCH_PRESSED;
118 events_[i].touching = (events_[i].tracking_id >= 0); 125 events_[i].x_ = info.GetSlotValue(ABS_MT_POSITION_X, i);
119 events_[i].slot = i; 126 events_[i].y_ = info.GetSlotValue(ABS_MT_POSITION_Y, i);
120 events_[i].radius_x = info.GetSlotValue(ABS_MT_TOUCH_MAJOR, i); 127 events_[i].radius_x_ = info.GetSlotValue(ABS_MT_TOUCH_MAJOR, i);
121 events_[i].radius_y = info.GetSlotValue(ABS_MT_TOUCH_MINOR, i); 128 events_[i].radius_y_ = info.GetSlotValue(ABS_MT_TOUCH_MINOR, i);
122 events_[i].pressure = info.GetSlotValue(ABS_MT_PRESSURE, i); 129 events_[i].pressure_ = info.GetSlotValue(ABS_MT_PRESSURE, i);
123 } 130 }
124 } 131 }
125 132
126 bool TouchEventConverterEvdev::Reinitialize() { 133 bool TouchEventConverterEvdev::Reinitialize() {
127 EventDeviceInfo info; 134 EventDeviceInfo info;
128 if (info.Initialize(fd_)) { 135 if (info.Initialize(fd_)) {
129 Initialize(info); 136 Initialize(info);
130 return true; 137 return true;
131 } 138 }
132 return false; 139 return false;
133 } 140 }
134 141
135 bool TouchEventConverterEvdev::HasTouchscreen() const { 142 bool TouchEventConverterEvdev::HasTouchscreen() const {
136 return true; 143 return true;
137 } 144 }
138 145
139 gfx::Size TouchEventConverterEvdev::GetTouchscreenSize() const { 146 gfx::Size TouchEventConverterEvdev::GetTouchscreenSize() const {
140 return native_size_; 147 return native_size_;
141 } 148 }
142 149
143 int TouchEventConverterEvdev::GetTouchPoints() const { 150 int TouchEventConverterEvdev::GetTouchPoints() const {
144 return touch_points_; 151 return touch_points_;
145 } 152 }
146 153
147 void TouchEventConverterEvdev::OnFileCanReadWithoutBlocking(int fd) { 154 void TouchEventConverterEvdev::OnFileCanReadWithoutBlocking(int fd) {
148 input_event inputs[kNumTouchEvdevSlots * 6 + 1]; 155 input_event inputs[MAX_FINGERS * 6 + 1];
149 ssize_t read_size = read(fd, inputs, sizeof(inputs)); 156 ssize_t read_size = read(fd, inputs, sizeof(inputs));
150 if (read_size < 0) { 157 if (read_size < 0) {
151 if (errno == EINTR || errno == EAGAIN) 158 if (errno == EINTR || errno == EAGAIN)
152 return; 159 return;
153 if (errno != ENODEV) 160 if (errno != ENODEV)
154 PLOG(ERROR) << "error reading device " << path_.value(); 161 PLOG(ERROR) << "error reading device " << path_.value();
155 Stop(); 162 Stop();
156 return; 163 return;
157 } 164 }
158 165
159 if (ignore_events_) 166 if (ignore_events_)
160 return; 167 return;
161 168
162 for (unsigned i = 0; i < read_size / sizeof(*inputs); i++) { 169 for (unsigned i = 0; i < read_size / sizeof(*inputs); i++) {
163 ProcessInputEvent(inputs[i]); 170 ProcessInputEvent(inputs[i]);
164 } 171 }
165 } 172 }
166 173
167 void TouchEventConverterEvdev::ProcessInputEvent(const input_event& input) { 174 void TouchEventConverterEvdev::ProcessInputEvent(const input_event& input) {
168 if (input.type == EV_SYN) { 175 if (input.type == EV_SYN) {
169 ProcessSyn(input); 176 ProcessSyn(input);
170 } else if (syn_dropped_) { 177 } else if(syn_dropped_) {
171 // Do nothing. This branch indicates we have lost sync with the driver. 178 // Do nothing. This branch indicates we have lost sync with the driver.
172 } else if (input.type == EV_ABS) { 179 } else if (input.type == EV_ABS) {
173 if (events_.size() <= current_slot_) { 180 if (events_.size() <= current_slot_) {
174 LOG(ERROR) << "current_slot_ (" << current_slot_ 181 LOG(ERROR) << "current_slot_ (" << current_slot_
175 << ") >= events_.size() (" << events_.size() << ")"; 182 << ") >= events_.size() (" << events_.size() << ")";
176 } else { 183 } else {
177 ProcessAbs(input); 184 ProcessAbs(input);
178 } 185 }
179 } else if (input.type == EV_KEY) { 186 } else if (input.type == EV_KEY) {
180 switch (input.code) { 187 switch (input.code) {
181 case BTN_TOUCH: 188 case BTN_TOUCH:
182 break; 189 break;
183 default: 190 default:
184 NOTIMPLEMENTED() << "invalid code for EV_KEY: " << input.code; 191 NOTIMPLEMENTED() << "invalid code for EV_KEY: " << input.code;
185 } 192 }
186 } else { 193 } else {
187 NOTIMPLEMENTED() << "invalid type: " << input.type; 194 NOTIMPLEMENTED() << "invalid type: " << input.type;
188 } 195 }
189 } 196 }
190 197
191 void TouchEventConverterEvdev::ProcessAbs(const input_event& input) { 198 void TouchEventConverterEvdev::ProcessAbs(const input_event& input) {
192 switch (input.code) { 199 switch (input.code) {
193 case ABS_MT_TOUCH_MAJOR: 200 case ABS_MT_TOUCH_MAJOR:
194 // TODO(spang): If we have all of major, minor, and orientation, 201 // TODO(spang): If we have all of major, minor, and orientation,
195 // we can scale the ellipse correctly. However on the Pixel we get 202 // we can scale the ellipse correctly. However on the Pixel we get
196 // neither minor nor orientation, so this is all we can do. 203 // neither minor nor orientation, so this is all we can do.
197 events_[current_slot_].radius_x = input.value / 2.0f; 204 events_[current_slot_].radius_x_ = input.value / 2.0f;
198 break; 205 break;
199 case ABS_MT_TOUCH_MINOR: 206 case ABS_MT_TOUCH_MINOR:
200 events_[current_slot_].radius_y = input.value / 2.0f; 207 events_[current_slot_].radius_y_ = input.value / 2.0f;
201 break; 208 break;
202 case ABS_MT_POSITION_X: 209 case ABS_MT_POSITION_X:
203 events_[current_slot_].x = input.value; 210 events_[current_slot_].x_ = input.value;
204 break; 211 break;
205 case ABS_MT_POSITION_Y: 212 case ABS_MT_POSITION_Y:
206 events_[current_slot_].y = input.value; 213 events_[current_slot_].y_ = input.value;
207 break; 214 break;
208 case ABS_MT_TRACKING_ID: 215 case ABS_MT_TRACKING_ID:
209 if (input.value < 0) { 216 if (input.value < 0) {
210 events_[current_slot_].touching = false; 217 events_[current_slot_].type_ = ET_TOUCH_RELEASED;
211 } else { 218 } else {
212 events_[current_slot_].touching = true; 219 events_[current_slot_].finger_ = input.value;
213 events_[current_slot_].cancelled = false; 220 events_[current_slot_].type_ = ET_TOUCH_PRESSED;
214 } 221 }
215 events_[current_slot_].tracking_id = input.value;
216 break; 222 break;
217 case ABS_MT_PRESSURE: 223 case ABS_MT_PRESSURE:
218 events_[current_slot_].pressure = input.value - pressure_min_; 224 events_[current_slot_].pressure_ = input.value - pressure_min_;
219 events_[current_slot_].pressure /= pressure_max_ - pressure_min_; 225 events_[current_slot_].pressure_ /= pressure_max_ - pressure_min_;
220 break; 226 break;
221 case ABS_MT_SLOT: 227 case ABS_MT_SLOT:
222 if (input.value >= 0 && 228 if (input.value >= 0 &&
223 static_cast<size_t>(input.value) < events_.size()) { 229 static_cast<size_t>(input.value) < events_.size()) {
224 current_slot_ = input.value; 230 current_slot_ = input.value;
225 } else { 231 } else {
226 LOG(ERROR) << "invalid touch event index: " << input.value; 232 LOG(ERROR) << "invalid touch event index: " << input.value;
227 return; 233 return;
228 } 234 }
229 break; 235 break;
230 default: 236 default:
231 DVLOG(5) << "unhandled code for EV_ABS: " << input.code; 237 DVLOG(5) << "unhandled code for EV_ABS: " << input.code;
232 return; 238 return;
233 } 239 }
234 events_[current_slot_].altered = true; 240 events_[current_slot_].altered_ = true;
235 } 241 }
236 242
237 void TouchEventConverterEvdev::ProcessSyn(const input_event& input) { 243 void TouchEventConverterEvdev::ProcessSyn(const input_event& input) {
238 switch (input.code) { 244 switch (input.code) {
239 case SYN_REPORT: 245 case SYN_REPORT:
240 if (syn_dropped_) { 246 if (syn_dropped_) {
241 // Have to re-initialize. 247 // Have to re-initialize.
242 if (Reinitialize()) { 248 if (Reinitialize()) {
243 syn_dropped_ = false; 249 syn_dropped_ = false;
244 for(InProgressTouchEvdev& event : events_) 250 for(InProgressEvents& event: events_)
245 event.altered = false; 251 event.altered_ = false;
246 } else { 252 } else {
247 LOG(ERROR) << "failed to re-initialize device info"; 253 LOG(ERROR) << "failed to re-initialize device info";
248 } 254 }
249 } else { 255 } else {
250 ReportEvents(EventConverterEvdev::TimeDeltaFromInputEvent(input)); 256 ReportEvents(EventConverterEvdev::TimeDeltaFromInputEvent(input));
251 } 257 }
258 if (is_type_a_)
259 current_slot_ = 0;
260 break;
261 case SYN_MT_REPORT:
262 // For type A devices, we just get a stream of all current contacts,
263 // in some arbitrary order.
264 events_[current_slot_].type_ = ET_TOUCH_PRESSED;
265 if (events_.size() - 1 > current_slot_)
266 current_slot_++;
267 is_type_a_ = true;
252 break; 268 break;
253 case SYN_DROPPED: 269 case SYN_DROPPED:
254 // Some buffer has overrun. We ignore all events up to and 270 // Some buffer has overrun. We ignore all events up to and
255 // including the next SYN_REPORT. 271 // including the next SYN_REPORT.
256 syn_dropped_ = true; 272 syn_dropped_ = true;
257 break; 273 break;
258 default: 274 default:
259 NOTIMPLEMENTED() << "invalid code for EV_SYN: " << input.code; 275 NOTIMPLEMENTED() << "invalid code for EV_SYN: " << input.code;
260 } 276 }
261 } 277 }
262 278
263 EventType TouchEventConverterEvdev::GetEventTypeForTouch( 279 void TouchEventConverterEvdev::ReportEvent(int touch_id,
264 const InProgressTouchEvdev& touch) { 280 const InProgressEvents& event,
265 if (touch.cancelled)
266 return ET_UNKNOWN;
267
268 if (touch_noise_finder_ && touch_noise_finder_->SlotHasNoise(touch.slot)) {
269 if (touch.touching && !touch.was_touching)
270 return ET_UNKNOWN;
271 return ET_TOUCH_CANCELLED;
272 }
273
274 if (touch.touching)
275 return touch.was_touching ? ET_TOUCH_MOVED : ET_TOUCH_PRESSED;
276 return touch.was_touching ? ET_TOUCH_RELEASED : ET_UNKNOWN;
277 }
278
279 void TouchEventConverterEvdev::ReportEvent(const InProgressTouchEvdev& event,
280 EventType event_type,
281 const base::TimeDelta& timestamp) { 281 const base::TimeDelta& timestamp) {
282 dispatcher_->DispatchTouchEvent(TouchEventParams( 282 dispatcher_->DispatchTouchEvent(TouchEventParams(
283 id_, event.slot, event_type, gfx::PointF(event.x, event.y), 283 id_, touch_id, event.type_, gfx::PointF(event.x_, event.y_),
284 gfx::Vector2dF(event.radius_x, event.radius_y), event.pressure, 284 gfx::Vector2dF(event.radius_x_, event.radius_y_), event.pressure_,
285 timestamp)); 285 timestamp));
286 } 286 }
287 287
288 void TouchEventConverterEvdev::ReportEvents(base::TimeDelta delta) { 288 void TouchEventConverterEvdev::ReportEvents(base::TimeDelta delta) {
289 if (touch_noise_finder_) 289 for (size_t i = 0; i < events_.size(); i++) {
290 touch_noise_finder_->HandleTouches(events_, delta); 290 if (events_[i].altered_) {
291 ReportEvent(i, events_[i], delta);
291 292
292 for (size_t i = 0; i < events_.size(); i++) { 293 // Subsequent events for this finger will be touch-move until it
293 InProgressTouchEvdev* event = &events_[i]; 294 // is released.
294 if (!event->altered) 295 events_[i].type_ = ET_TOUCH_MOVED;
295 continue; 296 events_[i].altered_ = false;
296 297 }
297 EventType event_type = GetEventTypeForTouch(*event);
298 if (event_type == ET_UNKNOWN || event_type == ET_TOUCH_CANCELLED)
299 event->cancelled = true;
300
301 if (event_type != ET_UNKNOWN)
302 ReportEvent(*event, event_type, delta);
303
304 event->was_touching = event->touching;
305 event->altered = false;
306 } 298 }
307 } 299 }
308 300
309 } // namespace ui 301 } // namespace ui
OLDNEW
« no previous file with comments | « ui/events/ozone/evdev/touch_event_converter_evdev.h ('k') | ui/events/ozone/evdev/touch_event_converter_evdev_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698