Skip to content

Commit

Permalink
Settings Split: Implement updating of touchpad settings in prefs
Browse files Browse the repository at this point in the history
Bug: b/241965700
Change-Id: I2b85744de7ba10d8f0dc6f154face7b1de1e41f9
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4195127
Commit-Queue: Michael Checo <michaelcheco@google.com>
Reviewed-by: David Padlipsky <dpad@google.com>
Reviewed-by: Will Harris <wfh@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1100681}
  • Loading branch information
Michael Checo authored and Chromium LUCI CQ committed Feb 2, 2023
1 parent 5b1cb58 commit 84ae6f7
Show file tree
Hide file tree
Showing 4 changed files with 321 additions and 6 deletions.
36 changes: 35 additions & 1 deletion ash/public/mojom/input_device_settings.mojom
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,40 @@ struct MouseSettings {

// Contains all information needed to display, apply, and update touchpad
// settings.
// TODO(michaelcheco): add `settings` to `mojom::Touchpad` struct.
struct Touchpad {
string name;
// Unique identifier for the touchpad which is assigned by ozone when it is
// connected and is reassigned when disconnected and reconnected to the
// system. These ids can be rarely reused for multiple devices if the original
// device holding the id had been disconnected.
uint32 id;
// Key used to lookup device settings in prefs in the format
// "vendor_id:product_id" where the ids are 16-bit hex in lowercase.
// Example: 5022:18d1.
string device_key;
TouchpadSettings settings;
};

// Contains all existing touchpad settings available for use.
struct TouchpadSettings {
// Control sensitivity of the device.
uint8 sensitivity;
// Toggles the direction of the scroll behavior.
bool reverse_scrolling;
// Controls whether acceleration is enabled.
bool acceleration_enabled;
// Toggles whether tap to click is enabled.
bool tap_to_click_enabled;
// Toggles whether three finger click is enabled.
bool three_finger_click_enabled;
// Toggles whether tap dragging is enabled.
bool tap_dragging_enabled;
// Controls the speed of touchpad scrolling.
uint8 scroll_sensitivity;
// Toggles whether scroll acceleration is enabled.
bool scroll_acceleration;
// Controls the sensitivity of the haptic feedback from the touchpad.
uint8 haptic_sensitivity;
// Toggles whether haptic feedback is enabled for the touchpad at all.
bool haptic_enabled;
};
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,19 @@ constexpr char kMouseSettingReverseScrolling[] = "reverse_scrolling";
constexpr char kMouseSettingAccelerationEnabled[] = "acceleration_enabled";
constexpr char kMouseSettingScrollSensitivity[] = "scroll_sensitivity";
constexpr char kMouseSettingScrollAcceleration[] = "scroll_acceleration";

// Touchpad settings dictionary keys.
constexpr char kTouchpadSettingSensitivity[] = "sensitivity";
constexpr char kTouchpadSettingReverseScrolling[] = "reverse_scrolling";
constexpr char kTouchpadSettingAccelerationEnabled[] = "acceleration_enabled";
constexpr char kTouchpadSettingScrollSensitivity[] = "scroll_sensitivity";
constexpr char kTouchpadSettingScrollAcceleration[] = "scroll_acceleration";
constexpr char kTouchpadSettingTapToClickEnabled[] = "tap_to_click_enabled";
constexpr char kTouchpadSettingThreeFingerClickEnabled[] =
"three_finger_click_enabled";
constexpr char kTouchpadSettingTapDraggingEnabled[] = "tap_dragging_enabled";
constexpr char kTouchpadSettingHapticSensitivity[] = "haptic_sensitivity";
constexpr char kTouchpadSettingHapticEnabled[] = "haptic_enabled";
} // namespace ash::prefs

#endif // ASH_SYSTEM_INPUT_DEVICE_SETTINGS_INPUT_DEVICE_SETTINGS_PREF_NAMES_H_
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
#include "ash/system/input_device_settings/pref_handlers/touchpad_pref_handler_impl.h"

#include "ash/public/mojom/input_device_settings.mojom-forward.h"
#include "ash/public/mojom/input_device_settings.mojom.h"
#include "ash/system/input_device_settings/input_device_settings_pref_names.h"
#include "base/check.h"
#include "base/notreached.h"
#include "components/prefs/pref_service.h"

Expand All @@ -20,11 +23,50 @@ void TouchpadPrefHandlerImpl::InitializeTouchpadSettings(
NOTIMPLEMENTED();
}

