From 8ec6aaa574230d326a602f1cd719cfff227e4279 Mon Sep 17 00:00:00 2001 From: spang Date: Tue, 24 Feb 2015 11:24:52 -0800 Subject: [PATCH] ozone: evdev: Keep track of settings & apply to new devices This closes two large holes in the settings code: (1) Any changes made before the input device thread starts are lost. (2) Settings are not internally applied to new devices on hotplug. In theory these problems should not have mattered because there is a DeviceChangeHandler class to watch for new devices & reapply settings whenever a new device appears. However, in practice that class is not actually instantiated. We've had several reports of settings not being properly applied. To fix (1) build up desired settings state on the UI thread in InputControllerEvdev, and push it to InputDeviceFactoryEvdev once the thread starts. To fix (2) keep the desired settings state on InputDeviceFactoryEvdev, and reapply settings on hotplug. BUG=451743 TEST=Turned on australian scrolling & ran "sudo restart udev" on link_freon. Verified scrolling is still australian. Review URL: https://codereview.chromium.org/951063004 Cr-Commit-Position: refs/heads/master@{#317851} --- ui/events/ozone/BUILD.gn | 2 + ui/events/ozone/evdev/event_factory_evdev.cc | 2 +- ui/events/ozone/evdev/input_controller_evdev.cc | 51 ++++++++++++------ ui/events/ozone/evdev/input_controller_evdev.h | 16 ++++++ .../ozone/evdev/input_device_factory_evdev.cc | 61 ++++++++++++---------- ui/events/ozone/evdev/input_device_factory_evdev.h | 15 +++--- .../evdev/input_device_factory_evdev_proxy.cc | 43 ++------------- .../ozone/evdev/input_device_factory_evdev_proxy.h | 9 +--- .../ozone/evdev/input_device_settings_evdev.cc | 30 +++++++++++ .../ozone/evdev/input_device_settings_evdev.h | 27 ++++++++++ ui/events/ozone/events_ozone.gyp | 2 + 11 files changed, 159 insertions(+), 99 deletions(-) create mode 100644 ui/events/ozone/evdev/input_device_settings_evdev.cc create mode 100644 ui/events/ozone/evdev/input_device_settings_evdev.h diff --git a/ui/events/ozone/BUILD.gn b/ui/events/ozone/BUILD.gn index 93e8d615c668..47efc197a523 100644 --- a/ui/events/ozone/BUILD.gn +++ b/ui/events/ozone/BUILD.gn @@ -85,6 +85,8 @@ component("events_ozone_evdev") { "evdev/input_device_factory_evdev.h", "evdev/input_device_factory_evdev_proxy.cc", "evdev/input_device_factory_evdev_proxy.h", + "evdev/input_device_settings_evdev.cc", + "evdev/input_device_settings_evdev.h", "evdev/input_injector_evdev.cc", "evdev/input_injector_evdev.h", "evdev/keyboard_evdev.cc", diff --git a/ui/events/ozone/evdev/event_factory_evdev.cc b/ui/events/ozone/evdev/event_factory_evdev.cc index 858f46355c8b..e264f3530a75 100644 --- a/ui/events/ozone/evdev/event_factory_evdev.cc +++ b/ui/events/ozone/evdev/event_factory_evdev.cc @@ -325,7 +325,7 @@ void EventFactoryEvdev::OnThreadStarted( scoped_ptr input_device_factory) { input_device_factory_proxy_ = input_device_factory.Pass(); - // TODO(spang): This settings interface is really broken. crbug.com/450899 + // Hook up device configuration. input_controller_.SetInputDeviceFactory(input_device_factory_proxy_.get()); // Scan & monitor devices. diff --git a/ui/events/ozone/evdev/input_controller_evdev.cc b/ui/events/ozone/evdev/input_controller_evdev.cc index 15fced21d9f6..0f3ba9c3b89c 100644 --- a/ui/events/ozone/evdev/input_controller_evdev.cc +++ b/ui/events/ozone/evdev/input_controller_evdev.cc @@ -7,6 +7,7 @@ #include #include +#include "base/thread_task_runner_handle.h" #include "ui/events/ozone/evdev/input_device_factory_evdev_proxy.h" #include "ui/events/ozone/evdev/keyboard_evdev.h" #include "ui/events/ozone/evdev/mouse_button_map_evdev.h" @@ -15,11 +16,13 @@ namespace ui { InputControllerEvdev::InputControllerEvdev(KeyboardEvdev* keyboard, MouseButtonMapEvdev* button_map) - : input_device_factory_(nullptr), + : settings_update_pending_(false), + input_device_factory_(nullptr), keyboard_(keyboard), button_map_(button_map), has_mouse_(false), - has_touchpad_(false) { + has_touchpad_(false), + weak_ptr_factory_(this) { } InputControllerEvdev::~InputControllerEvdev() { @@ -28,6 +31,8 @@ InputControllerEvdev::~InputControllerEvdev() { void InputControllerEvdev::SetInputDeviceFactory( InputDeviceFactoryEvdevProxy* input_device_factory) { input_device_factory_ = input_device_factory; + + UpdateDeviceSettings(); } void InputControllerEvdev::set_has_mouse(bool has_mouse) { @@ -100,33 +105,33 @@ void InputControllerEvdev::EnableInternalKeyboard() { } void InputControllerEvdev::SetTouchpadSensitivity(int value) { - if (input_device_factory_) - input_device_factory_->SetTouchpadSensitivity(value); + input_device_settings_.touchpad_sensitivity = value; + ScheduleUpdateDeviceSettings(); } void InputControllerEvdev::SetTapToClick(bool enabled) { - if (input_device_factory_) - input_device_factory_->SetTapToClick(enabled); + input_device_settings_.tap_to_click_enabled = enabled; + ScheduleUpdateDeviceSettings(); } void InputControllerEvdev::SetThreeFingerClick(bool enabled) { - if (input_device_factory_) - input_device_factory_->SetThreeFingerClick(enabled); + input_device_settings_.three_finger_click_enabled = enabled; + ScheduleUpdateDeviceSettings(); } void InputControllerEvdev::SetTapDragging(bool enabled) { - if (input_device_factory_) - input_device_factory_->SetTapDragging(enabled); + input_device_settings_.tap_dragging_enabled = enabled; + ScheduleUpdateDeviceSettings(); } void InputControllerEvdev::SetNaturalScroll(bool enabled) { - if (input_device_factory_) - input_device_factory_->SetNaturalScroll(enabled); + input_device_settings_.natural_scroll_enabled = enabled; + ScheduleUpdateDeviceSettings(); } void InputControllerEvdev::SetMouseSensitivity(int value) { - if (input_device_factory_) - input_device_factory_->SetMouseSensitivity(value); + input_device_settings_.mouse_sensitivity = value; + ScheduleUpdateDeviceSettings(); } void InputControllerEvdev::SetPrimaryButtonRight(bool right) { @@ -135,8 +140,8 @@ void InputControllerEvdev::SetPrimaryButtonRight(bool right) { } void InputControllerEvdev::SetTapToClickPaused(bool state) { - if (input_device_factory_) - input_device_factory_->SetTapToClickPaused(state); + input_device_settings_.tap_to_click_paused = state; + ScheduleUpdateDeviceSettings(); } void InputControllerEvdev::GetTouchDeviceStatus( @@ -147,4 +152,18 @@ void InputControllerEvdev::GetTouchDeviceStatus( reply.Run(make_scoped_ptr(new std::string)); } +void InputControllerEvdev::ScheduleUpdateDeviceSettings() { + if (!input_device_factory_ || settings_update_pending_) + return; + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::Bind(&InputControllerEvdev::UpdateDeviceSettings, + weak_ptr_factory_.GetWeakPtr())); + settings_update_pending_ = true; +} + +void InputControllerEvdev::UpdateDeviceSettings() { + input_device_factory_->UpdateInputDeviceSettings(input_device_settings_); + settings_update_pending_ = false; +} + } // namespace ui diff --git a/ui/events/ozone/evdev/input_controller_evdev.h b/ui/events/ozone/evdev/input_controller_evdev.h index d5e26eccc279..21ffe7b99ffe 100644 --- a/ui/events/ozone/evdev/input_controller_evdev.h +++ b/ui/events/ozone/evdev/input_controller_evdev.h @@ -8,7 +8,9 @@ #include #include "base/basictypes.h" +#include "base/memory/weak_ptr.h" #include "ui/events/ozone/evdev/events_ozone_evdev_export.h" +#include "ui/events/ozone/evdev/input_device_settings_evdev.h" #include "ui/ozone/public/input_controller.h" namespace ui { @@ -60,6 +62,18 @@ class EVENTS_OZONE_EVDEV_EXPORT InputControllerEvdev : public InputController { void EnableInternalKeyboard() override; private: + // Post task to update settings. + void ScheduleUpdateDeviceSettings(); + + // Send settings update to input_device_factory_. + void UpdateDeviceSettings(); + + // Configuration that needs to be passed on to InputDeviceFactory. + InputDeviceSettingsEvdev input_device_settings_; + + // Task to update config from input_device_settings_ is pending. + bool settings_update_pending_; + // Factory for devices. Needed to update device config. InputDeviceFactoryEvdevProxy* input_device_factory_; @@ -73,6 +87,8 @@ class EVENTS_OZONE_EVDEV_EXPORT InputControllerEvdev : public InputController { bool has_mouse_; bool has_touchpad_; + base::WeakPtrFactory weak_ptr_factory_; + DISALLOW_COPY_AND_ASSIGN(InputControllerEvdev); }; diff --git a/ui/events/ozone/evdev/input_device_factory_evdev.cc b/ui/events/ozone/evdev/input_device_factory_evdev.cc index 020c28842afb..82d30959c1eb 100644 --- a/ui/events/ozone/evdev/input_device_factory_evdev.cc +++ b/ui/events/ozone/evdev/input_device_factory_evdev.cc @@ -318,6 +318,9 @@ void InputDeviceFactoryEvdev::AttachInputDevice( converters_[path] = converter.release(); converters_[path]->Start(); UpdateDirtyFlags(converters_[path]); + + // Sync settings to new device. + ApplyInputDeviceSettings(); } if (--pending_device_changes_ == 0) @@ -390,35 +393,10 @@ void InputDeviceFactoryEvdev::EnableInternalKeyboard() { } } -void InputDeviceFactoryEvdev::SetTouchpadSensitivity(int value) { - SetIntPropertyForOneType(DT_TOUCHPAD, "Pointer Sensitivity", value); - SetIntPropertyForOneType(DT_TOUCHPAD, "Scroll Sensitivity", value); -} - -void InputDeviceFactoryEvdev::SetTapToClick(bool enabled) { - SetBoolPropertyForOneType(DT_TOUCHPAD, "Tap Enable", enabled); -} - -void InputDeviceFactoryEvdev::SetThreeFingerClick(bool enabled) { - SetBoolPropertyForOneType(DT_TOUCHPAD, "T5R2 Three Finger Click Enable", - enabled); -} - -void InputDeviceFactoryEvdev::SetTapDragging(bool enabled) { - SetBoolPropertyForOneType(DT_TOUCHPAD, "Tap Drag Enable", enabled); -} - -void InputDeviceFactoryEvdev::SetNaturalScroll(bool enabled) { - SetBoolPropertyForOneType(DT_MULTITOUCH, "Australian Scrolling", enabled); -} - -void InputDeviceFactoryEvdev::SetMouseSensitivity(int value) { - SetIntPropertyForOneType(DT_MOUSE, "Pointer Sensitivity", value); - SetIntPropertyForOneType(DT_MOUSE, "Scroll Sensitivity", value); -} - -void InputDeviceFactoryEvdev::SetTapToClickPaused(bool state) { - SetBoolPropertyForOneType(DT_TOUCHPAD, "Tap Paused", state); +void InputDeviceFactoryEvdev::UpdateInputDeviceSettings( + const InputDeviceSettingsEvdev& settings) { + input_device_settings_ = settings; + ApplyInputDeviceSettings(); } void InputDeviceFactoryEvdev::GetTouchDeviceStatus( @@ -434,6 +412,31 @@ base::WeakPtr InputDeviceFactoryEvdev::GetWeakPtr() { return weak_ptr_factory_.GetWeakPtr(); } +void InputDeviceFactoryEvdev::ApplyInputDeviceSettings() { + SetIntPropertyForOneType(DT_TOUCHPAD, "Pointer Sensitivity", + input_device_settings_.touchpad_sensitivity); + SetIntPropertyForOneType(DT_TOUCHPAD, "Scroll Sensitivity", + input_device_settings_.touchpad_sensitivity); + + SetBoolPropertyForOneType(DT_TOUCHPAD, "Tap Enable", + input_device_settings_.tap_to_click_enabled); + SetBoolPropertyForOneType(DT_TOUCHPAD, "T5R2 Three Finger Click Enable", + input_device_settings_.three_finger_click_enabled); + SetBoolPropertyForOneType(DT_TOUCHPAD, "Tap Drag Enable", + input_device_settings_.tap_dragging_enabled); + + SetBoolPropertyForOneType(DT_MULTITOUCH, "Australian Scrolling", + input_device_settings_.natural_scroll_enabled); + + SetIntPropertyForOneType(DT_MOUSE, "Pointer Sensitivity", + input_device_settings_.mouse_sensitivity); + SetIntPropertyForOneType(DT_MOUSE, "Scroll Sensitivity", + input_device_settings_.mouse_sensitivity); + + SetBoolPropertyForOneType(DT_TOUCHPAD, "Tap Paused", + input_device_settings_.tap_to_click_paused); +} + void InputDeviceFactoryEvdev::UpdateDirtyFlags( const EventConverterEvdev* converter) { if (converter->HasTouchscreen()) diff --git a/ui/events/ozone/evdev/input_device_factory_evdev.h b/ui/events/ozone/evdev/input_device_factory_evdev.h index 919fb74376c6..2444898b390e 100644 --- a/ui/events/ozone/evdev/input_device_factory_evdev.h +++ b/ui/events/ozone/evdev/input_device_factory_evdev.h @@ -17,6 +17,7 @@ #include "ui/events/ozone/evdev/event_converter_evdev.h" #include "ui/events/ozone/evdev/event_device_info.h" #include "ui/events/ozone/evdev/events_ozone_evdev_export.h" +#include "ui/events/ozone/evdev/input_device_settings_evdev.h" namespace ui { @@ -61,13 +62,7 @@ class EVENTS_OZONE_EVDEV_EXPORT InputDeviceFactoryEvdev { void EnableInternalKeyboard(); // Bits from InputController that have to be answered on IO. - void SetTouchpadSensitivity(int value); - void SetTapToClick(bool enabled); - void SetThreeFingerClick(bool enabled); - void SetTapDragging(bool enabled); - void SetNaturalScroll(bool enabled); - void SetMouseSensitivity(int value); - void SetTapToClickPaused(bool state); + void UpdateInputDeviceSettings(const InputDeviceSettingsEvdev& settings); void GetTouchDeviceStatus(const GetTouchDeviceStatusReply& reply); base::WeakPtr GetWeakPtr(); @@ -79,6 +74,9 @@ class EVENTS_OZONE_EVDEV_EXPORT InputDeviceFactoryEvdev { // Close device at path (on UI thread). void DetachInputDevice(const base::FilePath& file_path); + // Sync input_device_settings_ to attached devices. + void ApplyInputDeviceSettings(); + // Update observers on device changes. void UpdateDirtyFlags(const EventConverterEvdev* converter); void NotifyDevicesUpdated(); @@ -118,6 +116,9 @@ class EVENTS_OZONE_EVDEV_EXPORT InputDeviceFactoryEvdev { bool mouse_list_dirty_; bool touchpad_list_dirty_; + // Device settings. These primarily affect libgestures behavior. + InputDeviceSettingsEvdev input_device_settings_; + // Support weak pointers for attach & detach callbacks. base::WeakPtrFactory weak_ptr_factory_; diff --git a/ui/events/ozone/evdev/input_device_factory_evdev_proxy.cc b/ui/events/ozone/evdev/input_device_factory_evdev_proxy.cc index 7ee1d6e47a10..ceb2efae109f 100644 --- a/ui/events/ozone/evdev/input_device_factory_evdev_proxy.cc +++ b/ui/events/ozone/evdev/input_device_factory_evdev_proxy.cc @@ -71,46 +71,11 @@ void InputDeviceFactoryEvdevProxy::EnableInternalKeyboard() { input_device_factory_)); } -void InputDeviceFactoryEvdevProxy::SetTouchpadSensitivity(int value) { +void InputDeviceFactoryEvdevProxy::UpdateInputDeviceSettings( + const InputDeviceSettingsEvdev& settings) { task_runner_->PostTask( - FROM_HERE, base::Bind(&InputDeviceFactoryEvdev::SetTouchpadSensitivity, - input_device_factory_, value)); -} - -void InputDeviceFactoryEvdevProxy::SetTapToClick(bool enabled) { - task_runner_->PostTask(FROM_HERE, - base::Bind(&InputDeviceFactoryEvdev::SetTapToClick, - input_device_factory_, enabled)); -} - -void InputDeviceFactoryEvdevProxy::SetThreeFingerClick(bool enabled) { - task_runner_->PostTask( - FROM_HERE, base::Bind(&InputDeviceFactoryEvdev::SetThreeFingerClick, - input_device_factory_, enabled)); -} - -void InputDeviceFactoryEvdevProxy::SetTapDragging(bool enabled) { - task_runner_->PostTask(FROM_HERE, - base::Bind(&InputDeviceFactoryEvdev::SetTapDragging, - input_device_factory_, enabled)); -} - -void InputDeviceFactoryEvdevProxy::SetNaturalScroll(bool enabled) { - task_runner_->PostTask(FROM_HERE, - base::Bind(&InputDeviceFactoryEvdev::SetNaturalScroll, - input_device_factory_, enabled)); -} - -void InputDeviceFactoryEvdevProxy::SetMouseSensitivity(int value) { - task_runner_->PostTask( - FROM_HERE, base::Bind(&InputDeviceFactoryEvdev::SetMouseSensitivity, - input_device_factory_, value)); -} - -void InputDeviceFactoryEvdevProxy::SetTapToClickPaused(bool state) { - task_runner_->PostTask( - FROM_HERE, base::Bind(&InputDeviceFactoryEvdev::SetTapToClickPaused, - input_device_factory_, state)); + FROM_HERE, base::Bind(&InputDeviceFactoryEvdev::UpdateInputDeviceSettings, + input_device_factory_, settings)); } void InputDeviceFactoryEvdevProxy::GetTouchDeviceStatus( diff --git a/ui/events/ozone/evdev/input_device_factory_evdev_proxy.h b/ui/events/ozone/evdev/input_device_factory_evdev_proxy.h index e231fa272e71..a7b4bb6e3d7c 100644 --- a/ui/events/ozone/evdev/input_device_factory_evdev_proxy.h +++ b/ui/events/ozone/evdev/input_device_factory_evdev_proxy.h @@ -18,6 +18,7 @@ namespace ui { enum class DomCode; class InputDeviceFactoryEvdev; +struct InputDeviceSettingsEvdev; typedef base::Callback)> GetTouchDeviceStatusReply; @@ -41,13 +42,7 @@ class EVENTS_OZONE_EVDEV_EXPORT InputDeviceFactoryEvdevProxy { void DisableInternalKeyboardExceptKeys( scoped_ptr> excepted_keys); void EnableInternalKeyboard(); - void SetTouchpadSensitivity(int value); - void SetTapToClick(bool enabled); - void SetThreeFingerClick(bool enabled); - void SetTapDragging(bool enabled); - void SetNaturalScroll(bool enabled); - void SetMouseSensitivity(int value); - void SetTapToClickPaused(bool state); + void UpdateInputDeviceSettings(const InputDeviceSettingsEvdev& settings); void GetTouchDeviceStatus(const GetTouchDeviceStatusReply& reply); private: diff --git a/ui/events/ozone/evdev/input_device_settings_evdev.cc b/ui/events/ozone/evdev/input_device_settings_evdev.cc new file mode 100644 index 000000000000..6393eb336ba8 --- /dev/null +++ b/ui/events/ozone/evdev/input_device_settings_evdev.cc @@ -0,0 +1,30 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/events/ozone/evdev/input_device_settings_evdev.h" + +namespace ui { + +const int kDefaultSensitivity = 3; + +// The initial settings are not critical since they will be shortly be changed +// to the user's preferences or the application's own defaults. + +InputDeviceSettingsEvdev::InputDeviceSettingsEvdev() + : tap_to_click_enabled(true), + three_finger_click_enabled(false), + tap_dragging_enabled(false), + natural_scroll_enabled(false), + tap_to_click_paused(false), + touchpad_sensitivity(kDefaultSensitivity), + mouse_sensitivity(kDefaultSensitivity) { +} + +InputDeviceSettingsEvdev::InputDeviceSettingsEvdev( + const InputDeviceSettingsEvdev& other) = default; + +InputDeviceSettingsEvdev::~InputDeviceSettingsEvdev() { +} + +} // namespace ui diff --git a/ui/events/ozone/evdev/input_device_settings_evdev.h b/ui/events/ozone/evdev/input_device_settings_evdev.h new file mode 100644 index 000000000000..6c04a16d2dac --- /dev/null +++ b/ui/events/ozone/evdev/input_device_settings_evdev.h @@ -0,0 +1,27 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_EVENTS_OZONE_EVDEV_INPUT_DEVICE_SETTINGS_EVDEV_H_ +#define UI_EVENTS_OZONE_EVDEV_INPUT_DEVICE_SETTINGS_EVDEV_H_ + +namespace ui { + +struct InputDeviceSettingsEvdev { + InputDeviceSettingsEvdev(); + InputDeviceSettingsEvdev(const InputDeviceSettingsEvdev& other); + ~InputDeviceSettingsEvdev(); + + bool tap_to_click_enabled; + bool three_finger_click_enabled; + bool tap_dragging_enabled; + bool natural_scroll_enabled; + bool tap_to_click_paused; + + int touchpad_sensitivity; + int mouse_sensitivity; +}; + +} // namespace ui + +#endif // UI_EVENTS_OZONE_EVDEV_INPUT_DEVICE_SETTINGS_EVDEV_H_ diff --git a/ui/events/ozone/events_ozone.gyp b/ui/events/ozone/events_ozone.gyp index b41748ecf2ef..d47f01477537 100644 --- a/ui/events/ozone/events_ozone.gyp +++ b/ui/events/ozone/events_ozone.gyp @@ -88,6 +88,8 @@ 'evdev/input_device_factory_evdev.h', 'evdev/input_device_factory_evdev_proxy.cc', 'evdev/input_device_factory_evdev_proxy.h', + 'evdev/input_device_settings_evdev.cc', + 'evdev/input_device_settings_evdev.h', 'evdev/input_injector_evdev.cc', 'evdev/input_injector_evdev.h', 'evdev/keyboard_evdev.cc', -- 2.11.4.GIT