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

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

Issue 645673003: ozone: evdev: Minor refactor of device open (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 2 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/event_factory_evdev.h" 5 #include "ui/events/ozone/evdev/event_factory_evdev.h"
6 6
7 #include <fcntl.h> 7 #include <fcntl.h>
8 #include <linux/input.h> 8 #include <linux/input.h>
9 9
10 #include "base/debug/trace_event.h" 10 #include "base/debug/trace_event.h"
(...skipping 15 matching lines...) Expand all
26 #endif 26 #endif
27 27
28 #ifndef EVIOCSCLOCKID 28 #ifndef EVIOCSCLOCKID
29 #define EVIOCSCLOCKID _IOW('E', 0xa0, int) 29 #define EVIOCSCLOCKID _IOW('E', 0xa0, int)
30 #endif 30 #endif
31 31
32 namespace ui { 32 namespace ui {
33 33
34 namespace { 34 namespace {
35 35
36 typedef base::Callback<void(scoped_ptr<EventConverterEvdev>)>
37 OpenInputDeviceReplyCallback;
38
39 struct OpenInputDeviceParams {
40 // Unique identifier for the new device.
41 int id;
42
43 // Device path to open.
44 base::FilePath path;
45
46 // Callback for dispatching events. Call on UI thread only.
47 EventDispatchCallback dispatch_callback;
48
49 // State shared between devices. Must not be dereferenced on worker thread.
50 EventModifiersEvdev* modifiers;
51 CursorDelegateEvdev* cursor;
52 };
53
36 #if defined(USE_EVDEV_GESTURES) 54 #if defined(USE_EVDEV_GESTURES)
37 bool UseGesturesLibraryForDevice(const EventDeviceInfo& devinfo) { 55 bool UseGesturesLibraryForDevice(const EventDeviceInfo& devinfo) {
38 if (devinfo.HasAbsXY() && !devinfo.IsMappedToScreen()) 56 if (devinfo.HasAbsXY() && !devinfo.IsMappedToScreen())
39 return true; // touchpad 57 return true; // touchpad
40 58
41 if (devinfo.HasRelXY()) 59 if (devinfo.HasRelXY())
42 return true; // mouse 60 return true; // mouse
43 61
44 return false; 62 return false;
45 } 63 }
46 #endif 64 #endif
47 65
48 scoped_ptr<EventConverterEvdev> CreateConverter( 66 scoped_ptr<EventConverterEvdev> CreateConverter(
67 const OpenInputDeviceParams& params,
49 int fd, 68 int fd,
50 const base::FilePath& path, 69 const EventDeviceInfo& devinfo) {
51 int id,
52 const EventDeviceInfo& devinfo,
53 const EventDispatchCallback& dispatch,
54 EventModifiersEvdev* modifiers,
55 CursorDelegateEvdev* cursor) {
56 #if defined(USE_EVDEV_GESTURES) 70 #if defined(USE_EVDEV_GESTURES)
57 // Touchpad or mouse: use gestures library. 71 // Touchpad or mouse: use gestures library.
58 // EventReaderLibevdevCros -> GestureInterpreterLibevdevCros -> DispatchEvent 72 // EventReaderLibevdevCros -> GestureInterpreterLibevdevCros -> DispatchEvent
59 if (UseGesturesLibraryForDevice(devinfo)) { 73 if (UseGesturesLibraryForDevice(devinfo)) {
60 scoped_ptr<GestureInterpreterLibevdevCros> gesture_interp = make_scoped_ptr( 74 scoped_ptr<GestureInterpreterLibevdevCros> gesture_interp =
61 new GestureInterpreterLibevdevCros(modifiers, cursor, dispatch)); 75 make_scoped_ptr(new GestureInterpreterLibevdevCros(
76 params.modifiers, params.cursor, params.dispatch_callback));
62 scoped_ptr<EventReaderLibevdevCros> libevdev_reader = 77 scoped_ptr<EventReaderLibevdevCros> libevdev_reader =
63 make_scoped_ptr(new EventReaderLibevdevCros( 78 make_scoped_ptr(new EventReaderLibevdevCros(
64 fd, 79 fd,
65 path, 80 params.path,
66 id, 81 params.id,
67 gesture_interp.PassAs<EventReaderLibevdevCros::Delegate>())); 82 gesture_interp.PassAs<EventReaderLibevdevCros::Delegate>()));
68 return libevdev_reader.PassAs<EventConverterEvdev>(); 83 return libevdev_reader.PassAs<EventConverterEvdev>();
69 } 84 }
70 #endif 85 #endif
71 86
72 // Touchscreen: use TouchEventConverterEvdev. 87 // Touchscreen: use TouchEventConverterEvdev.
73 scoped_ptr<EventConverterEvdev> converter; 88 scoped_ptr<EventConverterEvdev> converter;
74 if (devinfo.HasAbsXY()) 89 if (devinfo.HasAbsXY())
75 return make_scoped_ptr<EventConverterEvdev>( 90 return make_scoped_ptr<EventConverterEvdev>(new TouchEventConverterEvdev(
76 new TouchEventConverterEvdev(fd, path, id, devinfo, dispatch)); 91 fd, params.path, params.id, devinfo, params.dispatch_callback));
77 92
78 // Everything else: use KeyEventConverterEvdev. 93 // Everything else: use KeyEventConverterEvdev.
79 return make_scoped_ptr<EventConverterEvdev>( 94 return make_scoped_ptr<EventConverterEvdev>(new KeyEventConverterEvdev(
80 new KeyEventConverterEvdev(fd, path, id, modifiers, dispatch)); 95 fd, params.path, params.id, params.modifiers, params.dispatch_callback));
81 } 96 }
82 97
83 // Open an input device. Opening may put the calling thread to sleep, and 98 // Open an input device. Opening may put the calling thread to sleep, and
84 // therefore should be run on a thread where latency is not critical. We 99 // therefore should be run on a thread where latency is not critical. We
85 // run it on a thread from the worker pool. 100 // run it on a thread from the worker pool.
86 // 101 //
87 // This takes a TaskRunner and runs the reply on that thread, so that we 102 // This takes a TaskRunner and runs the reply on that thread, so that we
88 // can hop threads if necessary (back to the UI thread). 103 // can hop threads if necessary (back to the UI thread).
89 void OpenInputDevice( 104 void OpenInputDevice(scoped_ptr<OpenInputDeviceParams> params,
90 const base::FilePath& path, 105 scoped_refptr<base::TaskRunner> reply_runner,
91 EventModifiersEvdev* modifiers, 106 const OpenInputDeviceReplyCallback& reply_callback) {
92 CursorDelegateEvdev* cursor, 107 const base::FilePath& path = params->path;
93 int device_id, 108
94 scoped_refptr<base::TaskRunner> reply_runner,
95 const EventDispatchCallback& dispatch,
96 base::Callback<void(scoped_ptr<EventConverterEvdev>)> reply_callback) {
97 TRACE_EVENT1("ozone", "OpenInputDevice", "path", path.value()); 109 TRACE_EVENT1("ozone", "OpenInputDevice", "path", path.value());
98 110
99 int fd = open(path.value().c_str(), O_RDONLY | O_NONBLOCK); 111 int fd = open(path.value().c_str(), O_RDONLY | O_NONBLOCK);
100 if (fd < 0) { 112 if (fd < 0) {
101 PLOG(ERROR) << "Cannot open '" << path.value(); 113 PLOG(ERROR) << "Cannot open '" << path.value();
102 return; 114 return;
103 } 115 }
104 116
105 // Use monotonic timestamps for events. The touch code in particular 117 // Use monotonic timestamps for events. The touch code in particular
106 // expects event timestamps to correlate to the monotonic clock 118 // expects event timestamps to correlate to the monotonic clock
107 // (base::TimeTicks). 119 // (base::TimeTicks).
108 unsigned int clk = CLOCK_MONOTONIC; 120 unsigned int clk = CLOCK_MONOTONIC;
109 if (ioctl(fd, EVIOCSCLOCKID, &clk)) 121 if (ioctl(fd, EVIOCSCLOCKID, &clk))
110 PLOG(ERROR) << "failed to set CLOCK_MONOTONIC"; 122 PLOG(ERROR) << "failed to set CLOCK_MONOTONIC";
111 123
112 EventDeviceInfo devinfo; 124 EventDeviceInfo devinfo;
113 if (!devinfo.Initialize(fd)) { 125 if (!devinfo.Initialize(fd)) {
114 LOG(ERROR) << "failed to get device information for " << path.value(); 126 LOG(ERROR) << "failed to get device information for " << path.value();
115 close(fd); 127 close(fd);
116 return; 128 return;
117 } 129 }
118 130
119 scoped_ptr<EventConverterEvdev> converter = CreateConverter( 131 scoped_ptr<EventConverterEvdev> converter =
120 fd, path, device_id, devinfo, dispatch, modifiers, cursor); 132 CreateConverter(*params, fd, devinfo);
121 133
122 // Reply with the constructed converter. 134 // Reply with the constructed converter.
123 reply_runner->PostTask(FROM_HERE, 135 reply_runner->PostTask(FROM_HERE,
124 base::Bind(reply_callback, base::Passed(&converter))); 136 base::Bind(reply_callback, base::Passed(&converter)));
125 } 137 }
126 138
127 // Close an input device. Closing may put the calling thread to sleep, and 139 // Close an input device. Closing may put the calling thread to sleep, and
128 // therefore should be run on a thread where latency is not critical. We 140 // therefore should be run on a thread where latency is not critical. We
129 // run it on the FILE thread. 141 // run it on the FILE thread.
130 void CloseInputDevice(const base::FilePath& path, 142 void CloseInputDevice(const base::FilePath& path,
(...skipping 16 matching lines...) Expand all
147 DCHECK(device_manager_); 159 DCHECK(device_manager_);
148 } 160 }
149 161
150 EventFactoryEvdev::~EventFactoryEvdev() { STLDeleteValues(&converters_); } 162 EventFactoryEvdev::~EventFactoryEvdev() { STLDeleteValues(&converters_); }
151 163
152 void EventFactoryEvdev::DispatchUiEvent(Event* event) { 164 void EventFactoryEvdev::DispatchUiEvent(Event* event) {
153 DispatchEvent(event); 165 DispatchEvent(event);
154 } 166 }
155 167
156 void EventFactoryEvdev::AttachInputDevice( 168 void EventFactoryEvdev::AttachInputDevice(
157 const base::FilePath& path,
158 scoped_ptr<EventConverterEvdev> converter) { 169 scoped_ptr<EventConverterEvdev> converter) {
170 const base::FilePath& path = converter->path();
171
159 TRACE_EVENT1("ozone", "AttachInputDevice", "path", path.value()); 172 TRACE_EVENT1("ozone", "AttachInputDevice", "path", path.value());
160 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); 173 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
161 174
162 // If we have an existing device, detach it. We don't want two 175 // If we have an existing device, detach it. We don't want two
163 // devices with the same name open at the same time. 176 // devices with the same name open at the same time.
164 if (converters_[path]) 177 if (converters_[path])
165 DetachInputDevice(path); 178 DetachInputDevice(path);
166 179
167 // Add initialized device to map. 180 // Add initialized device to map.
168 converters_[path] = converter.release(); 181 converters_[path] = converter.release();
169 converters_[path]->Start(); 182 converters_[path]->Start();
170 183
171 NotifyHotplugEventObserver(*converters_[path]); 184 NotifyHotplugEventObserver(*converters_[path]);
172 } 185 }
173 186
174 void EventFactoryEvdev::OnDeviceEvent(const DeviceEvent& event) { 187 void EventFactoryEvdev::OnDeviceEvent(const DeviceEvent& event) {
175 if (event.device_type() != DeviceEvent::INPUT) 188 if (event.device_type() != DeviceEvent::INPUT)
176 return; 189 return;
177 190
178 switch (event.action_type()) { 191 switch (event.action_type()) {
179 case DeviceEvent::ADD: 192 case DeviceEvent::ADD:
180 case DeviceEvent::CHANGE: { 193 case DeviceEvent::CHANGE: {
181 TRACE_EVENT1("ozone", "OnDeviceAdded", "path", event.path().value()); 194 TRACE_EVENT1("ozone", "OnDeviceAdded", "path", event.path().value());
182 195
196 scoped_ptr<OpenInputDeviceParams> params(new OpenInputDeviceParams);
197 params->id = NextDeviceId();
198 params->path = event.path();
199 params->dispatch_callback = dispatch_callback_;
200 params->modifiers = &modifiers_;
201 params->cursor = cursor_;
202
203 OpenInputDeviceReplyCallback reply_callback =
204 base::Bind(&EventFactoryEvdev::AttachInputDevice,
205 weak_ptr_factory_.GetWeakPtr());
206
183 // Dispatch task to open from the worker pool, since open may block. 207 // Dispatch task to open from the worker pool, since open may block.
184 base::WorkerPool::PostTask( 208 base::WorkerPool::PostTask(FROM_HERE,
185 FROM_HERE, 209 base::Bind(&OpenInputDevice,
186 base::Bind(&OpenInputDevice, 210 base::Passed(&params),
187 event.path(), 211 ui_task_runner_,
188 &modifiers_, 212 reply_callback),
189 cursor_, 213 true /* task_is_slow */);
190 NextDeviceId(),
191 ui_task_runner_,
192 dispatch_callback_,
193 base::Bind(&EventFactoryEvdev::AttachInputDevice,
194 weak_ptr_factory_.GetWeakPtr(),
195 event.path())),
196 true);
197 } 214 }
198 break; 215 break;
199 case DeviceEvent::REMOVE: { 216 case DeviceEvent::REMOVE: {
200 TRACE_EVENT1("ozone", "OnDeviceRemoved", "path", event.path().value()); 217 TRACE_EVENT1("ozone", "OnDeviceRemoved", "path", event.path().value());
201 DetachInputDevice(event.path()); 218 DetachInputDevice(event.path());
202 } 219 }
203 break; 220 break;
204 } 221 }
205 } 222 }
206 223
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
267 } 284 }
268 285
269 observer->OnTouchscreenDevicesUpdated(touchscreens); 286 observer->OnTouchscreenDevicesUpdated(touchscreens);
270 } 287 }
271 288
272 int EventFactoryEvdev::NextDeviceId() { 289 int EventFactoryEvdev::NextDeviceId() {
273 return ++last_device_id_; 290 return ++last_device_id_;
274 } 291 }
275 292
276 } // namespace ui 293 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698