// TODO(michaelcheco): Implement touchpad settings updates.
void TouchpadPrefHandlerImpl::UpdateTouchpadSettings(
PrefService* pref_service,
const mojom::Touchpad& touchpad) {
NOTIMPLEMENTED();
DCHECK(touchpad.settings);
const mojom::TouchpadSettings& settings = *touchpad.settings;
// Populate `settings_dict` with all settings in `settings`.
base::Value::Dict settings_dict;
settings_dict.Set(prefs::kTouchpadSettingSensitivity, settings.sensitivity);
settings_dict.Set(prefs::kTouchpadSettingReverseScrolling,
settings.reverse_scrolling);
settings_dict.Set(prefs::kTouchpadSettingAccelerationEnabled,
settings.acceleration_enabled);
settings_dict.Set(prefs::kTouchpadSettingScrollSensitivity,
settings.scroll_sensitivity);
settings_dict.Set(prefs::kTouchpadSettingScrollAcceleration,
settings.scroll_acceleration);
settings_dict.Set(prefs::kTouchpadSettingTapToClickEnabled,
settings.tap_to_click_enabled);
settings_dict.Set(prefs::kTouchpadSettingThreeFingerClickEnabled,
settings.three_finger_click_enabled);
settings_dict.Set(prefs::kTouchpadSettingTapDraggingEnabled,
settings.tap_dragging_enabled);
settings_dict.Set(prefs::kTouchpadSettingHapticSensitivity,
settings.haptic_sensitivity);
settings_dict.Set(prefs::kTouchpadSettingHapticEnabled,
settings.haptic_enabled);

// Retrieve old settings and merge with the new ones.
base::Value::Dict devices_dict =
pref_service->GetDict(prefs::kTouchpadDeviceSettingsDictPref).Clone();

// If an old settings dict already exists for the device, merge the updated
// settings into the old settings. Otherwise, insert the dict at
// `touchpad.device_key`.
base::Value::Dict* old_settings_dict =
devices_dict.FindDict(touchpad.device_key);
if (old_settings_dict) {
old_settings_dict->Merge(std::move(settings_dict));
} else {
devices_dict.Set(touchpad.device_key, std::move(settings_dict));
}

pref_service->SetDict(std::string(prefs::kTouchpadDeviceSettingsDictPref),
std::move(devices_dict));
}

} // namespace ash
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,46 @@

#include "ash/system/input_device_settings/pref_handlers/touchpad_pref_handler_impl.h"

#include "ash/public/mojom/input_device_settings.mojom.h"
#include "ash/system/input_device_settings/input_device_settings_pref_names.h"
#include "ash/test/ash_test_base.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/testing_pref_service.h"

