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 "ash/common/system/chromeos/ime_menu/ime_menu_tray.h" | |
6 | |
7 #include "ash/common/accelerators/accelerator_controller.h" | |
8 #include "ash/common/accessibility_delegate.h" | |
9 #include "ash/common/system/chromeos/ime_menu/ime_list_view.h" | |
10 #include "ash/common/system/status_area_widget.h" | |
11 #include "ash/common/system/tray/ime_info.h" | |
12 #include "ash/common/system/tray/system_tray_notifier.h" | |
13 #include "ash/common/test/test_system_tray_delegate.h" | |
14 #include "ash/common/wm_shell.h" | |
15 #include "ash/test/ash_test_base.h" | |
16 #include "ash/test/status_area_widget_test_helper.h" | |
17 #include "base/strings/utf_string_conversions.h" | |
18 #include "ui/accessibility/ax_node_data.h" | |
19 #include "ui/base/ime/chromeos/input_method_manager.h" | |
20 #include "ui/base/ime/chromeos/mock_input_method_manager.h" | |
21 #include "ui/base/ime/ime_bridge.h" | |
22 #include "ui/base/ime/text_input_flags.h" | |
23 #include "ui/events/event.h" | |
24 #include "ui/views/controls/label.h" | |
25 | |
26 using base::UTF8ToUTF16; | |
27 | |
28 namespace ash { | |
29 | |
30 ImeMenuTray* GetTray() { | |
31 return StatusAreaWidgetTestHelper::GetStatusAreaWidget()->ime_menu_tray(); | |
32 } | |
33 | |
34 class ImeMenuTrayTest : public test::AshTestBase { | |
35 public: | |
36 ImeMenuTrayTest() {} | |
37 ~ImeMenuTrayTest() override {} | |
38 | |
39 protected: | |
40 // Returns true if the IME menu tray is visible. | |
41 bool IsVisible() { return GetTray()->visible(); } | |
42 | |
43 // Returns the label text of the tray. | |
44 const base::string16& GetTrayText() { return GetTray()->label_->text(); } | |
45 | |
46 // Returns true if the background color of the tray is active. | |
47 bool IsTrayBackgroundActive() { return GetTray()->is_active(); } | |
48 | |
49 // Returns true if the IME menu bubble has been shown. | |
50 bool IsBubbleShown() { return GetTray()->IsImeMenuBubbleShown(); } | |
51 | |
52 // Returns true if the IME menu list has been updated with the right IME list. | |
53 bool IsTrayImeListValid(const std::vector<IMEInfo>& expected_imes, | |
54 const IMEInfo& expected_current_ime) { | |
55 const std::map<views::View*, std::string>& ime_map = | |
56 ImeListViewTestApi(GetTray()->ime_list_view_).ime_map(); | |
57 if (ime_map.size() != expected_imes.size()) | |
58 return false; | |
59 | |
60 std::vector<std::string> expected_ime_ids; | |
61 for (const auto& ime : expected_imes) { | |
62 expected_ime_ids.push_back(ime.id); | |
63 } | |
64 for (const auto& ime : ime_map) { | |
65 // Tests that all the IMEs on the view is in the list of selected IMEs. | |
66 if (std::find(expected_ime_ids.begin(), expected_ime_ids.end(), | |
67 ime.second) == expected_ime_ids.end()) { | |
68 return false; | |
69 } | |
70 | |
71 // Tests that the checked IME is the current IME. | |
72 ui::AXNodeData node_data; | |
73 node_data.state = 0; | |
74 ime.first->GetAccessibleNodeData(&node_data); | |
75 if (node_data.HasStateFlag(ui::AX_STATE_CHECKED)) { | |
76 if (ime.second != expected_current_ime.id) | |
77 return false; | |
78 } | |
79 } | |
80 return true; | |
81 } | |
82 | |
83 // Focuses in the given type of input context. | |
84 void FocusInInputContext(ui::TextInputType input_type) { | |
85 ui::IMEEngineHandlerInterface::InputContext input_context( | |
86 input_type, ui::TEXT_INPUT_MODE_DEFAULT, ui::TEXT_INPUT_FLAG_NONE); | |
87 ui::IMEBridge::Get()->SetCurrentInputContext(input_context); | |
88 } | |
89 | |
90 private: | |
91 DISALLOW_COPY_AND_ASSIGN(ImeMenuTrayTest); | |
92 }; | |
93 | |
94 // Tests that visibility of IME menu tray should be consistent with the | |
95 // activation of the IME menu. | |
96 TEST_F(ImeMenuTrayTest, ImeMenuTrayVisibility) { | |
97 ASSERT_FALSE(IsVisible()); | |
98 | |
99 WmShell::Get()->system_tray_notifier()->NotifyRefreshIMEMenu(true); | |
100 EXPECT_TRUE(IsVisible()); | |
101 | |
102 WmShell::Get()->system_tray_notifier()->NotifyRefreshIMEMenu(false); | |
103 EXPECT_FALSE(IsVisible()); | |
104 } | |
105 | |
106 // Tests that IME menu tray shows the right info of the current IME. | |
107 TEST_F(ImeMenuTrayTest, TrayLabelTest) { | |
108 WmShell::Get()->system_tray_notifier()->NotifyRefreshIMEMenu(true); | |
109 ASSERT_TRUE(IsVisible()); | |
110 | |
111 // Changes the input method to "ime1". | |
112 IMEInfo info1; | |
113 info1.id = "ime1"; | |
114 info1.name = UTF8ToUTF16("English"); | |
115 info1.medium_name = UTF8ToUTF16("English"); | |
116 info1.short_name = UTF8ToUTF16("US"); | |
117 info1.third_party = false; | |
118 info1.selected = true; | |
119 GetSystemTrayDelegate()->SetCurrentIME(info1); | |
120 WmShell::Get()->system_tray_notifier()->NotifyRefreshIME(); | |
121 EXPECT_EQ(UTF8ToUTF16("US"), GetTrayText()); | |
122 | |
123 // Changes the input method to a third-party IME extension. | |
124 IMEInfo info2; | |
125 info2.id = "ime2"; | |
126 info2.name = UTF8ToUTF16("English UK"); | |
127 info2.medium_name = UTF8ToUTF16("English UK"); | |
128 info2.short_name = UTF8ToUTF16("UK"); | |
129 info2.third_party = true; | |
130 info2.selected = true; | |
131 GetSystemTrayDelegate()->SetCurrentIME(info2); | |
132 WmShell::Get()->system_tray_notifier()->NotifyRefreshIME(); | |
133 EXPECT_EQ(UTF8ToUTF16("UK*"), GetTrayText()); | |
134 } | |
135 | |
136 // Tests that IME menu tray changes background color when tapped/clicked. And | |
137 // tests that the background color becomes 'inactive' when disabling the IME | |
138 // menu feature. | |
139 TEST_F(ImeMenuTrayTest, PerformAction) { | |
140 WmShell::Get()->system_tray_notifier()->NotifyRefreshIMEMenu(true); | |
141 ASSERT_TRUE(IsVisible()); | |
142 ASSERT_FALSE(IsTrayBackgroundActive()); | |
143 | |
144 ui::GestureEvent tap(0, 0, 0, base::TimeTicks(), | |
145 ui::GestureEventDetails(ui::ET_GESTURE_TAP)); | |
146 GetTray()->PerformAction(tap); | |
147 EXPECT_TRUE(IsTrayBackgroundActive()); | |
148 EXPECT_TRUE(IsBubbleShown()); | |
149 | |
150 GetTray()->PerformAction(tap); | |
151 EXPECT_FALSE(IsTrayBackgroundActive()); | |
152 EXPECT_FALSE(IsBubbleShown()); | |
153 | |
154 // If disabling the IME menu feature when the menu tray is activated, the tray | |
155 // element will be deactivated. | |
156 GetTray()->PerformAction(tap); | |
157 EXPECT_TRUE(IsTrayBackgroundActive()); | |
158 WmShell::Get()->system_tray_notifier()->NotifyRefreshIMEMenu(false); | |
159 EXPECT_FALSE(IsVisible()); | |
160 EXPECT_FALSE(IsBubbleShown()); | |
161 EXPECT_FALSE(IsTrayBackgroundActive()); | |
162 } | |
163 | |
164 // Tests that IME menu list updates when changing the current IME. This should | |
165 // only happen by using shortcuts (Ctrl + Space / Ctrl + Shift + Space) to | |
166 // switch IMEs. | |
167 TEST_F(ImeMenuTrayTest, RefreshImeWithListViewCreated) { | |
168 ui::GestureEvent tap(0, 0, 0, base::TimeTicks(), | |
169 ui::GestureEventDetails(ui::ET_GESTURE_TAP)); | |
170 GetTray()->PerformAction(tap); | |
171 | |
172 EXPECT_TRUE(IsTrayBackgroundActive()); | |
173 EXPECT_TRUE(IsBubbleShown()); | |
174 | |
175 IMEInfo info1, info2, info3; | |
176 info1.id = "ime1"; | |
177 info1.name = UTF8ToUTF16("English"); | |
178 info1.medium_name = UTF8ToUTF16("English"); | |
179 info1.short_name = UTF8ToUTF16("US"); | |
180 info1.third_party = false; | |
181 info1.selected = true; | |
182 | |
183 info2.id = "ime2"; | |
184 info2.name = UTF8ToUTF16("English UK"); | |
185 info2.medium_name = UTF8ToUTF16("English UK"); | |
186 info2.short_name = UTF8ToUTF16("UK"); | |
187 info2.third_party = true; | |
188 info2.selected = false; | |
189 | |
190 info3.id = "ime3"; | |
191 info3.name = UTF8ToUTF16("Pinyin"); | |
192 info3.medium_name = UTF8ToUTF16("Chinese Pinyin"); | |
193 info3.short_name = UTF8ToUTF16("拼"); | |
194 info3.third_party = false; | |
195 info3.selected = false; | |
196 | |
197 std::vector<IMEInfo> ime_info_list{info1, info2, info3}; | |
198 | |
199 GetSystemTrayDelegate()->SetAvailableIMEList(ime_info_list); | |
200 GetSystemTrayDelegate()->SetCurrentIME(info1); | |
201 WmShell::Get()->system_tray_notifier()->NotifyRefreshIME(); | |
202 EXPECT_EQ(UTF8ToUTF16("US"), GetTrayText()); | |
203 EXPECT_TRUE(IsTrayImeListValid(ime_info_list, info1)); | |
204 | |
205 ime_info_list[0].selected = false; | |
206 ime_info_list[2].selected = true; | |
207 GetSystemTrayDelegate()->SetAvailableIMEList(ime_info_list); | |
208 GetSystemTrayDelegate()->SetCurrentIME(info3); | |
209 WmShell::Get()->system_tray_notifier()->NotifyRefreshIME(); | |
210 EXPECT_EQ(UTF8ToUTF16("拼"), GetTrayText()); | |
211 EXPECT_TRUE(IsTrayImeListValid(ime_info_list, info3)); | |
212 | |
213 // Closes the menu before quitting. | |
214 GetTray()->PerformAction(tap); | |
215 EXPECT_FALSE(IsTrayBackgroundActive()); | |
216 EXPECT_FALSE(IsBubbleShown()); | |
217 } | |
218 | |
219 // Tests that quits Chrome with IME menu openned will not crash. | |
220 TEST_F(ImeMenuTrayTest, QuitChromeWithMenuOpen) { | |
221 WmShell::Get()->system_tray_notifier()->NotifyRefreshIMEMenu(true); | |
222 ASSERT_TRUE(IsVisible()); | |
223 ASSERT_FALSE(IsTrayBackgroundActive()); | |
224 | |
225 ui::GestureEvent tap(0, 0, 0, base::TimeTicks(), | |
226 ui::GestureEventDetails(ui::ET_GESTURE_TAP)); | |
227 GetTray()->PerformAction(tap); | |
228 EXPECT_TRUE(IsTrayBackgroundActive()); | |
229 EXPECT_TRUE(IsBubbleShown()); | |
230 } | |
231 | |
232 // Tests using 'Alt+Shift+K' to open the menu. | |
233 TEST_F(ImeMenuTrayTest, TestAccelerator) { | |
234 WmShell::Get()->system_tray_notifier()->NotifyRefreshIMEMenu(true); | |
235 ASSERT_TRUE(IsVisible()); | |
236 ASSERT_FALSE(IsTrayBackgroundActive()); | |
237 | |
238 WmShell::Get()->accelerator_controller()->PerformActionIfEnabled( | |
239 SHOW_IME_MENU_BUBBLE); | |
240 EXPECT_TRUE(IsTrayBackgroundActive()); | |
241 EXPECT_TRUE(IsBubbleShown()); | |
242 | |
243 ui::GestureEvent tap(0, 0, 0, base::TimeTicks(), | |
244 ui::GestureEventDetails(ui::ET_GESTURE_TAP)); | |
245 GetTray()->PerformAction(tap); | |
246 EXPECT_FALSE(IsTrayBackgroundActive()); | |
247 EXPECT_FALSE(IsBubbleShown()); | |
248 } | |
249 | |
250 TEST_F(ImeMenuTrayTest, ShowEmojiKeyset) { | |
251 WmShell::Get()->system_tray_notifier()->NotifyRefreshIMEMenu(true); | |
252 ASSERT_TRUE(IsVisible()); | |
253 ASSERT_FALSE(IsTrayBackgroundActive()); | |
254 | |
255 ui::GestureEvent tap(0, 0, 0, base::TimeTicks(), | |
256 ui::GestureEventDetails(ui::ET_GESTURE_TAP)); | |
257 GetTray()->PerformAction(tap); | |
258 EXPECT_TRUE(IsTrayBackgroundActive()); | |
259 EXPECT_TRUE(IsBubbleShown()); | |
260 | |
261 AccessibilityDelegate* accessibility_delegate = | |
262 WmShell::Get()->accessibility_delegate(); | |
263 | |
264 accessibility_delegate->SetVirtualKeyboardEnabled(true); | |
265 EXPECT_TRUE(accessibility_delegate->IsVirtualKeyboardEnabled()); | |
266 | |
267 GetTray()->ShowKeyboardWithKeyset("emoji"); | |
268 // The menu should be hidden. | |
269 EXPECT_FALSE(IsBubbleShown()); | |
270 // The virtual keyboard should be enabled. | |
271 EXPECT_TRUE(accessibility_delegate->IsVirtualKeyboardEnabled()); | |
272 | |
273 // Hides the keyboard. | |
274 GetTray()->OnKeyboardHidden(); | |
275 // The keyboard should still be enabled. | |
276 EXPECT_TRUE(accessibility_delegate->IsVirtualKeyboardEnabled()); | |
277 } | |
278 | |
279 TEST_F(ImeMenuTrayTest, ForceToShowEmojiKeyset) { | |
280 AccessibilityDelegate* accessibility_delegate = | |
281 WmShell::Get()->accessibility_delegate(); | |
282 accessibility_delegate->SetVirtualKeyboardEnabled(false); | |
283 ASSERT_FALSE(accessibility_delegate->IsVirtualKeyboardEnabled()); | |
284 | |
285 GetTray()->ShowKeyboardWithKeyset("emoji"); | |
286 // The virtual keyboard should be enabled. | |
287 EXPECT_TRUE(accessibility_delegate->IsVirtualKeyboardEnabled()); | |
288 | |
289 // Hides the keyboard. | |
290 GetTray()->OnKeyboardHidden(); | |
291 // The keyboard should still be disabled. | |
292 EXPECT_FALSE(accessibility_delegate->IsVirtualKeyboardEnabled()); | |
293 } | |
294 | |
295 TEST_F(ImeMenuTrayTest, ShowEmojiHandwritingVoiceButtons) { | |
296 FocusInInputContext(ui::TEXT_INPUT_TYPE_TEXT); | |
297 EXPECT_FALSE(GetTray()->ShouldShowEmojiHandwritingVoiceButtons()); | |
298 | |
299 chromeos::input_method::InputMethodManager* input_method_manager = | |
300 chromeos::input_method::InputMethodManager::Get(); | |
301 EXPECT_FALSE(input_method_manager); | |
302 chromeos::input_method::InputMethodManager::Initialize( | |
303 new chromeos::input_method::MockInputMethodManager); | |
304 input_method_manager = chromeos::input_method::InputMethodManager::Get(); | |
305 EXPECT_TRUE(input_method_manager && | |
306 input_method_manager->IsEmojiHandwritingVoiceOnImeMenuEnabled()); | |
307 EXPECT_TRUE(GetTray()->ShouldShowEmojiHandwritingVoiceButtons()); | |
308 | |
309 FocusInInputContext(ui::TEXT_INPUT_TYPE_PASSWORD); | |
310 EXPECT_FALSE(GetTray()->ShouldShowEmojiHandwritingVoiceButtons()); | |
311 } | |
312 | |
313 } // namespace ash | |
OLD | NEW |