#include "ash/accelerators/ash_accelerator_configuration.h"
#include <algorithm>
#include <memory>
#include <string>
#include "ash/accelerators/ash_accelerator_configuration.h"
#include "ash/constants/ash_pref_names.h"
#include "ash/public/cpp/accelerator_configuration.h"
#include "ash/public/cpp/accelerators.h"
#include "ash/public/cpp/accelerators_util.h"
#include "ash/public/mojom/accelerator_configuration.mojom.h"
#include "ash/session/session_controller_impl.h"
#include "ash/shell.h"
#include "ash/test/ash_test_base.h"
#include "base/containers/contains.h"
#include "base/strings/string_number_conversions.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "base/types/optional_ref.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/accelerators/accelerator.h"
#include "ui/base/ui_base_features.h"
#include "ui/events/event_constants.h"
#include "ui/events/keycodes/dom/dom_code.h"
#include "ui/events/keycodes/dom/dom_codes_array.h"
#include "ui/events/keycodes/dom/dom_key.h"
#include "ui/events/keycodes/keyboard_codes_posix.h"
namespace {
using ::ash::mojom::AcceleratorConfigResult;
constexpr char kAcceleratorModifiersKey[] = "modifiers";
constexpr char kAcceleratorKeyCodeKey[] = "key";
constexpr char kAcceleratorModificationActionKey[] = "action";
constexpr char kAcceleratorStateKey[] = "state";
constexpr char kAcceleratorTypeKey[] = "type";
constexpr char kAcceleratorKeyStateKey[] = "key_state";
constexpr char kFakeUserEmail[] = "fakeuser@gmail.com";
constexpr char kFakeUserEmail2[] = "fakeuser2@gmail.com";
class UpdatedAcceleratorsObserver
: public ash::AshAcceleratorConfiguration::Observer {
public:
UpdatedAcceleratorsObserver() = default;
UpdatedAcceleratorsObserver(const UpdatedAcceleratorsObserver&) = delete;
UpdatedAcceleratorsObserver& operator=(const UpdatedAcceleratorsObserver&) =
delete;
~UpdatedAcceleratorsObserver() override = default;
void OnAcceleratorsUpdated() override {
++num_times_accelerator_updated_called_;
}
int num_times_accelerator_updated_called() {
return num_times_accelerator_updated_called_;
}
private:
int num_times_accelerator_updated_called_ = 0;
};
base::Value AcceleratorModificationDataToValue(
const ui::Accelerator& accelerator,
AcceleratorModificationAction action) {
base::Value::Dict accelerator_values;
accelerator_values.Set(kAcceleratorModifiersKey, accelerator.modifiers());
accelerator_values.Set(kAcceleratorKeyCodeKey,
static_cast<int>(accelerator.key_code()));
accelerator_values.Set(
kAcceleratorTypeKey,
static_cast<int>(ash::mojom::AcceleratorType::kDefault));
accelerator_values.Set(
kAcceleratorStateKey,
static_cast<int>(ash::mojom::AcceleratorState::kEnabled));
accelerator_values.Set(kAcceleratorModificationActionKey,
static_cast<int>(action));
return base::Value(std::move(accelerator_values));
}
base::Value::Dict GetOverridePref() {
return ash::Shell::Get()
->session_controller()
->GetActivePrefService()
->GetDict(ash::prefs::kShortcutCustomizationOverrides)
.Clone();
}
void SetOverridePref(const ui::Accelerator& accelerator,
AcceleratorModificationAction action,
uint32_t action_id) {
base::Value::List override_list;
override_list.Append(AcceleratorModificationDataToValue(accelerator, action));
base::Value::Dict overrides;
overrides.Set(base::NumberToString(action_id), std::move(override_list));
ash::Shell::Get()->session_controller()->GetActivePrefService()->SetDict(
ash::prefs::kShortcutCustomizationOverrides, std::move(overrides));
}
AcceleratorModificationData ValueToAcceleratorModificationData(
const base::Value::Dict& value) {
std::optional<int> keycode = value.FindInt(kAcceleratorKeyCodeKey);
std::optional<int> modifier = value.FindInt(kAcceleratorModifiersKey);
std::optional<int> modification_action =
value.FindInt(kAcceleratorModificationActionKey);
std::optional<int> key_state = value.FindInt(kAcceleratorKeyStateKey);
CHECK(keycode.has_value());
CHECK(modifier.has_value());
CHECK(modification_action.has_value());
CHECK(key_state.has_value());
ui::Accelerator accelerator(
static_cast<ui::KeyboardCode>(*keycode), static_cast<int>(*modifier),
static_cast<ui::Accelerator::KeyState>(*key_state));
return {accelerator,
static_cast<AcceleratorModificationAction>(*modification_action)};
}
bool CompareAccelerators(const ash::AcceleratorData& expected_data,
const ui::Accelerator& actual_accelerator) {
ui::Accelerator expected_accel(expected_data.keycode, expected_data.modifiers,
expected_data.trigger_on_press
? ui::Accelerator::KeyState::PRESSED
: ui::Accelerator::KeyState::RELEASED);
return expected_accel.key_code() == actual_accelerator.key_code() &&
expected_accel.modifiers() == actual_accelerator.modifiers() &&
expected_accel.key_state() == actual_accelerator.key_state();
}
void ExpectAllAcceleratorsEqual(
const base::span<const ash::AcceleratorData> expected,
const std::vector<ui::Accelerator>& actual) {
EXPECT_EQ(std::size(expected), actual.size());
for (const auto& actual_accelerator : actual) {
bool found_match = false;
for (const auto& expected_data : expected) {
found_match = CompareAccelerators(expected_data, actual_accelerator);
if (found_match) {
break;
}
}
EXPECT_TRUE(found_match);
}
}
}
namespace ash {
class AshAcceleratorConfigurationTest : public NoSessionAshTestBase {
public:
AshAcceleratorConfigurationTest() = default;
~AshAcceleratorConfigurationTest() override = default;
void SetUp() override {
NoSessionAshTestBase::SetUp();
config_ = std::make_unique<AshAcceleratorConfiguration>();
config_->AddObserver(&observer_);
histogram_tester_ = std::make_unique<base::HistogramTester>();
}
void TearDown() override {
config_->RemoveObserver(&observer_);
NoSessionAshTestBase::TearDown();
histogram_tester_.reset();
}
protected:
base::optional_ref<const std::vector<ui::Accelerator>>
GetAcceleratorsForAction(AcceleratorActionId action_id) {
return config_->GetAcceleratorsForAction(action_id);
}
base::test::ScopedFeatureList scoped_feature_list_;
UpdatedAcceleratorsObserver observer_;
std::unique_ptr<AshAcceleratorConfiguration> config_;
std::unique_ptr<base::HistogramTester> histogram_tester_;
};
TEST_F(AshAcceleratorConfigurationTest, VerifyAcceleratorMappingPopulated) {
const AcceleratorData test_data[] = {
{true, ui::VKEY_SPACE, ui::EF_CONTROL_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_SPACE,
ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_TAB, ui::EF_ALT_DOWN,
AcceleratorAction::kCycleForwardMru},
{true, ui::VKEY_TAB,
ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kCycleBackwardMru},
{true, ui::VKEY_SPACE, ui::EF_SHIFT_DOWN | ui::EF_COMMAND_DOWN,
AcceleratorAction::kShowEmojiPicker, true},
{true, ui::VKEY_EMOJI_PICKER, ui::EF_NONE,
AcceleratorAction::kShowEmojiPicker, true},
};
config_->Initialize(test_data);
const std::vector<ui::Accelerator>& accelerators =
config_->GetAllAccelerators();
ExpectAllAcceleratorsEqual(test_data, accelerators);
ui::Accelerator accelerator(ui::VKEY_EMOJI_PICKER, ui::EF_NONE);
EXPECT_TRUE(config_->IsAcceleratorLocked(accelerator));
}
TEST_F(AshAcceleratorConfigurationTest, DeprecatedAccelerators) {
const AcceleratorData initial_test_data[] = {
{true, ui::VKEY_TAB, ui::EF_ALT_DOWN,
AcceleratorAction::kCycleForwardMru},
{true, ui::VKEY_TAB,
ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kCycleBackwardMru},
{true, ui::VKEY_ESCAPE, ui::EF_COMMAND_DOWN,
AcceleratorAction::kShowTaskManager},
};
const AcceleratorData expected_test_data[] = {
{true, ui::VKEY_TAB, ui::EF_ALT_DOWN,
AcceleratorAction::kCycleForwardMru},
{true, ui::VKEY_TAB,
ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kCycleBackwardMru},
{true, ui::VKEY_ESCAPE, ui::EF_COMMAND_DOWN,
AcceleratorAction::kShowTaskManager},
{true, ui::VKEY_ESCAPE, ui::EF_SHIFT_DOWN,
AcceleratorAction::kShowTaskManager},
};
const DeprecatedAcceleratorData deprecated_data[] = {
{AcceleratorAction::kShowTaskManager,
"deprecated.showTaskManager",
1,
2,
ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_COMMAND_DOWN),
true},
};
const AcceleratorData test_deprecated_accelerators[] = {
{true, ui::VKEY_ESCAPE, ui::EF_SHIFT_DOWN,
AcceleratorAction::kShowTaskManager},
};
config_->Initialize(initial_test_data);
config_->InitializeDeprecatedAccelerators(deprecated_data,
test_deprecated_accelerators);
const std::vector<ui::Accelerator>& accelerators =
config_->GetAllAccelerators();
ExpectAllAcceleratorsEqual(expected_test_data, accelerators);
std::vector<ui::Accelerator> deprecated_accelerators;
for (const auto& accel : accelerators) {
if (config_->IsDeprecated(accel)) {
deprecated_accelerators.push_back(accel);
}
}
ExpectAllAcceleratorsEqual(test_deprecated_accelerators,
deprecated_accelerators);
const ui::Accelerator deprecated_accelerator(ui::VKEY_ESCAPE,
ui::EF_SHIFT_DOWN);
EXPECT_TRUE(config_->IsDeprecated(deprecated_accelerator));
EXPECT_EQ(deprecated_data, config_->GetDeprecatedAcceleratorData(
AcceleratorAction::kShowTaskManager));
EXPECT_EQ(nullptr, config_->GetDeprecatedAcceleratorData(
AcceleratorAction::kCycleBackwardMru));
const ui::Accelerator active_accelerator(ui::VKEY_ESCAPE,
ui::EF_COMMAND_DOWN);
EXPECT_FALSE(config_->IsDeprecated(active_accelerator));
}
TEST_F(AshAcceleratorConfigurationTest,
RemoveAndRestoreDeprecatedAccelerators) {
const AcceleratorData initial_test_data[] = {
{true, ui::VKEY_TAB, ui::EF_ALT_DOWN,
AcceleratorAction::kCycleForwardMru},
{true, ui::VKEY_TAB,
ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kCycleBackwardMru},
{true, ui::VKEY_ESCAPE, ui::EF_COMMAND_DOWN,
AcceleratorAction::kShowTaskManager},
};
const AcceleratorData expected_test_data[] = {
{true, ui::VKEY_TAB, ui::EF_ALT_DOWN,
AcceleratorAction::kCycleForwardMru},
{true, ui::VKEY_TAB,
ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kCycleBackwardMru},
{true, ui::VKEY_ESCAPE, ui::EF_COMMAND_DOWN,
AcceleratorAction::kShowTaskManager},
{true, ui::VKEY_ESCAPE, ui::EF_SHIFT_DOWN,
AcceleratorAction::kShowTaskManager},
};
const DeprecatedAcceleratorData deprecated_data[] = {
{AcceleratorAction::kShowTaskManager,
"deprecated.showTaskManager",
1,
2,
ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_COMMAND_DOWN),
true},
};
const AcceleratorData test_deprecated_accelerators[] = {
{true, ui::VKEY_ESCAPE, ui::EF_SHIFT_DOWN,
AcceleratorAction::kShowTaskManager},
};
config_->Initialize(initial_test_data);
config_->InitializeDeprecatedAccelerators(deprecated_data,
test_deprecated_accelerators);
const ui::Accelerator deprecated_accelerator(ui::VKEY_ESCAPE,
ui::EF_SHIFT_DOWN);
const AcceleratorData updated_expected_test_data[] = {
{true, ui::VKEY_TAB, ui::EF_ALT_DOWN,
AcceleratorAction::kCycleForwardMru},
{true, ui::VKEY_TAB,
ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kCycleBackwardMru},
{true, ui::VKEY_ESCAPE, ui::EF_COMMAND_DOWN,
AcceleratorAction::kShowTaskManager},
};
AcceleratorConfigResult result = config_->RemoveAccelerator(
AcceleratorAction::kShowTaskManager, deprecated_accelerator);
EXPECT_EQ(AcceleratorConfigResult::kSuccess, result);
EXPECT_FALSE(config_->IsDeprecated(deprecated_accelerator));
EXPECT_FALSE(config_->GetDeprecatedAcceleratorData(
AcceleratorAction::kShowTaskManager));
ExpectAllAcceleratorsEqual(updated_expected_test_data,
config_->GetAllAccelerators());
result = config_->RestoreDefault(AcceleratorAction::kShowTaskManager);
EXPECT_EQ(AcceleratorConfigResult::kSuccess, result);
EXPECT_FALSE(config_->IsDeprecated(deprecated_accelerator));
EXPECT_FALSE(config_->GetDeprecatedAcceleratorData(
AcceleratorAction::kShowTaskManager));
ExpectAllAcceleratorsEqual(updated_expected_test_data,
config_->GetAllAccelerators());
result = config_->RestoreAllDefaults();
EXPECT_EQ(AcceleratorConfigResult::kSuccess, result);
EXPECT_TRUE(config_->IsDeprecated(deprecated_accelerator));
EXPECT_EQ(deprecated_data, config_->GetDeprecatedAcceleratorData(
AcceleratorAction::kShowTaskManager));
ExpectAllAcceleratorsEqual(expected_test_data, config_->GetAllAccelerators());
}
TEST_F(AshAcceleratorConfigurationTest, IsDefaultAccelerator) {
const AcceleratorData test_data[] = {
{true, ui::VKEY_ZOOM, ui::EF_CONTROL_DOWN,
AcceleratorAction::kToggleMirrorMode},
{true, ui::VKEY_ZOOM, ui::EF_ALT_DOWN,
AcceleratorAction::kSwapPrimaryDisplay},
{true, ui::VKEY_MEDIA_LAUNCH_APP1,
ui::EF_CONTROL_DOWN, AcceleratorAction::kTakeScreenshot},
{true, ui::VKEY_KBD_BRIGHTNESS_UP, ui::EF_NONE,
AcceleratorAction::kKeyboardBrightnessUp},
{true, ui::VKEY_BRIGHTNESS_UP, ui::EF_ALT_DOWN,
AcceleratorAction::kKeyboardBrightnessUp},
};
config_->Initialize(test_data);
ExpectAllAcceleratorsEqual(test_data, config_->GetAllAccelerators());
ui::Accelerator expected_default =
ui::Accelerator(ui::VKEY_ZOOM, ui::EF_CONTROL_DOWN);
std::optional<AcceleratorAction> accelerator_id =
config_->GetIdForDefaultAccelerator(expected_default);
EXPECT_TRUE(accelerator_id.has_value());
EXPECT_EQ(AcceleratorAction::kToggleMirrorMode, accelerator_id.value());
std::vector<ui::Accelerator> default_accelerators =
config_->GetDefaultAcceleratorsForId(
AcceleratorAction::kToggleMirrorMode);
EXPECT_EQ(1u, default_accelerators.size());
EXPECT_EQ(expected_default, default_accelerators[0]);
std::vector<ui::Accelerator> nonexistent_defaults =
config_->GetDefaultAcceleratorsForId(
789987);
EXPECT_EQ(0u, nonexistent_defaults.size());
}
TEST_F(AshAcceleratorConfigurationTest, MultipleDefaultAccelerators) {
const AcceleratorData test_data[] = {
{true, ui::VKEY_ZOOM, ui::EF_CONTROL_DOWN,
AcceleratorAction::kToggleMirrorMode},
{true, ui::VKEY_ZOOM, ui::EF_ALT_DOWN,
AcceleratorAction::kToggleMirrorMode},
{true, ui::VKEY_MEDIA_LAUNCH_APP1,
ui::EF_CONTROL_DOWN, AcceleratorAction::kTakeScreenshot},
{true, ui::VKEY_KBD_BRIGHTNESS_UP, ui::EF_NONE,
AcceleratorAction::kKeyboardBrightnessUp},
{true, ui::VKEY_BRIGHTNESS_UP, ui::EF_ALT_DOWN,
AcceleratorAction::kKeyboardBrightnessUp},
};
config_->Initialize(test_data);
ExpectAllAcceleratorsEqual(test_data, config_->GetAllAccelerators());
ui::Accelerator expected_default =
ui::Accelerator(ui::VKEY_ZOOM, ui::EF_CONTROL_DOWN);
ui::Accelerator expected_default_2 =
ui::Accelerator(ui::VKEY_ZOOM, ui::EF_ALT_DOWN);
std::optional<AcceleratorAction> accelerator_id =
config_->GetIdForDefaultAccelerator(expected_default);
EXPECT_TRUE(accelerator_id.has_value());
EXPECT_EQ(AcceleratorAction::kToggleMirrorMode, accelerator_id.value());
accelerator_id = config_->GetIdForDefaultAccelerator(expected_default_2);
EXPECT_TRUE(accelerator_id.has_value());
EXPECT_EQ(AcceleratorAction::kToggleMirrorMode, accelerator_id.value());
std::vector<ui::Accelerator> default_accelerators =
config_->GetDefaultAcceleratorsForId(
AcceleratorAction::kToggleMirrorMode);
EXPECT_EQ(2u, default_accelerators.size());
EXPECT_TRUE(base::Contains(default_accelerators, expected_default));
EXPECT_TRUE(base::Contains(default_accelerators, expected_default_2));
}
TEST_F(AshAcceleratorConfigurationTest, DefaultNotFound) {
const AcceleratorData test_data[] = {
{true, ui::VKEY_ZOOM, ui::EF_CONTROL_DOWN,
AcceleratorAction::kToggleMirrorMode},
{true, ui::VKEY_ZOOM, ui::EF_ALT_DOWN,
AcceleratorAction::kSwapPrimaryDisplay},
{true, ui::VKEY_MEDIA_LAUNCH_APP1,
ui::EF_CONTROL_DOWN, AcceleratorAction::kTakeScreenshot},
{true, ui::VKEY_KBD_BRIGHTNESS_UP, ui::EF_NONE,
AcceleratorAction::kKeyboardBrightnessUp},
{true, ui::VKEY_BRIGHTNESS_UP, ui::EF_ALT_DOWN,
AcceleratorAction::kKeyboardBrightnessUp},
};
config_->Initialize(test_data);
ExpectAllAcceleratorsEqual(test_data, config_->GetAllAccelerators());
ui::Accelerator fake_default =
ui::Accelerator(ui::VKEY_U, ui::EF_CONTROL_DOWN);
std::optional<AcceleratorAction> accelerator_id =
config_->GetIdForDefaultAccelerator(fake_default);
EXPECT_FALSE(accelerator_id.has_value());
}
TEST_F(AshAcceleratorConfigurationTest, GetAcceleratorsFromActionId) {
const AcceleratorData test_data[] = {
{true, ui::VKEY_ZOOM, ui::EF_CONTROL_DOWN,
AcceleratorAction::kToggleMirrorMode},
{true, ui::VKEY_ZOOM, ui::EF_ALT_DOWN,
AcceleratorAction::kSwapPrimaryDisplay},
{true, ui::VKEY_MEDIA_LAUNCH_APP1,
ui::EF_CONTROL_DOWN, AcceleratorAction::kTakeScreenshot},
{true, ui::VKEY_KBD_BRIGHTNESS_UP, ui::EF_NONE,
AcceleratorAction::kKeyboardBrightnessUp},
{true, ui::VKEY_BRIGHTNESS_UP, ui::EF_ALT_DOWN,
AcceleratorAction::kKeyboardBrightnessUp},
};
config_->Initialize(test_data);
std::map<AcceleratorActionId, std::vector<AcceleratorData>>
id_to_accelerator_data;
for (const auto& data : test_data) {
id_to_accelerator_data[static_cast<uint32_t>(data.action)].push_back(data);
}
for (const auto& data : test_data) {
std::vector<AcceleratorData> expected =
id_to_accelerator_data.at(data.action);
base::optional_ref<const std::vector<ui::Accelerator>> actual =
GetAcceleratorsForAction(data.action);
ASSERT_TRUE(actual.has_value());
ExpectAllAcceleratorsEqual(expected, *actual);
}
}
TEST_F(AshAcceleratorConfigurationTest, VerifyObserversAreNotified) {
EXPECT_EQ(0, observer_.num_times_accelerator_updated_called());
const AcceleratorData test_data[] = {
{true, ui::VKEY_SPACE, ui::EF_CONTROL_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_SPACE,
ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_TAB, ui::EF_ALT_DOWN,
AcceleratorAction::kCycleForwardMru},
{true, ui::VKEY_TAB,
ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kCycleBackwardMru},
};
config_->Initialize(test_data);
const std::vector<ui::Accelerator>& accelerators =
config_->GetAllAccelerators();
ExpectAllAcceleratorsEqual(test_data, accelerators);
EXPECT_EQ(1, observer_.num_times_accelerator_updated_called());
const AcceleratorData test_data_updated[] = {
{true, ui::VKEY_J, ui::EF_CONTROL_DOWN,
AcceleratorAction::kToggleFullscreen},
};
config_->Initialize(test_data_updated);
const std::vector<ui::Accelerator>& accelerators_updated =
config_->GetAllAccelerators();
ExpectAllAcceleratorsEqual(test_data_updated, accelerators_updated);
EXPECT_EQ(2, observer_.num_times_accelerator_updated_called());
}
TEST_F(AshAcceleratorConfigurationTest, RemoveAccelerator) {
EXPECT_EQ(0, observer_.num_times_accelerator_updated_called());
const AcceleratorData test_data[] = {
{true, ui::VKEY_SPACE, ui::EF_CONTROL_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{false, ui::VKEY_SPACE, ui::EF_CONTROL_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_SPACE,
ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_TAB, ui::EF_ALT_DOWN,
AcceleratorAction::kCycleForwardMru},
{true, ui::VKEY_TAB,
ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kCycleBackwardMru},
};
config_->Initialize(test_data);
ExpectAllAcceleratorsEqual(test_data, config_->GetAllAccelerators());
EXPECT_EQ(1, observer_.num_times_accelerator_updated_called());
const base::Value::Dict& pref_overrides = GetOverridePref();
EXPECT_TRUE(pref_overrides.empty());
const AcceleratorData updated_test_data[] = {
{true, ui::VKEY_SPACE,
ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_TAB, ui::EF_ALT_DOWN,
AcceleratorAction::kCycleForwardMru},
{true, ui::VKEY_TAB,
ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kCycleBackwardMru},
};
AcceleratorConfigResult result = config_->RemoveAccelerator(
AcceleratorAction::kSwitchToLastUsedIme,
ui::Accelerator(ui::VKEY_SPACE, ui::EF_CONTROL_DOWN));
EXPECT_EQ(AcceleratorConfigResult::kSuccess, result);
const base::Value::Dict& updated_overrides = GetOverridePref();
EXPECT_EQ(1u, updated_overrides.size());
const base::Value::List* accelerator_overrides = updated_overrides.FindList(
base::NumberToString(AcceleratorAction::kSwitchToLastUsedIme));
EXPECT_EQ(1u, accelerator_overrides->size());
AcceleratorModificationData override_data =
ValueToAcceleratorModificationData(
accelerator_overrides->front().GetDict());
EXPECT_TRUE(CompareAccelerators(
{true, ui::VKEY_SPACE, ui::EF_CONTROL_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
override_data.accelerator));
EXPECT_EQ(AcceleratorModificationAction::kRemove, override_data.action);
ExpectAllAcceleratorsEqual(updated_test_data, config_->GetAllAccelerators());
EXPECT_EQ(2, observer_.num_times_accelerator_updated_called());
AcceleratorConfigResult re_remove_result = config_->RemoveAccelerator(
AcceleratorAction::kSwitchToLastUsedIme,
ui::Accelerator(ui::VKEY_SPACE, ui::EF_CONTROL_DOWN));
EXPECT_EQ(AcceleratorConfigResult::kNotFound, re_remove_result);
ExpectAllAcceleratorsEqual(updated_test_data, config_->GetAllAccelerators());
EXPECT_EQ(2, observer_.num_times_accelerator_updated_called());
}
TEST_F(AshAcceleratorConfigurationTest, RemoveAcceleratorIDThatDoesntExist) {
EXPECT_EQ(0, observer_.num_times_accelerator_updated_called());
const AcceleratorData test_data[] = {
{true, ui::VKEY_SPACE, ui::EF_CONTROL_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
};
config_->Initialize(test_data);
ExpectAllAcceleratorsEqual(test_data, config_->GetAllAccelerators());
EXPECT_EQ(1, observer_.num_times_accelerator_updated_called());
AcceleratorConfigResult result = config_->RemoveAccelerator(
AcceleratorAction::kCycleBackwardMru,
ui::Accelerator(ui::VKEY_SPACE, ui::EF_CONTROL_DOWN));
EXPECT_EQ(AcceleratorConfigResult::kNotFound, result);
ExpectAllAcceleratorsEqual(test_data, config_->GetAllAccelerators());
EXPECT_EQ(1, observer_.num_times_accelerator_updated_called());
}
TEST_F(AshAcceleratorConfigurationTest, RemoveAcceleratorThatDoesntExist) {
EXPECT_EQ(0, observer_.num_times_accelerator_updated_called());
const AcceleratorData test_data[] = {
{true, ui::VKEY_SPACE, ui::EF_CONTROL_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
};
config_->Initialize(test_data);
ExpectAllAcceleratorsEqual(test_data, config_->GetAllAccelerators());
EXPECT_EQ(1, observer_.num_times_accelerator_updated_called());
AcceleratorConfigResult updated_result = config_->RemoveAccelerator(
AcceleratorAction::kSwitchToLastUsedIme,
ui::Accelerator(ui::VKEY_M, ui::EF_CONTROL_DOWN));
EXPECT_EQ(AcceleratorConfigResult::kNotFound, updated_result);
ExpectAllAcceleratorsEqual(test_data, config_->GetAllAccelerators());
EXPECT_EQ(1, observer_.num_times_accelerator_updated_called());
}
TEST_F(AshAcceleratorConfigurationTest, RemoveDefaultAccelerator) {
EXPECT_EQ(0, observer_.num_times_accelerator_updated_called());
const AcceleratorData test_data[] = {
{true, ui::VKEY_SPACE, ui::EF_CONTROL_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_SPACE,
ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kBrightnessDown},
{true, ui::VKEY_TAB, ui::EF_ALT_DOWN,
AcceleratorAction::kCycleForwardMru},
{true, ui::VKEY_TAB,
ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kCycleBackwardMru},
};
config_->Initialize(test_data);
ExpectAllAcceleratorsEqual(test_data, config_->GetAllAccelerators());
EXPECT_EQ(1, observer_.num_times_accelerator_updated_called());
const AcceleratorData updated_test_data[] = {
{true, ui::VKEY_SPACE,
ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_TAB, ui::EF_ALT_DOWN,
AcceleratorAction::kCycleForwardMru},
{true, ui::VKEY_TAB,
ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kCycleBackwardMru},
};
ui::Accelerator removed_accelerator =
ui::Accelerator(ui::VKEY_SPACE, ui::EF_CONTROL_DOWN);
AcceleratorConfigResult result = config_->RemoveAccelerator(
AcceleratorAction::kSwitchToLastUsedIme, removed_accelerator);
EXPECT_EQ(AcceleratorConfigResult::kSuccess, result);
EXPECT_EQ(AcceleratorAction::kSwitchToLastUsedIme,
config_->GetIdForDefaultAccelerator(removed_accelerator));
std::vector<ui::Accelerator> default_accelerators =
config_->GetDefaultAcceleratorsForId(
AcceleratorAction::kSwitchToLastUsedIme);
EXPECT_EQ(1u, default_accelerators.size());
EXPECT_EQ(removed_accelerator, default_accelerators[0]);
ExpectAllAcceleratorsEqual(updated_test_data, config_->GetAllAccelerators());
EXPECT_EQ(2, observer_.num_times_accelerator_updated_called());
}
TEST_F(AshAcceleratorConfigurationTest, RemoveAndRestoreDefault) {
EXPECT_EQ(0, observer_.num_times_accelerator_updated_called());
const AcceleratorData test_data[] = {
{true, ui::VKEY_SPACE, ui::EF_CONTROL_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_SPACE,
ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_TAB, ui::EF_ALT_DOWN,
AcceleratorAction::kCycleForwardMru},
{true, ui::VKEY_TAB,
ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kCycleBackwardMru},
};
config_->Initialize(test_data);
ExpectAllAcceleratorsEqual(test_data, config_->GetAllAccelerators());
EXPECT_EQ(1, observer_.num_times_accelerator_updated_called());
const AcceleratorData updated_test_data[] = {
{true, ui::VKEY_SPACE,
ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_TAB, ui::EF_ALT_DOWN,
AcceleratorAction::kCycleForwardMru},
{true, ui::VKEY_TAB,
ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kCycleBackwardMru},
};
AcceleratorConfigResult result = config_->RemoveAccelerator(
AcceleratorAction::kSwitchToLastUsedIme,
ui::Accelerator(ui::VKEY_SPACE, ui::EF_CONTROL_DOWN));
EXPECT_EQ(AcceleratorConfigResult::kSuccess, result);
ExpectAllAcceleratorsEqual(updated_test_data, config_->GetAllAccelerators());
EXPECT_EQ(2, observer_.num_times_accelerator_updated_called());
result = config_->RestoreAllDefaults();
EXPECT_EQ(AcceleratorConfigResult::kSuccess, result);
ExpectAllAcceleratorsEqual(test_data, config_->GetAllAccelerators());
EXPECT_EQ(3, observer_.num_times_accelerator_updated_called());
}
TEST_F(AshAcceleratorConfigurationTest, RestoreAllConsecutively) {
EXPECT_EQ(0, observer_.num_times_accelerator_updated_called());
const AcceleratorData test_data[] = {
{true, ui::VKEY_SPACE, ui::EF_CONTROL_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_SPACE,
ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_TAB, ui::EF_ALT_DOWN,
AcceleratorAction::kCycleForwardMru},
{true, ui::VKEY_TAB,
ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kCycleBackwardMru},
};
config_->Initialize(test_data);
ExpectAllAcceleratorsEqual(test_data, config_->GetAllAccelerators());
EXPECT_EQ(1, observer_.num_times_accelerator_updated_called());
AcceleratorConfigResult reset_result = config_->RestoreAllDefaults();
EXPECT_EQ(AcceleratorConfigResult::kSuccess, reset_result);
ExpectAllAcceleratorsEqual(test_data, config_->GetAllAccelerators());
EXPECT_EQ(2, observer_.num_times_accelerator_updated_called());
reset_result = config_->RestoreAllDefaults();
EXPECT_EQ(AcceleratorConfigResult::kSuccess, reset_result);
ExpectAllAcceleratorsEqual(test_data, config_->GetAllAccelerators());
EXPECT_EQ(3, observer_.num_times_accelerator_updated_called());
}
TEST_F(AshAcceleratorConfigurationTest, RemoveAndRestoreOneAction) {
EXPECT_EQ(0, observer_.num_times_accelerator_updated_called());
const AcceleratorData test_data[] = {
{true, ui::VKEY_SPACE, ui::EF_CONTROL_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_SPACE,
ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_TAB, ui::EF_ALT_DOWN,
AcceleratorAction::kCycleForwardMru},
{true, ui::VKEY_TAB,
ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kCycleBackwardMru},
};
config_->Initialize(test_data);
ExpectAllAcceleratorsEqual(test_data, config_->GetAllAccelerators());
EXPECT_EQ(1, observer_.num_times_accelerator_updated_called());
const AcceleratorData updated_test_data[] = {
{true, ui::VKEY_SPACE,
ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_TAB, ui::EF_ALT_DOWN,
AcceleratorAction::kCycleForwardMru},
{true, ui::VKEY_TAB,
ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kCycleBackwardMru},
};
AcceleratorConfigResult result = config_->RemoveAccelerator(
AcceleratorAction::kSwitchToLastUsedIme,
ui::Accelerator(ui::VKEY_SPACE, ui::EF_CONTROL_DOWN));
EXPECT_EQ(AcceleratorConfigResult::kSuccess, result);
ExpectAllAcceleratorsEqual(updated_test_data, config_->GetAllAccelerators());
EXPECT_EQ(2, observer_.num_times_accelerator_updated_called());
result = config_->RestoreDefault(AcceleratorAction::kSwitchToLastUsedIme);
EXPECT_EQ(AcceleratorConfigResult::kSuccess, result);
ExpectAllAcceleratorsEqual(test_data, config_->GetAllAccelerators());
EXPECT_EQ(3, observer_.num_times_accelerator_updated_called());
result = config_->RestoreDefault(AcceleratorAction::kSwitchToLastUsedIme);
EXPECT_EQ(AcceleratorConfigResult::kSuccess, result);
ExpectAllAcceleratorsEqual(test_data, config_->GetAllAccelerators());
EXPECT_EQ(4, observer_.num_times_accelerator_updated_called());
}
TEST_F(AshAcceleratorConfigurationTest, RestoreInvalidAction) {
EXPECT_EQ(0, observer_.num_times_accelerator_updated_called());
const AcceleratorData test_data[] = {
{true, ui::VKEY_SPACE, ui::EF_CONTROL_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_SPACE,
ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_TAB, ui::EF_ALT_DOWN,
AcceleratorAction::kCycleForwardMru},
{true, ui::VKEY_TAB,
ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kCycleBackwardMru},
};
config_->Initialize(test_data);
ExpectAllAcceleratorsEqual(test_data, config_->GetAllAccelerators());
EXPECT_EQ(1, observer_.num_times_accelerator_updated_called());
const AcceleratorConfigResult result =
config_->RestoreDefault(AcceleratorAction::kBrightnessDown);
EXPECT_EQ(AcceleratorConfigResult::kNotFound, result);
ExpectAllAcceleratorsEqual(test_data, config_->GetAllAccelerators());
EXPECT_EQ(1, observer_.num_times_accelerator_updated_called());
}
TEST_F(AshAcceleratorConfigurationTest, AddAccelerator) {
EXPECT_EQ(0, observer_.num_times_accelerator_updated_called());
const AcceleratorData test_data[] = {
{true, ui::VKEY_SPACE,
ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_TAB, ui::EF_ALT_DOWN,
AcceleratorAction::kCycleForwardMru},
{true, ui::VKEY_TAB,
ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kCycleBackwardMru},
};
config_->Initialize(test_data);
ExpectAllAcceleratorsEqual(test_data, config_->GetAllAccelerators());
EXPECT_EQ(1, observer_.num_times_accelerator_updated_called());
const AcceleratorData updated_test_data[] = {
{true, ui::VKEY_SPACE, ui::EF_CONTROL_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_SPACE,
ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_TAB, ui::EF_ALT_DOWN,
AcceleratorAction::kCycleForwardMru},
{true, ui::VKEY_TAB,
ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kCycleBackwardMru},
};
const ui::Accelerator new_accelerator(ui::VKEY_SPACE, ui::EF_CONTROL_DOWN);
AcceleratorConfigResult result = config_->AddUserAccelerator(
AcceleratorAction::kSwitchToLastUsedIme, new_accelerator);
EXPECT_EQ(AcceleratorConfigResult::kSuccess, result);
EXPECT_EQ(2, observer_.num_times_accelerator_updated_called());
ExpectAllAcceleratorsEqual(updated_test_data, config_->GetAllAccelerators());
const AcceleratorAction* found_action =
config_->FindAcceleratorAction(new_accelerator);
EXPECT_TRUE(found_action);
EXPECT_EQ(AcceleratorAction::kSwitchToLastUsedIme, *found_action);
}
TEST_F(AshAcceleratorConfigurationTest, AddAcceleratorDefaultConflict) {
EXPECT_EQ(0, observer_.num_times_accelerator_updated_called());
const AcceleratorData test_data[] = {
{true, ui::VKEY_SPACE,
ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_TAB, ui::EF_ALT_DOWN,
AcceleratorAction::kCycleForwardMru},
{true, ui::VKEY_TAB,
ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kCycleBackwardMru},
};
config_->Initialize(test_data);
ExpectAllAcceleratorsEqual(test_data, config_->GetAllAccelerators());
EXPECT_EQ(1, observer_.num_times_accelerator_updated_called());
const AcceleratorData updated_test_data[] = {
{true, ui::VKEY_TAB,
ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_SPACE,
ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_TAB, ui::EF_ALT_DOWN,
AcceleratorAction::kCycleForwardMru},
};
const ui::Accelerator new_accelerator(ui::VKEY_TAB,
ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
AcceleratorConfigResult result = config_->AddUserAccelerator(
AcceleratorAction::kSwitchToLastUsedIme, new_accelerator);
EXPECT_EQ(AcceleratorConfigResult::kSuccess, result);
EXPECT_EQ(2, observer_.num_times_accelerator_updated_called());
ExpectAllAcceleratorsEqual(updated_test_data, config_->GetAllAccelerators());
const AcceleratorAction* found_action =
config_->FindAcceleratorAction(new_accelerator);
EXPECT_TRUE(found_action);
EXPECT_EQ(AcceleratorAction::kSwitchToLastUsedIme, *found_action);
base::optional_ref<const std::vector<ui::Accelerator>>
backward_mru_accelerators =
GetAcceleratorsForAction(AcceleratorAction::kCycleBackwardMru);
ASSERT_TRUE(backward_mru_accelerators->empty());
}
TEST_F(AshAcceleratorConfigurationTest, AddAcceleratorDeprecatedConflict) {
EXPECT_EQ(0, observer_.num_times_accelerator_updated_called());
const AcceleratorData test_data[] = {
{true, ui::VKEY_SPACE,
ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_TAB, ui::EF_ALT_DOWN,
AcceleratorAction::kCycleForwardMru},
{true, ui::VKEY_TAB,
ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kCycleBackwardMru},
};
const DeprecatedAcceleratorData deprecated_data[] = {
{AcceleratorAction::kShowTaskManager,
"deprecated.showTaskManager",
1,
2,
ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_COMMAND_DOWN),
true},
};
const AcceleratorData test_deprecated_accelerators[] = {
{true, ui::VKEY_ESCAPE, ui::EF_SHIFT_DOWN,
AcceleratorAction::kShowTaskManager},
{true, ui::VKEY_ESCAPE,
ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kShowTaskManager},
};
const AcceleratorData initial_expected_data[] = {
{true, ui::VKEY_SPACE,
ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_TAB, ui::EF_ALT_DOWN,
AcceleratorAction::kCycleForwardMru},
{true, ui::VKEY_TAB,
ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kCycleBackwardMru},
{true, ui::VKEY_ESCAPE, ui::EF_SHIFT_DOWN,
AcceleratorAction::kShowTaskManager},
{true, ui::VKEY_ESCAPE,
ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kShowTaskManager},
};
config_->Initialize(test_data);
config_->InitializeDeprecatedAccelerators(deprecated_data,
test_deprecated_accelerators);
ExpectAllAcceleratorsEqual(initial_expected_data,
config_->GetAllAccelerators());
EXPECT_EQ(2, observer_.num_times_accelerator_updated_called());
const ui::Accelerator deprecated_accelerator(ui::VKEY_ESCAPE,
ui::EF_SHIFT_DOWN);
EXPECT_TRUE(config_->IsDeprecated(deprecated_accelerator));
const ui::Accelerator deprecated_accelerator_2(
ui::VKEY_ESCAPE, ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN);
EXPECT_TRUE(config_->IsDeprecated(deprecated_accelerator_2));
const AcceleratorData updated_test_data[] = {
{true, ui::VKEY_SPACE,
ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_ESCAPE, ui::EF_SHIFT_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_TAB, ui::EF_ALT_DOWN,
AcceleratorAction::kCycleForwardMru},
{true, ui::VKEY_TAB,
ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kCycleBackwardMru},
{true, ui::VKEY_ESCAPE,
ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kShowTaskManager},
};
AcceleratorConfigResult result = config_->AddUserAccelerator(
AcceleratorAction::kSwitchToLastUsedIme, deprecated_accelerator);
EXPECT_EQ(AcceleratorConfigResult::kSuccess, result);
EXPECT_EQ(3, observer_.num_times_accelerator_updated_called());
ExpectAllAcceleratorsEqual(updated_test_data, config_->GetAllAccelerators());
const AcceleratorAction* found_action =
config_->FindAcceleratorAction(deprecated_accelerator);
EXPECT_TRUE(found_action);
EXPECT_EQ(AcceleratorAction::kSwitchToLastUsedIme, *found_action);
EXPECT_FALSE(config_->IsDeprecated(deprecated_accelerator));
const DeprecatedAcceleratorData* task_manager_deprecated_data =
config_->GetDeprecatedAcceleratorData(
AcceleratorAction::kShowTaskManager);
EXPECT_EQ(AcceleratorAction::kShowTaskManager,
task_manager_deprecated_data->action);
EXPECT_TRUE(config_->IsDeprecated(deprecated_accelerator_2));
}
TEST_F(AshAcceleratorConfigurationTest, AddRemoveAccelerator) {
EXPECT_EQ(0, observer_.num_times_accelerator_updated_called());
const AcceleratorData test_data[] = {
{true, ui::VKEY_SPACE,
ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_TAB, ui::EF_ALT_DOWN,
AcceleratorAction::kCycleForwardMru},
{true, ui::VKEY_TAB,
ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kCycleBackwardMru},
};
config_->Initialize(test_data);
ExpectAllAcceleratorsEqual(test_data, config_->GetAllAccelerators());
EXPECT_EQ(1, observer_.num_times_accelerator_updated_called());
const AcceleratorData added_updated_test_data[] = {
{true, ui::VKEY_SPACE, ui::EF_CONTROL_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_SPACE,
ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_TAB, ui::EF_ALT_DOWN,
AcceleratorAction::kCycleForwardMru},
{true, ui::VKEY_TAB,
ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kCycleBackwardMru},
};
const ui::Accelerator new_accelerator(ui::VKEY_SPACE, ui::EF_CONTROL_DOWN);
AcceleratorConfigResult result = config_->AddUserAccelerator(
AcceleratorAction::kSwitchToLastUsedIme, new_accelerator);
EXPECT_EQ(AcceleratorConfigResult::kSuccess, result);
EXPECT_EQ(2, observer_.num_times_accelerator_updated_called());
ExpectAllAcceleratorsEqual(added_updated_test_data,
config_->GetAllAccelerators());
const AcceleratorAction* found_action =
config_->FindAcceleratorAction(new_accelerator);
EXPECT_TRUE(found_action);
EXPECT_EQ(AcceleratorAction::kSwitchToLastUsedIme, *found_action);
const AcceleratorData removed_updated_test_data[] = {
{true, ui::VKEY_SPACE,
ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_TAB, ui::EF_ALT_DOWN,
AcceleratorAction::kCycleForwardMru},
{true, ui::VKEY_TAB,
ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kCycleBackwardMru},
};
result = config_->RemoveAccelerator(AcceleratorAction::kSwitchToLastUsedIme,
new_accelerator);
EXPECT_EQ(AcceleratorConfigResult::kSuccess, result);
EXPECT_EQ(3, observer_.num_times_accelerator_updated_called());
ExpectAllAcceleratorsEqual(removed_updated_test_data,
config_->GetAllAccelerators());
EXPECT_FALSE(config_->FindAcceleratorAction(new_accelerator));
}
TEST_F(AshAcceleratorConfigurationTest, AddRestoreAccelerator) {
EXPECT_EQ(0, observer_.num_times_accelerator_updated_called());
const AcceleratorData test_data[] = {
{true, ui::VKEY_SPACE,
ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_TAB, ui::EF_ALT_DOWN,
AcceleratorAction::kCycleForwardMru},
{true, ui::VKEY_TAB,
ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kCycleBackwardMru},
};
config_->Initialize(test_data);
ExpectAllAcceleratorsEqual(test_data, config_->GetAllAccelerators());
EXPECT_EQ(1, observer_.num_times_accelerator_updated_called());
const AcceleratorData updated_test_data[] = {
{true, ui::VKEY_SPACE, ui::EF_CONTROL_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_SPACE,
ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_TAB, ui::EF_ALT_DOWN,
AcceleratorAction::kCycleForwardMru},
{true, ui::VKEY_TAB,
ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kCycleBackwardMru},
};
const ui::Accelerator new_accelerator(ui::VKEY_SPACE, ui::EF_CONTROL_DOWN);
AcceleratorConfigResult result = config_->AddUserAccelerator(
AcceleratorAction::kSwitchToLastUsedIme, new_accelerator);
EXPECT_EQ(AcceleratorConfigResult::kSuccess, result);
EXPECT_EQ(2, observer_.num_times_accelerator_updated_called());
ExpectAllAcceleratorsEqual(updated_test_data, config_->GetAllAccelerators());
const AcceleratorAction* found_action =
config_->FindAcceleratorAction(new_accelerator);
EXPECT_TRUE(found_action);
EXPECT_EQ(AcceleratorAction::kSwitchToLastUsedIme, *found_action);
result = config_->RestoreDefault(AcceleratorAction::kSwitchToLastUsedIme);
EXPECT_EQ(3, observer_.num_times_accelerator_updated_called());
EXPECT_EQ(AcceleratorConfigResult::kSuccess, result);
EXPECT_FALSE(config_->FindAcceleratorAction(new_accelerator));
ExpectAllAcceleratorsEqual(test_data, config_->GetAllAccelerators());
}
TEST_F(AshAcceleratorConfigurationTest, RestoreWithDefaultConflicts) {
EXPECT_EQ(0, observer_.num_times_accelerator_updated_called());
const AcceleratorData test_data[] = {
{true, ui::VKEY_SPACE,
ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_TAB, ui::EF_ALT_DOWN,
AcceleratorAction::kCycleForwardMru},
{true, ui::VKEY_C, ui::EF_ALT_DOWN,
AcceleratorAction::kCycleForwardMru},
};
config_->Initialize(test_data);
ExpectAllAcceleratorsEqual(test_data, config_->GetAllAccelerators());
EXPECT_EQ(1, observer_.num_times_accelerator_updated_called());
const AcceleratorData updated_test_data[] = {
{true, ui::VKEY_C, ui::EF_ALT_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_SPACE,
ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_TAB, ui::EF_ALT_DOWN,
AcceleratorAction::kCycleForwardMru},
};
const ui::Accelerator new_accelerator(ui::VKEY_C, ui::EF_ALT_DOWN);
AcceleratorConfigResult result = config_->AddUserAccelerator(
AcceleratorAction::kSwitchToLastUsedIme, new_accelerator);
EXPECT_EQ(AcceleratorConfigResult::kSuccess, result);
EXPECT_EQ(2, observer_.num_times_accelerator_updated_called());
ExpectAllAcceleratorsEqual(updated_test_data, config_->GetAllAccelerators());
const AcceleratorAction* found_action =
config_->FindAcceleratorAction(new_accelerator);
EXPECT_TRUE(found_action);
EXPECT_EQ(AcceleratorAction::kSwitchToLastUsedIme, *found_action);
base::optional_ref<const std::vector<ui::Accelerator>>
forward_mru_accelerators =
GetAcceleratorsForAction(AcceleratorAction::kCycleForwardMru);
ASSERT_TRUE(forward_mru_accelerators.has_value());
EXPECT_EQ(1u, forward_mru_accelerators->size());
result = config_->RestoreDefault(AcceleratorAction::kCycleForwardMru);
EXPECT_EQ(3, observer_.num_times_accelerator_updated_called());
EXPECT_EQ(AcceleratorConfigResult::kRestoreSuccessWithConflicts, result);
ExpectAllAcceleratorsEqual(updated_test_data, config_->GetAllAccelerators());
}
TEST_F(AshAcceleratorConfigurationTest, ReAddAcceleratorToAnotherAction) {
EXPECT_EQ(0, observer_.num_times_accelerator_updated_called());
const AcceleratorData test_data[] = {
{true, ui::VKEY_SPACE,
ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_TAB, ui::EF_ALT_DOWN,
AcceleratorAction::kCycleForwardMru},
{true, ui::VKEY_TAB,
ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kCycleBackwardMru},
};
config_->Initialize(test_data);
ExpectAllAcceleratorsEqual(test_data, config_->GetAllAccelerators());
EXPECT_EQ(1, observer_.num_times_accelerator_updated_called());
const AcceleratorData updated_test_data[] = {
{true, ui::VKEY_SPACE, ui::EF_CONTROL_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_SPACE,
ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_TAB, ui::EF_ALT_DOWN,
AcceleratorAction::kCycleForwardMru},
{true, ui::VKEY_TAB,
ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kCycleBackwardMru},
};
const ui::Accelerator new_accelerator(ui::VKEY_SPACE, ui::EF_CONTROL_DOWN);
AcceleratorConfigResult result = config_->AddUserAccelerator(
AcceleratorAction::kSwitchToLastUsedIme, new_accelerator);
EXPECT_EQ(AcceleratorConfigResult::kSuccess, result);
EXPECT_EQ(2, observer_.num_times_accelerator_updated_called());
ExpectAllAcceleratorsEqual(updated_test_data, config_->GetAllAccelerators());
const AcceleratorAction* found_action =
config_->FindAcceleratorAction(new_accelerator);
EXPECT_TRUE(found_action);
EXPECT_EQ(AcceleratorAction::kSwitchToLastUsedIme, *found_action);
const AcceleratorData reupdated_test_data[] = {
{true, ui::VKEY_SPACE,
ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_TAB, ui::EF_ALT_DOWN,
AcceleratorAction::kCycleForwardMru},
{true, ui::VKEY_TAB,
ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kCycleBackwardMru},
{true, ui::VKEY_SPACE, ui::EF_CONTROL_DOWN,
AcceleratorAction::kCycleBackwardMru},
};
result = config_->AddUserAccelerator(AcceleratorAction::kCycleBackwardMru,
new_accelerator);
EXPECT_EQ(AcceleratorConfigResult::kSuccess, result);
ExpectAllAcceleratorsEqual(reupdated_test_data,
config_->GetAllAccelerators());
const AcceleratorAction* found_action2 =
config_->FindAcceleratorAction(new_accelerator);
EXPECT_TRUE(found_action2);
EXPECT_EQ(AcceleratorAction::kCycleBackwardMru, *found_action2);
}
TEST_F(AshAcceleratorConfigurationTest, ReplaceAccelerator) {
EXPECT_EQ(0, observer_.num_times_accelerator_updated_called());
const AcceleratorData test_data[] = {
{true, ui::VKEY_SPACE,
ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
};
config_->Initialize(test_data);
ExpectAllAcceleratorsEqual(test_data, config_->GetAllAccelerators());
EXPECT_EQ(1, observer_.num_times_accelerator_updated_called());
const AcceleratorData updated_test_data[] = {
{true, ui::VKEY_M, ui::EF_CONTROL_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
};
const ui::Accelerator old_accelerator(ui::VKEY_SPACE,
ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN);
const ui::Accelerator new_accelerator(ui::VKEY_M, ui::EF_CONTROL_DOWN);
AcceleratorConfigResult result =
config_->ReplaceAccelerator(AcceleratorAction::kSwitchToLastUsedIme,
old_accelerator, new_accelerator);
EXPECT_EQ(AcceleratorConfigResult::kSuccess, result);
EXPECT_EQ(2, observer_.num_times_accelerator_updated_called());
ExpectAllAcceleratorsEqual(updated_test_data, config_->GetAllAccelerators());
const AcceleratorAction* found_action =
config_->FindAcceleratorAction(new_accelerator);
EXPECT_TRUE(found_action);
EXPECT_EQ(AcceleratorAction::kSwitchToLastUsedIme, *found_action);
}
TEST_F(AshAcceleratorConfigurationTest, ReplaceNonExistentAccelerator) {
EXPECT_EQ(0, observer_.num_times_accelerator_updated_called());
const AcceleratorData test_data[] = {
{true, ui::VKEY_SPACE,
ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
};
config_->Initialize(test_data);
ExpectAllAcceleratorsEqual(test_data, config_->GetAllAccelerators());
EXPECT_EQ(1, observer_.num_times_accelerator_updated_called());
const ui::Accelerator old_accelerator(ui::VKEY_J, ui::EF_CONTROL_DOWN);
const ui::Accelerator new_accelerator(ui::VKEY_C, ui::EF_COMMAND_DOWN);
AcceleratorConfigResult result =
config_->ReplaceAccelerator(AcceleratorAction::kSwitchToLastUsedIme,
old_accelerator, new_accelerator);
EXPECT_EQ(AcceleratorConfigResult::kNotFound, result);
ExpectAllAcceleratorsEqual(test_data, config_->GetAllAccelerators());
}
TEST_F(AshAcceleratorConfigurationTest, ReplaceThenRestoreAccelerator) {
EXPECT_EQ(0, observer_.num_times_accelerator_updated_called());
const AcceleratorData test_data[] = {
{true, ui::VKEY_SPACE,
ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
};
config_->Initialize(test_data);
ExpectAllAcceleratorsEqual(test_data, config_->GetAllAccelerators());
EXPECT_EQ(1, observer_.num_times_accelerator_updated_called());
const AcceleratorData updated_test_data[] = {
{true, ui::VKEY_M, ui::EF_CONTROL_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
};
const ui::Accelerator old_accelerator(ui::VKEY_SPACE,
ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN);
const ui::Accelerator new_accelerator(ui::VKEY_M, ui::EF_CONTROL_DOWN);
AcceleratorConfigResult result =
config_->ReplaceAccelerator(AcceleratorAction::kSwitchToLastUsedIme,
old_accelerator, new_accelerator);
EXPECT_EQ(AcceleratorConfigResult::kSuccess, result);
EXPECT_EQ(2, observer_.num_times_accelerator_updated_called());
ExpectAllAcceleratorsEqual(updated_test_data, config_->GetAllAccelerators());
const AcceleratorAction* found_action =
config_->FindAcceleratorAction(new_accelerator);
EXPECT_TRUE(found_action);
EXPECT_EQ(AcceleratorAction::kSwitchToLastUsedIme, *found_action);
config_->RestoreAllDefaults();
EXPECT_EQ(3, observer_.num_times_accelerator_updated_called());
ExpectAllAcceleratorsEqual(test_data, config_->GetAllAccelerators());
}
TEST_F(AshAcceleratorConfigurationTest, RemoveAcceleratorPref) {
SimulateNewUserFirstLogin(kFakeUserEmail);
const AcceleratorData test_data[] = {
{true, ui::VKEY_SPACE, ui::EF_CONTROL_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_SPACE,
ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_TAB, ui::EF_ALT_DOWN,
AcceleratorAction::kCycleForwardMru},
{true, ui::VKEY_TAB,
ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kCycleBackwardMru},
};
config_->Initialize(test_data);
const base::Value::Dict& pref_overrides = GetOverridePref();
EXPECT_TRUE(pref_overrides.empty());
AcceleratorConfigResult result = config_->RemoveAccelerator(
AcceleratorAction::kSwitchToLastUsedIme,
ui::Accelerator(ui::VKEY_SPACE, ui::EF_CONTROL_DOWN));
EXPECT_EQ(AcceleratorConfigResult::kSuccess, result);
const base::Value::Dict& updated_overrides = GetOverridePref();
EXPECT_EQ(1u, updated_overrides.size());
const base::Value::List* accelerator_overrides = updated_overrides.FindList(
base::NumberToString(AcceleratorAction::kSwitchToLastUsedIme));
EXPECT_EQ(1u, accelerator_overrides->size());
AcceleratorModificationData override_data =
ValueToAcceleratorModificationData(
accelerator_overrides->front().GetDict());
EXPECT_TRUE(CompareAccelerators(
{true, ui::VKEY_SPACE, ui::EF_CONTROL_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
override_data.accelerator));
EXPECT_EQ(AcceleratorModificationAction::kRemove, override_data.action);
ClearLogin();
SimulateNewUserFirstLogin(kFakeUserEmail2);
const base::Value::Dict& other_user_pref_overrides = GetOverridePref();
EXPECT_TRUE(other_user_pref_overrides.empty());
ClearLogin();
config_->Initialize(test_data);
SimulateUserLogin({kFakeUserEmail});
const base::Value::Dict& original_pref_overrides = GetOverridePref();
EXPECT_FALSE(original_pref_overrides.empty());
const AcceleratorData updated_test_data[] = {
{true, ui::VKEY_SPACE,
ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_TAB, ui::EF_ALT_DOWN,
AcceleratorAction::kCycleForwardMru},
{true, ui::VKEY_TAB,
ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kCycleBackwardMru},
};
ExpectAllAcceleratorsEqual(updated_test_data, config_->GetAllAccelerators());
}
TEST_F(AshAcceleratorConfigurationTest, RemoveAcceleratorThenResetAllPref) {
SimulateNewUserFirstLogin(kFakeUserEmail);
histogram_tester_->ExpectBucketCount(
"Ash.ShortcutCustomization.CustomizationsLoadedOnStartup", 0, 2);
histogram_tester_->ExpectBucketCount(
"Ash.ShortcutCustomization.CustomizationsBeforeResetAll", 1, 0);
const AcceleratorData test_data[] = {
{true, ui::VKEY_SPACE, ui::EF_CONTROL_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_SPACE,
ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_TAB, ui::EF_ALT_DOWN,
AcceleratorAction::kCycleForwardMru},
{true, ui::VKEY_TAB,
ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kCycleBackwardMru},
};
config_->Initialize(test_data);
const base::Value::Dict& pref_overrides = GetOverridePref();
EXPECT_TRUE(pref_overrides.empty());
AcceleratorConfigResult result = config_->RemoveAccelerator(
AcceleratorAction::kSwitchToLastUsedIme,
ui::Accelerator(ui::VKEY_SPACE, ui::EF_CONTROL_DOWN));
EXPECT_EQ(AcceleratorConfigResult::kSuccess, result);
const base::Value::Dict& updated_overrides = GetOverridePref();
EXPECT_EQ(1u, updated_overrides.size());
const base::Value::List* accelerator_overrides = updated_overrides.FindList(
base::NumberToString(AcceleratorAction::kSwitchToLastUsedIme));
EXPECT_EQ(1u, accelerator_overrides->size());
AcceleratorModificationData override_data =
ValueToAcceleratorModificationData(
accelerator_overrides->front().GetDict());
EXPECT_TRUE(CompareAccelerators(
{true, ui::VKEY_SPACE, ui::EF_CONTROL_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
override_data.accelerator));
EXPECT_EQ(AcceleratorModificationAction::kRemove, override_data.action);
ClearLogin();
config_->Initialize(test_data);
SimulateUserLogin({kFakeUserEmail});
const base::Value::Dict& original_pref_overrides = GetOverridePref();
EXPECT_FALSE(original_pref_overrides.empty());
const AcceleratorData updated_test_data[] = {
{true, ui::VKEY_SPACE,
ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_TAB, ui::EF_ALT_DOWN,
AcceleratorAction::kCycleForwardMru},
{true, ui::VKEY_TAB,
ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kCycleBackwardMru},
};
ExpectAllAcceleratorsEqual(updated_test_data, config_->GetAllAccelerators());
histogram_tester_->ExpectBucketCount(
"Ash.ShortcutCustomization.CustomizationsLoadedOnStartup", 1, 2);
result = config_->RestoreAllDefaults();
EXPECT_EQ(AcceleratorConfigResult::kSuccess, result);
EXPECT_TRUE(GetOverridePref().empty());
ClearLogin();
config_->Initialize(test_data);
SimulateUserLogin({kFakeUserEmail});
const base::Value::Dict& reset_pref_overrides = GetOverridePref();
EXPECT_TRUE(reset_pref_overrides.empty());
ExpectAllAcceleratorsEqual(test_data, config_->GetAllAccelerators());
histogram_tester_->ExpectBucketCount(
"Ash.ShortcutCustomization.CustomizationsLoadedOnStartup", 0, 4);
histogram_tester_->ExpectBucketCount(
"Ash.ShortcutCustomization.CustomizationsBeforeResetAll", 1, 1);
}
TEST_F(AshAcceleratorConfigurationTest, RemoveAcceleratorThenResetPref) {
SimulateNewUserFirstLogin(kFakeUserEmail);
const AcceleratorData test_data[] = {
{true, ui::VKEY_SPACE, ui::EF_CONTROL_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_SPACE,
ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_TAB, ui::EF_ALT_DOWN,
AcceleratorAction::kCycleForwardMru},
{true, ui::VKEY_TAB,
ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kCycleBackwardMru},
};
config_->Initialize(test_data);
const base::Value::Dict& pref_overrides = GetOverridePref();
EXPECT_TRUE(pref_overrides.empty());
AcceleratorConfigResult result = config_->RemoveAccelerator(
AcceleratorAction::kSwitchToLastUsedIme,
ui::Accelerator(ui::VKEY_SPACE, ui::EF_CONTROL_DOWN));
EXPECT_EQ(AcceleratorConfigResult::kSuccess, result);
const base::Value::Dict& updated_overrides = GetOverridePref();
EXPECT_EQ(1u, updated_overrides.size());
const base::Value::List* accelerator_overrides = updated_overrides.FindList(
base::NumberToString(AcceleratorAction::kSwitchToLastUsedIme));
EXPECT_EQ(1u, accelerator_overrides->size());
AcceleratorModificationData override_data =
ValueToAcceleratorModificationData(
accelerator_overrides->front().GetDict());
EXPECT_TRUE(CompareAccelerators(
{true, ui::VKEY_SPACE, ui::EF_CONTROL_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
override_data.accelerator));
EXPECT_EQ(AcceleratorModificationAction::kRemove, override_data.action);
ClearLogin();
config_->Initialize(test_data);
SimulateUserLogin({kFakeUserEmail});
const base::Value::Dict& original_pref_overrides = GetOverridePref();
EXPECT_FALSE(original_pref_overrides.empty());
const AcceleratorData updated_test_data[] = {
{true, ui::VKEY_SPACE,
ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_TAB, ui::EF_ALT_DOWN,
AcceleratorAction::kCycleForwardMru},
{true, ui::VKEY_TAB,
ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kCycleBackwardMru},
};
ExpectAllAcceleratorsEqual(updated_test_data, config_->GetAllAccelerators());
result = config_->RestoreDefault(AcceleratorAction::kSwitchToLastUsedIme);
EXPECT_EQ(AcceleratorConfigResult::kSuccess, result);
ClearLogin();
config_->Initialize(test_data);
SimulateUserLogin({kFakeUserEmail});
const base::Value::Dict& reset_pref_overrides = GetOverridePref();
EXPECT_TRUE(reset_pref_overrides.empty());
ExpectAllAcceleratorsEqual(test_data, config_->GetAllAccelerators());
}
TEST_F(AshAcceleratorConfigurationTest, AddAcceleratorWithPrefs) {
SimulateNewUserFirstLogin(kFakeUserEmail);
const AcceleratorData test_data[] = {
{true, ui::VKEY_SPACE, ui::EF_CONTROL_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_SPACE,
ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
};
config_->Initialize(test_data);
histogram_tester_->ExpectBucketCount(
"Ash.ShortcutCustomization.CustomizationsLoadedOnStartup", 0, 2);
const base::Value::Dict& pref_overrides = GetOverridePref();
EXPECT_TRUE(pref_overrides.empty());
const ui::Accelerator new_accelerator(ui::VKEY_A, ui::EF_COMMAND_DOWN);
AcceleratorConfigResult result = config_->AddUserAccelerator(
AcceleratorAction::kSwitchToLastUsedIme, new_accelerator);
EXPECT_EQ(AcceleratorConfigResult::kSuccess, result);
const base::Value::Dict& updated_overrides = GetOverridePref();
EXPECT_EQ(1u, updated_overrides.size());
const base::Value::List* accelerator_overrides = updated_overrides.FindList(
base::NumberToString(AcceleratorAction::kSwitchToLastUsedIme));
EXPECT_EQ(1u, accelerator_overrides->size());
const AcceleratorData updated_test_data[] = {
{true, ui::VKEY_SPACE, ui::EF_CONTROL_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_SPACE,
ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_A, ui::EF_COMMAND_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
};
AcceleratorModificationData override_data =
ValueToAcceleratorModificationData(
accelerator_overrides->front().GetDict());
EXPECT_TRUE(CompareAccelerators(
{true, ui::VKEY_A, ui::EF_COMMAND_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
override_data.accelerator));
EXPECT_EQ(AcceleratorModificationAction::kAdd, override_data.action);
ExpectAllAcceleratorsEqual(updated_test_data, config_->GetAllAccelerators());
ClearLogin();
SimulateNewUserFirstLogin(kFakeUserEmail2);
const base::Value::Dict& other_user_pref_overrides = GetOverridePref();
EXPECT_TRUE(other_user_pref_overrides.empty());
ClearLogin();
config_->Initialize(test_data);
SimulateUserLogin({kFakeUserEmail});
const base::Value::Dict& original_pref_overrides = GetOverridePref();
EXPECT_FALSE(original_pref_overrides.empty());
const base::Value::Dict& relogin_overrides = GetOverridePref();
EXPECT_EQ(1u, relogin_overrides.size());
ExpectAllAcceleratorsEqual(updated_test_data, config_->GetAllAccelerators());
histogram_tester_->ExpectBucketCount(
"Ash.ShortcutCustomization.CustomizationsLoadedOnStartup", 1, 2);
}
TEST_F(AshAcceleratorConfigurationTest, AddAcceleratorWithConflictWithPrefs) {
SimulateNewUserFirstLogin(kFakeUserEmail);
const AcceleratorData test_data[] = {
{true, ui::VKEY_SPACE, ui::EF_CONTROL_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_C, ui::EF_COMMAND_DOWN,
AcceleratorAction::kToggleCalendar},
};
config_->Initialize(test_data);
const base::Value::Dict& pref_overrides = GetOverridePref();
EXPECT_TRUE(pref_overrides.empty());
const ui::Accelerator new_accelerator(ui::VKEY_C, ui::EF_COMMAND_DOWN);
AcceleratorConfigResult result = config_->AddUserAccelerator(
AcceleratorAction::kSwitchToLastUsedIme, new_accelerator);
EXPECT_EQ(AcceleratorConfigResult::kSuccess, result);
const base::Value::Dict& updated_overrides = GetOverridePref();
EXPECT_EQ(1u, updated_overrides.size());
const base::Value::List* switch_to_last_used_ime_overrides =
updated_overrides.FindList(
base::NumberToString(AcceleratorAction::kSwitchToLastUsedIme));
EXPECT_EQ(1u, switch_to_last_used_ime_overrides->size());
AcceleratorModificationData switch_ime_override_data =
ValueToAcceleratorModificationData(
switch_to_last_used_ime_overrides->front().GetDict());
EXPECT_TRUE(CompareAccelerators(
{true, ui::VKEY_C, ui::EF_COMMAND_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
switch_ime_override_data.accelerator));
EXPECT_EQ(AcceleratorModificationAction::kAdd,
switch_ime_override_data.action);
const AcceleratorData expected_test_data[] = {
{true, ui::VKEY_C, ui::EF_COMMAND_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_SPACE, ui::EF_CONTROL_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
};
ExpectAllAcceleratorsEqual(expected_test_data, config_->GetAllAccelerators());
ClearLogin();
SimulateNewUserFirstLogin(kFakeUserEmail2);
const base::Value::Dict& other_user_pref_overrides = GetOverridePref();
EXPECT_TRUE(other_user_pref_overrides.empty());
ClearLogin();
config_->Initialize(test_data);
SimulateUserLogin({kFakeUserEmail});
const base::Value::Dict& original_pref_overrides = GetOverridePref();
EXPECT_FALSE(original_pref_overrides.empty());
const base::Value::Dict& relogin_overrides = GetOverridePref();
EXPECT_EQ(1u, relogin_overrides.size());
EXPECT_EQ(AcceleratorAction::kSwitchToLastUsedIme,
*config_->FindAcceleratorAction(new_accelerator));
ExpectAllAcceleratorsEqual(expected_test_data, config_->GetAllAccelerators());
}
TEST_F(AshAcceleratorConfigurationTest,
MultipleActionsAddSameAcceleratorWithPrefs) {
SimulateNewUserFirstLogin(kFakeUserEmail);
const AcceleratorData test_data[] = {
{true, ui::VKEY_SPACE, ui::EF_CONTROL_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_C, ui::EF_COMMAND_DOWN,
AcceleratorAction::kToggleCalendar},
{true, ui::VKEY_A, ui::EF_COMMAND_DOWN,
AcceleratorAction::kEnableOrToggleDictation},
};
config_->Initialize(test_data);
histogram_tester_->ExpectBucketCount(
"Ash.ShortcutCustomization.CustomizationsLoadedOnStartup", 0, 2);
const base::Value::Dict& pref_overrides = GetOverridePref();
EXPECT_TRUE(pref_overrides.empty());
const ui::Accelerator new_accelerator(ui::VKEY_C, ui::EF_COMMAND_DOWN);
AcceleratorConfigResult result = config_->AddUserAccelerator(
AcceleratorAction::kSwitchToLastUsedIme, new_accelerator);
EXPECT_EQ(AcceleratorConfigResult::kSuccess, result);
const base::Value::Dict& updated_overrides = GetOverridePref();
EXPECT_EQ(1u, updated_overrides.size());
const base::Value::List* switch_to_last_used_ime_overrides =
updated_overrides.FindList(
base::NumberToString(AcceleratorAction::kSwitchToLastUsedIme));
EXPECT_EQ(1u, switch_to_last_used_ime_overrides->size());
AcceleratorModificationData switch_ime_override_data =
ValueToAcceleratorModificationData(
switch_to_last_used_ime_overrides->front().GetDict());
EXPECT_TRUE(CompareAccelerators(
{true, ui::VKEY_C, ui::EF_COMMAND_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
switch_ime_override_data.accelerator));
EXPECT_EQ(AcceleratorModificationAction::kAdd,
switch_ime_override_data.action);
const AcceleratorData expected_test_data[] = {
{true, ui::VKEY_C, ui::EF_COMMAND_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_SPACE, ui::EF_CONTROL_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_A, ui::EF_COMMAND_DOWN,
AcceleratorAction::kEnableOrToggleDictation},
};
ExpectAllAcceleratorsEqual(expected_test_data, config_->GetAllAccelerators());
result = config_->AddUserAccelerator(
AcceleratorAction::kEnableOrToggleDictation, new_accelerator);
EXPECT_EQ(AcceleratorConfigResult::kSuccess, result);
const base::Value::Dict& updated_overrides_2 = GetOverridePref();
EXPECT_EQ(1u, updated_overrides_2.size());
const base::Value::List* toggle_dictation_overrides =
updated_overrides_2.FindList(
base::NumberToString(AcceleratorAction::kEnableOrToggleDictation));
EXPECT_EQ(1u, toggle_dictation_overrides->size());
AcceleratorModificationData toggle_dictation_data =
ValueToAcceleratorModificationData(
toggle_dictation_overrides->front().GetDict());
EXPECT_TRUE(CompareAccelerators(
{true, ui::VKEY_C, ui::EF_COMMAND_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
toggle_dictation_data.accelerator));
EXPECT_EQ(AcceleratorModificationAction::kAdd, toggle_dictation_data.action);
const AcceleratorData expected_test_data_2[] = {
{true, ui::VKEY_C, ui::EF_COMMAND_DOWN,
AcceleratorAction::kEnableOrToggleDictation},
{true, ui::VKEY_A, ui::EF_COMMAND_DOWN,
AcceleratorAction::kEnableOrToggleDictation},
{true, ui::VKEY_SPACE, ui::EF_CONTROL_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
};
ExpectAllAcceleratorsEqual(expected_test_data_2,
config_->GetAllAccelerators());
ClearLogin();
SimulateNewUserFirstLogin(kFakeUserEmail2);
const base::Value::Dict& other_user_pref_overrides = GetOverridePref();
EXPECT_TRUE(other_user_pref_overrides.empty());
histogram_tester_->ExpectBucketCount(
"Ash.ShortcutCustomization.CustomizationsLoadedOnStartup", 0, 4);
ClearLogin();
config_->Initialize(test_data);
SimulateUserLogin({kFakeUserEmail});
const base::Value::Dict& original_pref_overrides = GetOverridePref();
EXPECT_FALSE(original_pref_overrides.empty());
const base::Value::Dict& relogin_overrides = GetOverridePref();
EXPECT_EQ(1u, relogin_overrides.size());
EXPECT_EQ(AcceleratorAction::kEnableOrToggleDictation,
*config_->FindAcceleratorAction(new_accelerator));
ExpectAllAcceleratorsEqual(expected_test_data_2,
config_->GetAllAccelerators());
histogram_tester_->ExpectBucketCount(
"Ash.ShortcutCustomization.CustomizationsLoadedOnStartup", 1, 2);
}
TEST_F(AshAcceleratorConfigurationTest,
AddCustomThenReAddAfterRemovedWithPrefs) {
SimulateNewUserFirstLogin(kFakeUserEmail);
const AcceleratorData test_data[] = {
{true, ui::VKEY_SPACE, ui::EF_CONTROL_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_C, ui::EF_COMMAND_DOWN,
AcceleratorAction::kToggleCalendar},
{true, ui::VKEY_A, ui::EF_COMMAND_DOWN,
AcceleratorAction::kEnableOrToggleDictation},
};
config_->Initialize(test_data);
histogram_tester_->ExpectBucketCount(
"Ash.ShortcutCustomization.CustomizationsLoadedOnStartup", 0, 2);
const base::Value::Dict& pref_overrides = GetOverridePref();
EXPECT_TRUE(pref_overrides.empty());
const ui::Accelerator new_accelerator(ui::VKEY_M,
ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN);
AcceleratorConfigResult result = config_->AddUserAccelerator(
AcceleratorAction::kSwitchToLastUsedIme, new_accelerator);
EXPECT_EQ(AcceleratorConfigResult::kSuccess, result);
const base::Value::Dict& updated_overrides = GetOverridePref();
EXPECT_EQ(1u, updated_overrides.size());
const base::Value::List* switch_to_last_used_ime_overrides =
updated_overrides.FindList(
base::NumberToString(AcceleratorAction::kSwitchToLastUsedIme));
EXPECT_EQ(1u, switch_to_last_used_ime_overrides->size());
AcceleratorModificationData switch_ime_override_data =
ValueToAcceleratorModificationData(
switch_to_last_used_ime_overrides->front().GetDict());
EXPECT_TRUE(CompareAccelerators({true, ui::VKEY_M,
ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
switch_ime_override_data.accelerator));
EXPECT_EQ(AcceleratorModificationAction::kAdd,
switch_ime_override_data.action);
const AcceleratorData expected_test_data[] = {
{true, ui::VKEY_M,
ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_SPACE, ui::EF_CONTROL_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_C, ui::EF_COMMAND_DOWN,
AcceleratorAction::kToggleCalendar},
{true, ui::VKEY_A, ui::EF_COMMAND_DOWN,
AcceleratorAction::kEnableOrToggleDictation},
};
ExpectAllAcceleratorsEqual(expected_test_data, config_->GetAllAccelerators());
result = config_->AddUserAccelerator(
AcceleratorAction::kEnableOrToggleDictation, new_accelerator);
EXPECT_EQ(AcceleratorConfigResult::kSuccess, result);
const base::Value::Dict& updated_overrides_2 = GetOverridePref();
EXPECT_EQ(1u, updated_overrides_2.size());
const base::Value::List* toggle_dictation_overrides =
updated_overrides_2.FindList(
base::NumberToString(AcceleratorAction::kEnableOrToggleDictation));
EXPECT_EQ(1u, toggle_dictation_overrides->size());
AcceleratorModificationData toggle_dictation_data =
ValueToAcceleratorModificationData(
toggle_dictation_overrides->front().GetDict());
EXPECT_TRUE(CompareAccelerators({true, ui::VKEY_M,
ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kEnableOrToggleDictation},
toggle_dictation_data.accelerator));
EXPECT_EQ(AcceleratorModificationAction::kAdd, toggle_dictation_data.action);
const AcceleratorData expected_test_data_2[] = {
{true, ui::VKEY_M,
ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kEnableOrToggleDictation},
{true, ui::VKEY_A, ui::EF_COMMAND_DOWN,
AcceleratorAction::kEnableOrToggleDictation},
{true, ui::VKEY_SPACE, ui::EF_CONTROL_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_C, ui::EF_COMMAND_DOWN,
AcceleratorAction::kToggleCalendar},
};
ExpectAllAcceleratorsEqual(expected_test_data_2,
config_->GetAllAccelerators());
result = config_->AddUserAccelerator(AcceleratorAction::kSwitchToLastUsedIme,
new_accelerator);
EXPECT_EQ(AcceleratorConfigResult::kSuccess, result);
const base::Value::Dict& updated_overrides_3 = GetOverridePref();
EXPECT_EQ(1u, updated_overrides_3.size());
const base::Value::List* switch_to_last_used_ime_overrides_2 =
updated_overrides_3.FindList(
base::NumberToString(AcceleratorAction::kSwitchToLastUsedIme));
EXPECT_EQ(1u, switch_to_last_used_ime_overrides_2->size());
switch_ime_override_data = ValueToAcceleratorModificationData(
switch_to_last_used_ime_overrides_2->front().GetDict());
EXPECT_TRUE(CompareAccelerators({true, ui::VKEY_M,
ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
switch_ime_override_data.accelerator));
EXPECT_EQ(AcceleratorModificationAction::kAdd,
switch_ime_override_data.action);
const AcceleratorData expected_test_data_3[] = {
{true, ui::VKEY_M,
ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_SPACE, ui::EF_CONTROL_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_C, ui::EF_COMMAND_DOWN,
AcceleratorAction::kToggleCalendar},
{true, ui::VKEY_A, ui::EF_COMMAND_DOWN,
AcceleratorAction::kEnableOrToggleDictation},
};
ExpectAllAcceleratorsEqual(expected_test_data_3,
config_->GetAllAccelerators());
ClearLogin();
SimulateNewUserFirstLogin(kFakeUserEmail2);
const base::Value::Dict& other_user_pref_overrides = GetOverridePref();
EXPECT_TRUE(other_user_pref_overrides.empty());
ClearLogin();
config_->Initialize(test_data);
SimulateUserLogin({kFakeUserEmail});
const base::Value::Dict& original_pref_overrides = GetOverridePref();
EXPECT_FALSE(original_pref_overrides.empty());
const base::Value::Dict& relogin_overrides = GetOverridePref();
EXPECT_EQ(1u, relogin_overrides.size());
EXPECT_EQ(AcceleratorAction::kSwitchToLastUsedIme,
*config_->FindAcceleratorAction(new_accelerator));
ExpectAllAcceleratorsEqual(expected_test_data_3,
config_->GetAllAccelerators());
histogram_tester_->ExpectBucketCount(
"Ash.ShortcutCustomization.CustomizationsLoadedOnStartup", 1, 2);
}
TEST_F(AshAcceleratorConfigurationTest, RemoveThenAddAcceleratorWithPrefs) {
SimulateNewUserFirstLogin(kFakeUserEmail);
const AcceleratorData test_data[] = {
{true, ui::VKEY_SPACE, ui::EF_CONTROL_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_SPACE,
ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_C, ui::EF_COMMAND_DOWN,
AcceleratorAction::kToggleCalendar},
};
config_->Initialize(test_data);
const base::Value::Dict& pref_overrides = GetOverridePref();
EXPECT_TRUE(pref_overrides.empty());
ui::Accelerator new_accelerator(ui::VKEY_SPACE, ui::EF_CONTROL_DOWN);
AcceleratorConfigResult result = config_->RemoveAccelerator(
AcceleratorAction::kSwitchToLastUsedIme, new_accelerator);
EXPECT_EQ(AcceleratorConfigResult::kSuccess, result);
result = config_->AddUserAccelerator(AcceleratorAction::kToggleCalendar,
new_accelerator);
EXPECT_EQ(AcceleratorConfigResult::kSuccess, result);
const base::Value::Dict& remove_add_overrides = GetOverridePref();
EXPECT_EQ(2u, remove_add_overrides.size());
const base::Value::Dict& updated_overrides = GetOverridePref();
const base::Value::List* last_used_ime_overrides = updated_overrides.FindList(
base::NumberToString(AcceleratorAction::kSwitchToLastUsedIme));
AcceleratorModificationData override_data =
ValueToAcceleratorModificationData(
last_used_ime_overrides->front().GetDict());
EXPECT_TRUE(CompareAccelerators(
{true, ui::VKEY_SPACE, ui::EF_CONTROL_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
override_data.accelerator));
EXPECT_EQ(AcceleratorModificationAction::kRemove, override_data.action);
const base::Value::List* toggle_calendar_overrides =
updated_overrides.FindList(
base::NumberToString(AcceleratorAction::kToggleCalendar));
override_data = ValueToAcceleratorModificationData(
toggle_calendar_overrides->front().GetDict());
EXPECT_TRUE(CompareAccelerators(
{true, ui::VKEY_SPACE, ui::EF_CONTROL_DOWN,
AcceleratorAction::kToggleCalendar},
override_data.accelerator));
EXPECT_EQ(AcceleratorModificationAction::kAdd, override_data.action);
const AcceleratorData updated_test_data[] = {
{true, ui::VKEY_SPACE,
ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_C, ui::EF_COMMAND_DOWN,
AcceleratorAction::kToggleCalendar},
{true, ui::VKEY_SPACE, ui::EF_CONTROL_DOWN,
AcceleratorAction::kToggleCalendar},
};
ExpectAllAcceleratorsEqual(updated_test_data, config_->GetAllAccelerators());
ClearLogin();
SimulateNewUserFirstLogin(kFakeUserEmail2);
const base::Value::Dict& other_user_pref_overrides = GetOverridePref();
EXPECT_TRUE(other_user_pref_overrides.empty());
ClearLogin();
config_->Initialize(test_data);
SimulateUserLogin({kFakeUserEmail});
const base::Value::Dict& original_pref_overrides = GetOverridePref();
EXPECT_FALSE(original_pref_overrides.empty());
const base::Value::Dict& relogin_overrides = GetOverridePref();
EXPECT_EQ(2u, relogin_overrides.size());
ExpectAllAcceleratorsEqual(updated_test_data, config_->GetAllAccelerators());
}
TEST_F(AshAcceleratorConfigurationTest, ReplaceAcceleratorWithPrefs) {
SimulateNewUserFirstLogin(kFakeUserEmail);
const AcceleratorData test_data[] = {
{true, ui::VKEY_SPACE, ui::EF_CONTROL_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_SPACE,
ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_C, ui::EF_COMMAND_DOWN,
AcceleratorAction::kToggleCalendar},
};
config_->Initialize(test_data);
const base::Value::Dict& pref_overrides = GetOverridePref();
EXPECT_TRUE(pref_overrides.empty());
ui::Accelerator old_accelerator(ui::VKEY_SPACE, ui::EF_CONTROL_DOWN);
ui::Accelerator new_accelerator(ui::VKEY_A, ui::EF_COMMAND_DOWN);
AcceleratorConfigResult result =
config_->ReplaceAccelerator(AcceleratorAction::kSwitchToLastUsedIme,
old_accelerator, new_accelerator);
EXPECT_EQ(AcceleratorConfigResult::kSuccess, result);
const base::Value::Dict& updated_overrides = GetOverridePref();
const base::Value::List* last_used_ime_overrides = updated_overrides.FindList(
base::NumberToString(AcceleratorAction::kSwitchToLastUsedIme));
AcceleratorModificationData remove_override_data =
ValueToAcceleratorModificationData(
last_used_ime_overrides->front().GetDict());
EXPECT_TRUE(CompareAccelerators(
{true, ui::VKEY_SPACE, ui::EF_CONTROL_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
remove_override_data.accelerator));
EXPECT_EQ(AcceleratorModificationAction::kRemove,
remove_override_data.action);
AcceleratorModificationData add_override_data =
ValueToAcceleratorModificationData(
last_used_ime_overrides->back().GetDict());
EXPECT_TRUE(CompareAccelerators(
{true, ui::VKEY_A, ui::EF_COMMAND_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
add_override_data.accelerator));
EXPECT_EQ(AcceleratorModificationAction::kAdd, add_override_data.action);
const AcceleratorData updated_test_data[] = {
{true, ui::VKEY_A, ui::EF_COMMAND_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_SPACE,
ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_C, ui::EF_COMMAND_DOWN,
AcceleratorAction::kToggleCalendar},
};
ExpectAllAcceleratorsEqual(updated_test_data, config_->GetAllAccelerators());
ClearLogin();
SimulateNewUserFirstLogin(kFakeUserEmail2);
const base::Value::Dict& other_user_pref_overrides = GetOverridePref();
EXPECT_TRUE(other_user_pref_overrides.empty());
ClearLogin();
config_->Initialize(test_data);
SimulateUserLogin({kFakeUserEmail});
const base::Value::Dict& original_pref_overrides = GetOverridePref();
EXPECT_FALSE(original_pref_overrides.empty());
const base::Value::Dict& relogin_overrides = GetOverridePref();
EXPECT_EQ(1u, relogin_overrides.size());
ExpectAllAcceleratorsEqual(updated_test_data, config_->GetAllAccelerators());
}
TEST_F(AshAcceleratorConfigurationTest, IgnoreBadActionIdPrefs) {
SimulateNewUserFirstLogin(kFakeUserEmail);
const AcceleratorData test_data[] = {
{true, ui::VKEY_SPACE, ui::EF_CONTROL_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_SPACE,
ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
};
config_->Initialize(test_data);
const base::Value::Dict& pref_overrides = GetOverridePref();
EXPECT_TRUE(pref_overrides.empty());
const ui::Accelerator bad_accelerator(ui::VKEY_B, ui::EF_ALT_DOWN);
SetOverridePref(bad_accelerator, AcceleratorModificationAction::kAdd,
7777777);
ClearLogin();
SimulateNewUserFirstLogin(kFakeUserEmail2);
const base::Value::Dict& other_user_pref_overrides = GetOverridePref();
EXPECT_TRUE(other_user_pref_overrides.empty());
ClearLogin();
config_->Initialize(test_data);
SimulateUserLogin({kFakeUserEmail});
const base::Value::Dict& original_pref_overrides = GetOverridePref();
EXPECT_TRUE(original_pref_overrides.empty());
const base::Value::Dict& relogin_overrides = GetOverridePref();
EXPECT_TRUE(relogin_overrides.empty());
ExpectAllAcceleratorsEqual(test_data, config_->GetAllAccelerators());
}
TEST_F(AshAcceleratorConfigurationTest, IgnoreBadAcceleratorPrefs) {
SimulateNewUserFirstLogin(kFakeUserEmail);
const AcceleratorData test_data[] = {
{true, ui::VKEY_SPACE, ui::EF_CONTROL_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_SPACE,
ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
};
config_->Initialize(test_data);
const base::Value::Dict& pref_overrides = GetOverridePref();
EXPECT_TRUE(pref_overrides.empty());
const ui::Accelerator bad_accelerator(ui::VKEY_B, ui::EF_ALT_DOWN);
SetOverridePref(bad_accelerator, AcceleratorModificationAction::kRemove,
kSwitchToLastUsedIme);
ClearLogin();
SimulateNewUserFirstLogin(kFakeUserEmail2);
const base::Value::Dict& other_user_pref_overrides = GetOverridePref();
EXPECT_TRUE(other_user_pref_overrides.empty());
ClearLogin();
config_->Initialize(test_data);
SimulateUserLogin({kFakeUserEmail});
const base::Value::Dict& original_pref_overrides = GetOverridePref();
EXPECT_TRUE(original_pref_overrides.empty());
const base::Value::Dict& relogin_overrides = GetOverridePref();
EXPECT_TRUE(relogin_overrides.empty());
ExpectAllAcceleratorsEqual(test_data, config_->GetAllAccelerators());
}
TEST_F(AshAcceleratorConfigurationTest, AddAcceleratorWithPrefReleasedState) {
SimulateNewUserFirstLogin(kFakeUserEmail);
const AcceleratorData test_data[] = {
{true, ui::VKEY_SPACE, ui::EF_CONTROL_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_SPACE,
ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
};
config_->Initialize(test_data);
const base::Value::Dict& pref_overrides = GetOverridePref();
EXPECT_TRUE(pref_overrides.empty());
const ui::Accelerator released_accelerator(
ui::VKEY_A, ui::EF_COMMAND_DOWN, ui::Accelerator::KeyState::RELEASED);
AcceleratorConfigResult result = config_->AddUserAccelerator(
AcceleratorAction::kSwitchToLastUsedIme, released_accelerator);
EXPECT_EQ(AcceleratorConfigResult::kSuccess, result);
const ui::Accelerator pressed_accelerator(ui::VKEY_A, ui::EF_COMMAND_DOWN,
ui::Accelerator::KeyState::PRESSED);
result = config_->AddUserAccelerator(AcceleratorAction::kSwitchToLastUsedIme,
pressed_accelerator);
EXPECT_EQ(AcceleratorConfigResult::kSuccess, result);
const base::Value::Dict& updated_overrides = GetOverridePref();
EXPECT_EQ(1u, updated_overrides.size());
const base::Value::List* accelerator_overrides = updated_overrides.FindList(
base::NumberToString(AcceleratorAction::kSwitchToLastUsedIme));
EXPECT_EQ(2u, accelerator_overrides->size());
const AcceleratorData updated_test_data[] = {
{true, ui::VKEY_SPACE, ui::EF_CONTROL_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_SPACE,
ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{false, ui::VKEY_A, ui::EF_COMMAND_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_A, ui::EF_COMMAND_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
};
AcceleratorModificationData override_data =
ValueToAcceleratorModificationData(
accelerator_overrides->front().GetDict());
EXPECT_TRUE(CompareAccelerators(
{false, ui::VKEY_A, ui::EF_COMMAND_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
override_data.accelerator));
EXPECT_EQ(AcceleratorModificationAction::kAdd, override_data.action);
override_data = ValueToAcceleratorModificationData(
accelerator_overrides->back().GetDict());
EXPECT_TRUE(CompareAccelerators(
{true, ui::VKEY_A, ui::EF_COMMAND_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
override_data.accelerator));
EXPECT_EQ(AcceleratorModificationAction::kAdd, override_data.action);
ExpectAllAcceleratorsEqual(updated_test_data, config_->GetAllAccelerators());
ClearLogin();
SimulateNewUserFirstLogin(kFakeUserEmail2);
const base::Value::Dict& other_user_pref_overrides = GetOverridePref();
EXPECT_TRUE(other_user_pref_overrides.empty());
ClearLogin();
config_->Initialize(test_data);
SimulateUserLogin({kFakeUserEmail});
const base::Value::Dict& original_pref_overrides = GetOverridePref();
EXPECT_FALSE(original_pref_overrides.empty());
const base::Value::Dict& relogin_overrides = GetOverridePref();
EXPECT_EQ(1u, relogin_overrides.size());
ExpectAllAcceleratorsEqual(updated_test_data, config_->GetAllAccelerators());
}
TEST_F(AshAcceleratorConfigurationTest, SwitchUserPrefsAreSeparate) {
SimulateNewUserFirstLogin(kFakeUserEmail);
const AcceleratorData test_data[] = {
{true, ui::VKEY_D,
ui::EF_COMMAND_DOWN | ui::EF_CONTROL_DOWN,
AcceleratorAction::kMagnifierZoomIn},
};
config_->Initialize(test_data);
const base::Value::Dict& pref_overrides = GetOverridePref();
EXPECT_TRUE(pref_overrides.empty());
const ui::Accelerator new_accelerator(ui::VKEY_A, ui::EF_COMMAND_DOWN);
AcceleratorConfigResult result = config_->AddUserAccelerator(
AcceleratorAction::kMagnifierZoomIn, new_accelerator);
EXPECT_EQ(AcceleratorConfigResult::kSuccess, result);
const base::Value::Dict& updated_overrides = GetOverridePref();
EXPECT_EQ(1u, updated_overrides.size());
const base::Value::List* accelerator_overrides = updated_overrides.FindList(
base::NumberToString(AcceleratorAction::kMagnifierZoomIn));
EXPECT_EQ(1u, accelerator_overrides->size());
const AcceleratorData updated_test_data[] = {
{true, ui::VKEY_D,
ui::EF_COMMAND_DOWN | ui::EF_CONTROL_DOWN,
AcceleratorAction::kMagnifierZoomIn},
{true, ui::VKEY_A, ui::EF_COMMAND_DOWN,
AcceleratorAction::kMagnifierZoomIn},
};
AcceleratorModificationData override_data =
ValueToAcceleratorModificationData(
accelerator_overrides->front().GetDict());
EXPECT_TRUE(CompareAccelerators(
{true, ui::VKEY_A, ui::EF_COMMAND_DOWN,
AcceleratorAction::kMagnifierZoomIn},
override_data.accelerator));
EXPECT_EQ(AcceleratorModificationAction::kAdd, override_data.action);
ExpectAllAcceleratorsEqual(updated_test_data, config_->GetAllAccelerators());
ClearLogin();
SimulateNewUserFirstLogin(kFakeUserEmail2);
const base::Value::Dict& other_user_pref_overrides = GetOverridePref();
EXPECT_TRUE(other_user_pref_overrides.empty());
ExpectAllAcceleratorsEqual(test_data, config_->GetAllAccelerators());
ClearLogin();
config_->Initialize(test_data);
SimulateUserLogin({kFakeUserEmail});
const base::Value::Dict& original_pref_overrides = GetOverridePref();
EXPECT_FALSE(original_pref_overrides.empty());
const base::Value::Dict& relogin_overrides = GetOverridePref();
EXPECT_EQ(1u, relogin_overrides.size());
ExpectAllAcceleratorsEqual(updated_test_data, config_->GetAllAccelerators());
}
TEST_F(AshAcceleratorConfigurationTest, PrefsResetWithFlag) {
scoped_feature_list_.Reset();
scoped_feature_list_.InitWithFeatures(
{features::kResetShortcutCustomizations},
{});
SimulateNewUserFirstLogin(kFakeUserEmail);
const AcceleratorData test_data[] = {
{true, ui::VKEY_SPACE, ui::EF_CONTROL_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_SPACE,
ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
};
config_->Initialize(test_data);
const base::Value::Dict& pref_overrides = GetOverridePref();
EXPECT_TRUE(pref_overrides.empty());
const ui::Accelerator new_accelerator(ui::VKEY_A, ui::EF_COMMAND_DOWN);
AcceleratorConfigResult result = config_->AddUserAccelerator(
AcceleratorAction::kSwitchToLastUsedIme, new_accelerator);
EXPECT_EQ(AcceleratorConfigResult::kSuccess, result);
const base::Value::Dict& updated_overrides = GetOverridePref();
EXPECT_EQ(1u, updated_overrides.size());
const base::Value::List* accelerator_overrides = updated_overrides.FindList(
base::NumberToString(AcceleratorAction::kSwitchToLastUsedIme));
EXPECT_EQ(1u, accelerator_overrides->size());
const AcceleratorData updated_test_data[] = {
{true, ui::VKEY_SPACE, ui::EF_CONTROL_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_SPACE,
ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
{true, ui::VKEY_A, ui::EF_COMMAND_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
};
AcceleratorModificationData override_data =
ValueToAcceleratorModificationData(
accelerator_overrides->front().GetDict());
EXPECT_TRUE(CompareAccelerators(
{true, ui::VKEY_A, ui::EF_COMMAND_DOWN,
AcceleratorAction::kSwitchToLastUsedIme},
override_data.accelerator));
EXPECT_EQ(AcceleratorModificationAction::kAdd, override_data.action);
ExpectAllAcceleratorsEqual(updated_test_data, config_->GetAllAccelerators());
ClearLogin();
SimulateNewUserFirstLogin(kFakeUserEmail2);
const base::Value::Dict& other_user_pref_overrides = GetOverridePref();
EXPECT_TRUE(other_user_pref_overrides.empty());
ClearLogin();
config_->Initialize(test_data);
SimulateUserLogin({kFakeUserEmail});
const base::Value::Dict& original_pref_overrides = GetOverridePref();
EXPECT_TRUE(original_pref_overrides.empty());
}
TEST_F(AshAcceleratorConfigurationTest, FindAcceleratorActionPositionalKeys) {
const AcceleratorData test_data[] = {
{true, ui::VKEY_OEM_4, ui::EF_ALT_DOWN,
AcceleratorAction::kWindowCycleSnapLeft},
};
config_->Initialize(test_data);
config_->SetUsePositionalLookup(true);
const ui::Accelerator de_alt_left_bracket(
ui::VKEY_OEM_1, ui::DomCode::BRACKET_LEFT, ui::EF_ALT_DOWN);
const AcceleratorAction* found_action =
config_->FindAcceleratorAction(de_alt_left_bracket);
EXPECT_TRUE(found_action);
EXPECT_EQ(AcceleratorAction::kWindowCycleSnapLeft, *found_action);
config_->RestoreAllDefaults();
const AcceleratorAction* found_action2 =
config_->FindAcceleratorAction(de_alt_left_bracket);
EXPECT_TRUE(found_action2);
EXPECT_EQ(AcceleratorAction::kWindowCycleSnapLeft, *found_action2);
}
TEST_F(AshAcceleratorConfigurationTest,
FindAcceleratorActionPositionalDisabledKeys) {
const AcceleratorData test_data[] = {
{true, ui::VKEY_OEM_4, ui::EF_ALT_DOWN,
AcceleratorAction::kWindowCycleSnapLeft},
};
config_->Initialize(test_data);
config_->SetUsePositionalLookup(false);
const ui::Accelerator de_alt_left_bracket(
ui::VKEY_OEM_1, ui::DomCode::BRACKET_LEFT, ui::EF_ALT_DOWN);
const AcceleratorAction* found_action =
config_->FindAcceleratorAction(de_alt_left_bracket);
EXPECT_FALSE(found_action);
}
}