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

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

Issue 891703004: Seeing crashes likely from negative touch indexes, check for them (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: switch to vector Created 5 years, 10 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
« no previous file with comments | « ui/events/ozone/evdev/touch_event_converter_evdev.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
53 if (!base::StringToInt(parts[3], &cal->bezel_bottom)) 53 if (!base::StringToInt(parts[3], &cal->bezel_bottom))
54 DLOG(ERROR) << "Incorrect bottom border calibration value passed."; 54 DLOG(ERROR) << "Incorrect bottom border calibration value passed.";
55 } 55 }
56 } 56 }
57 57
58 } // namespace 58 } // namespace
59 59
60 namespace ui { 60 namespace ui {
61 61
62 TouchEventConverterEvdev::InProgressEvents::InProgressEvents() 62 TouchEventConverterEvdev::InProgressEvents::InProgressEvents()
63 : x_(0), 63 : altered_(false),
64 x_(0),
64 y_(0), 65 y_(0),
65 id_(-1), 66 id_(-1),
66 finger_(-1), 67 finger_(-1),
67 type_(ET_UNKNOWN), 68 type_(ET_UNKNOWN),
68 radius_x_(0), 69 radius_x_(0),
69 radius_y_(0), 70 radius_y_(0),
70 pressure_(0) { 71 pressure_(0) {
71 } 72 }
72 73
73 TouchEventConverterEvdev::TouchEventConverterEvdev( 74 TouchEventConverterEvdev::TouchEventConverterEvdev(
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
105 y_min_tuxels_ += cal.bezel_top; 106 y_min_tuxels_ += cal.bezel_top;
106 y_num_tuxels_ -= cal.bezel_top + cal.bezel_bottom; 107 y_num_tuxels_ -= cal.bezel_top + cal.bezel_bottom;
107 108
108 VLOG(1) << "applying touch calibration: " 109 VLOG(1) << "applying touch calibration: "
109 << base::StringPrintf("[%d, %d, %d, %d]", cal.bezel_left, 110 << base::StringPrintf("[%d, %d, %d, %d]", cal.bezel_left,
110 cal.bezel_right, cal.bezel_top, 111 cal.bezel_right, cal.bezel_top,
111 cal.bezel_bottom); 112 cal.bezel_bottom);
112 } 113 }
113 114
114 native_size_ = gfx::Size(x_num_tuxels_, y_num_tuxels_); 115 native_size_ = gfx::Size(x_num_tuxels_, y_num_tuxels_);
115 116
spang 2015/02/02 22:09:42 I think you should create events_ here with size o
achaulk 2015/02/03 16:51:49 Done.
116 for (int i = 0; 117 for (int i = 0;
117 i < std::min<int>(info.GetAbsMaximum(ABS_MT_SLOT) + 1, MAX_FINGERS); 118 i < std::min<int>(info.GetAbsMaximum(ABS_MT_SLOT) + 1, MAX_FINGERS);
spang 2015/02/02 22:09:42 needs adjustment to iterate the whole vector & ini
118 ++i) { 119 ++i) {
119 events_[i].finger_ = info.GetSlotValue(ABS_MT_TRACKING_ID, i); 120 events_[i].finger_ = info.GetSlotValue(ABS_MT_TRACKING_ID, i);
120 events_[i].type_ = 121 events_[i].type_ =
121 events_[i].finger_ < 0 ? ET_TOUCH_RELEASED : ET_TOUCH_PRESSED; 122 events_[i].finger_ < 0 ? ET_TOUCH_RELEASED : ET_TOUCH_PRESSED;
122 events_[i].x_ = info.GetSlotValue(ABS_MT_POSITION_X, i); 123 events_[i].x_ = info.GetSlotValue(ABS_MT_POSITION_X, i);
123 events_[i].y_ = info.GetSlotValue(ABS_MT_POSITION_Y, i); 124 events_[i].y_ = info.GetSlotValue(ABS_MT_POSITION_Y, i);
124 events_[i].radius_x_ = info.GetSlotValue(ABS_MT_TOUCH_MAJOR, i); 125 events_[i].radius_x_ = info.GetSlotValue(ABS_MT_TOUCH_MAJOR, i);
125 events_[i].radius_y_ = info.GetSlotValue(ABS_MT_TOUCH_MINOR, i); 126 events_[i].radius_y_ = info.GetSlotValue(ABS_MT_TOUCH_MINOR, i);
126 events_[i].pressure_ = info.GetSlotValue(ABS_MT_PRESSURE, i); 127 events_[i].pressure_ = info.GetSlotValue(ABS_MT_PRESSURE, i);
127 } 128 }
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
163 ProcessInputEvent(inputs[i]); 164 ProcessInputEvent(inputs[i]);
164 } 165 }
165 } 166 }
166 167
167 void TouchEventConverterEvdev::ProcessInputEvent(const input_event& input) { 168 void TouchEventConverterEvdev::ProcessInputEvent(const input_event& input) {
168 if (input.type == EV_SYN) { 169 if (input.type == EV_SYN) {
169 ProcessSyn(input); 170 ProcessSyn(input);
170 } else if(syn_dropped_) { 171 } else if(syn_dropped_) {
171 // Do nothing. This branch indicates we have lost sync with the driver. 172 // Do nothing. This branch indicates we have lost sync with the driver.
172 } else if (input.type == EV_ABS) { 173 } else if (input.type == EV_ABS) {
173 if (current_slot_ >= MAX_FINGERS) {
174 LOG(ERROR) << "too many touch events: " << current_slot_;
175 return;
176 }
177 ProcessAbs(input); 174 ProcessAbs(input);
178 } else if (input.type == EV_KEY) { 175 } else if (input.type == EV_KEY) {
179 switch (input.code) { 176 switch (input.code) {
180 case BTN_TOUCH: 177 case BTN_TOUCH:
181 break; 178 break;
182 default: 179 default:
183 NOTIMPLEMENTED() << "invalid code for EV_KEY: " << input.code; 180 NOTIMPLEMENTED() << "invalid code for EV_KEY: " << input.code;
184 } 181 }
185 } else { 182 } else {
186 NOTIMPLEMENTED() << "invalid type: " << input.type; 183 NOTIMPLEMENTED() << "invalid type: " << input.type;
187 } 184 }
188 } 185 }
189 186
190 void TouchEventConverterEvdev::ProcessAbs(const input_event& input) { 187 void TouchEventConverterEvdev::ProcessAbs(const input_event& input) {
188 if (events_.size() <= current_slot_)
189 events_.resize(current_slot_ + 1);
191 switch (input.code) { 190 switch (input.code) {
192 case ABS_MT_TOUCH_MAJOR: 191 case ABS_MT_TOUCH_MAJOR:
193 altered_slots_.set(current_slot_);
194 // TODO(spang): If we have all of major, minor, and orientation, 192 // TODO(spang): If we have all of major, minor, and orientation,
195 // we can scale the ellipse correctly. However on the Pixel we get 193 // we can scale the ellipse correctly. However on the Pixel we get
196 // neither minor nor orientation, so this is all we can do. 194 // neither minor nor orientation, so this is all we can do.
197 events_[current_slot_].radius_x_ = input.value / 2.0f; 195 events_[current_slot_].radius_x_ = input.value / 2.0f;
198 break; 196 break;
199 case ABS_MT_TOUCH_MINOR: 197 case ABS_MT_TOUCH_MINOR:
200 altered_slots_.set(current_slot_);
201 events_[current_slot_].radius_y_ = input.value / 2.0f; 198 events_[current_slot_].radius_y_ = input.value / 2.0f;
202 break; 199 break;
203 case ABS_MT_POSITION_X: 200 case ABS_MT_POSITION_X:
204 altered_slots_.set(current_slot_);
205 events_[current_slot_].x_ = input.value; 201 events_[current_slot_].x_ = input.value;
206 break; 202 break;
207 case ABS_MT_POSITION_Y: 203 case ABS_MT_POSITION_Y:
208 altered_slots_.set(current_slot_);
209 events_[current_slot_].y_ = input.value; 204 events_[current_slot_].y_ = input.value;
210 break; 205 break;
211 case ABS_MT_TRACKING_ID: 206 case ABS_MT_TRACKING_ID:
212 altered_slots_.set(current_slot_);
213 if (input.value < 0) { 207 if (input.value < 0) {
214 events_[current_slot_].type_ = ET_TOUCH_RELEASED; 208 events_[current_slot_].type_ = ET_TOUCH_RELEASED;
215 } else { 209 } else {
216 events_[current_slot_].finger_ = input.value; 210 events_[current_slot_].finger_ = input.value;
217 events_[current_slot_].type_ = ET_TOUCH_PRESSED; 211 events_[current_slot_].type_ = ET_TOUCH_PRESSED;
218 } 212 }
219 break; 213 break;
220 case ABS_MT_PRESSURE: 214 case ABS_MT_PRESSURE:
221 altered_slots_.set(current_slot_);
222 events_[current_slot_].pressure_ = input.value - pressure_min_; 215 events_[current_slot_].pressure_ = input.value - pressure_min_;
223 events_[current_slot_].pressure_ /= pressure_max_ - pressure_min_; 216 events_[current_slot_].pressure_ /= pressure_max_ - pressure_min_;
224 break; 217 break;
225 case ABS_MT_SLOT: 218 case ABS_MT_SLOT:
226 if (input.value >= MAX_FINGERS) { 219 if (input.value >= 0 && input.value < MAX_FINGERS) {
227 LOG(ERROR) << "multi-touch slot " << input.value 220 current_slot_ = input.value;
228 << " exceeds MAX_FINGERS"; 221 } else {
229 break; 222 LOG(ERROR) << "invalid touch event index: " << input.value;
223 return;
230 } 224 }
231 current_slot_ = input.value;
232 altered_slots_.set(current_slot_);
233 break; 225 break;
234 default: 226 default:
235 DVLOG(5) << "unhandled code for EV_ABS: " << input.code; 227 DVLOG(5) << "unhandled code for EV_ABS: " << input.code;
228 return;
236 } 229 }
230 events_[current_slot_].altered_ = true;
spang 2015/02/02 22:09:42 ABS_VOLUME or something like that shouldn't genera
achaulk 2015/02/03 16:51:49 The default action returns early now
237 } 231 }
238 232
239 void TouchEventConverterEvdev::ProcessSyn(const input_event& input) { 233 void TouchEventConverterEvdev::ProcessSyn(const input_event& input) {
240 switch (input.code) { 234 switch (input.code) {
241 case SYN_REPORT: 235 case SYN_REPORT:
242 if (syn_dropped_) { 236 if (syn_dropped_) {
243 // Have to re-initialize. 237 // Have to re-initialize.
244 if (Reinitialize()) { 238 if (Reinitialize()) {
245 syn_dropped_ = false; 239 syn_dropped_ = false;
246 altered_slots_.reset(); 240 events_.clear();
247 } else { 241 } else {
248 LOG(ERROR) << "failed to re-initialize device info"; 242 LOG(ERROR) << "failed to re-initialize device info";
249 } 243 }
250 } else { 244 } else {
251 ReportEvents(base::TimeDelta::FromMicroseconds( 245 ReportEvents(base::TimeDelta::FromMicroseconds(
252 input.time.tv_sec * 1000000 + input.time.tv_usec)); 246 input.time.tv_sec * 1000000 + input.time.tv_usec));
253 } 247 }
254 if (is_type_a_) 248 if (is_type_a_)
255 current_slot_ = 0; 249 current_slot_ = 0;
256 break; 250 break;
257 case SYN_MT_REPORT: 251 case SYN_MT_REPORT:
258 // For type A devices, we just get a stream of all current contacts, 252 // For type A devices, we just get a stream of all current contacts,
259 // in some arbitrary order. 253 // in some arbitrary order.
254 if (events_.size() <= current_slot_ + 1)
255 events_.resize(current_slot_ + 2);
260 events_[current_slot_++].type_ = ET_TOUCH_PRESSED; 256 events_[current_slot_++].type_ = ET_TOUCH_PRESSED;
261 is_type_a_ = true; 257 is_type_a_ = true;
262 break; 258 break;
263 case SYN_DROPPED: 259 case SYN_DROPPED:
264 // Some buffer has overrun. We ignore all events up to and 260 // Some buffer has overrun. We ignore all events up to and
265 // including the next SYN_REPORT. 261 // including the next SYN_REPORT.
266 syn_dropped_ = true; 262 syn_dropped_ = true;
267 break; 263 break;
268 default: 264 default:
269 NOTIMPLEMENTED() << "invalid code for EV_SYN: " << input.code; 265 NOTIMPLEMENTED() << "invalid code for EV_SYN: " << input.code;
270 } 266 }
271 } 267 }
272 268
273 void TouchEventConverterEvdev::ReportEvent(int touch_id, 269 void TouchEventConverterEvdev::ReportEvent(int touch_id,
274 const InProgressEvents& event, 270 const InProgressEvents& event,
275 const base::TimeDelta& timestamp) { 271 const base::TimeDelta& timestamp) {
276 dispatcher_->DispatchTouchEvent(TouchEventParams( 272 dispatcher_->DispatchTouchEvent(TouchEventParams(
277 id_, touch_id, event.type_, gfx::PointF(event.x_, event.y_), 273 id_, touch_id, event.type_, gfx::PointF(event.x_, event.y_),
278 gfx::Vector2dF(event.radius_x_, event.radius_y_), event.pressure_, 274 gfx::Vector2dF(event.radius_x_, event.radius_y_), event.pressure_,
279 timestamp)); 275 timestamp));
280 } 276 }
281 277
282 void TouchEventConverterEvdev::ReportEvents(base::TimeDelta delta) { 278 void TouchEventConverterEvdev::ReportEvents(base::TimeDelta delta) {
283 for (int i = 0; i < MAX_FINGERS; i++) { 279 for (size_t i = 0; i < events_.size(); i++) {
284 if (altered_slots_[i]) { 280 if (events_[i].altered_) {
285 ReportEvent(i, events_[i], delta); 281 ReportEvent(i, events_[i], delta);
286 282
287 // Subsequent events for this finger will be touch-move until it 283 // Subsequent events for this finger will be touch-move until it
288 // is released. 284 // is released.
289 events_[i].type_ = ET_TOUCH_MOVED; 285 events_[i].type_ = ET_TOUCH_MOVED;
286 events_[i].altered_ = false;
290 } 287 }
291 } 288 }
292 altered_slots_.reset();
293 } 289 }
294 290
295 } // namespace ui 291 } // namespace ui
OLDNEW
« no previous file with comments | « ui/events/ozone/evdev/touch_event_converter_evdev.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698