Skip to content
This repository has been archived by the owner on Apr 3, 2020. It is now read-only.

Commit

Permalink
ozone: evdev: Keep track of settings & apply to new devices
Browse files Browse the repository at this point in the history
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}
  • Loading branch information
mspang authored and Commit bot committed Feb 24, 2015
1 parent 615f823 commit 8ec6aaa
Show file tree
Hide file tree
Showing 11 changed files with 159 additions and 99 deletions.
2 changes: 2 additions & 0 deletions ui/events/ozone/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
2 changes: 1 addition & 1 deletion ui/events/ozone/evdev/event_factory_evdev.cc
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ void EventFactoryEvdev::OnThreadStarted(
scoped_ptr<InputDeviceFactoryEvdevProxy> 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.
Expand Down
51 changes: 35 additions & 16 deletions ui/events/ozone/evdev/input_controller_evdev.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <algorithm>
#include <linux/input.h>

#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"
Expand All @@ -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() {
Expand All @@ -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) {
Expand Down Expand Up @@ -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) {
Expand All @@ -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(
Expand All @@ -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
16 changes: 16 additions & 0 deletions ui/events/ozone/evdev/input_controller_evdev.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
#include <string>

#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 {
Expand Down Expand Up @@ -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_;

Expand All @@ -73,6 +87,8 @@ class EVENTS_OZONE_EVDEV_EXPORT InputControllerEvdev : public InputController {
bool has_mouse_;
bool has_touchpad_;

base::WeakPtrFactory<InputControllerEvdev> weak_ptr_factory_;

DISALLOW_COPY_AND_ASSIGN(InputControllerEvdev);
};

Expand Down
61 changes: 32 additions & 29 deletions ui/events/ozone/evdev/input_device_factory_evdev.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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(
Expand All @@ -434,6 +412,31 @@ base::WeakPtr<InputDeviceFactoryEvdev> 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())
Expand Down
15 changes: 8 additions & 7 deletions ui/events/ozone/evdev/input_device_factory_evdev.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {

Expand Down Expand Up @@ -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<InputDeviceFactoryEvdev> GetWeakPtr();
Expand All @@ -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();
Expand Down Expand Up @@ -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<InputDeviceFactoryEvdev> weak_ptr_factory_;

Expand Down
43 changes: 4 additions & 39 deletions ui/events/ozone/evdev/input_device_factory_evdev_proxy.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
9 changes: 2 additions & 7 deletions ui/events/ozone/evdev/input_device_factory_evdev_proxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ namespace ui {

enum class DomCode;
class InputDeviceFactoryEvdev;
struct InputDeviceSettingsEvdev;

typedef base::Callback<void(scoped_ptr<std::string>)> GetTouchDeviceStatusReply;

Expand All @@ -41,13 +42,7 @@ class EVENTS_OZONE_EVDEV_EXPORT InputDeviceFactoryEvdevProxy {
void DisableInternalKeyboardExceptKeys(
scoped_ptr<std::set<DomCode>> 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:
Expand Down
30 changes: 30 additions & 0 deletions ui/events/ozone/evdev/input_device_settings_evdev.cc
Original file line number Diff line number Diff line change
@@ -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
Loading

0 comments on commit 8ec6aaa

Please sign in to comment.