Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include <stddef.h> | |
| 6 | |
| 7 #include <set> | |
| 8 | |
| 9 #include "build/build_config.h" | |
| 10 #include "chrome/app/chrome_command_ids.h" | |
| 11 #include "chrome/browser/global_keyboard_shortcuts_mac.h" | |
| 12 #include "chrome/browser/ui/views/accelerator_table.h" | |
| 13 #include "testing/gtest/include/gtest/gtest.h" | |
| 14 #include "ui/events/event_constants.h" | |
| 15 #include "ui/events/keycodes/keyboard_code_conversion_mac.h" | |
| 16 | |
| 17 namespace chrome { | |
| 18 | |
| 19 // Vefifies that only the whitelisted accelerators could have Control key | |
| 20 // modifier, while running on macOS. | |
| 21 TEST(AcceleratorTableTest, CheckMacOSControlAccelerators) { | |
| 22 // Only the accelerators that also work in Cocoa browser are allowed to appear | |
| 23 // on this whitelist. | |
| 24 const std::set<int> whitelisted_control_shortcuts = { | |
| 25 IDC_SELECT_NEXT_TAB, | |
| 26 IDC_SELECT_PREVIOUS_TAB, | |
| 27 IDC_FULLSCREEN, | |
| 28 }; | |
| 29 | |
| 30 const std::vector<AcceleratorMapping> accelerator_list(GetAcceleratorList()); | |
| 31 | |
| 32 // Control modifier is rarely used on Mac, and all valid uses must be | |
| 33 // whitelisted. | |
| 34 for (const auto& entry : accelerator_list) { | |
| 35 if (whitelisted_control_shortcuts.count(entry.command_id)) | |
| 36 continue; | |
| 37 EXPECT_FALSE(entry.modifiers & ui::EF_CONTROL_DOWN) | |
| 38 << "Found non-whitelisted accelerator that contains Control " | |
| 39 "modifier: " << entry.command_id; | |
| 40 } | |
| 41 | |
| 42 // Test that whitelist is not outdated. | |
| 43 for (const auto& whitelist_entry : whitelisted_control_shortcuts) { | |
| 44 const auto entry = | |
| 45 std::find_if(accelerator_list.begin(), accelerator_list.end(), | |
| 46 [whitelist_entry](const AcceleratorMapping& a) { | |
| 47 return a.command_id == whitelist_entry && | |
| 48 a.modifiers & ui::EF_CONTROL_DOWN; | |
| 49 }); | |
| 50 EXPECT_TRUE(entry != accelerator_list.end()) | |
| 51 << "Whitelisted accelerator not found in the actual list: " | |
| 52 << whitelist_entry; | |
| 53 } | |
| 54 } | |
| 55 | |
| 56 // Verifies that Alt-only (or with just Shift) accelerators are not present in | |
| 57 // the list. | |
| 58 TEST(AcceleratorTableTest, CheckMacOSAltAccelerators) { | |
| 59 const int kNonShiftMask = | |
| 60 ui::EF_COMMAND_DOWN | ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN; | |
| 61 for (const auto& entry : GetAcceleratorList()) { | |
| 62 EXPECT_FALSE((entry.modifiers & kNonShiftMask) == ui::EF_ALT_DOWN) | |
| 63 << "Found accelerator that uses solely Alt modifier: " | |
| 64 << entry.command_id; | |
| 65 } | |
| 66 } | |
| 67 | |
| 68 // Vefifies that accelerator filtering works correctly and we have an | |
| 69 // alternative shortcut for each filtered-out accelerator. | |
| 70 TEST(AcceleratorTableTest, CheckMacOSFilteredOutAcceleratorsHaveAlternatives) { | |
| 71 // It's okay not to have an alternative accelerator for these commands as | |
| 72 // there's no alternative for them in the Cocoa browser. | |
| 73 const std::set<int> whitelisted_unique_shortcuts = { | |
| 74 IDC_FOCUS_TOOLBAR, | |
| 75 IDC_FOCUS_BOOKMARKS, | |
| 76 IDC_FOCUS_INFOBARS, | |
| 77 IDC_SHOW_APP_MENU, | |
| 78 }; | |
| 79 | |
| 80 const std::vector<AcceleratorMapping> accelerator_list(GetAcceleratorList()); | |
| 81 const std::vector<AcceleratorMapping> full_accelerator_list( | |
| 82 GetUnfilteredAcceleratorListForTesting()); | |
| 83 | |
| 84 // Ensure that we still have alternative mappings for all filtered-out | |
| 85 // accelerators. | |
| 86 std::vector<AcceleratorMapping> filtered_list(full_accelerator_list); | |
| 87 auto remove_start = | |
| 88 std::remove_if(filtered_list.begin(), filtered_list.end(), | |
| 89 [&accelerator_list](const AcceleratorMapping& m1) { | |
| 90 // Remove all accelerators that are present in |accelerator_list| | |
| 91 return std::find_if(accelerator_list.begin(), accelerator_list.end(), | |
| 92 [&m1](const AcceleratorMapping& m2) { | |
| 93 return m1.command_id == m2.command_id && | |
| 94 m1.keycode == m2.keycode && | |
| 95 m1.modifiers == m2.modifiers; | |
| 96 }) != accelerator_list.end(); | |
| 97 }); | |
| 98 filtered_list.erase(remove_start, filtered_list.end()); | |
| 99 EXPECT_GT(filtered_list.size(), 1u); | |
| 100 | |
| 101 for (const auto& removed_entry : filtered_list) { | |
| 102 if (whitelisted_unique_shortcuts.count(removed_entry.command_id)) | |
| 103 continue; | |
| 104 | |
| 105 const auto entry = | |
| 106 std::find_if(accelerator_list.begin(), accelerator_list.end(), | |
| 107 [&removed_entry](const AcceleratorMapping& m) { | |
| 108 return removed_entry.command_id == m.command_id; | |
| 109 }); | |
| 110 EXPECT_TRUE(entry != accelerator_list.end()) | |
| 111 << "Filtered command doesn't have an alternative mapping: " | |
| 112 << removed_entry.command_id; | |
| 113 } | |
| 114 | |
| 115 for (const auto& whitelist_entry : whitelisted_unique_shortcuts) { | |
| 116 const auto entry = | |
| 117 std::find_if(filtered_list.begin(), filtered_list.end(), | |
| 118 [&whitelist_entry](const AcceleratorMapping& m) { | |
| 119 return whitelist_entry == m.command_id; | |
| 120 }); | |
| 121 EXPECT_TRUE(entry != filtered_list.end()) | |
| 122 << "Whitelisted accelerator not found in the filtered-out list: " | |
| 123 << whitelist_entry; | |
| 124 } | |
| 125 } | |
| 126 | |
| 127 namespace { | |
| 128 | |
| 129 static void VerifyTable( | |
| 130 const KeyboardShortcutData* (*get_keyboard_shortcut_table)(size_t*), | |
| 131 const std::string& table_name) { | |
| 132 const std::vector<AcceleratorMapping> accelerator_list(GetAcceleratorList()); | |
| 133 | |
| 134 size_t num_shortcuts = 0; | |
| 135 const KeyboardShortcutData *it = get_keyboard_shortcut_table(&num_shortcuts); | |
| 136 for (size_t i = 0; i < num_shortcuts; ++i, ++it) { | |
| 137 int modifiers = 0; | |
| 138 if (it->command_key) | |
| 139 modifiers |= ui::EF_COMMAND_DOWN; | |
| 140 if (it->shift_key) | |
| 141 modifiers |= ui::EF_SHIFT_DOWN; | |
| 142 if (it->cntrl_key) | |
| 143 modifiers |= ui::EF_CONTROL_DOWN; | |
| 144 if (it->opt_key) | |
| 145 modifiers |= ui::EF_ALT_DOWN; | |
| 146 | |
| 147 for (const auto& entry : accelerator_list) { | |
| 148 unichar character; | |
| 149 unichar shifted_character; | |
| 150 const int vkey_code = ui::MacKeyCodeForWindowsKeyCode( | |
| 151 entry.keycode, entry.modifiers, &shifted_character, &character); | |
| 152 | |
| 153 if (it->vkey_code) { | |
| 154 if (modifiers == entry.modifiers && it->vkey_code == vkey_code && | |
| 155 it->chrome_command == entry.command_id) { | |
| 156 EXPECT_TRUE(false) << "Duplicate command: " << entry.command_id | |
| 157 << " in table " << table_name; | |
| 158 } | |
| 159 } else { | |
| 160 if (modifiers == entry.modifiers && | |
| 161 (it->key_char == character || it->key_char == shifted_character) && | |
| 162 it->chrome_command == entry.command_id) { | |
| 163 EXPECT_TRUE(false) << "Duplicate command: " << entry.command_id | |
| 164 << " in table " << table_name; | |
| 165 } | |
| 166 } | |
| 167 } | |
| 168 } | |
| 169 } | |
| 170 | |
| 171 } // namespace | |
| 172 | |
| 173 // Verifies that we're not processing any duplicate accelerators in | |
| 174 // global_keyboard_shortcuts_mac.mm functions. | |
| 175 TEST(AcceleratorTableTest, CheckNoDuplicatesGlobalKeyboardShortcutsMac) { | |
| 176 // VerifyTable(GetWindowKeyboardShortcutTable, "WindowKeyboardShortcutTable"); | |
|
tapted
2016/10/26 08:40:47
We don't commit commented-out code. I'm guessing t
themblsha
2016/10/26 17:10:03
Yep, I should remove it in the final version. Idea
themblsha
2016/10/28 17:32:22
With the split now all the tables are always used
| |
| 177 // VerifyTable(GetDelayedWindowKeyboardShortcutTable, | |
| 178 // "DelayedWindowKeyboardShortcutTable"); | |
| 179 // VerifyTable(GetBrowserKeyboardShortcutTable, | |
| 180 // "BrowserKeyboardShortcutTable"); | |
| 181 VerifyTable(GetMacViewsKeyboardShortcutTable, | |
| 182 "MacViewsKeyboardShortcutTable"); | |
| 183 } | |
| 184 | |
| 185 } // namespace chrome | |
| OLD | NEW |