namespace ash {

namespace {
const std::string kDictFakeKey = "fake_key";
const std::string kDictFakeValue = "fake_value";

const std::string kTouchpadKey1 = "device_key1";
const std::string kTouchpadKey2 = "device_key2";

const mojom::TouchpadSettings kTouchpadSettings1(
/*sensitivity=*/1,
/*reverse_scrolling=*/false,
/*acceleration_enabled=*/false,
/*tap_to_click_enabled=*/false,
/*three_finger_click_enabled=*/false,
/*tap_dragging_enabled=*/false,
/*scroll_sensitivity=*/1,
/*scroll_acceleration=*/false,
/*haptic_sensitivity=*/1,
/*haptic_enabled);=*/false);

const mojom::TouchpadSettings kTouchpadSettings2(
/*sensitivity=*/3,
/*reverse_scrolling=*/false,
/*acceleration_enabled=*/false,
/*tap_to_click_enabled=*/false,
/*three_finger_click_enabled=*/false,
/*tap_dragging_enabled=*/false,
/*scroll_sensitivity=*/3,
/*scroll_acceleration=*/false,
/*haptic_sensitivity=*/3,
/*haptic_enabled);=*/false);
} // namespace

class TouchpadPrefHandlerTest : public AshTestBase {
public:
TouchpadPrefHandlerTest() = default;
Expand All @@ -18,6 +54,7 @@ class TouchpadPrefHandlerTest : public AshTestBase {
// testing::Test:
void SetUp() override {
AshTestBase::SetUp();
InitializePrefService();
pref_handler_ = std::make_unique<TouchpadPrefHandlerImpl>();
}

Expand All @@ -26,12 +63,201 @@ class TouchpadPrefHandlerTest : public AshTestBase {
AshTestBase::TearDown();
}

void InitializePrefService() {
pref_service_ = std::make_unique<TestingPrefServiceSimple>();

pref_service_->registry()->RegisterDictionaryPref(
prefs::kTouchpadDeviceSettingsDictPref);
}

void CheckTouchpadSettingsAndDictAreEqual(
const mojom::TouchpadSettings& settings,
const base::Value::Dict& settings_dict) {
const auto sensitivity =
settings_dict.FindInt(prefs::kTouchpadSettingSensitivity);
ASSERT_TRUE(sensitivity.has_value());
EXPECT_EQ(settings.sensitivity, sensitivity);

const auto reverse_scrolling =
settings_dict.FindBool(prefs::kTouchpadSettingReverseScrolling);
ASSERT_TRUE(reverse_scrolling.has_value());
EXPECT_EQ(settings.reverse_scrolling, reverse_scrolling);

const auto acceleration_enabled =
settings_dict.FindBool(prefs::kTouchpadSettingAccelerationEnabled);
ASSERT_TRUE(acceleration_enabled.has_value());
EXPECT_EQ(settings.acceleration_enabled, acceleration_enabled);

const auto scroll_sensitivity =
settings_dict.FindInt(prefs::kTouchpadSettingScrollSensitivity);
ASSERT_TRUE(scroll_sensitivity.has_value());
EXPECT_EQ(settings.scroll_sensitivity, scroll_sensitivity);

const auto scroll_acceleration =
settings_dict.FindBool(prefs::kTouchpadSettingScrollAcceleration);
ASSERT_TRUE(scroll_acceleration.has_value());
EXPECT_EQ(settings.scroll_acceleration, scroll_acceleration);

const auto tap_to_click_enabled =
settings_dict.FindBool(prefs::kTouchpadSettingTapToClickEnabled);
ASSERT_TRUE(tap_to_click_enabled.has_value());
EXPECT_EQ(settings.tap_to_click_enabled, tap_to_click_enabled);

const auto three_finger_click_enabled =
settings_dict.FindBool(prefs::kTouchpadSettingThreeFingerClickEnabled);
ASSERT_TRUE(three_finger_click_enabled.has_value());
EXPECT_EQ(settings.three_finger_click_enabled, three_finger_click_enabled);

const auto tap_dragging_enabled =
settings_dict.FindBool(prefs::kTouchpadSettingTapDraggingEnabled);
ASSERT_TRUE(tap_dragging_enabled.has_value());
EXPECT_EQ(settings.tap_dragging_enabled, tap_dragging_enabled);

const auto haptic_sensitivity =
settings_dict.FindInt(prefs::kTouchpadSettingHapticSensitivity);
ASSERT_TRUE(haptic_sensitivity.has_value());
EXPECT_EQ(settings.haptic_sensitivity, haptic_sensitivity);

const auto haptic_enabled =
settings_dict.FindBool(prefs::kTouchpadSettingHapticEnabled);
ASSERT_TRUE(haptic_enabled.has_value());
EXPECT_EQ(settings.haptic_enabled, haptic_enabled);
}

void CallUpdateTouchpadSettings(const std::string& device_key,
const mojom::TouchpadSettings& settings) {
mojom::TouchpadPtr touchpad = mojom::Touchpad::New();
touchpad->settings = settings.Clone();
touchpad->device_key = device_key;

pref_handler_->UpdateTouchpadSettings(pref_service_.get(), *touchpad);
}

protected:
std::unique_ptr<TouchpadPrefHandlerImpl> pref_handler_;
std::unique_ptr<TestingPrefServiceSimple> pref_service_;
};

TEST_F(TouchpadPrefHandlerTest, InitializationTest) {
EXPECT_NE(pref_handler_.get(), nullptr);
TEST_F(TouchpadPrefHandlerTest, MultipleDevices) {
CallUpdateTouchpadSettings(kTouchpadKey1, kTouchpadSettings1);
CallUpdateTouchpadSettings(kTouchpadKey2, kTouchpadSettings2);

const auto& devices_dict =
pref_service_->GetDict(prefs::kTouchpadDeviceSettingsDictPref);
ASSERT_EQ(2u, devices_dict.size());

auto* settings_dict = devices_dict.FindDict(kTouchpadKey1);
ASSERT_NE(nullptr, settings_dict);
CheckTouchpadSettingsAndDictAreEqual(kTouchpadSettings1, *settings_dict);

settings_dict = devices_dict.FindDict(kTouchpadKey2);
ASSERT_NE(nullptr, settings_dict);
CheckTouchpadSettingsAndDictAreEqual(kTouchpadSettings2, *settings_dict);
}

TEST_F(TouchpadPrefHandlerTest, PreservesOldSettings) {
CallUpdateTouchpadSettings(kTouchpadKey1, kTouchpadSettings1);

auto devices_dict =
pref_service_->GetDict(prefs::kTouchpadDeviceSettingsDictPref).Clone();
auto* settings_dict = devices_dict.FindDict(kTouchpadKey1);
ASSERT_NE(nullptr, settings_dict);

// Set a fake key to simulate a setting being removed from 1 milestone to the
// next.
settings_dict->Set(kDictFakeKey, kDictFakeValue);
pref_service_->SetDict(prefs::kTouchpadDeviceSettingsDictPref,
std::move(devices_dict));

// Update the settings again and verify the fake key and value still exist.
CallUpdateTouchpadSettings(kTouchpadKey1, kTouchpadSettings1);

const auto& updated_devices_dict =
pref_service_->GetDict(prefs::kTouchpadDeviceSettingsDictPref);
const auto* updated_settings_dict =
updated_devices_dict.FindDict(kTouchpadKey1);

const std::string* value = updated_settings_dict->FindString(kDictFakeKey);
ASSERT_NE(nullptr, value);
EXPECT_EQ(kDictFakeValue, *value);
}

TEST_F(TouchpadPrefHandlerTest, UpdateSettings) {
CallUpdateTouchpadSettings(kTouchpadKey1, kTouchpadSettings1);
CallUpdateTouchpadSettings(kTouchpadKey2, kTouchpadSettings2);

auto devices_dict =
pref_service_->GetDict(prefs::kTouchpadDeviceSettingsDictPref).Clone();
auto* settings_dict = devices_dict.FindDict(kTouchpadKey1);
ASSERT_NE(nullptr, settings_dict);
CheckTouchpadSettingsAndDictAreEqual(kTouchpadSettings1, *settings_dict);

settings_dict = devices_dict.FindDict(kTouchpadKey2);
ASSERT_NE(nullptr, settings_dict);
CheckTouchpadSettingsAndDictAreEqual(kTouchpadSettings2, *settings_dict);

mojom::TouchpadSettings updated_settings = kTouchpadSettings1;
updated_settings.reverse_scrolling = !updated_settings.reverse_scrolling;

// Update the settings again and verify the settings are updated in place.
CallUpdateTouchpadSettings(kTouchpadKey1, updated_settings);

const auto& updated_devices_dict =
pref_service_->GetDict(prefs::kTouchpadDeviceSettingsDictPref);
const auto* updated_settings_dict =
updated_devices_dict.FindDict(kTouchpadKey1);
ASSERT_NE(nullptr, updated_settings_dict);
CheckTouchpadSettingsAndDictAreEqual(updated_settings,
*updated_settings_dict);

// Verify other device remains unmodified.
const auto* unchanged_settings_dict =
updated_devices_dict.FindDict(kTouchpadKey2);
ASSERT_NE(nullptr, unchanged_settings_dict);
CheckTouchpadSettingsAndDictAreEqual(kTouchpadSettings2,
*unchanged_settings_dict);
}

class TouchpadSettingsPrefConversionTest
: public TouchpadPrefHandlerTest,
public testing::WithParamInterface<
std::tuple<std::string, mojom::TouchpadSettings>> {
public:
TouchpadSettingsPrefConversionTest() = default;
TouchpadSettingsPrefConversionTest(
const TouchpadSettingsPrefConversionTest&) = delete;
TouchpadSettingsPrefConversionTest& operator=(
const TouchpadSettingsPrefConversionTest&) = delete;
~TouchpadSettingsPrefConversionTest() override = default;

// testing::Test:
void SetUp() override {
TouchpadPrefHandlerTest::SetUp();
std::tie(device_key_, settings_) = GetParam();
}

protected:
std::string device_key_;
mojom::TouchpadSettings settings_;
};

INSTANTIATE_TEST_SUITE_P(
// Empty to simplify gtest output
,
TouchpadSettingsPrefConversionTest,
testing::Combine(testing::Values(kTouchpadKey1, kTouchpadKey2),
testing::Values(kTouchpadSettings1, kTouchpadSettings2)));

TEST_P(TouchpadSettingsPrefConversionTest, CheckConversion) {
CallUpdateTouchpadSettings(device_key_, settings_);

const auto& devices_dict =
pref_service_->GetDict(prefs::kTouchpadDeviceSettingsDictPref);
ASSERT_EQ(1u, devices_dict.size());
auto* settings_dict = devices_dict.FindDict(device_key_);
ASSERT_NE(nullptr, settings_dict);

CheckTouchpadSettingsAndDictAreEqual(settings_, *settings_dict);
}

} // namespace ash
} // namespace ash

0 comments on commit 84ae6f7

Please sign in to comment.