| // Copyright 2022 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "ash/accelerators/ash_accelerator_configuration.h" |
| |
| #include <memory> |
| #include <string> |
| |
| #include "ash/accelerators/ash_accelerator_configuration.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 "base/containers/contains.h" |
| #include "base/ranges/algorithm.h" |
| #include "base/test/scoped_feature_list.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_codes_array.h" |
| #include "ui/events/keycodes/dom/dom_key.h" |
| #include "ui/events/keycodes/keyboard_codes_posix.h" |
| |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| namespace { |
| |
| using ::ash::mojom::AcceleratorConfigResult; |
| |
| class UpdatedAcceleratorsObserver |
| : public ash::AshAcceleratorConfiguration::Observer { |
| public: |
| UpdatedAcceleratorsObserver() = default; |
| UpdatedAcceleratorsObserver(const UpdatedAcceleratorsObserver&) = delete; |
| UpdatedAcceleratorsObserver& operator=(const UpdatedAcceleratorsObserver&) = |
| delete; |
| ~UpdatedAcceleratorsObserver() override = default; |
| |
| // ash::AshAcceleratorConfiguration::Observer: |
| 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; |
| }; |
| |
| bool CompareAccelerators(const ash::AcceleratorData& expected_data, |
| const ui::Accelerator& actual_accelerator) { |
| ui::Accelerator expected_accel(expected_data.keycode, |
| expected_data.modifiers); |
| return expected_accel.key_code() == actual_accelerator.key_code() && |
| expected_accel.modifiers() == actual_accelerator.modifiers(); |
| } |
| |
| 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 |
| |
| namespace ash { |
| |
| class AshAcceleratorConfigurationTest : public testing::Test { |
| public: |
| AshAcceleratorConfigurationTest() { |
| scoped_feature_list_.InitAndEnableFeature( |
| ::features::kShortcutCustomization); |
| config_ = std::make_unique<AshAcceleratorConfiguration>(); |
| config_->AddObserver(&observer_); |
| } |
| |
| ~AshAcceleratorConfigurationTest() override { |
| config_->RemoveObserver(&observer_); |
| } |
| |
| protected: |
| base::test::ScopedFeatureList scoped_feature_list_; |
| UpdatedAcceleratorsObserver observer_; |
| std::unique_ptr<AshAcceleratorConfiguration> config_; |
| }; |
| |
| TEST_F(AshAcceleratorConfigurationTest, VerifyAcceleratorMappingPopulated) { |
| const AcceleratorData test_data[] = { |
| {/*trigger_on_press=*/true, ui::VKEY_SPACE, ui::EF_CONTROL_DOWN, |
| SWITCH_TO_LAST_USED_IME}, |
| {/*trigger_on_press=*/true, ui::VKEY_SPACE, |
| ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN, SWITCH_TO_LAST_USED_IME}, |
| {/*trigger_on_press=*/true, ui::VKEY_TAB, ui::EF_ALT_DOWN, |
| CYCLE_FORWARD_MRU}, |
| {/*trigger_on_press=*/true, ui::VKEY_TAB, |
| ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN, CYCLE_BACKWARD_MRU}, |
| }; |
| |
| config_->Initialize(test_data); |
| const std::vector<ui::Accelerator>& accelerators = |
| config_->GetAllAccelerators(); |
| |
| ExpectAllAcceleratorsEqual(test_data, accelerators); |
| } |
| |
| TEST_F(AshAcceleratorConfigurationTest, DeprecatedAccelerators) { |
| // Test deprecated accelerators, in this case `SHOW_TASK_MANAGER` has two |
| // associated accelerators: (deprecated) ESCAPE + SHIFT and |
| // (active) ESCAPE + COMMAND. |
| const AcceleratorData initial_test_data[] = { |
| {/*trigger_on_press=*/true, ui::VKEY_TAB, ui::EF_ALT_DOWN, |
| CYCLE_FORWARD_MRU}, |
| {/*trigger_on_press=*/true, ui::VKEY_TAB, |
| ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN, CYCLE_BACKWARD_MRU}, |
| {/*trigger_on_press=*/true, ui::VKEY_ESCAPE, ui::EF_COMMAND_DOWN, |
| SHOW_TASK_MANAGER}, |
| }; |
| |
| const AcceleratorData expected_test_data[] = { |
| {/*trigger_on_press=*/true, ui::VKEY_TAB, ui::EF_ALT_DOWN, |
| CYCLE_FORWARD_MRU}, |
| {/*trigger_on_press=*/true, ui::VKEY_TAB, |
| ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN, CYCLE_BACKWARD_MRU}, |
| {/*trigger_on_press=*/true, ui::VKEY_ESCAPE, ui::EF_COMMAND_DOWN, |
| SHOW_TASK_MANAGER}, |
| {/*trigger_on_press=*/true, ui::VKEY_ESCAPE, ui::EF_SHIFT_DOWN, |
| SHOW_TASK_MANAGER}, |
| }; |
| |
| const DeprecatedAcceleratorData deprecated_data[] = { |
| {SHOW_TASK_MANAGER, /*uma_histogram_name=*/"deprecated.showTaskManager", |
| /*notification_message_id=*/1, /*old_shortcut_id=*/1, |
| /*new_shortcut_id=*/2, /*deprecated_enabled=*/true}, |
| }; |
| |
| const AcceleratorData test_deprecated_accelerators[] = { |
| {/*trigger_on_press=*/true, ui::VKEY_ESCAPE, ui::EF_SHIFT_DOWN, |
| SHOW_TASK_MANAGER}, |
| }; |
| |
| config_->Initialize(initial_test_data); |
| config_->InitializeDeprecatedAccelerators(deprecated_data, |
| test_deprecated_accelerators); |
| |
| const std::vector<ui::Accelerator>& accelerators = |
| config_->GetAllAccelerators(); |
| |
| // When initializing deprecated accelerators, expect them to be added to the |
| // overall accelerators list too. |
| ExpectAllAcceleratorsEqual(expected_test_data, accelerators); |
| |
| // Verify that the fetched deprecated accelerators are correct. |
| 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); |
| |
| // Verify ESCAPE + SHIFT is deprecated. |
| const ui::Accelerator deprecated_accelerator(ui::VKEY_ESCAPE, |
| ui::EF_SHIFT_DOWN); |
| EXPECT_TRUE(config_->IsDeprecated(deprecated_accelerator)); |
| // Verify fetching a deprecated accelerator works. |
| EXPECT_EQ(deprecated_data, |
| config_->GetDeprecatedAcceleratorData(SHOW_TASK_MANAGER)); |
| // CYCLE_BACKWARD_MRU is not a deprecated action, expect nullptr. |
| EXPECT_EQ(nullptr, config_->GetDeprecatedAcceleratorData(CYCLE_BACKWARD_MRU)); |
| |
| // Verify that ESCAPE + COMMAND is not deprecated. |
| const ui::Accelerator active_accelerator(ui::VKEY_ESCAPE, |
| ui::EF_COMMAND_DOWN); |
| EXPECT_FALSE(config_->IsDeprecated(active_accelerator)); |
| } |
| |
| TEST_F(AshAcceleratorConfigurationTest, |
| RemoveAndRestoreDeprecatedAccelerators) { |
| // Test deprecated accelerators, in this case `SHOW_TASK_MANAGER` has two |
| // associated accelerators: (deprecated) ESCAPE + SHIFT and |
| // (active) ESCAPE + COMMAND. |
| const AcceleratorData initial_test_data[] = { |
| {/*trigger_on_press=*/true, ui::VKEY_TAB, ui::EF_ALT_DOWN, |
| CYCLE_FORWARD_MRU}, |
| {/*trigger_on_press=*/true, ui::VKEY_TAB, |
| ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN, CYCLE_BACKWARD_MRU}, |
| {/*trigger_on_press=*/true, ui::VKEY_ESCAPE, ui::EF_COMMAND_DOWN, |
| SHOW_TASK_MANAGER}, |
| }; |
| |
| const AcceleratorData expected_test_data[] = { |
| {/*trigger_on_press=*/true, ui::VKEY_TAB, ui::EF_ALT_DOWN, |
| CYCLE_FORWARD_MRU}, |
| {/*trigger_on_press=*/true, ui::VKEY_TAB, |
| ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN, CYCLE_BACKWARD_MRU}, |
| {/*trigger_on_press=*/true, ui::VKEY_ESCAPE, ui::EF_COMMAND_DOWN, |
| SHOW_TASK_MANAGER}, |
| {/*trigger_on_press=*/true, ui::VKEY_ESCAPE, ui::EF_SHIFT_DOWN, |
| SHOW_TASK_MANAGER}, |
| }; |
| |
| const DeprecatedAcceleratorData deprecated_data[] = { |
| {SHOW_TASK_MANAGER, /*uma_histogram_name=*/"deprecated.showTaskManager", |
| /*notification_message_id=*/1, /*old_shortcut_id=*/1, |
| /*new_shortcut_id=*/2, /*deprecated_enabled=*/true}, |
| }; |
| |
| const AcceleratorData test_deprecated_accelerators[] = { |
| {/*trigger_on_press=*/true, ui::VKEY_ESCAPE, ui::EF_SHIFT_DOWN, |
| SHOW_TASK_MANAGER}, |
| }; |
| |
| config_->Initialize(initial_test_data); |
| config_->InitializeDeprecatedAccelerators(deprecated_data, |
| test_deprecated_accelerators); |
| |
| const ui::Accelerator deprecated_accelerator(ui::VKEY_ESCAPE, |
| ui::EF_SHIFT_DOWN); |
| |
| // Remove the deprecated accelerator ESCAPE + SHIFT. |
| const AcceleratorData updated_expected_test_data[] = { |
| {/*trigger_on_press=*/true, ui::VKEY_TAB, ui::EF_ALT_DOWN, |
| CYCLE_FORWARD_MRU}, |
| {/*trigger_on_press=*/true, ui::VKEY_TAB, |
| ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN, CYCLE_BACKWARD_MRU}, |
| {/*trigger_on_press=*/true, ui::VKEY_ESCAPE, ui::EF_COMMAND_DOWN, |
| SHOW_TASK_MANAGER}, |
| }; |
| AcceleratorConfigResult result = |
| config_->RemoveAccelerator(SHOW_TASK_MANAGER, deprecated_accelerator); |
| EXPECT_EQ(AcceleratorConfigResult::kSuccess, result); |
| // Verify that the accelerator is no longer deprecated. |
| EXPECT_FALSE(config_->IsDeprecated(deprecated_accelerator)); |
| EXPECT_FALSE(config_->GetDeprecatedAcceleratorData(SHOW_TASK_MANAGER)); |
| ExpectAllAcceleratorsEqual(updated_expected_test_data, |
| config_->GetAllAccelerators()); |
| |
| // Attempt to restore SHOW_TASK_MANAGER, expect deprecated accelerator to NOT |
| // be re-added. |
| result = config_->RestoreDefault(SHOW_TASK_MANAGER); |
| EXPECT_EQ(AcceleratorConfigResult::kSuccess, result); |
| EXPECT_FALSE(config_->IsDeprecated(deprecated_accelerator)); |
| EXPECT_FALSE(config_->GetDeprecatedAcceleratorData(SHOW_TASK_MANAGER)); |
| ExpectAllAcceleratorsEqual(updated_expected_test_data, |
| config_->GetAllAccelerators()); |
| |
| // Now restore all accelerators, this time deprecated accelerators should be |
| // restored. |
| result = config_->RestoreAllDefaults(); |
| EXPECT_EQ(AcceleratorConfigResult::kSuccess, result); |
| EXPECT_TRUE(config_->IsDeprecated(deprecated_accelerator)); |
| EXPECT_EQ(deprecated_data, |
| config_->GetDeprecatedAcceleratorData(SHOW_TASK_MANAGER)); |
| ExpectAllAcceleratorsEqual(expected_test_data, config_->GetAllAccelerators()); |
| } |
| |
| TEST_F(AshAcceleratorConfigurationTest, IsDefaultAccelerator) { |
| const AcceleratorData test_data[] = { |
| {/*trigger_on_press=*/true, ui::VKEY_ZOOM, ui::EF_CONTROL_DOWN, |
| TOGGLE_MIRROR_MODE}, |
| {/*trigger_on_press=*/true, ui::VKEY_ZOOM, ui::EF_ALT_DOWN, |
| SWAP_PRIMARY_DISPLAY}, |
| {/*trigger_on_press=*/true, ui::VKEY_MEDIA_LAUNCH_APP1, |
| ui::EF_CONTROL_DOWN, TAKE_SCREENSHOT}, |
| {/*trigger_on_press=*/true, ui::VKEY_KBD_BRIGHTNESS_UP, ui::EF_NONE, |
| KEYBOARD_BRIGHTNESS_UP}, |
| {/*trigger_on_press=*/true, ui::VKEY_BRIGHTNESS_UP, ui::EF_ALT_DOWN, |
| KEYBOARD_BRIGHTNESS_UP}, |
| }; |
| |
| // `Initialize()` sets up the default accelerators. |
| config_->Initialize(test_data); |
| ExpectAllAcceleratorsEqual(test_data, config_->GetAllAccelerators()); |
| |
| // Verify that Control + Zoom is the default for TOGGLE_MIRROR_MODE. |
| ui::Accelerator expected_default = |
| ui::Accelerator(ui::VKEY_ZOOM, ui::EF_CONTROL_DOWN); |
| absl::optional<AcceleratorAction> accelerator_id = |
| config_->GetIdForDefaultAccelerator(expected_default); |
| EXPECT_TRUE(accelerator_id.has_value()); |
| EXPECT_EQ(TOGGLE_MIRROR_MODE, accelerator_id.value()); |
| std::vector<ui::Accelerator> default_accelerators = |
| config_->GetDefaultAcceleratorsForId(TOGGLE_MIRROR_MODE); |
| EXPECT_EQ(1u, default_accelerators.size()); |
| EXPECT_EQ(expected_default, default_accelerators[0]); |
| } |
| |
| TEST_F(AshAcceleratorConfigurationTest, MultipleDefaultAccelerators) { |
| const AcceleratorData test_data[] = { |
| {/*trigger_on_press=*/true, ui::VKEY_ZOOM, ui::EF_CONTROL_DOWN, |
| TOGGLE_MIRROR_MODE}, |
| {/*trigger_on_press=*/true, ui::VKEY_ZOOM, ui::EF_ALT_DOWN, |
| TOGGLE_MIRROR_MODE}, |
| {/*trigger_on_press=*/true, ui::VKEY_MEDIA_LAUNCH_APP1, |
| ui::EF_CONTROL_DOWN, TAKE_SCREENSHOT}, |
| {/*trigger_on_press=*/true, ui::VKEY_KBD_BRIGHTNESS_UP, ui::EF_NONE, |
| KEYBOARD_BRIGHTNESS_UP}, |
| {/*trigger_on_press=*/true, ui::VKEY_BRIGHTNESS_UP, ui::EF_ALT_DOWN, |
| KEYBOARD_BRIGHTNESS_UP}, |
| }; |
| |
| // `Initialize()` sets up the default accelerators. |
| config_->Initialize(test_data); |
| ExpectAllAcceleratorsEqual(test_data, config_->GetAllAccelerators()); |
| |
| // Verify that Control + Zoom and Alt + Zoom are defaults for |
| // TOGGLE_MIRROR_MODE. |
| 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); |
| |
| absl::optional<AcceleratorAction> accelerator_id = |
| config_->GetIdForDefaultAccelerator(expected_default); |
| EXPECT_TRUE(accelerator_id.has_value()); |
| EXPECT_EQ(TOGGLE_MIRROR_MODE, accelerator_id.value()); |
| |
| accelerator_id = config_->GetIdForDefaultAccelerator(expected_default_2); |
| EXPECT_TRUE(accelerator_id.has_value()); |
| EXPECT_EQ(TOGGLE_MIRROR_MODE, accelerator_id.value()); |
| |
| std::vector<ui::Accelerator> default_accelerators = |
| config_->GetDefaultAcceleratorsForId(TOGGLE_MIRROR_MODE); |
| |
| 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[] = { |
| {/*trigger_on_press=*/true, ui::VKEY_ZOOM, ui::EF_CONTROL_DOWN, |
| TOGGLE_MIRROR_MODE}, |
| {/*trigger_on_press=*/true, ui::VKEY_ZOOM, ui::EF_ALT_DOWN, |
| SWAP_PRIMARY_DISPLAY}, |
| {/*trigger_on_press=*/true, ui::VKEY_MEDIA_LAUNCH_APP1, |
| ui::EF_CONTROL_DOWN, TAKE_SCREENSHOT}, |
| {/*trigger_on_press=*/true, ui::VKEY_KBD_BRIGHTNESS_UP, ui::EF_NONE, |
| KEYBOARD_BRIGHTNESS_UP}, |
| {/*trigger_on_press=*/true, ui::VKEY_BRIGHTNESS_UP, ui::EF_ALT_DOWN, |
| KEYBOARD_BRIGHTNESS_UP}, |
| }; |
| |
| // `Initialize()` sets up the default accelerators. |
| config_->Initialize(test_data); |
| ExpectAllAcceleratorsEqual(test_data, config_->GetAllAccelerators()); |
| |
| // Verify that Ctrl + U is not a default accelerator in this test set. |
| ui::Accelerator fake_default = |
| ui::Accelerator(ui::VKEY_U, ui::EF_CONTROL_DOWN); |
| absl::optional<AcceleratorAction> accelerator_id = |
| config_->GetIdForDefaultAccelerator(fake_default); |
| EXPECT_FALSE(accelerator_id.has_value()); |
| } |
| |
| TEST_F(AshAcceleratorConfigurationTest, GetAcceleratorsFromActionId) { |
| const AcceleratorData test_data[] = { |
| {/*trigger_on_press=*/true, ui::VKEY_ZOOM, ui::EF_CONTROL_DOWN, |
| TOGGLE_MIRROR_MODE}, |
| {/*trigger_on_press=*/true, ui::VKEY_ZOOM, ui::EF_ALT_DOWN, |
| SWAP_PRIMARY_DISPLAY}, |
| {/*trigger_on_press=*/true, ui::VKEY_MEDIA_LAUNCH_APP1, |
| ui::EF_CONTROL_DOWN, TAKE_SCREENSHOT}, |
| {/*trigger_on_press=*/true, ui::VKEY_KBD_BRIGHTNESS_UP, ui::EF_NONE, |
| KEYBOARD_BRIGHTNESS_UP}, |
| {/*trigger_on_press=*/true, ui::VKEY_BRIGHTNESS_UP, ui::EF_ALT_DOWN, |
| KEYBOARD_BRIGHTNESS_UP}, |
| }; |
| config_->Initialize(test_data); |
| |
| // Create expected id_to_accelerator_data map. |
| 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); |
| } |
| |
| // Verify that expected and actual are equal. |
| for (const auto& data : test_data) { |
| std::vector<AcceleratorData> expected = |
| id_to_accelerator_data.at(data.action); |
| std::vector<ui::Accelerator> actual = |
| config_->GetAcceleratorsForAction(data.action); |
| ExpectAllAcceleratorsEqual(expected, actual); |
| } |
| } |
| |
| TEST_F(AshAcceleratorConfigurationTest, VerifyObserversAreNotified) { |
| EXPECT_EQ(0, observer_.num_times_accelerator_updated_called()); |
| |
| const AcceleratorData test_data[] = { |
| {/*trigger_on_press=*/true, ui::VKEY_SPACE, ui::EF_CONTROL_DOWN, |
| SWITCH_TO_LAST_USED_IME}, |
| {/*trigger_on_press=*/true, ui::VKEY_SPACE, |
| ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN, SWITCH_TO_LAST_USED_IME}, |
| {/*trigger_on_press=*/true, ui::VKEY_TAB, ui::EF_ALT_DOWN, |
| CYCLE_FORWARD_MRU}, |
| {/*trigger_on_press=*/true, ui::VKEY_TAB, |
| ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN, CYCLE_BACKWARD_MRU}, |
| }; |
| |
| 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()); |
| |
| // Now update accelerators with a different set of accelerators. |
| const AcceleratorData test_data_updated[] = { |
| {/*trigger_on_press=*/true, ui::VKEY_J, ui::EF_CONTROL_DOWN, |
| TOGGLE_FULLSCREEN}, |
| }; |
| |
| 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[] = { |
| {/*trigger_on_press=*/true, ui::VKEY_SPACE, ui::EF_CONTROL_DOWN, |
| SWITCH_TO_LAST_USED_IME}, |
| {/*trigger_on_press=*/true, ui::VKEY_SPACE, |
| ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN, SWITCH_TO_LAST_USED_IME}, |
| {/*trigger_on_press=*/true, ui::VKEY_TAB, ui::EF_ALT_DOWN, |
| CYCLE_FORWARD_MRU}, |
| {/*trigger_on_press=*/true, ui::VKEY_TAB, |
| ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN, CYCLE_BACKWARD_MRU}, |
| }; |
| |
| config_->Initialize(test_data); |
| |
| ExpectAllAcceleratorsEqual(test_data, config_->GetAllAccelerators()); |
| EXPECT_EQ(1, observer_.num_times_accelerator_updated_called()); |
| |
| // Remove `SWITCH_TO_LAST_USE_IME`. |
| const AcceleratorData updated_test_data[] = { |
| {/*trigger_on_press=*/true, ui::VKEY_SPACE, |
| ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN, SWITCH_TO_LAST_USED_IME}, |
| {/*trigger_on_press=*/true, ui::VKEY_TAB, ui::EF_ALT_DOWN, |
| CYCLE_FORWARD_MRU}, |
| {/*trigger_on_press=*/true, ui::VKEY_TAB, |
| ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN, CYCLE_BACKWARD_MRU}, |
| }; |
| AcceleratorConfigResult result = config_->RemoveAccelerator( |
| SWITCH_TO_LAST_USED_IME, |
| ui::Accelerator(ui::VKEY_SPACE, ui::EF_CONTROL_DOWN)); |
| EXPECT_EQ(AcceleratorConfigResult::kSuccess, result); |
| |
| // Compare expected accelerators and that the observer was fired after |
| // removing an accelerator. |
| ExpectAllAcceleratorsEqual(updated_test_data, config_->GetAllAccelerators()); |
| EXPECT_EQ(2, observer_.num_times_accelerator_updated_called()); |
| |
| // Attempt to remove the accelerator again, expect to return error. |
| AcceleratorConfigResult re_remove_result = config_->RemoveAccelerator( |
| SWITCH_TO_LAST_USED_IME, |
| ui::Accelerator(ui::VKEY_SPACE, ui::EF_CONTROL_DOWN)); |
| EXPECT_EQ(AcceleratorConfigResult::kNotFound, re_remove_result); |
| |
| // Expect no changes to be made. |
| 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[] = { |
| {/*trigger_on_press=*/true, ui::VKEY_SPACE, ui::EF_CONTROL_DOWN, |
| SWITCH_TO_LAST_USED_IME}, |
| }; |
| |
| config_->Initialize(test_data); |
| |
| ExpectAllAcceleratorsEqual(test_data, config_->GetAllAccelerators()); |
| EXPECT_EQ(1, observer_.num_times_accelerator_updated_called()); |
| |
| // Attempt to remove an accelerator with an action ID that doesn't exist. |
| AcceleratorConfigResult result = config_->RemoveAccelerator( |
| CYCLE_BACKWARD_MRU, ui::Accelerator(ui::VKEY_SPACE, ui::EF_CONTROL_DOWN)); |
| EXPECT_EQ(AcceleratorConfigResult::kNotFound, result); |
| |
| // Nothing should change. |
| 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[] = { |
| {/*trigger_on_press=*/true, ui::VKEY_SPACE, ui::EF_CONTROL_DOWN, |
| SWITCH_TO_LAST_USED_IME}, |
| }; |
| |
| config_->Initialize(test_data); |
| |
| ExpectAllAcceleratorsEqual(test_data, config_->GetAllAccelerators()); |
| EXPECT_EQ(1, observer_.num_times_accelerator_updated_called()); |
| |
| // Remove an accelerator that doesn't exist, but with an |
| // existing action ID. Expect no change. |
| AcceleratorConfigResult updated_result = config_->RemoveAccelerator( |
| SWITCH_TO_LAST_USED_IME, |
| ui::Accelerator(ui::VKEY_M, ui::EF_CONTROL_DOWN)); |
| EXPECT_EQ(AcceleratorConfigResult::kNotFound, updated_result); |
| |
| // Nothing should change. |
| 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[] = { |
| {/*trigger_on_press=*/true, ui::VKEY_SPACE, ui::EF_CONTROL_DOWN, |
| SWITCH_TO_LAST_USED_IME}, |
| {/*trigger_on_press=*/true, ui::VKEY_SPACE, |
| ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN, BRIGHTNESS_DOWN}, |
| {/*trigger_on_press=*/true, ui::VKEY_TAB, ui::EF_ALT_DOWN, |
| CYCLE_FORWARD_MRU}, |
| {/*trigger_on_press=*/true, ui::VKEY_TAB, |
| ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN, CYCLE_BACKWARD_MRU}, |
| }; |
| |
| config_->Initialize(test_data); |
| |
| ExpectAllAcceleratorsEqual(test_data, config_->GetAllAccelerators()); |
| EXPECT_EQ(1, observer_.num_times_accelerator_updated_called()); |
| |
| // Remove `SWITCH_TO_LAST_USE_IME`. |
| const AcceleratorData updated_test_data[] = { |
| {/*trigger_on_press=*/true, ui::VKEY_SPACE, |
| ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN, SWITCH_TO_LAST_USED_IME}, |
| {/*trigger_on_press=*/true, ui::VKEY_TAB, ui::EF_ALT_DOWN, |
| CYCLE_FORWARD_MRU}, |
| {/*trigger_on_press=*/true, ui::VKEY_TAB, |
| ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN, CYCLE_BACKWARD_MRU}, |
| }; |
| |
| ui::Accelerator removed_accelerator = |
| ui::Accelerator(ui::VKEY_SPACE, ui::EF_CONTROL_DOWN); |
| AcceleratorConfigResult result = |
| config_->RemoveAccelerator(SWITCH_TO_LAST_USED_IME, removed_accelerator); |
| EXPECT_EQ(AcceleratorConfigResult::kSuccess, result); |
| |
| // We removed a default accelerator, it should still be cached as a default. |
| EXPECT_EQ(SWITCH_TO_LAST_USED_IME, |
| config_->GetIdForDefaultAccelerator(removed_accelerator)); |
| std::vector<ui::Accelerator> default_accelerators = |
| config_->GetDefaultAcceleratorsForId(SWITCH_TO_LAST_USED_IME); |
| EXPECT_EQ(1u, default_accelerators.size()); |
| EXPECT_EQ(removed_accelerator, default_accelerators[0]); |
| |
| // Compare expected accelerators and that the observer was fired after |
| // removing an accelerator. |
| 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[] = { |
| {/*trigger_on_press=*/true, ui::VKEY_SPACE, ui::EF_CONTROL_DOWN, |
| SWITCH_TO_LAST_USED_IME}, |
| {/*trigger_on_press=*/true, ui::VKEY_SPACE, |
| ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN, SWITCH_TO_LAST_USED_IME}, |
| {/*trigger_on_press=*/true, ui::VKEY_TAB, ui::EF_ALT_DOWN, |
| CYCLE_FORWARD_MRU}, |
| {/*trigger_on_press=*/true, ui::VKEY_TAB, |
| ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN, CYCLE_BACKWARD_MRU}, |
| }; |
| |
| config_->Initialize(test_data); |
| |
| ExpectAllAcceleratorsEqual(test_data, config_->GetAllAccelerators()); |
| EXPECT_EQ(1, observer_.num_times_accelerator_updated_called()); |
| |
| // Remove `SWITCH_TO_LAST_USE_IME`. |
| const AcceleratorData updated_test_data[] = { |
| {/*trigger_on_press=*/true, ui::VKEY_SPACE, |
| ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN, SWITCH_TO_LAST_USED_IME}, |
| {/*trigger_on_press=*/true, ui::VKEY_TAB, ui::EF_ALT_DOWN, |
| CYCLE_FORWARD_MRU}, |
| {/*trigger_on_press=*/true, ui::VKEY_TAB, |
| ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN, CYCLE_BACKWARD_MRU}, |
| }; |
| AcceleratorConfigResult result = config_->RemoveAccelerator( |
| SWITCH_TO_LAST_USED_IME, |
| ui::Accelerator(ui::VKEY_SPACE, ui::EF_CONTROL_DOWN)); |
| EXPECT_EQ(AcceleratorConfigResult::kSuccess, result); |
| |
| // Compare expected accelerators and that the observer was fired after |
| // removing an accelerator. |
| ExpectAllAcceleratorsEqual(updated_test_data, config_->GetAllAccelerators()); |
| EXPECT_EQ(2, observer_.num_times_accelerator_updated_called()); |
| |
| // Restore all defaults. |
| result = config_->RestoreAllDefaults(); |
| EXPECT_EQ(AcceleratorConfigResult::kSuccess, result); |
| |
| // Expect accelerators to revert back to the default state and observer |
| // is called. |
| 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[] = { |
| {/*trigger_on_press=*/true, ui::VKEY_SPACE, ui::EF_CONTROL_DOWN, |
| SWITCH_TO_LAST_USED_IME}, |
| {/*trigger_on_press=*/true, ui::VKEY_SPACE, |
| ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN, SWITCH_TO_LAST_USED_IME}, |
| {/*trigger_on_press=*/true, ui::VKEY_TAB, ui::EF_ALT_DOWN, |
| CYCLE_FORWARD_MRU}, |
| {/*trigger_on_press=*/true, ui::VKEY_TAB, |
| ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN, CYCLE_BACKWARD_MRU}, |
| }; |
| |
| config_->Initialize(test_data); |
| |
| ExpectAllAcceleratorsEqual(test_data, config_->GetAllAccelerators()); |
| EXPECT_EQ(1, observer_.num_times_accelerator_updated_called()); |
| |
| // Restore all defaults, even though no change was made. |
| AcceleratorConfigResult reset_result = config_->RestoreAllDefaults(); |
| EXPECT_EQ(AcceleratorConfigResult::kSuccess, reset_result); |
| |
| // Nothing should have changed, but the observer is called. |
| ExpectAllAcceleratorsEqual(test_data, config_->GetAllAccelerators()); |
| EXPECT_EQ(2, observer_.num_times_accelerator_updated_called()); |
| |
| // Restore all defaults again, even though no change was made. |
| reset_result = config_->RestoreAllDefaults(); |
| EXPECT_EQ(AcceleratorConfigResult::kSuccess, reset_result); |
| |
| // Nothing should have changed, but the observer is called. |
| 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[] = { |
| {/*trigger_on_press=*/true, ui::VKEY_SPACE, ui::EF_CONTROL_DOWN, |
| SWITCH_TO_LAST_USED_IME}, |
| {/*trigger_on_press=*/true, ui::VKEY_SPACE, |
| ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN, SWITCH_TO_LAST_USED_IME}, |
| {/*trigger_on_press=*/true, ui::VKEY_TAB, ui::EF_ALT_DOWN, |
| CYCLE_FORWARD_MRU}, |
| {/*trigger_on_press=*/true, ui::VKEY_TAB, |
| ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN, CYCLE_BACKWARD_MRU}, |
| }; |
| |
| config_->Initialize(test_data); |
| |
| ExpectAllAcceleratorsEqual(test_data, config_->GetAllAccelerators()); |
| EXPECT_EQ(1, observer_.num_times_accelerator_updated_called()); |
| |
| // Remove `SWITCH_TO_LAST_USE_IME`. |
| const AcceleratorData updated_test_data[] = { |
| {/*trigger_on_press=*/true, ui::VKEY_SPACE, |
| ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN, SWITCH_TO_LAST_USED_IME}, |
| {/*trigger_on_press=*/true, ui::VKEY_TAB, ui::EF_ALT_DOWN, |
| CYCLE_FORWARD_MRU}, |
| {/*trigger_on_press=*/true, ui::VKEY_TAB, |
| ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN, CYCLE_BACKWARD_MRU}, |
| }; |
| AcceleratorConfigResult result = config_->RemoveAccelerator( |
| SWITCH_TO_LAST_USED_IME, |
| ui::Accelerator(ui::VKEY_SPACE, ui::EF_CONTROL_DOWN)); |
| EXPECT_EQ(AcceleratorConfigResult::kSuccess, result); |
| |
| // Compare expected accelerators and that the observer was fired after |
| // removing an accelerator. |
| ExpectAllAcceleratorsEqual(updated_test_data, config_->GetAllAccelerators()); |
| EXPECT_EQ(2, observer_.num_times_accelerator_updated_called()); |
| |
| // Reset the `SWITCH_TO_LAST_USED_IME` action.. |
| result = config_->RestoreDefault(SWITCH_TO_LAST_USED_IME); |
| EXPECT_EQ(AcceleratorConfigResult::kSuccess, result); |
| |
| // Expect accelerators to revert back to the default state and observer |
| // is called. |
| ExpectAllAcceleratorsEqual(test_data, config_->GetAllAccelerators()); |
| EXPECT_EQ(3, observer_.num_times_accelerator_updated_called()); |
| |
| // Reset one more time, no changes should be made. |
| result = config_->RestoreDefault(SWITCH_TO_LAST_USED_IME); |
| EXPECT_EQ(AcceleratorConfigResult::kSuccess, result); |
| |
| // No changes to be made, but observer should be called. |
| 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[] = { |
| {/*trigger_on_press=*/true, ui::VKEY_SPACE, ui::EF_CONTROL_DOWN, |
| SWITCH_TO_LAST_USED_IME}, |
| {/*trigger_on_press=*/true, ui::VKEY_SPACE, |
| ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN, SWITCH_TO_LAST_USED_IME}, |
| {/*trigger_on_press=*/true, ui::VKEY_TAB, ui::EF_ALT_DOWN, |
| CYCLE_FORWARD_MRU}, |
| {/*trigger_on_press=*/true, ui::VKEY_TAB, |
| ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN, CYCLE_BACKWARD_MRU}, |
| }; |
| |
| config_->Initialize(test_data); |
| |
| ExpectAllAcceleratorsEqual(test_data, config_->GetAllAccelerators()); |
| EXPECT_EQ(1, observer_.num_times_accelerator_updated_called()); |
| |
| // `BRIGHTNESS_DOWN` is not a valid accelerator, so this should return an |
| // error. |
| const AcceleratorConfigResult result = |
| config_->RestoreDefault(BRIGHTNESS_DOWN); |
| EXPECT_EQ(AcceleratorConfigResult::kNotFound, result); |
| |
| // Expect nothing to change. |
| ExpectAllAcceleratorsEqual(test_data, config_->GetAllAccelerators()); |
| EXPECT_EQ(1, observer_.num_times_accelerator_updated_called()); |
| } |
| |
| // Add accelerator with no conflict. |
| TEST_F(AshAcceleratorConfigurationTest, AddAccelerator) { |
| EXPECT_EQ(0, observer_.num_times_accelerator_updated_called()); |
| const AcceleratorData test_data[] = { |
| {/*trigger_on_press=*/true, ui::VKEY_SPACE, |
| ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN, SWITCH_TO_LAST_USED_IME}, |
| {/*trigger_on_press=*/true, ui::VKEY_TAB, ui::EF_ALT_DOWN, |
| CYCLE_FORWARD_MRU}, |
| {/*trigger_on_press=*/true, ui::VKEY_TAB, |
| ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN, CYCLE_BACKWARD_MRU}, |
| }; |
| |
| config_->Initialize(test_data); |
| |
| ExpectAllAcceleratorsEqual(test_data, config_->GetAllAccelerators()); |
| EXPECT_EQ(1, observer_.num_times_accelerator_updated_called()); |
| |
| // Add CTRL + SPACE to SWITCH_TO_LAST_USED_IME. |
| const AcceleratorData updated_test_data[] = { |
| {/*trigger_on_press=*/true, ui::VKEY_SPACE, ui::EF_CONTROL_DOWN, |
| SWITCH_TO_LAST_USED_IME}, |
| {/*trigger_on_press=*/true, ui::VKEY_SPACE, |
| ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN, SWITCH_TO_LAST_USED_IME}, |
| {/*trigger_on_press=*/true, ui::VKEY_TAB, ui::EF_ALT_DOWN, |
| CYCLE_FORWARD_MRU}, |
| {/*trigger_on_press=*/true, ui::VKEY_TAB, |
| ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN, CYCLE_BACKWARD_MRU}, |
| }; |
| |
| const ui::Accelerator new_accelerator(ui::VKEY_SPACE, ui::EF_CONTROL_DOWN); |
| AcceleratorConfigResult result = |
| config_->AddUserAccelerator(SWITCH_TO_LAST_USED_IME, new_accelerator); |
| EXPECT_EQ(AcceleratorConfigResult::kSuccess, result); |
| |
| // Compare expected accelerators and that the observer was fired after |
| // adding an accelerator. |
| 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(SWITCH_TO_LAST_USED_IME, *found_action); |
| } |
| |
| // Add accelerator that conflict with default accelerator. |
| TEST_F(AshAcceleratorConfigurationTest, AddAcceleratorDefaultConflict) { |
| EXPECT_EQ(0, observer_.num_times_accelerator_updated_called()); |
| const AcceleratorData test_data[] = { |
| {/*trigger_on_press=*/true, ui::VKEY_SPACE, |
| ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN, SWITCH_TO_LAST_USED_IME}, |
| {/*trigger_on_press=*/true, ui::VKEY_TAB, ui::EF_ALT_DOWN, |
| CYCLE_FORWARD_MRU}, |
| {/*trigger_on_press=*/true, ui::VKEY_TAB, |
| ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN, CYCLE_BACKWARD_MRU}, |
| }; |
| |
| config_->Initialize(test_data); |
| |
| ExpectAllAcceleratorsEqual(test_data, config_->GetAllAccelerators()); |
| EXPECT_EQ(1, observer_.num_times_accelerator_updated_called()); |
| |
| // Add ALT + SHIFT + TAB to SWITCH_TO_LAST_USED_IME, which conflicts with |
| // CYCLE_BACKWARD_MRU. |
| const AcceleratorData updated_test_data[] = { |
| {/*trigger_on_press=*/true, ui::VKEY_TAB, |
| ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN, SWITCH_TO_LAST_USED_IME}, |
| {/*trigger_on_press=*/true, ui::VKEY_SPACE, |
| ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN, SWITCH_TO_LAST_USED_IME}, |
| {/*trigger_on_press=*/true, ui::VKEY_TAB, ui::EF_ALT_DOWN, |
| CYCLE_FORWARD_MRU}, |
| }; |
| |
| const ui::Accelerator new_accelerator(ui::VKEY_TAB, |
| ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN); |
| AcceleratorConfigResult result = |
| config_->AddUserAccelerator(SWITCH_TO_LAST_USED_IME, new_accelerator); |
| EXPECT_EQ(AcceleratorConfigResult::kSuccess, result); |
| |
| // Compare expected accelerators and that the observer was fired after |
| // removing an accelerator. |
| 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(SWITCH_TO_LAST_USED_IME, *found_action); |
| |
| // Confirm that conflicting accelerator was removed. |
| const std::vector<ui::Accelerator>& backward_mru_accelerators = |
| config_->GetAcceleratorsForAction(CYCLE_BACKWARD_MRU); |
| EXPECT_TRUE(backward_mru_accelerators.empty()); |
| } |
| |
| // Add accelerator that conflicts with a deprecated accelerator. |
| TEST_F(AshAcceleratorConfigurationTest, AddAcceleratorDeprecatedConflict) { |
| EXPECT_EQ(0, observer_.num_times_accelerator_updated_called()); |
| const AcceleratorData test_data[] = { |
| {/*trigger_on_press=*/true, ui::VKEY_SPACE, |
| ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN, SWITCH_TO_LAST_USED_IME}, |
| {/*trigger_on_press=*/true, ui::VKEY_TAB, ui::EF_ALT_DOWN, |
| CYCLE_FORWARD_MRU}, |
| {/*trigger_on_press=*/true, ui::VKEY_TAB, |
| ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN, CYCLE_BACKWARD_MRU}, |
| }; |
| |
| const DeprecatedAcceleratorData deprecated_data[] = { |
| {SHOW_TASK_MANAGER, /*uma_histogram_name=*/"deprecated.showTaskManager", |
| /*notification_message_id=*/1, /*old_shortcut_id=*/1, |
| /*new_shortcut_id=*/2, /*deprecated_enabled=*/true}, |
| }; |
| |
| const AcceleratorData test_deprecated_accelerators[] = { |
| {/*trigger_on_press=*/true, ui::VKEY_ESCAPE, ui::EF_SHIFT_DOWN, |
| SHOW_TASK_MANAGER}, |
| }; |
| |
| const AcceleratorData initial_expected_data[] = { |
| {/*trigger_on_press=*/true, ui::VKEY_SPACE, |
| ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN, SWITCH_TO_LAST_USED_IME}, |
| {/*trigger_on_press=*/true, ui::VKEY_TAB, ui::EF_ALT_DOWN, |
| CYCLE_FORWARD_MRU}, |
| {/*trigger_on_press=*/true, ui::VKEY_TAB, |
| ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN, CYCLE_BACKWARD_MRU}, |
| {/*trigger_on_press=*/true, ui::VKEY_ESCAPE, ui::EF_SHIFT_DOWN, |
| SHOW_TASK_MANAGER}, |
| }; |
| |
| config_->Initialize(test_data); |
| config_->InitializeDeprecatedAccelerators(deprecated_data, |
| test_deprecated_accelerators); |
| |
| ExpectAllAcceleratorsEqual(initial_expected_data, |
| config_->GetAllAccelerators()); |
| // Initializing deprecated accelerators will also trigger the observer. |
| 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)); |
| |
| // Add SHIFT + ESCAPE to SWITCH_TO_LAST_USED_IME, which conflicts with |
| // a deprecated accelerator. |
| const AcceleratorData updated_test_data[] = { |
| {/*trigger_on_press=*/true, ui::VKEY_SPACE, |
| ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN, SWITCH_TO_LAST_USED_IME}, |
| {/*trigger_on_press=*/true, ui::VKEY_ESCAPE, ui::EF_SHIFT_DOWN, |
| SWITCH_TO_LAST_USED_IME}, |
| {/*trigger_on_press=*/true, ui::VKEY_TAB, ui::EF_ALT_DOWN, |
| CYCLE_FORWARD_MRU}, |
| {/*trigger_on_press=*/true, ui::VKEY_TAB, |
| ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN, CYCLE_BACKWARD_MRU}, |
| }; |
| |
| AcceleratorConfigResult result = config_->AddUserAccelerator( |
| SWITCH_TO_LAST_USED_IME, deprecated_accelerator); |
| EXPECT_EQ(AcceleratorConfigResult::kSuccess, result); |
| |
| // Compare expected accelerators and that the observer was fired after |
| // removing an accelerator. |
| 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(SWITCH_TO_LAST_USED_IME, *found_action); |
| |
| // Confirm that the deprecated accelerator was removed. |
| EXPECT_FALSE(config_->IsDeprecated(deprecated_accelerator)); |
| } |
| |
| // Add and then remove an accelerator. |
| TEST_F(AshAcceleratorConfigurationTest, AddRemoveAccelerator) { |
| EXPECT_EQ(0, observer_.num_times_accelerator_updated_called()); |
| const AcceleratorData test_data[] = { |
| {/*trigger_on_press=*/true, ui::VKEY_SPACE, |
| ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN, SWITCH_TO_LAST_USED_IME}, |
| {/*trigger_on_press=*/true, ui::VKEY_TAB, ui::EF_ALT_DOWN, |
| CYCLE_FORWARD_MRU}, |
| {/*trigger_on_press=*/true, ui::VKEY_TAB, |
| ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN, CYCLE_BACKWARD_MRU}, |
| }; |
| |
| config_->Initialize(test_data); |
| |
| ExpectAllAcceleratorsEqual(test_data, config_->GetAllAccelerators()); |
| EXPECT_EQ(1, observer_.num_times_accelerator_updated_called()); |
| |
| // Add CTRL + SPACE to SWITCH_TO_LAST_USED_IME. |
| const AcceleratorData added_updated_test_data[] = { |
| {/*trigger_on_press=*/true, ui::VKEY_SPACE, ui::EF_CONTROL_DOWN, |
| SWITCH_TO_LAST_USED_IME}, |
| {/*trigger_on_press=*/true, ui::VKEY_SPACE, |
| ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN, SWITCH_TO_LAST_USED_IME}, |
| {/*trigger_on_press=*/true, ui::VKEY_TAB, ui::EF_ALT_DOWN, |
| CYCLE_FORWARD_MRU}, |
| {/*trigger_on_press=*/true, ui::VKEY_TAB, |
| ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN, CYCLE_BACKWARD_MRU}, |
| }; |
| |
| const ui::Accelerator new_accelerator(ui::VKEY_SPACE, ui::EF_CONTROL_DOWN); |
| AcceleratorConfigResult result = |
| config_->AddUserAccelerator(SWITCH_TO_LAST_USED_IME, new_accelerator); |
| EXPECT_EQ(AcceleratorConfigResult::kSuccess, result); |
| |
| // Compare expected accelerators and that the observer was fired after |
| // adding an accelerator. |
| 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(SWITCH_TO_LAST_USED_IME, *found_action); |
| |
| // Remove CTRL + SPACE from SWITCH_TO_LAST_USED_IME. |
| const AcceleratorData removed_updated_test_data[] = { |
| {/*trigger_on_press=*/true, ui::VKEY_SPACE, |
| ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN, SWITCH_TO_LAST_USED_IME}, |
| {/*trigger_on_press=*/true, ui::VKEY_TAB, ui::EF_ALT_DOWN, |
| CYCLE_FORWARD_MRU}, |
| {/*trigger_on_press=*/true, ui::VKEY_TAB, |
| ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN, CYCLE_BACKWARD_MRU}, |
| }; |
| |
| // Remove the accelerator now. |
| result = config_->RemoveAccelerator(SWITCH_TO_LAST_USED_IME, 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)); |
| } |
| |
| // Add accelerator and restore its default. |
| TEST_F(AshAcceleratorConfigurationTest, AddRestoreAccelerator) { |
| EXPECT_EQ(0, observer_.num_times_accelerator_updated_called()); |
| const AcceleratorData test_data[] = { |
| {/*trigger_on_press=*/true, ui::VKEY_SPACE, |
| ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN, SWITCH_TO_LAST_USED_IME}, |
| {/*trigger_on_press=*/true, ui::VKEY_TAB, ui::EF_ALT_DOWN, |
| CYCLE_FORWARD_MRU}, |
| {/*trigger_on_press=*/true, ui::VKEY_TAB, |
| ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN, CYCLE_BACKWARD_MRU}, |
| }; |
| |
| config_->Initialize(test_data); |
| |
| ExpectAllAcceleratorsEqual(test_data, config_->GetAllAccelerators()); |
| EXPECT_EQ(1, observer_.num_times_accelerator_updated_called()); |
| |
| // Add CTRL + SPACE to SWITCH_TO_LAST_USED_IME. |
| const AcceleratorData updated_test_data[] = { |
| {/*trigger_on_press=*/true, ui::VKEY_SPACE, ui::EF_CONTROL_DOWN, |
| SWITCH_TO_LAST_USED_IME}, |
| {/*trigger_on_press=*/true, ui::VKEY_SPACE, |
| ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN, SWITCH_TO_LAST_USED_IME}, |
| {/*trigger_on_press=*/true, ui::VKEY_TAB, ui::EF_ALT_DOWN, |
| CYCLE_FORWARD_MRU}, |
| {/*trigger_on_press=*/true, ui::VKEY_TAB, |
| ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN, CYCLE_BACKWARD_MRU}, |
| }; |
| |
| const ui::Accelerator new_accelerator(ui::VKEY_SPACE, ui::EF_CONTROL_DOWN); |
| AcceleratorConfigResult result = |
| config_->AddUserAccelerator(SWITCH_TO_LAST_USED_IME, new_accelerator); |
| EXPECT_EQ(AcceleratorConfigResult::kSuccess, result); |
| |
| // Compare expected accelerators and that the observer was fired after |
| // adding an accelerator. |
| 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(SWITCH_TO_LAST_USED_IME, *found_action); |
| |
| // Restore default, expect to be back to default state. |
| result = config_->RestoreDefault(SWITCH_TO_LAST_USED_IME); |
| 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()); |
| } |
| |
| // Add an accelerator, then add the same accelerator to another action. |
| TEST_F(AshAcceleratorConfigurationTest, ReAddAcceleratorToAnotherAction) { |
| EXPECT_EQ(0, observer_.num_times_accelerator_updated_called()); |
| const AcceleratorData test_data[] = { |
| {/*trigger_on_press=*/true, ui::VKEY_SPACE, |
| ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN, SWITCH_TO_LAST_USED_IME}, |
| {/*trigger_on_press=*/true, ui::VKEY_TAB, ui::EF_ALT_DOWN, |
| CYCLE_FORWARD_MRU}, |
| {/*trigger_on_press=*/true, ui::VKEY_TAB, |
| ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN, CYCLE_BACKWARD_MRU}, |
| }; |
| |
| config_->Initialize(test_data); |
| |
| ExpectAllAcceleratorsEqual(test_data, config_->GetAllAccelerators()); |
| EXPECT_EQ(1, observer_.num_times_accelerator_updated_called()); |
| |
| // Add CTRL + SPACE to SWITCH_TO_LAST_USED_IME. |
| const AcceleratorData updated_test_data[] = { |
| {/*trigger_on_press=*/true, ui::VKEY_SPACE, ui::EF_CONTROL_DOWN, |
| SWITCH_TO_LAST_USED_IME}, |
| {/*trigger_on_press=*/true, ui::VKEY_SPACE, |
| ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN, SWITCH_TO_LAST_USED_IME}, |
| {/*trigger_on_press=*/true, ui::VKEY_TAB, ui::EF_ALT_DOWN, |
| CYCLE_FORWARD_MRU}, |
| {/*trigger_on_press=*/true, ui::VKEY_TAB, |
| ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN, CYCLE_BACKWARD_MRU}, |
| }; |
| |
| const ui::Accelerator new_accelerator(ui::VKEY_SPACE, ui::EF_CONTROL_DOWN); |
| AcceleratorConfigResult result = |
| config_->AddUserAccelerator(SWITCH_TO_LAST_USED_IME, new_accelerator); |
| EXPECT_EQ(AcceleratorConfigResult::kSuccess, result); |
| |
| // Compare expected accelerators and that the observer was fired after |
| // adding an accelerator. |
| 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(SWITCH_TO_LAST_USED_IME, *found_action); |
| |
| // Add CTRL + SPACE to CYCLE_BACKWARD_MRU. |
| const AcceleratorData reupdated_test_data[] = { |
| {/*trigger_on_press=*/true, ui::VKEY_SPACE, |
| ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN, SWITCH_TO_LAST_USED_IME}, |
| {/*trigger_on_press=*/true, ui::VKEY_TAB, ui::EF_ALT_DOWN, |
| CYCLE_FORWARD_MRU}, |
| {/*trigger_on_press=*/true, ui::VKEY_TAB, |
| ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN, CYCLE_BACKWARD_MRU}, |
| {/*trigger_on_press=*/true, ui::VKEY_SPACE, ui::EF_CONTROL_DOWN, |
| CYCLE_BACKWARD_MRU}, |
| }; |
| result = config_->AddUserAccelerator(CYCLE_BACKWARD_MRU, 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(CYCLE_BACKWARD_MRU, *found_action2); |
| } |
| } // namespace ash |