OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/chromeos/input_method/xkeyboard.h" | 5 #include "chrome/browser/chromeos/input_method/xkeyboard.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <set> | 8 #include <set> |
9 #include <string> | 9 #include <string> |
10 | 10 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
42 } | 42 } |
43 | 43 |
44 InputMethodWhitelist whitelist_; | 44 InputMethodWhitelist whitelist_; |
45 InputMethodUtil util_; | 45 InputMethodUtil util_; |
46 scoped_ptr<XKeyboard> xkey_; | 46 scoped_ptr<XKeyboard> xkey_; |
47 | 47 |
48 MessageLoopForUI message_loop_; | 48 MessageLoopForUI message_loop_; |
49 content::TestBrowserThread ui_thread_; | 49 content::TestBrowserThread ui_thread_; |
50 }; | 50 }; |
51 | 51 |
52 // Returns a ModifierMap object that contains the following mapping: | |
53 // - kSearchKey is mapped to |search|. | |
54 // - kControl key is mapped to |control|. | |
55 // - kAlt key is mapped to |alt|. | |
56 ModifierMap GetMap(ModifierKey search, ModifierKey control, ModifierKey alt) { | |
57 ModifierMap modifier_key; | |
58 // Use the Search key as |search|. | |
59 modifier_key.push_back(ModifierKeyPair(kSearchKey, search)); | |
60 modifier_key.push_back(ModifierKeyPair(kControlKey, control)); | |
61 modifier_key.push_back(ModifierKeyPair(kAltKey, alt)); | |
62 return modifier_key; | |
63 } | |
64 | |
65 // Checks |modifier_map| and returns true if the following conditions are met: | |
66 // - kSearchKey is mapped to |search|. | |
67 // - kControl key is mapped to |control|. | |
68 // - kAlt key is mapped to |alt|. | |
69 bool CheckMap(const ModifierMap& modifier_map, | |
70 ModifierKey search, ModifierKey control, ModifierKey alt) { | |
71 ModifierMap::const_iterator begin = modifier_map.begin(); | |
72 ModifierMap::const_iterator end = modifier_map.end(); | |
73 if ((std::count(begin, end, ModifierKeyPair(kSearchKey, search)) == 1) && | |
74 (std::count(begin, end, | |
75 ModifierKeyPair(kControlKey, control)) == 1) && | |
76 (std::count(begin, end, ModifierKeyPair(kAltKey, alt)) == 1)) { | |
77 return true; | |
78 } | |
79 return false; | |
80 } | |
81 | |
82 // Returns true if X display is available. | 52 // Returns true if X display is available. |
83 bool DisplayAvailable() { | 53 bool DisplayAvailable() { |
84 return ui::GetXDisplay() ? true : false; | 54 return ui::GetXDisplay() ? true : false; |
85 } | 55 } |
86 | 56 |
87 } // namespace | 57 } // namespace |
88 | 58 |
89 // Tests CreateFullXkbLayoutName() function. | 59 // Tests CreateFullXkbLayoutName() function. |
90 TEST_F(XKeyboardTest, TestCreateFullXkbLayoutNameBasic) { | 60 TEST_F(XKeyboardTest, TestCreateFullXkbLayoutNameBasic) { |
91 // CreateFullXkbLayoutName should not accept an empty |layout_name|. | |
92 EXPECT_STREQ("", xkey_->CreateFullXkbLayoutName( | |
93 "", GetMap(kVoidKey, kVoidKey, kVoidKey)).c_str()); | |
94 | |
95 // CreateFullXkbLayoutName should not accept an empty ModifierMap. | |
96 EXPECT_STREQ("", xkey_->CreateFullXkbLayoutName( | |
97 "us", ModifierMap()).c_str()); | |
98 | |
99 // CreateFullXkbLayoutName should not accept an incomplete ModifierMap. | |
100 ModifierMap tmp_map = GetMap(kVoidKey, kVoidKey, kVoidKey); | |
101 tmp_map.pop_back(); | |
102 EXPECT_STREQ("", xkey_->CreateFullXkbLayoutName("us", tmp_map).c_str()); | |
103 | |
104 // CreateFullXkbLayoutName should not accept redundant ModifierMaps. | |
105 tmp_map = GetMap(kVoidKey, kVoidKey, kVoidKey); | |
106 tmp_map.push_back(ModifierKeyPair(kSearchKey, kVoidKey)); // two search maps | |
107 EXPECT_STREQ("", xkey_->CreateFullXkbLayoutName("us", tmp_map).c_str()); | |
108 tmp_map = GetMap(kVoidKey, kVoidKey, kVoidKey); | |
109 tmp_map.push_back(ModifierKeyPair(kControlKey, kVoidKey)); // two ctrls | |
110 EXPECT_STREQ("", xkey_->CreateFullXkbLayoutName("us", tmp_map).c_str()); | |
111 tmp_map = GetMap(kVoidKey, kVoidKey, kVoidKey); | |
112 tmp_map.push_back(ModifierKeyPair(kAltKey, kVoidKey)); // two alts. | |
113 EXPECT_STREQ("", xkey_->CreateFullXkbLayoutName("us", tmp_map).c_str()); | |
114 | |
115 // CreateFullXkbLayoutName should not accept invalid ModifierMaps. | |
116 tmp_map = GetMap(kVoidKey, kVoidKey, kVoidKey); | |
117 tmp_map.push_back(ModifierKeyPair(kVoidKey, kSearchKey)); // can't remap void | |
118 EXPECT_STREQ("", xkey_->CreateFullXkbLayoutName("us", tmp_map).c_str()); | |
119 tmp_map = GetMap(kVoidKey, kVoidKey, kVoidKey); | |
120 tmp_map.push_back(ModifierKeyPair(kCapsLockKey, kSearchKey)); // ditto | |
121 EXPECT_STREQ("", xkey_->CreateFullXkbLayoutName("us", tmp_map).c_str()); | |
122 | |
123 // CreateFullXkbLayoutName can remap Search/Ctrl/Alt to CapsLock. | |
124 EXPECT_STREQ("us+chromeos(capslock_disabled_disabled)", | |
125 xkey_->CreateFullXkbLayoutName( | |
126 "us", | |
127 GetMap(kCapsLockKey, kVoidKey, kVoidKey)).c_str()); | |
128 EXPECT_STREQ("us+chromeos(disabled_capslock_disabled)", | |
129 xkey_->CreateFullXkbLayoutName( | |
130 "us", | |
131 GetMap(kVoidKey, kCapsLockKey, kVoidKey)).c_str()); | |
132 EXPECT_STREQ("us+chromeos(disabled_disabled_capslock)", | |
133 xkey_->CreateFullXkbLayoutName( | |
134 "us", | |
135 GetMap(kVoidKey, kVoidKey, kCapsLockKey)).c_str()); | |
136 | |
137 // CreateFullXkbLayoutName should not accept non-alphanumeric characters | 61 // CreateFullXkbLayoutName should not accept non-alphanumeric characters |
138 // except "()-_". | 62 // except "()-_". |
139 EXPECT_STREQ("", xkey_->CreateFullXkbLayoutName( | 63 EXPECT_EQ("", xkey_->CreateFullXkbLayoutName("us!")); |
140 "us!", GetMap(kVoidKey, kVoidKey, kVoidKey)).c_str()); | 64 EXPECT_EQ("", xkey_->CreateFullXkbLayoutName("us; /bin/sh")); |
141 EXPECT_STREQ("", xkey_->CreateFullXkbLayoutName( | 65 EXPECT_EQ("ab-c_12+chromeos(search_leftcontrol_leftalt_keepralt)", |
142 "us; /bin/sh", GetMap(kVoidKey, kVoidKey, kVoidKey)).c_str()); | 66 xkey_->CreateFullXkbLayoutName("ab-c_12")); |
143 EXPECT_STREQ("ab-c_12+chromeos(disabled_disabled_disabled)", | |
144 xkey_->CreateFullXkbLayoutName( | |
145 "ab-c_12", | |
146 GetMap(kVoidKey, kVoidKey, kVoidKey)).c_str()); | |
147 | 67 |
148 // CreateFullXkbLayoutName should not accept upper-case ascii characters. | 68 // CreateFullXkbLayoutName should not accept upper-case ascii characters. |
149 EXPECT_STREQ("", xkey_->CreateFullXkbLayoutName( | 69 EXPECT_EQ("", xkey_->CreateFullXkbLayoutName("US")); |
150 "US", GetMap(kVoidKey, kVoidKey, kVoidKey)).c_str()); | |
151 | 70 |
152 // CreateFullXkbLayoutName should accept lower-case ascii characters. | 71 // CreateFullXkbLayoutName should accept lower-case ascii characters. |
153 for (int c = 'a'; c <= 'z'; ++c) { | 72 for (int c = 'a'; c <= 'z'; ++c) { |
154 EXPECT_STRNE("", xkey_->CreateFullXkbLayoutName( | 73 EXPECT_NE("", xkey_->CreateFullXkbLayoutName(std::string(3, c))); |
155 std::string(3, c), | |
156 GetMap(kVoidKey, kVoidKey, kVoidKey)).c_str()); | |
157 } | 74 } |
158 | 75 |
159 // CreateFullXkbLayoutName should accept numbers. | 76 // CreateFullXkbLayoutName should accept numbers. |
160 for (int c = '0'; c <= '9'; ++c) { | 77 for (int c = '0'; c <= '9'; ++c) { |
161 EXPECT_STRNE("", xkey_->CreateFullXkbLayoutName( | 78 EXPECT_NE("", xkey_->CreateFullXkbLayoutName(std::string(3, c))); |
162 std::string(3, c), | |
163 GetMap(kVoidKey, kVoidKey, kVoidKey)).c_str()); | |
164 } | 79 } |
165 | 80 |
166 // CreateFullXkbLayoutName should accept a layout with a variant name. | 81 // CreateFullXkbLayoutName should accept a layout with a variant name. |
167 EXPECT_STREQ("us(dvorak)+chromeos(disabled_disabled_disabled)", | 82 EXPECT_EQ("us(dvorak)+chromeos(search_leftcontrol_leftalt_keepralt)", |
168 xkey_->CreateFullXkbLayoutName( | 83 xkey_->CreateFullXkbLayoutName("us(dvorak)")); |
169 "us(dvorak)", | 84 EXPECT_EQ("jp+chromeos(search_leftcontrol_leftalt_keepralt)", |
170 GetMap(kVoidKey, kVoidKey, kVoidKey)).c_str()); | 85 xkey_->CreateFullXkbLayoutName("jp")); |
171 EXPECT_STREQ("jp+chromeos(disabled_disabled_disabled)", | |
172 xkey_->CreateFullXkbLayoutName( | |
173 "jp", // does not use AltGr, therefore no _keepralt. | |
174 GetMap(kVoidKey, kVoidKey, kVoidKey)).c_str()); | |
175 } | |
176 | |
177 TEST_F(XKeyboardTest, TestCreateFullXkbLayoutNameKeepCapsLock) { | |
178 EXPECT_STREQ("us(colemak)+chromeos(search_disabled_disabled)", | |
179 xkey_->CreateFullXkbLayoutName( | |
180 "us(colemak)", | |
181 // The 1st kVoidKey should be ignored. | |
182 GetMap(kVoidKey, kVoidKey, kVoidKey)).c_str()); | |
183 EXPECT_STREQ("de(neo)+chromeos(search_leftcontrol_leftcontrol_keepralt)", | |
184 xkey_->CreateFullXkbLayoutName( | |
185 // The 1st kControlKey should be ignored. | |
186 "de(neo)", GetMap(kControlKey, | |
187 kControlKey, | |
188 kControlKey)).c_str()); | |
189 EXPECT_STREQ("gb(extd)+chromeos(disabled_disabled_disabled_keepralt)", | |
190 xkey_->CreateFullXkbLayoutName( | |
191 "gb(extd)", | |
192 GetMap(kVoidKey, kVoidKey, kVoidKey)).c_str()); | |
193 } | |
194 | |
195 TEST_F(XKeyboardTest, TestCreateFullXkbLayoutNameKeepAlt) { | |
196 EXPECT_STREQ("us(intl)+chromeos(disabled_disabled_disabled_keepralt)", | |
197 xkey_->CreateFullXkbLayoutName( | |
198 "us(intl)", GetMap(kVoidKey, kVoidKey, kVoidKey)).c_str()); | |
199 EXPECT_STREQ("kr(kr104)+" | |
200 "chromeos(leftcontrol_leftcontrol_leftcontrol_keepralt)", | |
201 xkey_->CreateFullXkbLayoutName( | |
202 "kr(kr104)", GetMap(kControlKey, | |
203 kControlKey, | |
204 kControlKey)).c_str()); | |
205 } | |
206 | |
207 // Tests if CreateFullXkbLayoutName and ExtractLayoutNameFromFullXkbLayoutName | |
208 // functions could handle all combinations of modifier remapping. | |
209 TEST_F(XKeyboardTest, TestCreateFullXkbLayoutNameModifierKeys) { | |
210 std::set<std::string> layouts; | |
211 for (int i = 0; i < static_cast<int>(kNumModifierKeys); ++i) { | |
212 for (int j = 0; j < static_cast<int>(kNumModifierKeys); ++j) { | |
213 for (int k = 0; k < static_cast<int>(kNumModifierKeys); ++k) { | |
214 const std::string layout = xkey_->CreateFullXkbLayoutName( | |
215 "us", GetMap(ModifierKey(i), ModifierKey(j), ModifierKey(k))); | |
216 // CreateFullXkbLayoutName should succeed (i.e. should not return "".) | |
217 EXPECT_STREQ("us+", layout.substr(0, 3).c_str()) | |
218 << "layout: " << layout; | |
219 // All 4*3*3 layouts should be different. | |
220 EXPECT_TRUE(layouts.insert(layout).second) << "layout: " << layout; | |
221 } | |
222 } | |
223 } | |
224 } | 86 } |
225 | 87 |
226 TEST_F(XKeyboardTest, TestSetCapsLockEnabled) { | 88 TEST_F(XKeyboardTest, TestSetCapsLockEnabled) { |
227 if (!DisplayAvailable()) { | 89 if (!DisplayAvailable()) { |
228 // Do not fail the test to allow developers to run unit_tests without an X | 90 // Do not fail the test to allow developers to run unit_tests without an X |
229 // server (e.g. via ssh). Note that both try bots and waterfall always have | 91 // server (e.g. via ssh). Note that both try bots and waterfall always have |
230 // an X server for running browser_tests. | 92 // an X server for running browser_tests. |
231 DVLOG(1) << "X server is not available. Skip the test."; | 93 DVLOG(1) << "X server is not available. Skip the test."; |
232 return; | 94 return; |
233 } | 95 } |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
315 | 177 |
316 // No-op SetLockedModifiers call. | 178 // No-op SetLockedModifiers call. |
317 xkey_->SetLockedModifiers(kDontChange, kDontChange); | 179 xkey_->SetLockedModifiers(kDontChange, kDontChange); |
318 EXPECT_EQ(initial_caps_lock_state, xkey_->CapsLockIsEnabled()); | 180 EXPECT_EQ(initial_caps_lock_state, xkey_->CapsLockIsEnabled()); |
319 EXPECT_EQ(initial_num_lock_state, xkey_->NumLockIsEnabled()); | 181 EXPECT_EQ(initial_num_lock_state, xkey_->NumLockIsEnabled()); |
320 | 182 |
321 // No-op GetLockedModifiers call. Confirm it does not crash. | 183 // No-op GetLockedModifiers call. Confirm it does not crash. |
322 xkey_->GetLockedModifiers(NULL, NULL); | 184 xkey_->GetLockedModifiers(NULL, NULL); |
323 } | 185 } |
324 | 186 |
325 TEST_F(XKeyboardTest, TestContainsModifierKeyAsReplacement) { | |
326 EXPECT_FALSE(XKeyboard::ContainsModifierKeyAsReplacement( | |
327 GetMap(kVoidKey, kVoidKey, kVoidKey), kCapsLockKey)); | |
328 EXPECT_TRUE(XKeyboard::ContainsModifierKeyAsReplacement( | |
329 GetMap(kCapsLockKey, kVoidKey, kVoidKey), kCapsLockKey)); | |
330 EXPECT_TRUE(XKeyboard::ContainsModifierKeyAsReplacement( | |
331 GetMap(kVoidKey, kCapsLockKey, kVoidKey), kCapsLockKey)); | |
332 EXPECT_TRUE(XKeyboard::ContainsModifierKeyAsReplacement( | |
333 GetMap(kVoidKey, kVoidKey, kCapsLockKey), kCapsLockKey)); | |
334 EXPECT_TRUE(XKeyboard::ContainsModifierKeyAsReplacement( | |
335 GetMap(kCapsLockKey, kCapsLockKey, kVoidKey), kCapsLockKey)); | |
336 EXPECT_TRUE(XKeyboard::ContainsModifierKeyAsReplacement( | |
337 GetMap(kCapsLockKey, kCapsLockKey, kCapsLockKey), kCapsLockKey)); | |
338 EXPECT_TRUE(XKeyboard::ContainsModifierKeyAsReplacement( | |
339 GetMap(kSearchKey, kVoidKey, kVoidKey), kSearchKey)); | |
340 } | |
341 | |
342 TEST_F(XKeyboardTest, TestSetAutoRepeatEnabled) { | 187 TEST_F(XKeyboardTest, TestSetAutoRepeatEnabled) { |
343 if (!DisplayAvailable()) { | 188 if (!DisplayAvailable()) { |
344 DVLOG(1) << "X server is not available. Skip the test."; | 189 DVLOG(1) << "X server is not available. Skip the test."; |
345 return; | 190 return; |
346 } | 191 } |
347 const bool state = XKeyboard::GetAutoRepeatEnabledForTesting(); | 192 const bool state = XKeyboard::GetAutoRepeatEnabledForTesting(); |
348 XKeyboard::SetAutoRepeatEnabled(!state); | 193 XKeyboard::SetAutoRepeatEnabled(!state); |
349 EXPECT_EQ(!state, XKeyboard::GetAutoRepeatEnabledForTesting()); | 194 EXPECT_EQ(!state, XKeyboard::GetAutoRepeatEnabledForTesting()); |
350 // Restore the initial state. | 195 // Restore the initial state. |
351 XKeyboard::SetAutoRepeatEnabled(state); | 196 XKeyboard::SetAutoRepeatEnabled(state); |
(...skipping 18 matching lines...) Expand all Loading... |
370 | 215 |
371 // Restore the initial state. | 216 // Restore the initial state. |
372 EXPECT_TRUE(XKeyboard::SetAutoRepeatRate(rate)); | 217 EXPECT_TRUE(XKeyboard::SetAutoRepeatRate(rate)); |
373 EXPECT_TRUE(XKeyboard::GetAutoRepeatRateForTesting(&tmp)); | 218 EXPECT_TRUE(XKeyboard::GetAutoRepeatRateForTesting(&tmp)); |
374 EXPECT_EQ(rate.initial_delay_in_ms, tmp.initial_delay_in_ms); | 219 EXPECT_EQ(rate.initial_delay_in_ms, tmp.initial_delay_in_ms); |
375 EXPECT_EQ(rate.repeat_interval_in_ms, tmp.repeat_interval_in_ms); | 220 EXPECT_EQ(rate.repeat_interval_in_ms, tmp.repeat_interval_in_ms); |
376 } | 221 } |
377 | 222 |
378 } // namespace input_method | 223 } // namespace input_method |
379 } // namespace chromeos | 224 } // namespace chromeos |
OLD | NEW |