| 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 |