OLD | NEW |
---|---|
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" |
11 #include "base/stl_util.h" | 11 #include "base/stl_util.h" |
12 #include "base/task_runner.h" | 12 #include "base/task_runner.h" |
13 #include "base/thread_task_runner_handle.h" | 13 #include "base/thread_task_runner_handle.h" |
14 #include "base/threading/worker_pool.h" | 14 #include "base/threading/worker_pool.h" |
15 #include "ui/events/device_data_manager.h" | 15 #include "ui/events/device_data_manager.h" |
16 #include "ui/events/ozone/device/device_event.h" | 16 #include "ui/events/ozone/device/device_event.h" |
17 #include "ui/events/ozone/device/device_manager.h" | 17 #include "ui/events/ozone/device/device_manager.h" |
18 #include "ui/events/ozone/evdev/cursor_delegate_evdev.h" | 18 #include "ui/events/ozone/evdev/cursor_delegate_evdev.h" |
19 #include "ui/events/ozone/evdev/event_device_info.h" | 19 #include "ui/events/ozone/evdev/event_device_info.h" |
20 #include "ui/events/ozone/evdev/key_event_converter_evdev.h" | 20 #include "ui/events/ozone/evdev/key_event_converter_evdev.h" |
21 #include "ui/events/ozone/evdev/touch_event_converter_evdev.h" | 21 #include "ui/events/ozone/evdev/touch_event_converter_evdev.h" |
22 | 22 |
23 #if defined(USE_EVDEV_GESTURES) | 23 #if defined(USE_EVDEV_GESTURES) |
24 #include "ui/events/ozone/evdev/libgestures_glue/event_reader_libevdev_cros.h" | 24 #include "ui/events/ozone/evdev/libgestures_glue/event_reader_libevdev_cros.h" |
25 #include "ui/events/ozone/evdev/libgestures_glue/gesture_interpreter_libevdev_cr os.h" | 25 #include "ui/events/ozone/evdev/libgestures_glue/gesture_interpreter_libevdev_cr os.h" |
26 #include "ui/events/ozone/evdev/libgestures_glue/gesture_property_provider.h" | |
26 #endif | 27 #endif |
27 | 28 |
28 #ifndef EVIOCSCLOCKID | 29 #ifndef EVIOCSCLOCKID |
29 #define EVIOCSCLOCKID _IOW('E', 0xa0, int) | 30 #define EVIOCSCLOCKID _IOW('E', 0xa0, int) |
30 #endif | 31 #endif |
31 | 32 |
32 namespace ui { | 33 namespace ui { |
33 | 34 |
34 namespace { | 35 namespace { |
35 | 36 |
37 // Max number of devices that we track. | |
38 const int kMaxDeviceNum = 0xffff; | |
39 | |
36 typedef base::Callback<void(scoped_ptr<EventConverterEvdev>)> | 40 typedef base::Callback<void(scoped_ptr<EventConverterEvdev>)> |
37 OpenInputDeviceReplyCallback; | 41 OpenInputDeviceReplyCallback; |
38 | 42 |
39 struct OpenInputDeviceParams { | 43 struct OpenInputDeviceParams { |
40 // Unique identifier for the new device. | 44 // Unique identifier for the new device. |
41 int id; | 45 int id; |
42 | 46 |
43 // Device path to open. | 47 // Device path to open. |
44 base::FilePath path; | 48 base::FilePath path; |
45 | 49 |
46 // Callback for dispatching events. Call on UI thread only. | 50 // Callback for dispatching events. Call on UI thread only. |
47 EventDispatchCallback dispatch_callback; | 51 EventDispatchCallback dispatch_callback; |
48 | 52 |
49 // State shared between devices. Must not be dereferenced on worker thread. | 53 // State shared between devices. Must not be dereferenced on worker thread. |
50 EventModifiersEvdev* modifiers; | 54 EventModifiersEvdev* modifiers; |
51 CursorDelegateEvdev* cursor; | 55 CursorDelegateEvdev* cursor; |
56 GesturePropertyProvider* gesture_property_provider; | |
52 }; | 57 }; |
53 | 58 |
54 #if defined(USE_EVDEV_GESTURES) | 59 #if defined(USE_EVDEV_GESTURES) |
55 bool UseGesturesLibraryForDevice(const EventDeviceInfo& devinfo) { | 60 bool UseGesturesLibraryForDevice(const EventDeviceInfo& devinfo) { |
56 if (devinfo.HasAbsXY() && !devinfo.IsMappedToScreen()) | 61 if (devinfo.HasAbsXY() && !devinfo.IsMappedToScreen()) |
57 return true; // touchpad | 62 return true; // touchpad |
58 | 63 |
59 if (devinfo.HasRelXY()) | 64 if (devinfo.HasRelXY()) |
60 return true; // mouse | 65 return true; // mouse |
61 | 66 |
62 return false; | 67 return false; |
63 } | 68 } |
64 #endif | 69 #endif |
65 | 70 |
66 scoped_ptr<EventConverterEvdev> CreateConverter( | 71 scoped_ptr<EventConverterEvdev> CreateConverter( |
67 const OpenInputDeviceParams& params, | 72 const OpenInputDeviceParams& params, |
68 int fd, | 73 int fd, |
69 const EventDeviceInfo& devinfo) { | 74 const EventDeviceInfo& devinfo) { |
70 #if defined(USE_EVDEV_GESTURES) | 75 #if defined(USE_EVDEV_GESTURES) |
71 // Touchpad or mouse: use gestures library. | 76 // Touchpad or mouse: use gestures library. |
72 // EventReaderLibevdevCros -> GestureInterpreterLibevdevCros -> DispatchEvent | 77 // EventReaderLibevdevCros -> GestureInterpreterLibevdevCros -> DispatchEvent |
73 if (UseGesturesLibraryForDevice(devinfo)) { | 78 if (UseGesturesLibraryForDevice(devinfo)) { |
74 scoped_ptr<GestureInterpreterLibevdevCros> gesture_interp = | 79 scoped_ptr<GestureInterpreterLibevdevCros> gesture_interp = |
75 make_scoped_ptr(new GestureInterpreterLibevdevCros( | 80 make_scoped_ptr(new GestureInterpreterLibevdevCros( |
76 params.modifiers, params.cursor, params.dispatch_callback)); | 81 params.id, params.modifiers, params.cursor, |
82 params.gesture_property_provider, params.dispatch_callback)); | |
77 scoped_ptr<EventReaderLibevdevCros> libevdev_reader = | 83 scoped_ptr<EventReaderLibevdevCros> libevdev_reader = |
78 make_scoped_ptr(new EventReaderLibevdevCros( | 84 make_scoped_ptr(new EventReaderLibevdevCros( |
79 fd, | 85 fd, |
80 params.path, | 86 params.path, |
81 params.id, | 87 params.id, |
82 gesture_interp.PassAs<EventReaderLibevdevCros::Delegate>())); | 88 gesture_interp.PassAs<EventReaderLibevdevCros::Delegate>())); |
83 return libevdev_reader.PassAs<EventConverterEvdev>(); | 89 return libevdev_reader.PassAs<EventConverterEvdev>(); |
84 } | 90 } |
85 #endif | 91 #endif |
86 | 92 |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
142 void CloseInputDevice(const base::FilePath& path, | 148 void CloseInputDevice(const base::FilePath& path, |
143 scoped_ptr<EventConverterEvdev> converter) { | 149 scoped_ptr<EventConverterEvdev> converter) { |
144 TRACE_EVENT1("ozone", "CloseInputDevice", "path", path.value()); | 150 TRACE_EVENT1("ozone", "CloseInputDevice", "path", path.value()); |
145 converter.reset(); | 151 converter.reset(); |
146 } | 152 } |
147 | 153 |
148 } // namespace | 154 } // namespace |
149 | 155 |
150 EventFactoryEvdev::EventFactoryEvdev(CursorDelegateEvdev* cursor, | 156 EventFactoryEvdev::EventFactoryEvdev(CursorDelegateEvdev* cursor, |
151 DeviceManager* device_manager) | 157 DeviceManager* device_manager) |
152 : last_device_id_(0), | 158 : device_id_counter_(0), |
153 device_manager_(device_manager), | 159 device_manager_(device_manager), |
154 cursor_(cursor), | 160 cursor_(cursor), |
161 #if defined(USE_EVDEV_GESTURES) | |
162 gesture_property_provider_(new GesturePropertyProvider), | |
163 #endif | |
155 dispatch_callback_( | 164 dispatch_callback_( |
156 base::Bind(base::IgnoreResult(&EventFactoryEvdev::DispatchUiEvent), | 165 base::Bind(base::IgnoreResult(&EventFactoryEvdev::DispatchUiEvent), |
157 base::Unretained(this))), | 166 base::Unretained(this))), |
158 weak_ptr_factory_(this) { | 167 weak_ptr_factory_(this) { |
159 DCHECK(device_manager_); | 168 DCHECK(device_manager_); |
160 } | 169 } |
161 | 170 |
162 EventFactoryEvdev::~EventFactoryEvdev() { STLDeleteValues(&converters_); } | 171 EventFactoryEvdev::~EventFactoryEvdev() { STLDeleteValues(&converters_); } |
163 | 172 |
164 void EventFactoryEvdev::DispatchUiEvent(Event* event) { | 173 void EventFactoryEvdev::DispatchUiEvent(Event* event) { |
(...skipping 22 matching lines...) Expand all Loading... | |
187 void EventFactoryEvdev::OnDeviceEvent(const DeviceEvent& event) { | 196 void EventFactoryEvdev::OnDeviceEvent(const DeviceEvent& event) { |
188 if (event.device_type() != DeviceEvent::INPUT) | 197 if (event.device_type() != DeviceEvent::INPUT) |
189 return; | 198 return; |
190 | 199 |
191 switch (event.action_type()) { | 200 switch (event.action_type()) { |
192 case DeviceEvent::ADD: | 201 case DeviceEvent::ADD: |
193 case DeviceEvent::CHANGE: { | 202 case DeviceEvent::CHANGE: { |
194 TRACE_EVENT1("ozone", "OnDeviceAdded", "path", event.path().value()); | 203 TRACE_EVENT1("ozone", "OnDeviceAdded", "path", event.path().value()); |
195 | 204 |
196 scoped_ptr<OpenInputDeviceParams> params(new OpenInputDeviceParams); | 205 scoped_ptr<OpenInputDeviceParams> params(new OpenInputDeviceParams); |
197 params->id = NextDeviceId(); | 206 params->id = GenerateDeviceId(event.path()); |
207 if (params->id < 0) | |
208 break; | |
198 params->path = event.path(); | 209 params->path = event.path(); |
199 params->dispatch_callback = dispatch_callback_; | 210 params->dispatch_callback = dispatch_callback_; |
200 params->modifiers = &modifiers_; | 211 params->modifiers = &modifiers_; |
201 params->cursor = cursor_; | 212 params->cursor = cursor_; |
213 params->gesture_property_provider = gesture_property_provider_.get(); | |
202 | 214 |
203 OpenInputDeviceReplyCallback reply_callback = | 215 OpenInputDeviceReplyCallback reply_callback = |
204 base::Bind(&EventFactoryEvdev::AttachInputDevice, | 216 base::Bind(&EventFactoryEvdev::AttachInputDevice, |
205 weak_ptr_factory_.GetWeakPtr()); | 217 weak_ptr_factory_.GetWeakPtr()); |
206 | 218 |
207 // Dispatch task to open from the worker pool, since open may block. | 219 // Dispatch task to open from the worker pool, since open may block. |
208 base::WorkerPool::PostTask(FROM_HERE, | 220 base::WorkerPool::PostTask(FROM_HERE, |
209 base::Bind(&OpenInputDevice, | 221 base::Bind(&OpenInputDevice, |
210 base::Passed(¶ms), | 222 base::Passed(¶ms), |
211 ui_task_runner_, | 223 ui_task_runner_, |
212 reply_callback), | 224 reply_callback), |
213 true /* task_is_slow */); | 225 true /* task_is_slow */); |
214 } | 226 } |
215 break; | 227 break; |
216 case DeviceEvent::REMOVE: { | 228 case DeviceEvent::REMOVE: { |
217 TRACE_EVENT1("ozone", "OnDeviceRemoved", "path", event.path().value()); | 229 TRACE_EVENT1("ozone", "OnDeviceRemoved", "path", event.path().value()); |
230 RevokeDeviceId(event.path()); | |
218 DetachInputDevice(event.path()); | 231 DetachInputDevice(event.path()); |
219 } | 232 } |
220 break; | 233 break; |
221 } | 234 } |
222 } | 235 } |
223 | 236 |
224 void EventFactoryEvdev::OnDispatcherListChanged() { | 237 void EventFactoryEvdev::OnDispatcherListChanged() { |
225 if (!ui_task_runner_.get()) { | 238 if (!ui_task_runner_.get()) { |
226 ui_task_runner_ = base::ThreadTaskRunnerHandle::Get(); | 239 ui_task_runner_ = base::ThreadTaskRunnerHandle::Get(); |
227 // Scan & monitor devices. | 240 // Scan & monitor devices. |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
279 if (it->second->HasTouchscreen()) { | 292 if (it->second->HasTouchscreen()) { |
280 touchscreens.push_back(TouchscreenDevice(it->second->id(), | 293 touchscreens.push_back(TouchscreenDevice(it->second->id(), |
281 it->second->GetTouchscreenSize(), | 294 it->second->GetTouchscreenSize(), |
282 false /* is_internal */)); | 295 false /* is_internal */)); |
283 } | 296 } |
284 } | 297 } |
285 | 298 |
286 observer->OnTouchscreenDevicesUpdated(touchscreens); | 299 observer->OnTouchscreenDevicesUpdated(touchscreens); |
287 } | 300 } |
288 | 301 |
289 int EventFactoryEvdev::NextDeviceId() { | 302 int EventFactoryEvdev::GenerateDeviceId(const base::FilePath& file_path) { |
290 return ++last_device_id_; | 303 // Do not generate if the maximum allowed device number is reached. |
304 if (used_device_ids_.size() >= kMaxDeviceNum) | |
305 return -1; | |
306 | |
307 // Generate a new device id for use. | |
308 int id = device_id_counter_; | |
309 while (used_device_ids_.find(id) != used_device_ids_.end()) | |
310 id = (id + 1) & kMaxDeviceNum; | |
spang
2014/10/15 11:36:41
This is way overkill. If 2 billion devices over th
Shecky Lin
2014/10/16 04:53:53
Done.
| |
311 device_id_counter_ = (id + 1) & kMaxDeviceNum; | |
312 used_device_ids_.insert(id); | |
313 | |
314 // If a same device node is opened again, we just replace its old id with a | |
315 // new one as this is the behavior we use for converters as well. | |
316 device_ids_map_[file_path] = id; | |
317 return id; | |
318 } | |
319 | |
320 void EventFactoryEvdev::RevokeDeviceId(const base::FilePath& file_path) { | |
321 DeviceIdMap::iterator it = device_ids_map_.find(file_path); | |
322 if (it == device_ids_map_.end()) | |
323 return; | |
324 used_device_ids_.erase(it->second); | |
325 device_ids_map_.erase(it); | |
291 } | 326 } |
292 | 327 |
293 } // namespace ui | 328 } // namespace ui |
OLD | NEW |