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

Side by Side Diff: ui/events/platform/x11/x11_hotplug_event_handler.cc

Issue 946173002: Make PointerDeviceObserver use ui::InputDeviceEventObserver on X11 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: 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
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/platform/x11/x11_hotplug_event_handler.h" 5 #include "ui/events/platform/x11/x11_hotplug_event_handler.h"
6 6
7 #include <X11/Xatom.h> 7 #include <X11/Xatom.h>
8 #include <X11/extensions/XInput.h> 8 #include <X11/extensions/XInput.h>
9 #include <X11/extensions/XInput2.h> 9 #include <X11/extensions/XInput2.h>
10 10
(...skipping 28 matching lines...) Expand all
39 // Names of all known internal devices that should not be considered as 39 // Names of all known internal devices that should not be considered as
40 // keyboards. 40 // keyboards.
41 // TODO(rsadam@): Identify these devices using udev rules. (Crbug.com/420728.) 41 // TODO(rsadam@): Identify these devices using udev rules. (Crbug.com/420728.)
42 const char* kKnownInvalidKeyboardDeviceNames[] = {"Power Button", 42 const char* kKnownInvalidKeyboardDeviceNames[] = {"Power Button",
43 "Sleep Button", 43 "Sleep Button",
44 "Video Bus"}; 44 "Video Bus"};
45 45
46 const char* kCachedAtomList[] = { 46 const char* kCachedAtomList[] = {
47 "Abs MT Position X", 47 "Abs MT Position X",
48 "Abs MT Position Y", 48 "Abs MT Position Y",
49 XI_KEYBOARD,
50 XI_MOUSE,
51 XI_TOUCHPAD,
52 XI_TOUCHSCREEN,
49 NULL, 53 NULL,
50 }; 54 };
51 55
56 enum DeviceType {
57 DEVICE_TYPE_KEYBOARD,
58 DEVICE_TYPE_MOUSE,
59 DEVICE_TYPE_TOUCHPAD,
60 DEVICE_TYPE_TOUCHSCREEN,
61 DEVICE_TYPE_OTHER
62 };
63
52 typedef base::Callback<void(const std::vector<KeyboardDevice>&)> 64 typedef base::Callback<void(const std::vector<KeyboardDevice>&)>
53 KeyboardDeviceCallback; 65 KeyboardDeviceCallback;
54 66
55 typedef base::Callback<void(const std::vector<TouchscreenDevice>&)> 67 typedef base::Callback<void(const std::vector<TouchscreenDevice>&)>
56 TouchscreenDeviceCallback; 68 TouchscreenDeviceCallback;
57 69
70 typedef base::Callback<void(const std::vector<InputDevice>&)>
71 InputDeviceCallback;
72
58 // Used for updating the state on the UI thread once device information is 73 // Used for updating the state on the UI thread once device information is
59 // parsed on helper threads. 74 // parsed on helper threads.
60 struct UiCallbacks { 75 struct UiCallbacks {
61 KeyboardDeviceCallback keyboard_callback; 76 KeyboardDeviceCallback keyboard_callback;
62 TouchscreenDeviceCallback touchscreen_callback; 77 TouchscreenDeviceCallback touchscreen_callback;
78 InputDeviceCallback mouse_callback;
79 InputDeviceCallback touchpad_callback;
63 }; 80 };
64 81
65 // Stores a copy of the XIValuatorClassInfo values so X11 device processing can 82 // Stores a copy of the XIValuatorClassInfo values so X11 device processing can
66 // happen on a worker thread. This is needed since X11 structs are not copyable. 83 // happen on a worker thread. This is needed since X11 structs are not copyable.
67 struct ValuatorClassInfo { 84 struct ValuatorClassInfo {
68 ValuatorClassInfo(const XIValuatorClassInfo& info) 85 ValuatorClassInfo(const XIValuatorClassInfo& info)
69 : label(info.label), 86 : label(info.label),
70 max(info.max), 87 max(info.max),
71 min(info.min), 88 min(info.min),
72 mode(info.mode), 89 mode(info.mode),
(...skipping 12 matching lines...) Expand all
85 TouchClassInfo() : mode(0), num_touches(0) {} 102 TouchClassInfo() : mode(0), num_touches(0) {}
86 103
87 explicit TouchClassInfo(const XITouchClassInfo& info) 104 explicit TouchClassInfo(const XITouchClassInfo& info)
88 : mode(info.mode), num_touches(info.num_touches) {} 105 : mode(info.mode), num_touches(info.num_touches) {}
89 106
90 int mode; 107 int mode;
91 int num_touches; 108 int num_touches;
92 }; 109 };
93 110
94 struct DeviceInfo { 111 struct DeviceInfo {
95 DeviceInfo(const XIDeviceInfo& device, const base::FilePath& path) 112 DeviceInfo(const XIDeviceInfo& device,
113 DeviceType type,
114 const base::FilePath& path)
96 : id(device.deviceid), 115 : id(device.deviceid),
97 name(device.name), 116 name(device.name),
98 use(device.use), 117 use(device.use),
99 enabled(device.enabled), 118 enabled(device.enabled),
119 type(type),
100 path(path) { 120 path(path) {
101 for (int i = 0; i < device.num_classes; ++i) { 121 for (int i = 0; i < device.num_classes; ++i) {
102 switch (device.classes[i]->type) { 122 switch (device.classes[i]->type) {
103 case XIValuatorClass: 123 case XIValuatorClass:
104 valuator_class_infos.push_back(ValuatorClassInfo( 124 valuator_class_infos.push_back(ValuatorClassInfo(
105 *reinterpret_cast<XIValuatorClassInfo*>(device.classes[i]))); 125 *reinterpret_cast<XIValuatorClassInfo*>(device.classes[i])));
106 break; 126 break;
107 case XITouchClass: 127 case XITouchClass:
108 // A device can have at most one XITouchClassInfo. Ref: 128 // A device can have at most one XITouchClassInfo. Ref:
109 // http://manpages.ubuntu.com/manpages/saucy/man3/XIQueryDevice.3.html 129 // http://manpages.ubuntu.com/manpages/saucy/man3/XIQueryDevice.3.html
(...skipping 12 matching lines...) Expand all
122 142
123 // Internal device name. 143 // Internal device name.
124 std::string name; 144 std::string name;
125 145
126 // Device type (ie: XIMasterPointer) 146 // Device type (ie: XIMasterPointer)
127 int use; 147 int use;
128 148
129 // Specifies if the device is enabled and can send events. 149 // Specifies if the device is enabled and can send events.
130 bool enabled; 150 bool enabled;
131 151
152 // Specifies the type of the device.
153 DeviceType type;
154
132 // Path to the actual device (ie: /dev/input/eventXX) 155 // Path to the actual device (ie: /dev/input/eventXX)
133 base::FilePath path; 156 base::FilePath path;
134 157
135 std::vector<ValuatorClassInfo> valuator_class_infos; 158 std::vector<ValuatorClassInfo> valuator_class_infos;
136 159
137 TouchClassInfo touch_class_info; 160 TouchClassInfo touch_class_info;
138 }; 161 };
139 162
140 // X11 display cache used on worker threads. This is filled on the UI thread and 163 // X11 display cache used on worker threads. This is filled on the UI thread and
141 // passed in to the worker threads. 164 // passed in to the worker threads.
142 struct DisplayState { 165 struct DisplayState {
143 Atom mt_position_x; 166 Atom mt_position_x;
144 Atom mt_position_y; 167 Atom mt_position_y;
145 }; 168 };
146 169
147 // Returns true if |name| is the name of a known invalid keyboard device. Note, 170 // Returns true if |name| is the name of a known invalid keyboard device. Note,
148 // this may return false negatives. 171 // this may return false negatives.
149 bool IsKnownInvalidKeyboardDevice(const std::string& name) { 172 bool IsKnownInvalidKeyboardDevice(const std::string& name) {
173 std::string trimmed(name);
174 base::TrimWhitespaceASCII(name, base::TRIM_TRAILING, &trimmed);
150 for (const char* device_name : kKnownInvalidKeyboardDeviceNames) { 175 for (const char* device_name : kKnownInvalidKeyboardDeviceNames) {
151 if (name == device_name) 176 if (trimmed == device_name)
152 return true; 177 return true;
153 } 178 }
154 return false; 179 return false;
155 } 180 }
156 181
157 // Returns true if |name| is the name of a known XTEST device. Note, this may 182 // Returns true if |name| is the name of a known XTEST device. Note, this may
158 // return false negatives. 183 // return false negatives.
159 bool IsTestKeyboard(const std::string& name) { 184 bool IsTestDevice(const std::string& name) {
160 return name.find("XTEST") != std::string::npos; 185 return name.find("XTEST") != std::string::npos;
161 } 186 }
162 187
163 base::FilePath GetDevicePath(XDisplay* dpy, const XIDeviceInfo& device) { 188 base::FilePath GetDevicePath(XDisplay* dpy, const XIDeviceInfo& device) {
164 // Skip the main pointer and keyboard since XOpenDevice() generates a 189 // Skip the main pointer and keyboard since XOpenDevice() generates a
165 // BadDevice error when passed these devices. 190 // BadDevice error when passed these devices.
166 if (device.use == XIMasterPointer || device.use == XIMasterKeyboard) 191 if (device.use == XIMasterPointer || device.use == XIMasterKeyboard)
167 return base::FilePath(); 192 return base::FilePath();
168 193
169 // Input device has a property "Device Node" pointing to its dev input node, 194 // Input device has a property "Device Node" pointing to its dev input node,
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
209 234
210 // Helper used to parse keyboard information. When it is done it uses 235 // Helper used to parse keyboard information. When it is done it uses
211 // |reply_runner| and |callback| to update the state on the UI thread. 236 // |reply_runner| and |callback| to update the state on the UI thread.
212 void HandleKeyboardDevicesInWorker( 237 void HandleKeyboardDevicesInWorker(
213 const std::vector<DeviceInfo>& device_infos, 238 const std::vector<DeviceInfo>& device_infos,
214 scoped_refptr<base::TaskRunner> reply_runner, 239 scoped_refptr<base::TaskRunner> reply_runner,
215 const KeyboardDeviceCallback& callback) { 240 const KeyboardDeviceCallback& callback) {
216 std::vector<KeyboardDevice> devices; 241 std::vector<KeyboardDevice> devices;
217 242
218 for (const DeviceInfo& device_info : device_infos) { 243 for (const DeviceInfo& device_info : device_infos) {
219 if (!device_info.enabled || device_info.use != XISlaveKeyboard) 244 if (!device_info.enabled || device_info.type != DEVICE_TYPE_KEYBOARD)
245 continue;
246 if (device_info.use != XISlaveKeyboard)
220 continue; // Assume all keyboards are keyboard slaves 247 continue; // Assume all keyboards are keyboard slaves
221 std::string device_name(device_info.name); 248 if (IsTestDevice(device_info.name))
222 base::TrimWhitespaceASCII(device_name, base::TRIM_TRAILING, &device_name);
223 if (IsTestKeyboard(device_name))
224 continue; // Skip test devices. 249 continue; // Skip test devices.
225 if (IsKnownInvalidKeyboardDevice(device_name)) 250 if (IsKnownInvalidKeyboardDevice(device_info.name))
226 continue; // Skip invalid devices. 251 continue; // Skip invalid devices.
227 InputDeviceType type = GetInputDeviceTypeFromPath(device_info.path); 252 InputDeviceType type = GetInputDeviceTypeFromPath(device_info.path);
228 devices.push_back(KeyboardDevice(device_info.id, type)); 253 devices.push_back(KeyboardDevice(device_info.id, type));
229 } 254 }
230 255
231 reply_runner->PostTask(FROM_HERE, base::Bind(callback, devices)); 256 reply_runner->PostTask(FROM_HERE, base::Bind(callback, devices));
232 } 257 }
233 258
259 // Helper used to parse mouse information. When it is done it uses
260 // |reply_runner| and |callback| to update the state on the UI thread.
261 void HandleMouseDevicesInWorker(const std::vector<DeviceInfo>& device_infos,
262 scoped_refptr<base::TaskRunner> reply_runner,
263 const InputDeviceCallback& callback) {
264 std::vector<InputDevice> devices;
265 for (const DeviceInfo& device_info : device_infos) {
266 if (!device_info.enabled || device_info.type != DEVICE_TYPE_MOUSE ||
267 device_info.use != XISlavePointer || IsTestDevice(device_info.name)) {
268 continue;
269 }
270
271 InputDeviceType type = GetInputDeviceTypeFromPath(device_info.path);
272 devices.push_back(InputDevice(device_info.id, type));
273 }
274
275 reply_runner->PostTask(FROM_HERE, base::Bind(callback, devices));
276 }
277
278 // Helper used to parse touchpad information. When it is done it uses
279 // |reply_runner| and |callback| to update the state on the UI thread.
280 void HandleTouchpadDevicesInWorker(const std::vector<DeviceInfo>& device_infos,
281 scoped_refptr<base::TaskRunner> reply_runner,
282 const InputDeviceCallback& callback) {
283 std::vector<InputDevice> devices;
284 for (const DeviceInfo& device_info : device_infos) {
285 if (!device_info.enabled || device_info.type != DEVICE_TYPE_TOUCHPAD ||
286 device_info.use != XISlavePointer || IsTestDevice(device_info.name)) {
287 continue;
288 }
289
290 InputDeviceType type = GetInputDeviceTypeFromPath(device_info.path);
291 devices.push_back(InputDevice(device_info.id, type));
292 }
293
294 reply_runner->PostTask(FROM_HERE, base::Bind(callback, devices));
295 }
296
234 // Helper used to parse touchscreen information. When it is done it uses 297 // Helper used to parse touchscreen information. When it is done it uses
235 // |reply_runner| and |callback| to update the state on the UI thread. 298 // |reply_runner| and |callback| to update the state on the UI thread.
236 void HandleTouchscreenDevicesInWorker( 299 void HandleTouchscreenDevicesInWorker(
237 const std::vector<DeviceInfo>& device_infos, 300 const std::vector<DeviceInfo>& device_infos,
238 const DisplayState& display_state, 301 const DisplayState& display_state,
239 scoped_refptr<base::TaskRunner> reply_runner, 302 scoped_refptr<base::TaskRunner> reply_runner,
240 const TouchscreenDeviceCallback& callback) { 303 const TouchscreenDeviceCallback& callback) {
241 std::vector<TouchscreenDevice> devices; 304 std::vector<TouchscreenDevice> devices;
242 if (display_state.mt_position_x == None || 305 if (display_state.mt_position_x == None ||
243 display_state.mt_position_y == None) 306 display_state.mt_position_y == None)
244 return; 307 return;
245 308
246 std::set<int> no_match_touchscreen;
247 for (const DeviceInfo& device_info : device_infos) { 309 for (const DeviceInfo& device_info : device_infos) {
248 if (!device_info.enabled || (device_info.use != XIFloatingSlave 310 if (!device_info.enabled ||
249 && device_info.use != XISlavePointer)) 311 device_info.type != DEVICE_TYPE_TOUCHSCREEN ||
312 (device_info.use != XIFloatingSlave &&
313 device_info.use != XISlavePointer)) {
314 continue;
315 }
316
317 // Touchscreens should be direct touch devices.
318 if (device_info.touch_class_info.mode != XIDirectTouch)
250 continue; 319 continue;
251 320
252 double max_x = -1.0; 321 double max_x = -1.0;
253 double max_y = -1.0; 322 double max_y = -1.0;
254 bool is_direct_touch = false;
255 323
256 for (const ValuatorClassInfo& valuator : device_info.valuator_class_infos) { 324 for (const ValuatorClassInfo& valuator : device_info.valuator_class_infos) {
257 if (display_state.mt_position_x == valuator.label) { 325 if (display_state.mt_position_x == valuator.label) {
258 // Ignore X axis valuator with unexpected properties 326 // Ignore X axis valuator with unexpected properties
259 if (valuator.number == 0 && valuator.mode == Absolute && 327 if (valuator.number == 0 && valuator.mode == Absolute &&
260 valuator.min == 0.0) { 328 valuator.min == 0.0) {
261 max_x = valuator.max; 329 max_x = valuator.max;
262 } 330 }
263 } else if (display_state.mt_position_y == valuator.label) { 331 } else if (display_state.mt_position_y == valuator.label) {
264 // Ignore Y axis valuator with unexpected properties 332 // Ignore Y axis valuator with unexpected properties
265 if (valuator.number == 1 && valuator.mode == Absolute && 333 if (valuator.number == 1 && valuator.mode == Absolute &&
266 valuator.min == 0.0) { 334 valuator.min == 0.0) {
267 max_y = valuator.max; 335 max_y = valuator.max;
268 } 336 }
269 } 337 }
270 } 338 }
271 339
272 if (device_info.touch_class_info.mode) 340 // Touchscreens should have absolute X and Y axes.
273 is_direct_touch = device_info.touch_class_info.mode == XIDirectTouch; 341 if (max_x > 0.0 && max_y > 0.0) {
274
275 // Touchscreens should have absolute X and Y axes, and be direct touch
276 // devices.
277 if (max_x > 0.0 && max_y > 0.0 && is_direct_touch) {
278 InputDeviceType type = GetInputDeviceTypeFromPath(device_info.path); 342 InputDeviceType type = GetInputDeviceTypeFromPath(device_info.path);
279 // |max_x| and |max_y| are inclusive values, so we need to add 1 to get 343 // |max_x| and |max_y| are inclusive values, so we need to add 1 to get
280 // the size. 344 // the size.
281 devices.push_back(TouchscreenDevice( 345 devices.push_back(TouchscreenDevice(
282 device_info.id, type, gfx::Size(max_x + 1, max_y + 1), 346 device_info.id, type, gfx::Size(max_x + 1, max_y + 1),
283 device_info.touch_class_info.num_touches)); 347 device_info.touch_class_info.num_touches));
284 } 348 }
285 } 349 }
286 350
287 reply_runner->PostTask(FROM_HERE, base::Bind(callback, devices)); 351 reply_runner->PostTask(FROM_HERE, base::Bind(callback, devices));
288 } 352 }
289 353
290 // Called on a worker thread to parse the device information. 354 // Called on a worker thread to parse the device information.
291 void HandleHotplugEventInWorker( 355 void HandleHotplugEventInWorker(
292 const std::vector<DeviceInfo>& devices, 356 const std::vector<DeviceInfo>& devices,
293 const DisplayState& display_state, 357 const DisplayState& display_state,
294 scoped_refptr<base::TaskRunner> reply_runner, 358 scoped_refptr<base::TaskRunner> reply_runner,
295 const UiCallbacks& callbacks) { 359 const UiCallbacks& callbacks) {
296 HandleTouchscreenDevicesInWorker( 360 HandleTouchscreenDevicesInWorker(
297 devices, display_state, reply_runner, callbacks.touchscreen_callback); 361 devices, display_state, reply_runner, callbacks.touchscreen_callback);
298 HandleKeyboardDevicesInWorker( 362 HandleKeyboardDevicesInWorker(
299 devices, reply_runner, callbacks.keyboard_callback); 363 devices, reply_runner, callbacks.keyboard_callback);
364 HandleMouseDevicesInWorker(devices, reply_runner, callbacks.mouse_callback);
365 HandleTouchpadDevicesInWorker(devices, reply_runner,
366 callbacks.touchpad_callback);
300 } 367 }
301 368
302 DeviceHotplugEventObserver* GetHotplugEventObserver() { 369 DeviceHotplugEventObserver* GetHotplugEventObserver() {
303 return DeviceDataManager::GetInstance(); 370 return DeviceDataManager::GetInstance();
304 } 371 }
305 372
306 void OnKeyboardDevices(const std::vector<KeyboardDevice>& devices) { 373 void OnKeyboardDevices(const std::vector<KeyboardDevice>& devices) {
307 GetHotplugEventObserver()->OnKeyboardDevicesUpdated(devices); 374 GetHotplugEventObserver()->OnKeyboardDevicesUpdated(devices);
308 } 375 }
309 376
310 void OnTouchscreenDevices(const std::vector<TouchscreenDevice>& devices) { 377 void OnTouchscreenDevices(const std::vector<TouchscreenDevice>& devices) {
311 GetHotplugEventObserver()->OnTouchscreenDevicesUpdated(devices); 378 GetHotplugEventObserver()->OnTouchscreenDevicesUpdated(devices);
312 } 379 }
313 380
381 void OnMouseDevices(const std::vector<InputDevice>& devices) {
382 GetHotplugEventObserver()->OnMouseDevicesUpdated(devices);
383 }
384
385 void OnTouchpadDevices(const std::vector<InputDevice>& devices) {
386 GetHotplugEventObserver()->OnTouchpadDevicesUpdated(devices);
387 }
388
314 } // namespace 389 } // namespace
315 390
316 X11HotplugEventHandler::X11HotplugEventHandler() 391 X11HotplugEventHandler::X11HotplugEventHandler()
317 : atom_cache_(gfx::GetXDisplay(), kCachedAtomList) { 392 : atom_cache_(gfx::GetXDisplay(), kCachedAtomList) {
318 } 393 }
319 394
320 X11HotplugEventHandler::~X11HotplugEventHandler() { 395 X11HotplugEventHandler::~X11HotplugEventHandler() {
321 } 396 }
322 397
323 void X11HotplugEventHandler::OnHotplugEvent() { 398 void X11HotplugEventHandler::OnHotplugEvent() {
324 const XIDeviceList& device_list =
325 DeviceListCacheX11::GetInstance()->GetXI2DeviceList(gfx::GetXDisplay());
326 Display* display = gfx::GetXDisplay(); 399 Display* display = gfx::GetXDisplay();
400 const XDeviceList& device_list_xi =
401 DeviceListCacheX11::GetInstance()->GetXDeviceList(display);
402 const XIDeviceList& device_list_xi2 =
403 DeviceListCacheX11::GetInstance()->GetXI2DeviceList(display);
404
405 const int kMaxDeviceNum = 128;
406 DeviceType device_types[kMaxDeviceNum];
407 for (int i = 0; i < kMaxDeviceNum; ++i)
408 device_types[i] = DEVICE_TYPE_OTHER;
409
410 for (int i = 0; i < device_list_xi.count; ++i) {
411 int id = device_list_xi[i].id;
412 if (id >= kMaxDeviceNum)
413 continue;
414
415 Atom type = device_list_xi[i].type;
416 if (type == atom_cache_.GetAtom(XI_KEYBOARD))
417 device_types[id] = DEVICE_TYPE_KEYBOARD;
418 else if (type == atom_cache_.GetAtom(XI_MOUSE))
419 device_types[id] = DEVICE_TYPE_MOUSE;
420 else if (type == atom_cache_.GetAtom(XI_TOUCHPAD))
421 device_types[id] = DEVICE_TYPE_TOUCHPAD;
422 else if (type == atom_cache_.GetAtom(XI_TOUCHSCREEN))
423 device_types[id] = DEVICE_TYPE_TOUCHSCREEN;
424 }
327 425
328 std::vector<DeviceInfo> device_infos; 426 std::vector<DeviceInfo> device_infos;
329 for (int i = 0; i < device_list.count; ++i) { 427 for (int i = 0; i < device_list_xi2.count; ++i) {
330 const XIDeviceInfo& device = device_list[i]; 428 const XIDeviceInfo& device = device_list_xi2[i];
331 device_infos.push_back(DeviceInfo(device, GetDevicePath(display, device))); 429 DeviceType device_type = (device.deviceid < kMaxDeviceNum)
430 ? device_types[device.deviceid]
431 : DEVICE_TYPE_OTHER;
432 device_infos.push_back(
433 DeviceInfo(device, device_type, GetDevicePath(display, device)));
sadrul 2015/02/23 21:54:04 Can we do some filtering here to avoid the same fi
332 } 434 }
333 435
334 // X11 is not thread safe, so first get all the required state. 436 // X11 is not thread safe, so first get all the required state.
335 DisplayState display_state; 437 DisplayState display_state;
336 display_state.mt_position_x = atom_cache_.GetAtom("Abs MT Position X"); 438 display_state.mt_position_x = atom_cache_.GetAtom("Abs MT Position X");
337 display_state.mt_position_y = atom_cache_.GetAtom("Abs MT Position Y"); 439 display_state.mt_position_y = atom_cache_.GetAtom("Abs MT Position Y");
338 440
339 UiCallbacks callbacks; 441 UiCallbacks callbacks;
340 callbacks.keyboard_callback = base::Bind(&OnKeyboardDevices); 442 callbacks.keyboard_callback = base::Bind(&OnKeyboardDevices);
341 callbacks.touchscreen_callback = base::Bind(&OnTouchscreenDevices); 443 callbacks.touchscreen_callback = base::Bind(&OnTouchscreenDevices);
342 // TODO(pkotwicz): Compute the lists of mice and touchpads and send the new 444 callbacks.mouse_callback = base::Bind(&OnMouseDevices);
343 // lists to DeviceHotplugEventObserver. 445 callbacks.touchpad_callback = base::Bind(&OnTouchpadDevices);
344 446
345 // Parsing the device information may block, so delegate the operation to a 447 // Parsing the device information may block, so delegate the operation to a
346 // worker thread. Once the device information is extracted the parsed devices 448 // worker thread. Once the device information is extracted the parsed devices
347 // will be returned via the callbacks. 449 // will be returned via the callbacks.
348 base::WorkerPool::PostTask(FROM_HERE, 450 base::WorkerPool::PostTask(FROM_HERE,
349 base::Bind(&HandleHotplugEventInWorker, 451 base::Bind(&HandleHotplugEventInWorker,
350 device_infos, 452 device_infos,
351 display_state, 453 display_state,
352 base::ThreadTaskRunnerHandle::Get(), 454 base::ThreadTaskRunnerHandle::Get(),
353 callbacks), 455 callbacks),
354 true /* task_is_slow */); 456 true /* task_is_slow */);
355 } 457 }
356 458
357 } // namespace ui 459 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698