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.
4 
5 #include "ui/events/ozone/evdev/input_controller_evdev.h"
6 
7 #include <linux/input.h>
8 
9 #include <algorithm>
10 #include <utility>
11 
12 #include "base/bind.h"
13 #include "base/callback.h"
14 #include "base/threading/thread_task_runner_handle.h"
15 #include "ui/events/devices/device_data_manager.h"
16 #include "ui/events/ozone/evdev/input_device_factory_evdev_proxy.h"
17 #include "ui/events/ozone/evdev/keyboard_evdev.h"
18 #include "ui/events/ozone/evdev/mouse_button_map_evdev.h"
19 
20 namespace ui {
21 
InputControllerEvdev(KeyboardEvdev * keyboard,MouseButtonMapEvdev * button_map)22 InputControllerEvdev::InputControllerEvdev(KeyboardEvdev* keyboard,
23                                            MouseButtonMapEvdev* button_map)
24     : keyboard_(keyboard), button_map_(button_map) {}
25 
~InputControllerEvdev()26 InputControllerEvdev::~InputControllerEvdev() {
27 }
28 
SetInputDeviceFactory(InputDeviceFactoryEvdevProxy * input_device_factory)29 void InputControllerEvdev::SetInputDeviceFactory(
30     InputDeviceFactoryEvdevProxy* input_device_factory) {
31   input_device_factory_ = input_device_factory;
32 
33   UpdateDeviceSettings();
34   UpdateCapsLockLed();
35 }
36 
set_has_mouse(bool has_mouse)37 void InputControllerEvdev::set_has_mouse(bool has_mouse) {
38   has_mouse_ = has_mouse;
39 }
40 
set_has_pointing_stick(bool has_pointing_stick)41 void InputControllerEvdev::set_has_pointing_stick(bool has_pointing_stick) {
42   has_pointing_stick_ = has_pointing_stick;
43 }
44 
set_has_touchpad(bool has_touchpad)45 void InputControllerEvdev::set_has_touchpad(bool has_touchpad) {
46   has_touchpad_ = has_touchpad;
47 }
48 
SetInputDevicesEnabled(bool enabled)49 void InputControllerEvdev::SetInputDevicesEnabled(bool enabled) {
50   input_device_settings_.enable_devices = enabled;
51   ScheduleUpdateDeviceSettings();
52 }
53 
HasMouse()54 bool InputControllerEvdev::HasMouse() {
55   return has_mouse_;
56 }
57 
HasPointingStick()58 bool InputControllerEvdev::HasPointingStick() {
59   return has_pointing_stick_;
60 }
61 
HasTouchpad()62 bool InputControllerEvdev::HasTouchpad() {
63   return has_touchpad_;
64 }
65 
IsCapsLockEnabled()66 bool InputControllerEvdev::IsCapsLockEnabled() {
67   return keyboard_->IsCapsLockEnabled();
68 }
69 
SetCapsLockEnabled(bool enabled)70 void InputControllerEvdev::SetCapsLockEnabled(bool enabled) {
71   keyboard_->SetCapsLockEnabled(enabled);
72   UpdateCapsLockLed();
73 }
74 
SetNumLockEnabled(bool enabled)75 void InputControllerEvdev::SetNumLockEnabled(bool enabled) {
76   // No num lock on Chrome OS.
77 }
78 
IsAutoRepeatEnabled()79 bool InputControllerEvdev::IsAutoRepeatEnabled() {
80   return keyboard_->IsAutoRepeatEnabled();
81 }
82 
SetAutoRepeatEnabled(bool enabled)83 void InputControllerEvdev::SetAutoRepeatEnabled(bool enabled) {
84   keyboard_->SetAutoRepeatEnabled(enabled);
85 }
86 
SetAutoRepeatRate(const base::TimeDelta & delay,const base::TimeDelta & interval)87 void InputControllerEvdev::SetAutoRepeatRate(const base::TimeDelta& delay,
88                                              const base::TimeDelta& interval) {
89   keyboard_->SetAutoRepeatRate(delay, interval);
90 }
91 
GetAutoRepeatRate(base::TimeDelta * delay,base::TimeDelta * interval)92 void InputControllerEvdev::GetAutoRepeatRate(base::TimeDelta* delay,
93                                              base::TimeDelta* interval) {
94   keyboard_->GetAutoRepeatRate(delay, interval);
95 }
96 
SetCurrentLayoutByName(const std::string & layout_name)97 void InputControllerEvdev::SetCurrentLayoutByName(
98     const std::string& layout_name) {
99   keyboard_->SetCurrentLayoutByName(layout_name);
100 }
101 
SetInternalTouchpadEnabled(bool enabled)102 void InputControllerEvdev::SetInternalTouchpadEnabled(bool enabled) {
103   input_device_settings_.enable_internal_touchpad = enabled;
104   ScheduleUpdateDeviceSettings();
105 }
106 
IsInternalTouchpadEnabled() const107 bool InputControllerEvdev::IsInternalTouchpadEnabled() const {
108   return input_device_settings_.enable_internal_touchpad;
109 }
110 
SetTouchscreensEnabled(bool enabled)111 void InputControllerEvdev::SetTouchscreensEnabled(bool enabled) {
112   input_device_settings_.enable_touch_screens = enabled;
113   ui::DeviceDataManager::GetInstance()->SetTouchscreensEnabled(enabled);
114   ScheduleUpdateDeviceSettings();
115 }
116 
SetTouchEventLoggingEnabled(bool enabled)117 void InputControllerEvdev::SetTouchEventLoggingEnabled(bool enabled) {
118   input_device_settings_.touch_event_logging_enabled = enabled;
119   ScheduleUpdateDeviceSettings();
120 }
121 
SetInternalKeyboardFilter(bool enable_filter,std::vector<DomCode> allowed_keys)122 void InputControllerEvdev::SetInternalKeyboardFilter(
123     bool enable_filter,
124     std::vector<DomCode> allowed_keys) {
125   input_device_settings_.enable_internal_keyboard_filter = enable_filter;
126   input_device_settings_.internal_keyboard_allowed_keys = allowed_keys;
127   ScheduleUpdateDeviceSettings();
128 }
129 
SetTouchpadSensitivity(int value)130 void InputControllerEvdev::SetTouchpadSensitivity(int value) {
131   input_device_settings_.touchpad_sensitivity = value;
132   ScheduleUpdateDeviceSettings();
133 }
134 
SetTouchpadScrollSensitivity(int value)135 void InputControllerEvdev::SetTouchpadScrollSensitivity(int value) {
136   input_device_settings_.touchpad_scroll_sensitivity = value;
137   ScheduleUpdateDeviceSettings();
138 }
139 
SetTapToClick(bool enabled)140 void InputControllerEvdev::SetTapToClick(bool enabled) {
141   input_device_settings_.tap_to_click_enabled = enabled;
142   ScheduleUpdateDeviceSettings();
143 }
144 
SetThreeFingerClick(bool enabled)145 void InputControllerEvdev::SetThreeFingerClick(bool enabled) {
146   input_device_settings_.three_finger_click_enabled = enabled;
147   ScheduleUpdateDeviceSettings();
148 }
149 
SetTapDragging(bool enabled)150 void InputControllerEvdev::SetTapDragging(bool enabled) {
151   input_device_settings_.tap_dragging_enabled = enabled;
152   ScheduleUpdateDeviceSettings();
153 }
154 
SetNaturalScroll(bool enabled)155 void InputControllerEvdev::SetNaturalScroll(bool enabled) {
156   input_device_settings_.natural_scroll_enabled = enabled;
157   ScheduleUpdateDeviceSettings();
158 }
159 
SetMouseSensitivity(int value)160 void InputControllerEvdev::SetMouseSensitivity(int value) {
161   input_device_settings_.mouse_sensitivity = value;
162   ScheduleUpdateDeviceSettings();
163 }
164 
SetMouseScrollSensitivity(int value)165 void InputControllerEvdev::SetMouseScrollSensitivity(int value) {
166   input_device_settings_.mouse_scroll_sensitivity = value;
167   ScheduleUpdateDeviceSettings();
168 }
169 
SetPrimaryButtonRight(bool right)170 void InputControllerEvdev::SetPrimaryButtonRight(bool right) {
171   button_map_->SetPrimaryButtonRight(right);
172 }
173 
SetMouseReverseScroll(bool enabled)174 void InputControllerEvdev::SetMouseReverseScroll(bool enabled) {
175   input_device_settings_.mouse_reverse_scroll_enabled = enabled;
176   ScheduleUpdateDeviceSettings();
177 }
178 
SetMouseAcceleration(bool enabled)179 void InputControllerEvdev::SetMouseAcceleration(bool enabled) {
180   if (mouse_acceleration_suspended_) {
181     stored_mouse_acceleration_setting_ = enabled;
182     return;
183   }
184   input_device_settings_.mouse_acceleration_enabled = enabled;
185   ScheduleUpdateDeviceSettings();
186 }
187 
SuspendMouseAcceleration()188 void InputControllerEvdev::SuspendMouseAcceleration() {
189   // multiple calls to suspend are currently not supported.
190   DCHECK(!mouse_acceleration_suspended_);
191   stored_mouse_acceleration_setting_ =
192       input_device_settings_.mouse_acceleration_enabled;
193   mouse_acceleration_suspended_ = true;
194   input_device_settings_.mouse_acceleration_enabled = false;
195   ScheduleUpdateDeviceSettings();
196 }
197 
EndMouseAccelerationSuspension()198 void InputControllerEvdev::EndMouseAccelerationSuspension() {
199   mouse_acceleration_suspended_ = false;
200   SetMouseAcceleration(stored_mouse_acceleration_setting_);
201 }
202 
SetMouseScrollAcceleration(bool enabled)203 void InputControllerEvdev::SetMouseScrollAcceleration(bool enabled) {
204   input_device_settings_.mouse_scroll_acceleration_enabled = enabled;
205   ScheduleUpdateDeviceSettings();
206 }
207 
SetTouchpadAcceleration(bool enabled)208 void InputControllerEvdev::SetTouchpadAcceleration(bool enabled) {
209   input_device_settings_.touchpad_acceleration_enabled = enabled;
210   ScheduleUpdateDeviceSettings();
211 }
212 
SetTouchpadScrollAcceleration(bool enabled)213 void InputControllerEvdev::SetTouchpadScrollAcceleration(bool enabled) {
214   input_device_settings_.touchpad_scroll_acceleration_enabled = enabled;
215   ScheduleUpdateDeviceSettings();
216 }
217 
SetTapToClickPaused(bool state)218 void InputControllerEvdev::SetTapToClickPaused(bool state) {
219   input_device_settings_.tap_to_click_paused = state;
220   ScheduleUpdateDeviceSettings();
221 }
222 
GetTouchDeviceStatus(GetTouchDeviceStatusReply reply)223 void InputControllerEvdev::GetTouchDeviceStatus(
224     GetTouchDeviceStatusReply reply) {
225   if (input_device_factory_)
226     input_device_factory_->GetTouchDeviceStatus(std::move(reply));
227   else
228     std::move(reply).Run(std::string());
229 }
230 
GetTouchEventLog(const base::FilePath & out_dir,GetTouchEventLogReply reply)231 void InputControllerEvdev::GetTouchEventLog(const base::FilePath& out_dir,
232                                             GetTouchEventLogReply reply) {
233   if (input_device_factory_)
234     input_device_factory_->GetTouchEventLog(out_dir, std::move(reply));
235   else
236     std::move(reply).Run(std::vector<base::FilePath>());
237 }
238 
GetGesturePropertiesService(mojo::PendingReceiver<ozone::mojom::GesturePropertiesService> receiver)239 void InputControllerEvdev::GetGesturePropertiesService(
240     mojo::PendingReceiver<ozone::mojom::GesturePropertiesService> receiver) {
241   if (input_device_factory_)
242     input_device_factory_->GetGesturePropertiesService(std::move(receiver));
243 }
244 
ScheduleUpdateDeviceSettings()245 void InputControllerEvdev::ScheduleUpdateDeviceSettings() {
246   if (!input_device_factory_ || settings_update_pending_)
247     return;
248   base::ThreadTaskRunnerHandle::Get()->PostTask(
249       FROM_HERE, base::BindOnce(&InputControllerEvdev::UpdateDeviceSettings,
250                                 weak_ptr_factory_.GetWeakPtr()));
251   settings_update_pending_ = true;
252 }
253 
UpdateDeviceSettings()254 void InputControllerEvdev::UpdateDeviceSettings() {
255   input_device_factory_->UpdateInputDeviceSettings(input_device_settings_);
256   settings_update_pending_ = false;
257 }
258 
UpdateCapsLockLed()259 void InputControllerEvdev::UpdateCapsLockLed() {
260   if (!input_device_factory_)
261     return;
262   bool caps_lock_state = IsCapsLockEnabled();
263   if (caps_lock_state != caps_lock_led_state_)
264     input_device_factory_->SetCapsLockLed(caps_lock_state);
265   caps_lock_led_state_ = caps_lock_state;
266 }
267 
PlayVibrationEffect(int id,uint8_t amplitude,uint16_t duration_millis)268 void InputControllerEvdev::PlayVibrationEffect(int id,
269                                                uint8_t amplitude,
270                                                uint16_t duration_millis) {
271   if (!input_device_factory_)
272     return;
273   input_device_factory_->PlayVibrationEffect(id, amplitude, duration_millis);
274 }
275 
StopVibration(int id)276 void InputControllerEvdev::StopVibration(int id) {
277   if (!input_device_factory_)
278     return;
279   input_device_factory_->StopVibration(id);
280 }
281 
282 }  // namespace ui
283