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
3 // found in the LICENSE file.
5 #include "ui/events/ozone/evdev/event_factory_evdev.h"
8 #include "base/task_runner.h"
9 #include "base/thread_task_runner_handle.h"
10 #include "base/threading/worker_pool.h"
11 #include "base/time/time.h"
12 #include "base/trace_event/trace_event.h"
13 #include "ui/events/devices/device_data_manager.h"
14 #include "ui/events/devices/input_device.h"
15 #include "ui/events/event_utils.h"
16 #include "ui/events/ozone/device/device_event.h"
17 #include "ui/events/ozone/device/device_manager.h"
18 #include "ui/events/ozone/evdev/cursor_delegate_evdev.h"
19 #include "ui/events/ozone/evdev/input_controller_evdev.h"
20 #include "ui/events/ozone/evdev/input_device_factory_evdev.h"
21 #include "ui/events/ozone/evdev/input_device_factory_evdev_proxy.h"
22 #include "ui/events/ozone/evdev/input_injector_evdev.h"
28 // Thread safe dispatcher proxy for EventFactoryEvdev.
30 // This is used on the device I/O thread for dispatching to UI.
31 class ProxyDeviceEventDispatcher
: public DeviceEventDispatcherEvdev
{
33 ProxyDeviceEventDispatcher(
34 scoped_refptr
<base::SingleThreadTaskRunner
> ui_thread_runner
,
35 base::WeakPtr
<EventFactoryEvdev
> event_factory_evdev
)
36 : ui_thread_runner_(ui_thread_runner
),
37 event_factory_evdev_(event_factory_evdev
) {}
38 ~ProxyDeviceEventDispatcher() override
{}
40 // DeviceEventDispatcher:
41 void DispatchKeyEvent(const KeyEventParams
& params
) override
{
42 ui_thread_runner_
->PostTask(FROM_HERE
,
43 base::Bind(&EventFactoryEvdev::DispatchKeyEvent
,
44 event_factory_evdev_
, params
));
47 void DispatchMouseMoveEvent(const MouseMoveEventParams
& params
) override
{
48 ui_thread_runner_
->PostTask(
49 FROM_HERE
, base::Bind(&EventFactoryEvdev::DispatchMouseMoveEvent
,
50 event_factory_evdev_
, params
));
53 void DispatchMouseButtonEvent(const MouseButtonEventParams
& params
) override
{
54 ui_thread_runner_
->PostTask(
55 FROM_HERE
, base::Bind(&EventFactoryEvdev::DispatchMouseButtonEvent
,
56 event_factory_evdev_
, params
));
59 void DispatchMouseWheelEvent(const MouseWheelEventParams
& params
) override
{
60 ui_thread_runner_
->PostTask(
61 FROM_HERE
, base::Bind(&EventFactoryEvdev::DispatchMouseWheelEvent
,
62 event_factory_evdev_
, params
));
65 void DispatchScrollEvent(const ScrollEventParams
& params
) override
{
66 ui_thread_runner_
->PostTask(
67 FROM_HERE
, base::Bind(&EventFactoryEvdev::DispatchScrollEvent
,
68 event_factory_evdev_
, params
));
71 void DispatchTouchEvent(const TouchEventParams
& params
) override
{
72 ui_thread_runner_
->PostTask(
73 FROM_HERE
, base::Bind(&EventFactoryEvdev::DispatchTouchEvent
,
74 event_factory_evdev_
, params
));
77 void DispatchKeyboardDevicesUpdated(
78 const std::vector
<KeyboardDevice
>& devices
) override
{
79 ui_thread_runner_
->PostTask(
81 base::Bind(&EventFactoryEvdev::DispatchKeyboardDevicesUpdated
,
82 event_factory_evdev_
, devices
));
84 void DispatchTouchscreenDevicesUpdated(
85 const std::vector
<TouchscreenDevice
>& devices
) override
{
86 ui_thread_runner_
->PostTask(
88 base::Bind(&EventFactoryEvdev::DispatchTouchscreenDevicesUpdated
,
89 event_factory_evdev_
, devices
));
91 void DispatchMouseDevicesUpdated(
92 const std::vector
<InputDevice
>& devices
) override
{
93 ui_thread_runner_
->PostTask(
94 FROM_HERE
, base::Bind(&EventFactoryEvdev::DispatchMouseDevicesUpdated
,
95 event_factory_evdev_
, devices
));
97 void DispatchTouchpadDevicesUpdated(
98 const std::vector
<InputDevice
>& devices
) override
{
99 ui_thread_runner_
->PostTask(
101 base::Bind(&EventFactoryEvdev::DispatchTouchpadDevicesUpdated
,
102 event_factory_evdev_
, devices
));
106 scoped_refptr
<base::SingleThreadTaskRunner
> ui_thread_runner_
;
107 base::WeakPtr
<EventFactoryEvdev
> event_factory_evdev_
;
112 EventFactoryEvdev::EventFactoryEvdev(CursorDelegateEvdev
* cursor
,
113 DeviceManager
* device_manager
,
114 KeyboardLayoutEngine
* keyboard_layout
)
115 : last_device_id_(0),
116 device_manager_(device_manager
),
117 keyboard_(&modifiers_
,
119 base::Bind(&EventFactoryEvdev::DispatchUiEvent
,
120 base::Unretained(this))),
122 input_controller_(&keyboard_
, &button_map_
),
124 weak_ptr_factory_(this) {
125 DCHECK(device_manager_
);
128 EventFactoryEvdev::~EventFactoryEvdev() {
131 void EventFactoryEvdev::Init() {
132 DCHECK(!initialized_
);
139 scoped_ptr
<SystemInputInjector
> EventFactoryEvdev::CreateSystemInputInjector() {
140 // Use forwarding dispatcher for the injector rather than dispatching
141 // directly. We cannot assume it is safe to (re-)enter ui::Event dispatch
142 // synchronously from the injection point.
143 scoped_ptr
<DeviceEventDispatcherEvdev
> proxy_dispatcher(
144 new ProxyDeviceEventDispatcher(base::ThreadTaskRunnerHandle::Get(),
145 weak_ptr_factory_
.GetWeakPtr()));
146 return make_scoped_ptr(
147 new InputInjectorEvdev(proxy_dispatcher
.Pass(), cursor_
));
150 void EventFactoryEvdev::DispatchKeyEvent(const KeyEventParams
& params
) {
151 keyboard_
.OnKeyChange(params
.code
, params
.down
, params
.timestamp
);
154 void EventFactoryEvdev::DispatchMouseMoveEvent(
155 const MouseMoveEventParams
& params
) {
156 MouseEvent
event(ui::ET_MOUSE_MOVED
, params
.location
, params
.location
,
157 params
.timestamp
, modifiers_
.GetModifierFlags(),
158 /* changed_button_flags */ 0);
159 event
.set_source_device_id(params
.device_id
);
160 DispatchUiEvent(&event
);
163 void EventFactoryEvdev::DispatchMouseButtonEvent(
164 const MouseButtonEventParams
& params
) {
165 // Mouse buttons can be remapped, touchpad taps & clicks cannot.
166 unsigned int button
= params
.button
;
167 if (params
.allow_remap
)
168 button
= button_map_
.GetMappedButton(button
);
170 int modifier
= EVDEV_MODIFIER_NONE
;
173 modifier
= EVDEV_MODIFIER_LEFT_MOUSE_BUTTON
;
176 modifier
= EVDEV_MODIFIER_RIGHT_MOUSE_BUTTON
;
179 modifier
= EVDEV_MODIFIER_MIDDLE_MOUSE_BUTTON
;
182 modifier
= EVDEV_MODIFIER_BACK_MOUSE_BUTTON
;
185 modifier
= EVDEV_MODIFIER_FORWARD_MOUSE_BUTTON
;
191 int flag
= modifiers_
.GetEventFlagFromModifier(modifier
);
192 modifiers_
.UpdateModifier(modifier
, params
.down
);
194 MouseEvent
event(params
.down
? ui::ET_MOUSE_PRESSED
: ui::ET_MOUSE_RELEASED
,
195 params
.location
, params
.location
, params
.timestamp
,
196 modifiers_
.GetModifierFlags() | flag
,
197 /* changed_button_flags */ flag
);
198 event
.set_source_device_id(params
.device_id
);
199 DispatchUiEvent(&event
);
202 void EventFactoryEvdev::DispatchMouseWheelEvent(
203 const MouseWheelEventParams
& params
) {
204 MouseWheelEvent
event(params
.delta
, params
.location
, params
.location
,
205 params
.timestamp
, modifiers_
.GetModifierFlags(),
206 0 /* changed_button_flags */);
207 event
.set_source_device_id(params
.device_id
);
208 DispatchUiEvent(&event
);
211 void EventFactoryEvdev::DispatchScrollEvent(const ScrollEventParams
& params
) {
212 ScrollEvent
event(params
.type
, params
.location
, params
.timestamp
,
213 modifiers_
.GetModifierFlags(), params
.delta
.x(),
214 params
.delta
.y(), params
.ordinal_delta
.x(),
215 params
.ordinal_delta
.y(), params
.finger_count
);
216 event
.set_source_device_id(params
.device_id
);
217 DispatchUiEvent(&event
);
220 void EventFactoryEvdev::DispatchTouchEvent(const TouchEventParams
& params
) {
221 float x
= params
.location
.x();
222 float y
= params
.location
.y();
223 double radius_x
= params
.radii
.x();
224 double radius_y
= params
.radii
.y();
226 // Transform the event to align touches to the image based on display mode.
227 DeviceDataManager::GetInstance()->ApplyTouchTransformer(params
.device_id
, &x
,
229 DeviceDataManager::GetInstance()->ApplyTouchRadiusScale(params
.device_id
,
231 DeviceDataManager::GetInstance()->ApplyTouchRadiusScale(params
.device_id
,
234 TouchEvent
touch_event(params
.type
, gfx::PointF(x
, y
),
235 modifiers_
.GetModifierFlags(), params
.touch_id
,
236 params
.timestamp
, radius_x
, radius_y
,
237 /* angle */ 0.f
, params
.pressure
);
238 touch_event
.set_source_device_id(params
.device_id
);
239 DispatchUiEvent(&touch_event
);
242 void EventFactoryEvdev::DispatchUiEvent(Event
* event
) {
243 // DispatchEvent takes PlatformEvent which is void*. This function
244 // wraps it with the real type.
245 DispatchEvent(event
);
248 void EventFactoryEvdev::DispatchKeyboardDevicesUpdated(
249 const std::vector
<KeyboardDevice
>& devices
) {
250 DeviceHotplugEventObserver
* observer
= DeviceDataManager::GetInstance();
251 observer
->OnKeyboardDevicesUpdated(devices
);
254 void EventFactoryEvdev::DispatchTouchscreenDevicesUpdated(
255 const std::vector
<TouchscreenDevice
>& devices
) {
256 DeviceHotplugEventObserver
* observer
= DeviceDataManager::GetInstance();
257 observer
->OnTouchscreenDevicesUpdated(devices
);
260 void EventFactoryEvdev::DispatchMouseDevicesUpdated(
261 const std::vector
<InputDevice
>& devices
) {
262 // There's no list of mice in DeviceDataManager.
263 input_controller_
.set_has_mouse(devices
.size() != 0);
264 DeviceHotplugEventObserver
* observer
= DeviceDataManager::GetInstance();
265 observer
->OnMouseDevicesUpdated(devices
);
268 void EventFactoryEvdev::DispatchTouchpadDevicesUpdated(
269 const std::vector
<InputDevice
>& devices
) {
270 // There's no list of touchpads in DeviceDataManager.
271 input_controller_
.set_has_touchpad(devices
.size() != 0);
272 DeviceHotplugEventObserver
* observer
= DeviceDataManager::GetInstance();
273 observer
->OnTouchpadDevicesUpdated(devices
);
277 void EventFactoryEvdev::OnDeviceEvent(const DeviceEvent
& event
) {
278 if (event
.device_type() != DeviceEvent::INPUT
)
281 switch (event
.action_type()) {
282 case DeviceEvent::ADD
:
283 case DeviceEvent::CHANGE
: {
284 TRACE_EVENT1("ozone", "OnDeviceAdded", "path", event
.path().value());
285 input_device_factory_proxy_
->AddInputDevice(NextDeviceId(), event
.path());
288 case DeviceEvent::REMOVE
: {
289 TRACE_EVENT1("ozone", "OnDeviceRemoved", "path", event
.path().value());
290 input_device_factory_proxy_
->RemoveInputDevice(event
.path());
296 void EventFactoryEvdev::OnDispatcherListChanged() {
301 void EventFactoryEvdev::WarpCursorTo(gfx::AcceleratedWidget widget
,
302 const gfx::PointF
& location
) {
306 cursor_
->MoveCursorTo(widget
, location
);
308 base::ThreadTaskRunnerHandle::Get()->PostTask(
309 FROM_HERE
, base::Bind(&EventFactoryEvdev::DispatchMouseMoveEvent
,
310 weak_ptr_factory_
.GetWeakPtr(),
311 MouseMoveEventParams(-1 /* device_id */,
312 cursor_
->GetLocation(),
313 EventTimeForNow())));
316 int EventFactoryEvdev::NextDeviceId() {
317 return ++last_device_id_
;
320 void EventFactoryEvdev::StartThread() {
321 // Set up device factory.
322 scoped_ptr
<DeviceEventDispatcherEvdev
> proxy_dispatcher(
323 new ProxyDeviceEventDispatcher(base::ThreadTaskRunnerHandle::Get(),
324 weak_ptr_factory_
.GetWeakPtr()));
325 thread_
.Start(proxy_dispatcher
.Pass(), cursor_
,
326 base::Bind(&EventFactoryEvdev::OnThreadStarted
,
327 weak_ptr_factory_
.GetWeakPtr()));
330 void EventFactoryEvdev::OnThreadStarted(
331 scoped_ptr
<InputDeviceFactoryEvdevProxy
> input_device_factory
) {
332 input_device_factory_proxy_
= input_device_factory
.Pass();
334 // Hook up device configuration.
335 input_controller_
.SetInputDeviceFactory(input_device_factory_proxy_
.get());
337 // Scan & monitor devices.
338 device_manager_
->AddObserver(this);
339 device_manager_
->ScanDevices(this);