input_method_manager_impl_unittest.cc revision 23730a6e56a168d1879203e4b3819bb36e3d8f1f
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 3// found in the LICENSE file. 4 5#include "chrome/browser/chromeos/input_method/input_method_manager_impl.h" 6 7#include <algorithm> 8 9#include "ash/ime/input_method_menu_item.h" 10#include "ash/ime/input_method_menu_manager.h" 11#include "base/basictypes.h" 12#include "base/bind.h" 13#include "base/bind_helpers.h" 14#include "base/compiler_specific.h" 15#include "base/logging.h" 16#include "base/memory/scoped_ptr.h" 17#include "base/message_loop/message_loop.h" 18#include "chrome/browser/chromeos/input_method/input_method_engine_interface.h" 19#include "chrome/browser/chromeos/input_method/mock_candidate_window_controller.h" 20#include "chrome/browser/chromeos/input_method/mock_input_method_engine.h" 21#include "chromeos/ime/extension_ime_util.h" 22#include "chromeos/ime/fake_input_method_delegate.h" 23#include "chromeos/ime/fake_xkeyboard.h" 24#include "chromeos/ime/mock_component_extension_ime_manager_delegate.h" 25#include "testing/gtest/include/gtest/gtest.h" 26#include "ui/base/accelerators/accelerator.h" 27#include "ui/base/ime/chromeos/mock_ime_engine_handler.h" 28#include "ui/events/keycodes/keyboard_codes.h" 29 30namespace chromeos { 31 32namespace input_method { 33namespace { 34 35const char kNaclMozcUsId[] = 36 "_comp_ime_fpfbhcjppmaeaijcidgiibchfbnhbeljnacl_mozc_us"; 37const char kNaclMozcJpId[] = 38 "_comp_ime_fpfbhcjppmaeaijcidgiibchfbnhbeljnacl_mozc_jp"; 39const char kExt2Engine1Id[] = 40 "_comp_ime_nmblnjkfdkabgdofidlkienfnnbjhnabext2_engine1_engine_id"; 41const char kExt2Engine2Id[] = 42 "_comp_ime_nmblnjkfdkabgdofidlkienfnnbjhnabext2_engine2_engine_id"; 43const char kXkbExtId[] = 44#if defined(OFFICIAL_BUILD) 45 "jkghodnilhceideoidjikpgommlajknk"; 46#else 47 "fgoepimhcoialccpbmpnnblemnepkkao"; 48#endif 49 50// Returns true if |descriptors| contain |target|. 51bool Contain(const InputMethodDescriptors& descriptors, 52 const InputMethodDescriptor& target) { 53 for (size_t i = 0; i < descriptors.size(); ++i) { 54 if (descriptors[i].id() == target.id()) 55 return true; 56 } 57 return false; 58} 59 60std::string XkbId(const std::string& id) { 61 return extension_ime_util::GetInputMethodIDByKeyboardLayout(id); 62} 63 64class InputMethodManagerImplTest : public testing::Test { 65 public: 66 InputMethodManagerImplTest() 67 : delegate_(NULL), 68 candidate_window_controller_(NULL), 69 xkeyboard_(NULL) { 70 } 71 virtual ~InputMethodManagerImplTest() {} 72 73 virtual void SetUp() OVERRIDE { 74 delegate_ = new FakeInputMethodDelegate(); 75 manager_.reset(new InputMethodManagerImpl( 76 scoped_ptr<InputMethodDelegate>(delegate_))); 77 manager_->GetInputMethodUtil()->UpdateHardwareLayoutCache(); 78 candidate_window_controller_ = new MockCandidateWindowController; 79 manager_->SetCandidateWindowControllerForTesting( 80 candidate_window_controller_); 81 xkeyboard_ = new FakeXKeyboard; 82 manager_->SetXKeyboardForTesting(xkeyboard_); 83 mock_engine_handler_.reset(new MockIMEEngineHandler()); 84 IMEBridge::Initialize(); 85 IMEBridge::Get()->SetCurrentEngineHandler(mock_engine_handler_.get()); 86 87 menu_manager_ = ash::ime::InputMethodMenuManager::GetInstance(); 88 89 ime_list_.clear(); 90 91 ComponentExtensionIME ext_xkb; 92 ext_xkb.id = kXkbExtId; 93 ext_xkb.description = "ext_xkb_description"; 94 ext_xkb.path = base::FilePath("ext_xkb_file_path"); 95 96 ComponentExtensionEngine ext_xkb_engine_us; 97 ext_xkb_engine_us.engine_id = "xkb:us::eng"; 98 ext_xkb_engine_us.display_name = "xkb:us::eng"; 99 ext_xkb_engine_us.language_codes.push_back("en-US"); 100 ext_xkb_engine_us.layouts.push_back("us"); 101 ext_xkb.engines.push_back(ext_xkb_engine_us); 102 103 ComponentExtensionEngine ext_xkb_engine_intl; 104 ext_xkb_engine_intl.engine_id = "xkb:us:intl:eng"; 105 ext_xkb_engine_intl.display_name = "xkb:us:intl:eng"; 106 ext_xkb_engine_intl.language_codes.push_back("en-US"); 107 ext_xkb_engine_intl.layouts.push_back("us(intl)"); 108 ext_xkb.engines.push_back(ext_xkb_engine_intl); 109 110 ComponentExtensionEngine ext_xkb_engine_altgr_intl; 111 ext_xkb_engine_altgr_intl.engine_id = "xkb:us:altgr-intl:eng"; 112 ext_xkb_engine_altgr_intl.display_name = "xkb:us:altgr-intl:eng"; 113 ext_xkb_engine_altgr_intl.language_codes.push_back("en-US"); 114 ext_xkb_engine_altgr_intl.layouts.push_back("us(altgr-intl)"); 115 ext_xkb.engines.push_back(ext_xkb_engine_altgr_intl); 116 117 ComponentExtensionEngine ext_xkb_engine_dvorak; 118 ext_xkb_engine_dvorak.engine_id = "xkb:us:dvorak:eng"; 119 ext_xkb_engine_dvorak.display_name = "xkb:us:dvorak:eng"; 120 ext_xkb_engine_dvorak.language_codes.push_back("en-US"); 121 ext_xkb_engine_dvorak.layouts.push_back("us(dvorak)"); 122 ext_xkb.engines.push_back(ext_xkb_engine_dvorak); 123 124 ComponentExtensionEngine ext_xkb_engine_colemak; 125 ext_xkb_engine_colemak.engine_id = "xkb:us:colemak:eng"; 126 ext_xkb_engine_colemak.display_name = "xkb:us:colemak:eng"; 127 ext_xkb_engine_colemak.language_codes.push_back("en-US"); 128 ext_xkb_engine_colemak.layouts.push_back("us(colemak)"); 129 ext_xkb.engines.push_back(ext_xkb_engine_colemak); 130 131 ComponentExtensionEngine ext_xkb_engine_fr; 132 ext_xkb_engine_fr.engine_id = "xkb:fr::fra"; 133 ext_xkb_engine_fr.display_name = "xkb:fr::fra"; 134 ext_xkb_engine_fr.language_codes.push_back("fr"); 135 ext_xkb_engine_fr.layouts.push_back("fr"); 136 ext_xkb.engines.push_back(ext_xkb_engine_fr); 137 138 ComponentExtensionEngine ext_xkb_engine_se; 139 ext_xkb_engine_se.engine_id = "xkb:se::swe"; 140 ext_xkb_engine_se.display_name = "xkb:se::swe"; 141 ext_xkb_engine_se.language_codes.push_back("sv"); 142 ext_xkb_engine_se.layouts.push_back("se"); 143 ext_xkb.engines.push_back(ext_xkb_engine_se); 144 145 ComponentExtensionEngine ext_xkb_engine_jp; 146 ext_xkb_engine_jp.engine_id = "xkb:jp::jpn"; 147 ext_xkb_engine_jp.display_name = "xkb:jp::jpn"; 148 ext_xkb_engine_jp.language_codes.push_back("ja"); 149 ext_xkb_engine_jp.layouts.push_back("jp"); 150 ext_xkb.engines.push_back(ext_xkb_engine_jp); 151 152 ComponentExtensionEngine ext_xkb_engine_ru; 153 ext_xkb_engine_ru.engine_id = "xkb:ru::rus"; 154 ext_xkb_engine_ru.display_name = "xkb:ru::rus"; 155 ext_xkb_engine_ru.language_codes.push_back("ru"); 156 ext_xkb_engine_ru.layouts.push_back("ru"); 157 ext_xkb.engines.push_back(ext_xkb_engine_ru); 158 159 ComponentExtensionEngine ext_xkb_engine_hu; 160 ext_xkb_engine_hu.engine_id = "xkb:hu::hun"; 161 ext_xkb_engine_hu.display_name = "xkb:hu::hun"; 162 ext_xkb_engine_hu.language_codes.push_back("hu"); 163 ext_xkb_engine_hu.layouts.push_back("hu"); 164 ext_xkb.engines.push_back(ext_xkb_engine_hu); 165 166 ime_list_.push_back(ext_xkb); 167 168 ComponentExtensionIME ext1; 169 ext1.id = "fpfbhcjppmaeaijcidgiibchfbnhbelj"; 170 ext1.description = "ext1_description"; 171 ext1.path = base::FilePath("ext1_file_path"); 172 173 ComponentExtensionEngine ext1_engine1; 174 ext1_engine1.engine_id = "nacl_mozc_us"; 175 ext1_engine1.display_name = "ext1_engine_1_display_name"; 176 ext1_engine1.language_codes.push_back("ja"); 177 ext1_engine1.layouts.push_back("us"); 178 ext1.engines.push_back(ext1_engine1); 179 180 ComponentExtensionEngine ext1_engine2; 181 ext1_engine2.engine_id = "nacl_mozc_jp"; 182 ext1_engine2.display_name = "ext1_engine_1_display_name"; 183 ext1_engine2.language_codes.push_back("ja"); 184 ext1_engine2.layouts.push_back("jp"); 185 ext1.engines.push_back(ext1_engine2); 186 187 ime_list_.push_back(ext1); 188 189 ComponentExtensionIME ext2; 190 ext2.id = "nmblnjkfdkabgdofidlkienfnnbjhnab"; 191 ext2.description = "ext2_description"; 192 ext2.path = base::FilePath("ext2_file_path"); 193 194 ComponentExtensionEngine ext2_engine1; 195 ext2_engine1.engine_id = "ext2_engine1_engine_id"; 196 ext2_engine1.display_name = "ext2_engine_1_display_name"; 197 ext2_engine1.language_codes.push_back("en"); 198 ext2_engine1.layouts.push_back("us"); 199 ext2.engines.push_back(ext2_engine1); 200 201 ComponentExtensionEngine ext2_engine2; 202 ext2_engine2.engine_id = "ext2_engine2_engine_id"; 203 ext2_engine2.display_name = "ext2_engine_2_display_name"; 204 ext2_engine2.language_codes.push_back("en"); 205 ext2_engine2.layouts.push_back("us(dvorak)"); 206 ext2.engines.push_back(ext2_engine2); 207 208 ime_list_.push_back(ext2); 209 } 210 211 virtual void TearDown() OVERRIDE { 212 delegate_ = NULL; 213 candidate_window_controller_ = NULL; 214 xkeyboard_ = NULL; 215 manager_.reset(); 216 217 IMEBridge::Get()->SetCurrentEngineHandler(NULL); 218 IMEBridge::Shutdown(); 219 } 220 221 protected: 222 // Helper function to initialize component extension stuff for testing. 223 void InitComponentExtension() { 224 mock_delegate_ = new MockComponentExtIMEManagerDelegate(); 225 mock_delegate_->set_ime_list(ime_list_); 226 scoped_ptr<ComponentExtensionIMEManagerDelegate> delegate(mock_delegate_); 227 // Note, for production, these SetEngineHandler are called when 228 // IMEEngineHandlerInterface is initialized via 229 // InitializeComponentextension. 230 IMEBridge::Get()->SetEngineHandler(kNaclMozcUsId, 231 mock_engine_handler_.get()); 232 IMEBridge::Get()->SetEngineHandler(kNaclMozcJpId, 233 mock_engine_handler_.get()); 234 IMEBridge::Get()->SetEngineHandler(kExt2Engine1Id, 235 mock_engine_handler_.get()); 236 IMEBridge::Get()->SetEngineHandler(kExt2Engine2Id, 237 mock_engine_handler_.get()); 238 manager_->InitializeComponentExtensionForTesting(delegate.Pass()); 239 } 240 241 scoped_ptr<InputMethodManagerImpl> manager_; 242 FakeInputMethodDelegate* delegate_; 243 MockCandidateWindowController* candidate_window_controller_; 244 scoped_ptr<MockIMEEngineHandler> mock_engine_handler_; 245 FakeXKeyboard* xkeyboard_; 246 base::MessageLoop message_loop_; 247 MockComponentExtIMEManagerDelegate* mock_delegate_; 248 std::vector<ComponentExtensionIME> ime_list_; 249 ash::ime::InputMethodMenuManager* menu_manager_; 250 251 private: 252 DISALLOW_COPY_AND_ASSIGN(InputMethodManagerImplTest); 253}; 254 255class TestObserver : public InputMethodManager::Observer, 256 public ash::ime::InputMethodMenuManager::Observer{ 257 public: 258 TestObserver() 259 : input_method_changed_count_(0), 260 input_method_menu_item_changed_count_(0), 261 last_show_message_(false) { 262 } 263 virtual ~TestObserver() {} 264 265 virtual void InputMethodChanged(InputMethodManager* manager, 266 bool show_message) OVERRIDE { 267 ++input_method_changed_count_; 268 last_show_message_ = show_message; 269 } 270 virtual void InputMethodMenuItemChanged( 271 ash::ime::InputMethodMenuManager* manager) OVERRIDE { 272 ++input_method_menu_item_changed_count_; 273 } 274 275 int input_method_changed_count_; 276 int input_method_menu_item_changed_count_; 277 bool last_show_message_; 278 279 private: 280 DISALLOW_COPY_AND_ASSIGN(TestObserver); 281}; 282 283class TestCandidateWindowObserver 284 : public InputMethodManager::CandidateWindowObserver { 285 public: 286 TestCandidateWindowObserver() 287 : candidate_window_opened_count_(0), 288 candidate_window_closed_count_(0) { 289 } 290 virtual ~TestCandidateWindowObserver() {} 291 292 virtual void CandidateWindowOpened(InputMethodManager* manager) OVERRIDE { 293 ++candidate_window_opened_count_; 294 } 295 virtual void CandidateWindowClosed(InputMethodManager* manager) OVERRIDE { 296 ++candidate_window_closed_count_; 297 } 298 299 int candidate_window_opened_count_; 300 int candidate_window_closed_count_; 301 302 private: 303 DISALLOW_COPY_AND_ASSIGN(TestCandidateWindowObserver); 304}; 305} // namespace 306 307TEST_F(InputMethodManagerImplTest, TestGetXKeyboard) { 308 EXPECT_TRUE(manager_->GetXKeyboard()); 309 EXPECT_EQ(xkeyboard_, manager_->GetXKeyboard()); 310} 311 312TEST_F(InputMethodManagerImplTest, TestCandidateWindowObserver) { 313 TestCandidateWindowObserver observer; 314 candidate_window_controller_->NotifyCandidateWindowOpened(); // nop 315 candidate_window_controller_->NotifyCandidateWindowClosed(); // nop 316 manager_->AddCandidateWindowObserver(&observer); 317 candidate_window_controller_->NotifyCandidateWindowOpened(); 318 EXPECT_EQ(1, observer.candidate_window_opened_count_); 319 candidate_window_controller_->NotifyCandidateWindowClosed(); 320 EXPECT_EQ(1, observer.candidate_window_closed_count_); 321 candidate_window_controller_->NotifyCandidateWindowOpened(); 322 EXPECT_EQ(2, observer.candidate_window_opened_count_); 323 candidate_window_controller_->NotifyCandidateWindowClosed(); 324 EXPECT_EQ(2, observer.candidate_window_closed_count_); 325 manager_->RemoveCandidateWindowObserver(&observer); 326} 327 328TEST_F(InputMethodManagerImplTest, TestObserver) { 329 // For http://crbug.com/19655#c11 - (3). browser_state_monitor_unittest.cc is 330 // also for the scenario. 331 std::vector<std::string> keyboard_layouts; 332 keyboard_layouts.push_back("xkb:us::eng"); 333 334 TestObserver observer; 335 InitComponentExtension(); 336 manager_->AddObserver(&observer); 337 menu_manager_->AddObserver(&observer); 338 EXPECT_EQ(0, observer.input_method_changed_count_); 339 manager_->EnableLoginLayouts("en-US", keyboard_layouts); 340 EXPECT_EQ(5U, manager_->GetActiveInputMethods()->size()); 341 EXPECT_EQ(1, observer.input_method_changed_count_); 342 EXPECT_EQ(1, observer.input_method_menu_item_changed_count_); 343 manager_->ChangeInputMethod(XkbId("xkb:us:dvorak:eng")); 344 EXPECT_FALSE(observer.last_show_message_); 345 EXPECT_EQ(2, observer.input_method_changed_count_); 346 EXPECT_EQ(2, observer.input_method_menu_item_changed_count_); 347 manager_->ChangeInputMethod(XkbId("xkb:us:dvorak:eng")); 348 EXPECT_FALSE(observer.last_show_message_); 349 350 // The observer is always notified even when the same input method ID is 351 // passed to ChangeInputMethod() more than twice. 352 // TODO(komatsu): Revisit if this is neccessary. 353 EXPECT_EQ(3, observer.input_method_changed_count_); 354 355 // If the same input method ID is passed, PropertyChanged() is not 356 // notified. 357 EXPECT_EQ(2, observer.input_method_menu_item_changed_count_); 358 359 manager_->RemoveObserver(&observer); 360 menu_manager_->RemoveObserver(&observer); 361} 362 363TEST_F(InputMethodManagerImplTest, TestGetSupportedInputMethods) { 364 InitComponentExtension(); 365 InputMethodDescriptors methods; 366 if (extension_ime_util::UseWrappedExtensionKeyboardLayouts()) { 367 methods = manager_->GetComponentExtensionIMEManager() 368 ->GetXkbIMEAsInputMethodDescriptor(); 369 } else { 370 methods = *(manager_->GetSupportedInputMethods()); 371 } 372 // Try to find random 4-5 layuts and IMEs to make sure the returned list is 373 // correct. 374 const InputMethodDescriptor* id_to_find = 375 manager_->GetInputMethodUtil()->GetInputMethodDescriptorFromId( 376 kNaclMozcUsId); 377 id_to_find = manager_->GetInputMethodUtil()->GetInputMethodDescriptorFromId( 378 XkbId("xkb:us::eng")); 379 EXPECT_TRUE(Contain(methods, *id_to_find)); 380 id_to_find = manager_->GetInputMethodUtil()->GetInputMethodDescriptorFromId( 381 XkbId("xkb:us:dvorak:eng")); 382 EXPECT_TRUE(Contain(methods, *id_to_find)); 383 id_to_find = manager_->GetInputMethodUtil()->GetInputMethodDescriptorFromId( 384 XkbId("xkb:fr::fra")); 385 EXPECT_TRUE(Contain(methods, *id_to_find)); 386} 387 388TEST_F(InputMethodManagerImplTest, TestEnableLayouts) { 389 // Currently 5 keyboard layouts are supported for en-US, and 1 for ja. See 390 // ibus_input_method.txt. 391 std::vector<std::string> keyboard_layouts; 392 393 InitComponentExtension(); 394 manager_->EnableLoginLayouts("en-US", keyboard_layouts); 395 EXPECT_EQ(5U, manager_->GetNumActiveInputMethods()); 396 397 // For http://crbug.com/19655#c11 - (5) 398 // The hardware keyboard layout "xkb:us::eng" is always active, hence 2U. 399 manager_->EnableLoginLayouts("ja", keyboard_layouts); // Japanese 400 EXPECT_EQ(2U, manager_->GetNumActiveInputMethods()); 401} 402 403TEST_F(InputMethodManagerImplTest, TestEnableLayoutsAndCurrentInputMethod) { 404 // For http://crbug.com/329061 405 std::vector<std::string> keyboard_layouts; 406 keyboard_layouts.push_back(XkbId("xkb:se::swe")); 407 408 InitComponentExtension(); 409 manager_->EnableLoginLayouts("en-US", keyboard_layouts); 410 const std::string im_id = manager_->GetCurrentInputMethod().id(); 411 EXPECT_EQ(XkbId("xkb:se::swe"), im_id); 412} 413 414TEST_F(InputMethodManagerImplTest, TestEnableLayoutsNonUsHardwareKeyboard) { 415 InitComponentExtension(); 416 // The physical layout is French. 417 manager_->GetInputMethodUtil()->SetHardwareKeyboardLayoutForTesting( 418 "xkb:fr::fra"); 419 manager_->EnableLoginLayouts( 420 "en-US", 421 manager_->GetInputMethodUtil()->GetHardwareLoginInputMethodIds()); 422 EXPECT_EQ(6U, manager_->GetNumActiveInputMethods()); // 5 + French 423 // The physical layout is Japanese. 424 manager_->GetInputMethodUtil()->SetHardwareKeyboardLayoutForTesting( 425 "xkb:jp::jpn"); 426 manager_->EnableLoginLayouts( 427 "ja", 428 manager_->GetInputMethodUtil()->GetHardwareLoginInputMethodIds()); 429 // "xkb:us::eng" is not needed, hence 1. 430 EXPECT_EQ(1U, manager_->GetNumActiveInputMethods()); 431 432 // The physical layout is Russian. 433 manager_->GetInputMethodUtil()->SetHardwareKeyboardLayoutForTesting( 434 "xkb:ru::rus"); 435 manager_->EnableLoginLayouts( 436 "ru", 437 manager_->GetInputMethodUtil()->GetHardwareLoginInputMethodIds()); 438 // "xkb:us::eng" only. 439 EXPECT_EQ(1U, manager_->GetNumActiveInputMethods()); 440 EXPECT_EQ(XkbId("xkb:us::eng"), 441 manager_->GetActiveInputMethodIds().front()); 442} 443 444TEST_F(InputMethodManagerImplTest, TestEnableMultipleHardwareKeyboardLayout) { 445 InitComponentExtension(); 446 // The physical layouts are French and Hungarian. 447 manager_->GetInputMethodUtil()->SetHardwareKeyboardLayoutForTesting( 448 "xkb:fr::fra,xkb:hu::hun"); 449 manager_->EnableLoginLayouts( 450 "en-US", 451 manager_->GetInputMethodUtil()->GetHardwareLoginInputMethodIds()); 452 // 5 + French + Hungarian 453 EXPECT_EQ(7U, manager_->GetNumActiveInputMethods()); 454} 455 456TEST_F(InputMethodManagerImplTest, 457 TestEnableMultipleHardwareKeyboardLayout_NoLoginKeyboard) { 458 InitComponentExtension(); 459 // The physical layouts are English (US) and Russian. 460 manager_->GetInputMethodUtil()->SetHardwareKeyboardLayoutForTesting( 461 "xkb:us::eng,xkb:ru::rus"); 462 manager_->EnableLoginLayouts( 463 "ru", 464 manager_->GetInputMethodUtil()->GetHardwareLoginInputMethodIds()); 465 // xkb:us:eng 466 EXPECT_EQ(1U, manager_->GetNumActiveInputMethods()); 467} 468 469TEST_F(InputMethodManagerImplTest, TestActiveInputMethods) { 470 InitComponentExtension(); 471 std::vector<std::string> keyboard_layouts; 472 manager_->EnableLoginLayouts("ja", keyboard_layouts); // Japanese 473 EXPECT_EQ(2U, manager_->GetNumActiveInputMethods()); 474 scoped_ptr<InputMethodDescriptors> methods( 475 manager_->GetActiveInputMethods()); 476 ASSERT_TRUE(methods.get()); 477 EXPECT_EQ(2U, methods->size()); 478 const InputMethodDescriptor* id_to_find = 479 manager_->GetInputMethodUtil()->GetInputMethodDescriptorFromId( 480 XkbId("xkb:us::eng")); 481 EXPECT_TRUE(id_to_find && Contain(*methods.get(), *id_to_find)); 482 id_to_find = manager_->GetInputMethodUtil()->GetInputMethodDescriptorFromId( 483 XkbId("xkb:jp::jpn")); 484 EXPECT_TRUE(id_to_find && Contain(*methods.get(), *id_to_find)); 485} 486 487TEST_F(InputMethodManagerImplTest, TestEnableTwoLayouts) { 488 // For http://crbug.com/19655#c11 - (8), step 6. 489 TestObserver observer; 490 manager_->AddObserver(&observer); 491 InitComponentExtension(); 492 manager_->SetState(InputMethodManager::STATE_BROWSER_SCREEN); 493 std::vector<std::string> ids; 494 ids.push_back(XkbId("xkb:us:dvorak:eng")); 495 ids.push_back(XkbId("xkb:us:colemak:eng")); 496 EXPECT_TRUE(manager_->ReplaceEnabledInputMethods(ids)); 497 EXPECT_EQ(2U, manager_->GetNumActiveInputMethods()); 498 // Since all the IDs added avobe are keyboard layouts, Start() should not be 499 // called. 500 EXPECT_EQ(1, observer.input_method_changed_count_); 501 EXPECT_EQ(XkbId(ids[0]), manager_->GetCurrentInputMethod().id()); 502 EXPECT_EQ("us(dvorak)", xkeyboard_->last_layout_); 503 // Disable Dvorak. 504 ids.erase(ids.begin()); 505 EXPECT_TRUE(manager_->ReplaceEnabledInputMethods(ids)); 506 EXPECT_EQ(1U, manager_->GetNumActiveInputMethods()); 507 EXPECT_EQ(2, observer.input_method_changed_count_); 508 EXPECT_EQ(XkbId(ids[0]), // colemak 509 manager_->GetCurrentInputMethod().id()); 510 EXPECT_EQ("us(colemak)", xkeyboard_->last_layout_); 511 manager_->RemoveObserver(&observer); 512} 513 514TEST_F(InputMethodManagerImplTest, TestEnableThreeLayouts) { 515 // For http://crbug.com/19655#c11 - (9). 516 TestObserver observer; 517 manager_->AddObserver(&observer); 518 InitComponentExtension(); 519 manager_->SetState(InputMethodManager::STATE_BROWSER_SCREEN); 520 std::vector<std::string> ids; 521 ids.push_back(XkbId("xkb:us::eng")); 522 ids.push_back(XkbId("xkb:us:dvorak:eng")); 523 ids.push_back(XkbId("xkb:us:colemak:eng")); 524 EXPECT_TRUE(manager_->ReplaceEnabledInputMethods(ids)); 525 EXPECT_EQ(3U, manager_->GetNumActiveInputMethods()); 526 EXPECT_EQ(1, observer.input_method_changed_count_); 527 EXPECT_EQ(XkbId(ids[0]), manager_->GetCurrentInputMethod().id()); 528 EXPECT_EQ("us", xkeyboard_->last_layout_); 529 // Switch to Dvorak. 530 manager_->SwitchToNextInputMethod(); 531 EXPECT_EQ(2, observer.input_method_changed_count_); 532 EXPECT_EQ(XkbId(ids[1]), manager_->GetCurrentInputMethod().id()); 533 EXPECT_EQ("us(dvorak)", xkeyboard_->last_layout_); 534 // Disable Dvorak. 535 ids.erase(ids.begin() + 1); 536 EXPECT_TRUE(manager_->ReplaceEnabledInputMethods(ids)); 537 EXPECT_EQ(2U, manager_->GetNumActiveInputMethods()); 538 EXPECT_EQ(3, observer.input_method_changed_count_); 539 EXPECT_EQ(XkbId(ids[0]), // US Qwerty 540 manager_->GetCurrentInputMethod().id()); 541 EXPECT_EQ("us", xkeyboard_->last_layout_); 542 manager_->RemoveObserver(&observer); 543} 544 545TEST_F(InputMethodManagerImplTest, TestEnableLayoutAndIme) { 546 // For http://crbug.com/19655#c11 - (10). 547 TestObserver observer; 548 manager_->AddObserver(&observer); 549 InitComponentExtension(); 550 manager_->SetState(InputMethodManager::STATE_BROWSER_SCREEN); 551 std::vector<std::string> ids; 552 ids.push_back(XkbId("xkb:us:dvorak:eng")); 553 ids.push_back(kNaclMozcUsId); 554 EXPECT_TRUE(manager_->ReplaceEnabledInputMethods(ids)); 555 EXPECT_EQ(1, observer.input_method_changed_count_); 556 EXPECT_EQ(XkbId(ids[0]), manager_->GetCurrentInputMethod().id()); 557 EXPECT_EQ("us(dvorak)", xkeyboard_->last_layout_); 558 // Switch to Mozc 559 manager_->SwitchToNextInputMethod(); 560 EXPECT_EQ(2, observer.input_method_changed_count_); 561 EXPECT_EQ(XkbId(ids[1]), manager_->GetCurrentInputMethod().id()); 562 EXPECT_EQ("us", xkeyboard_->last_layout_); 563 // Disable Mozc. 564 ids.erase(ids.begin() + 1); 565 EXPECT_TRUE(manager_->ReplaceEnabledInputMethods(ids)); 566 EXPECT_EQ(1U, manager_->GetNumActiveInputMethods()); 567 EXPECT_EQ(XkbId(ids[0]), manager_->GetCurrentInputMethod().id()); 568 EXPECT_EQ("us(dvorak)", xkeyboard_->last_layout_); 569} 570 571TEST_F(InputMethodManagerImplTest, TestEnableLayoutAndIme2) { 572 // For http://crbug.com/19655#c11 - (11). 573 TestObserver observer; 574 manager_->AddObserver(&observer); 575 InitComponentExtension(); 576 manager_->SetState(InputMethodManager::STATE_BROWSER_SCREEN); 577 std::vector<std::string> ids; 578 ids.push_back(XkbId("xkb:us:dvorak:eng")); 579 ids.push_back(kNaclMozcUsId); 580 EXPECT_TRUE(manager_->ReplaceEnabledInputMethods(ids)); 581 EXPECT_EQ(1, observer.input_method_changed_count_); 582 EXPECT_EQ(XkbId(ids[0]), manager_->GetCurrentInputMethod().id()); 583 EXPECT_EQ("us(dvorak)", xkeyboard_->last_layout_); 584 585 // Disable Dvorak. 586 ids.erase(ids.begin()); 587 EXPECT_TRUE(manager_->ReplaceEnabledInputMethods(ids)); 588 EXPECT_EQ(1U, manager_->GetNumActiveInputMethods()); 589 EXPECT_EQ(XkbId(ids[0]), // Mozc 590 manager_->GetCurrentInputMethod().id()); 591 EXPECT_EQ("us", xkeyboard_->last_layout_); 592 manager_->RemoveObserver(&observer); 593} 594 595TEST_F(InputMethodManagerImplTest, TestEnableImes) { 596 TestObserver observer; 597 manager_->AddObserver(&observer); 598 InitComponentExtension(); 599 manager_->SetState(InputMethodManager::STATE_BROWSER_SCREEN); 600 std::vector<std::string> ids; 601 ids.push_back(kExt2Engine1Id); 602 ids.push_back("mozc-dv"); 603 EXPECT_TRUE(manager_->ReplaceEnabledInputMethods(ids)); 604 EXPECT_EQ(1, observer.input_method_changed_count_); 605 EXPECT_EQ(XkbId(ids[0]), manager_->GetCurrentInputMethod().id()); 606 EXPECT_EQ("us", xkeyboard_->last_layout_); 607 manager_->RemoveObserver(&observer); 608} 609 610TEST_F(InputMethodManagerImplTest, TestEnableUnknownIds) { 611 TestObserver observer; 612 manager_->AddObserver(&observer); 613 manager_->SetState(InputMethodManager::STATE_BROWSER_SCREEN); 614 std::vector<std::string> ids; 615 ids.push_back("xkb:tl::tlh"); // Klingon, which is not supported. 616 ids.push_back("unknown-super-cool-ime"); 617 EXPECT_FALSE(manager_->ReplaceEnabledInputMethods(ids)); 618 619 // TODO(yusukes): Should we fall back to the hardware keyboard layout in this 620 // case? 621 EXPECT_EQ(0, observer.input_method_changed_count_); 622 623 manager_->RemoveObserver(&observer); 624} 625 626TEST_F(InputMethodManagerImplTest, TestEnableLayoutsThenLock) { 627 // For http://crbug.com/19655#c11 - (14). 628 TestObserver observer; 629 manager_->AddObserver(&observer); 630 InitComponentExtension(); 631 manager_->SetState(InputMethodManager::STATE_BROWSER_SCREEN); 632 std::vector<std::string> ids; 633 ids.push_back(XkbId("xkb:us::eng")); 634 ids.push_back(XkbId("xkb:us:dvorak:eng")); 635 EXPECT_TRUE(manager_->ReplaceEnabledInputMethods(ids)); 636 EXPECT_EQ(2U, manager_->GetNumActiveInputMethods()); 637 EXPECT_EQ(1, observer.input_method_changed_count_); 638 EXPECT_EQ(XkbId(ids[0]), manager_->GetCurrentInputMethod().id()); 639 EXPECT_EQ("us", xkeyboard_->last_layout_); 640 641 // Switch to Dvorak. 642 manager_->SwitchToNextInputMethod(); 643 EXPECT_EQ(2, observer.input_method_changed_count_); 644 EXPECT_EQ(XkbId(ids[1]), manager_->GetCurrentInputMethod().id()); 645 EXPECT_EQ("us(dvorak)", xkeyboard_->last_layout_); 646 647 // Lock screen 648 manager_->SetState(InputMethodManager::STATE_LOCK_SCREEN); 649 EXPECT_EQ(2U, manager_->GetNumActiveInputMethods()); 650 EXPECT_EQ(XkbId(ids[1]), // still Dvorak 651 manager_->GetCurrentInputMethod().id()); 652 EXPECT_EQ("us(dvorak)", xkeyboard_->last_layout_); 653 // Switch back to Qwerty. 654 manager_->SwitchToNextInputMethod(); 655 EXPECT_EQ(XkbId(ids[0]), manager_->GetCurrentInputMethod().id()); 656 EXPECT_EQ("us", xkeyboard_->last_layout_); 657 658 // Unlock screen. The original state, Dvorak, is restored. 659 manager_->SetState(InputMethodManager::STATE_BROWSER_SCREEN); 660 EXPECT_EQ(2U, manager_->GetNumActiveInputMethods()); 661 EXPECT_EQ(XkbId(ids[1]), manager_->GetCurrentInputMethod().id()); 662 EXPECT_EQ("us(dvorak)", xkeyboard_->last_layout_); 663 664 manager_->RemoveObserver(&observer); 665} 666 667TEST_F(InputMethodManagerImplTest, SwitchInputMethodTest) { 668 // For http://crbug.com/19655#c11 - (15). 669 TestObserver observer; 670 manager_->AddObserver(&observer); 671 InitComponentExtension(); 672 manager_->SetState(InputMethodManager::STATE_BROWSER_SCREEN); 673 std::vector<std::string> ids; 674 ids.push_back(XkbId("xkb:us:dvorak:eng")); 675 ids.push_back(kExt2Engine2Id); 676 ids.push_back(kExt2Engine1Id); 677 EXPECT_TRUE(manager_->ReplaceEnabledInputMethods(ids)); 678 EXPECT_EQ(3U, manager_->GetNumActiveInputMethods()); 679 EXPECT_EQ(1, observer.input_method_changed_count_); 680 EXPECT_EQ(XkbId(ids[0]), manager_->GetCurrentInputMethod().id()); 681 EXPECT_EQ("us(dvorak)", xkeyboard_->last_layout_); 682 683 // Switch to Mozc. 684 manager_->SwitchToNextInputMethod(); 685 EXPECT_EQ(2, observer.input_method_changed_count_); 686 EXPECT_EQ(XkbId(ids[1]), manager_->GetCurrentInputMethod().id()); 687 EXPECT_EQ("us(dvorak)", xkeyboard_->last_layout_); 688 689 // Lock screen 690 manager_->SetState(InputMethodManager::STATE_LOCK_SCREEN); 691 EXPECT_EQ(2U, manager_->GetNumActiveInputMethods()); // Qwerty+Dvorak. 692 EXPECT_EQ(XkbId("xkb:us:dvorak:eng"), 693 manager_->GetCurrentInputMethod().id()); 694 EXPECT_EQ("us(dvorak)", xkeyboard_->last_layout_); 695 manager_->SwitchToNextInputMethod(); 696 EXPECT_EQ(XkbId("xkb:us::eng"), // The hardware keyboard layout. 697 manager_->GetCurrentInputMethod().id()); 698 EXPECT_EQ("us", xkeyboard_->last_layout_); 699 700 // Unlock screen. The original state, pinyin-dv, is restored. 701 manager_->SetState(InputMethodManager::STATE_BROWSER_SCREEN); 702 EXPECT_EQ(3U, manager_->GetNumActiveInputMethods()); // Dvorak and 2 IMEs. 703 EXPECT_EQ(XkbId(ids[1]), manager_->GetCurrentInputMethod().id()); 704 EXPECT_EQ("us(dvorak)", xkeyboard_->last_layout_); 705 706 manager_->RemoveObserver(&observer); 707} 708 709TEST_F(InputMethodManagerImplTest, TestXkbSetting) { 710 // For http://crbug.com/19655#c11 - (8), step 7-11. 711 InitComponentExtension(); 712 manager_->SetState(InputMethodManager::STATE_BROWSER_SCREEN); 713 std::vector<std::string> ids; 714 ids.push_back(XkbId("xkb:us:dvorak:eng")); 715 ids.push_back(XkbId("xkb:us:colemak:eng")); 716 ids.push_back(kNaclMozcJpId); 717 ids.push_back(kNaclMozcUsId); 718 EXPECT_TRUE(manager_->ReplaceEnabledInputMethods(ids)); 719 EXPECT_EQ(4U, manager_->GetNumActiveInputMethods()); 720 EXPECT_EQ(1, xkeyboard_->set_current_keyboard_layout_by_name_count_); 721 // See input_methods.txt for an expected XKB layout name. 722 EXPECT_EQ("us(dvorak)", xkeyboard_->last_layout_); 723 manager_->SwitchToNextInputMethod(); 724 EXPECT_EQ(2, xkeyboard_->set_current_keyboard_layout_by_name_count_); 725 EXPECT_EQ("us(colemak)", xkeyboard_->last_layout_); 726 manager_->SwitchToNextInputMethod(); 727 EXPECT_EQ(3, xkeyboard_->set_current_keyboard_layout_by_name_count_); 728 EXPECT_EQ("jp", xkeyboard_->last_layout_); 729 manager_->SwitchToNextInputMethod(); 730 EXPECT_EQ(4, xkeyboard_->set_current_keyboard_layout_by_name_count_); 731 EXPECT_EQ("us", xkeyboard_->last_layout_); 732 manager_->SwitchToNextInputMethod(); 733 EXPECT_EQ(5, xkeyboard_->set_current_keyboard_layout_by_name_count_); 734 EXPECT_EQ("us(dvorak)", xkeyboard_->last_layout_); 735 // Disable Dvorak. 736 ids.erase(ids.begin()); 737 EXPECT_TRUE(manager_->ReplaceEnabledInputMethods(ids)); 738 EXPECT_EQ(3U, manager_->GetNumActiveInputMethods()); 739 EXPECT_EQ(6, xkeyboard_->set_current_keyboard_layout_by_name_count_); 740 EXPECT_EQ("us(colemak)", xkeyboard_->last_layout_); 741} 742 743TEST_F(InputMethodManagerImplTest, TestActivateInputMethodMenuItem) { 744 const std::string kKey = "key"; 745 ash::ime::InputMethodMenuItemList menu_list; 746 menu_list.push_back(ash::ime::InputMethodMenuItem( 747 kKey, "label", false, false)); 748 menu_manager_->SetCurrentInputMethodMenuItemList(menu_list); 749 750 manager_->ActivateInputMethodMenuItem(kKey); 751 EXPECT_EQ(kKey, mock_engine_handler_->last_activated_property()); 752 753 // Key2 is not registered, so activated property should not be changed. 754 manager_->ActivateInputMethodMenuItem("key2"); 755 EXPECT_EQ(kKey, mock_engine_handler_->last_activated_property()); 756} 757 758TEST_F(InputMethodManagerImplTest, TestGetCurrentInputMethodProperties) { 759 InitComponentExtension(); 760 EXPECT_TRUE(menu_manager_->GetCurrentInputMethodMenuItemList().empty()); 761 762 manager_->SetState(InputMethodManager::STATE_BROWSER_SCREEN); 763 std::vector<std::string> ids; 764 ids.push_back(XkbId("xkb:us::eng")); 765 ids.push_back(kNaclMozcUsId); 766 EXPECT_TRUE(manager_->ReplaceEnabledInputMethods(ids)); 767 EXPECT_EQ(2U, manager_->GetNumActiveInputMethods()); 768 EXPECT_TRUE(menu_manager_->GetCurrentInputMethodMenuItemList().empty()); 769 manager_->ChangeInputMethod(kNaclMozcUsId); 770 771 ash::ime::InputMethodMenuItemList current_property_list; 772 current_property_list.push_back(ash::ime::InputMethodMenuItem( 773 "key", "label", false, false)); 774 menu_manager_->SetCurrentInputMethodMenuItemList(current_property_list); 775 776 ASSERT_EQ(1U, menu_manager_->GetCurrentInputMethodMenuItemList().size()); 777 EXPECT_EQ("key", 778 menu_manager_->GetCurrentInputMethodMenuItemList().at(0).key); 779 780 manager_->ChangeInputMethod("xkb:us::eng"); 781 EXPECT_TRUE(menu_manager_->GetCurrentInputMethodMenuItemList().empty()); 782} 783 784TEST_F(InputMethodManagerImplTest, TestGetCurrentInputMethodPropertiesTwoImes) { 785 InitComponentExtension(); 786 EXPECT_TRUE(menu_manager_->GetCurrentInputMethodMenuItemList().empty()); 787 788 manager_->SetState(InputMethodManager::STATE_BROWSER_SCREEN); 789 std::vector<std::string> ids; 790 ids.push_back(kNaclMozcUsId); // Japanese 791 ids.push_back(kExt2Engine1Id); // T-Chinese 792 EXPECT_TRUE(manager_->ReplaceEnabledInputMethods(ids)); 793 EXPECT_EQ(2U, manager_->GetNumActiveInputMethods()); 794 EXPECT_TRUE(menu_manager_->GetCurrentInputMethodMenuItemList().empty()); 795 796 ash::ime::InputMethodMenuItemList current_property_list; 797 current_property_list.push_back(ash::ime::InputMethodMenuItem("key-mozc", 798 "label", 799 false, 800 false)); 801 menu_manager_->SetCurrentInputMethodMenuItemList(current_property_list); 802 803 ASSERT_EQ(1U, menu_manager_->GetCurrentInputMethodMenuItemList().size()); 804 EXPECT_EQ("key-mozc", 805 menu_manager_->GetCurrentInputMethodMenuItemList().at(0).key); 806 807 manager_->ChangeInputMethod(kExt2Engine1Id); 808 // Since the IME is changed, the property for mozc Japanese should be hidden. 809 EXPECT_TRUE(menu_manager_->GetCurrentInputMethodMenuItemList().empty()); 810 811 // Asynchronous property update signal from mozc-chewing. 812 current_property_list.clear(); 813 current_property_list.push_back(ash::ime::InputMethodMenuItem( 814 "key-chewing", "label", false, false)); 815 menu_manager_->SetCurrentInputMethodMenuItemList(current_property_list); 816 ASSERT_EQ(1U, menu_manager_->GetCurrentInputMethodMenuItemList().size()); 817 EXPECT_EQ("key-chewing", 818 menu_manager_->GetCurrentInputMethodMenuItemList().at(0).key); 819} 820 821TEST_F(InputMethodManagerImplTest, TestNextInputMethod) { 822 TestObserver observer; 823 manager_->AddObserver(&observer); 824 InitComponentExtension(); 825 std::vector<std::string> keyboard_layouts; 826 keyboard_layouts.push_back(XkbId("xkb:us::eng")); 827 // For http://crbug.com/19655#c11 - (1) 828 manager_->EnableLoginLayouts("en-US", keyboard_layouts); 829 EXPECT_EQ(5U, manager_->GetNumActiveInputMethods()); 830 EXPECT_EQ(XkbId("xkb:us::eng"), manager_->GetCurrentInputMethod().id()); 831 EXPECT_EQ("us", xkeyboard_->last_layout_); 832 manager_->SwitchToNextInputMethod(); 833 EXPECT_TRUE(observer.last_show_message_); 834 EXPECT_EQ(XkbId("xkb:us:intl:eng"), manager_->GetCurrentInputMethod().id()); 835 EXPECT_EQ("us(intl)", xkeyboard_->last_layout_); 836 manager_->SwitchToNextInputMethod(); 837 EXPECT_TRUE(observer.last_show_message_); 838 EXPECT_EQ(XkbId("xkb:us:altgr-intl:eng"), 839 manager_->GetCurrentInputMethod().id()); 840 EXPECT_EQ("us(altgr-intl)", xkeyboard_->last_layout_); 841 manager_->SwitchToNextInputMethod(); 842 EXPECT_TRUE(observer.last_show_message_); 843 EXPECT_EQ(XkbId("xkb:us:dvorak:eng"), 844 manager_->GetCurrentInputMethod().id()); 845 EXPECT_EQ("us(dvorak)", xkeyboard_->last_layout_); 846 manager_->SwitchToNextInputMethod(); 847 EXPECT_TRUE(observer.last_show_message_); 848 EXPECT_EQ(XkbId("xkb:us:colemak:eng"), 849 manager_->GetCurrentInputMethod().id()); 850 EXPECT_EQ("us(colemak)", xkeyboard_->last_layout_); 851 manager_->SwitchToNextInputMethod(); 852 EXPECT_TRUE(observer.last_show_message_); 853 EXPECT_EQ(XkbId("xkb:us::eng"), manager_->GetCurrentInputMethod().id()); 854 EXPECT_EQ("us", xkeyboard_->last_layout_); 855 856 manager_->RemoveObserver(&observer); 857} 858 859TEST_F(InputMethodManagerImplTest, TestPreviousInputMethod) { 860 TestObserver observer; 861 manager_->AddObserver(&observer); 862 InitComponentExtension(); 863 864 ui::Accelerator keydown_accelerator(ui::VKEY_SPACE, ui::EF_CONTROL_DOWN); 865 keydown_accelerator.set_type(ui::ET_KEY_PRESSED); 866 ui::Accelerator keyup_accelerator(ui::VKEY_SPACE, ui::EF_CONTROL_DOWN); 867 keyup_accelerator.set_type(ui::ET_KEY_RELEASED); 868 869 std::vector<std::string> keyboard_layouts; 870 keyboard_layouts.push_back(XkbId("xkb:us::eng")); 871 manager_->EnableLoginLayouts("en-US", keyboard_layouts); 872 EXPECT_EQ(5U, manager_->GetNumActiveInputMethods()); 873 EXPECT_EQ(XkbId("xkb:us::eng"), manager_->GetCurrentInputMethod().id()); 874 EXPECT_EQ("us", xkeyboard_->last_layout_); 875 EXPECT_TRUE(manager_->SwitchToNextInputMethod()); 876 EXPECT_TRUE(observer.last_show_message_); 877 EXPECT_EQ(XkbId("xkb:us:intl:eng"), 878 manager_->GetCurrentInputMethod().id()); 879 EXPECT_EQ("us(intl)", xkeyboard_->last_layout_); 880 EXPECT_TRUE(manager_->SwitchToPreviousInputMethod(keydown_accelerator)); 881 EXPECT_TRUE(manager_->SwitchToPreviousInputMethod(keyup_accelerator)); 882 EXPECT_TRUE(observer.last_show_message_); 883 EXPECT_EQ(XkbId("xkb:us::eng"), manager_->GetCurrentInputMethod().id()); 884 EXPECT_EQ("us", xkeyboard_->last_layout_); 885 EXPECT_TRUE(manager_->SwitchToPreviousInputMethod(keydown_accelerator)); 886 EXPECT_TRUE(manager_->SwitchToPreviousInputMethod(keyup_accelerator)); 887 EXPECT_TRUE(observer.last_show_message_); 888 EXPECT_EQ(XkbId("xkb:us:intl:eng"), manager_->GetCurrentInputMethod().id()); 889 EXPECT_EQ("us(intl)", xkeyboard_->last_layout_); 890 EXPECT_TRUE(manager_->SwitchToPreviousInputMethod(keydown_accelerator)); 891 EXPECT_TRUE(manager_->SwitchToPreviousInputMethod(keyup_accelerator)); 892 EXPECT_TRUE(observer.last_show_message_); 893 EXPECT_EQ(XkbId("xkb:us::eng"), manager_->GetCurrentInputMethod().id()); 894 EXPECT_EQ("us", xkeyboard_->last_layout_); 895 EXPECT_TRUE(manager_->SwitchToNextInputMethod()); 896 EXPECT_TRUE(observer.last_show_message_); 897 EXPECT_EQ(XkbId("xkb:us:intl:eng"), manager_->GetCurrentInputMethod().id()); 898 EXPECT_EQ("us(intl)", xkeyboard_->last_layout_); 899 EXPECT_TRUE(manager_->SwitchToNextInputMethod()); 900 EXPECT_TRUE(observer.last_show_message_); 901 EXPECT_EQ(XkbId("xkb:us:altgr-intl:eng"), 902 manager_->GetCurrentInputMethod().id()); 903 EXPECT_EQ("us(altgr-intl)", xkeyboard_->last_layout_); 904 EXPECT_TRUE(manager_->SwitchToPreviousInputMethod(keydown_accelerator)); 905 EXPECT_TRUE(manager_->SwitchToPreviousInputMethod(keyup_accelerator)); 906 EXPECT_TRUE(observer.last_show_message_); 907 EXPECT_EQ(XkbId("xkb:us:intl:eng"), manager_->GetCurrentInputMethod().id()); 908 EXPECT_EQ("us(intl)", xkeyboard_->last_layout_); 909 EXPECT_TRUE(manager_->SwitchToPreviousInputMethod(keydown_accelerator)); 910 EXPECT_TRUE(manager_->SwitchToPreviousInputMethod(keyup_accelerator)); 911 EXPECT_TRUE(observer.last_show_message_); 912 EXPECT_EQ(XkbId("xkb:us:altgr-intl:eng"), 913 manager_->GetCurrentInputMethod().id()); 914 EXPECT_EQ("us(altgr-intl)", xkeyboard_->last_layout_); 915 916 manager_->RemoveObserver(&observer); 917} 918 919TEST_F(InputMethodManagerImplTest, 920 TestSwitchToPreviousInputMethodForOneActiveInputMethod) { 921 TestObserver observer; 922 manager_->AddObserver(&observer); 923 InitComponentExtension(); 924 925 ui::Accelerator keydown_accelerator(ui::VKEY_SPACE, ui::EF_CONTROL_DOWN); 926 keydown_accelerator.set_type(ui::ET_KEY_PRESSED); 927 ui::Accelerator keyup_accelerator(ui::VKEY_SPACE, ui::EF_CONTROL_DOWN); 928 keyup_accelerator.set_type(ui::ET_KEY_RELEASED); 929 930 std::vector<std::string> ids; 931 ids.push_back(XkbId("xkb:us:dvorak:eng")); 932 EXPECT_TRUE(manager_->ReplaceEnabledInputMethods(ids)); 933 EXPECT_EQ(1U, manager_->GetNumActiveInputMethods()); 934 935 // Ctrl+Space accelerator should not be consumed if there is only one active 936 // input method. 937 EXPECT_FALSE(manager_->SwitchToPreviousInputMethod(keydown_accelerator)); 938 EXPECT_FALSE(manager_->SwitchToPreviousInputMethod(keyup_accelerator)); 939 940 manager_->RemoveObserver(&observer); 941} 942 943TEST_F(InputMethodManagerImplTest, TestSwitchInputMethodWithUsLayouts) { 944 std::string expect_id = XkbId("xkb:us::eng"); 945 TestObserver observer; 946 manager_->AddObserver(&observer); 947 InitComponentExtension(); 948 std::vector<std::string> keyboard_layouts; 949 keyboard_layouts.push_back(XkbId("xkb:us::eng")); 950 manager_->EnableLoginLayouts("en-US", keyboard_layouts); 951 EXPECT_EQ(5U, manager_->GetNumActiveInputMethods()); 952 EXPECT_EQ(expect_id, manager_->GetCurrentInputMethod().id()); 953 EXPECT_EQ("us", xkeyboard_->last_layout_); 954 955 // Henkan, Muhenkan, ZenkakuHankaku should be ignored when no Japanese IMEs 956 // and keyboards are enabled. 957 EXPECT_FALSE(manager_->SwitchInputMethod( 958 ui::Accelerator(ui::VKEY_CONVERT, ui::EF_NONE))); 959 EXPECT_FALSE(observer.last_show_message_); 960 EXPECT_EQ(expect_id, manager_->GetCurrentInputMethod().id()); 961 EXPECT_EQ("us", xkeyboard_->last_layout_); 962 EXPECT_FALSE(manager_->SwitchInputMethod( 963 ui::Accelerator(ui::VKEY_NONCONVERT, ui::EF_NONE))); 964 EXPECT_EQ(expect_id, manager_->GetCurrentInputMethod().id()); 965 EXPECT_EQ("us", xkeyboard_->last_layout_); 966 EXPECT_FALSE(manager_->SwitchInputMethod( 967 ui::Accelerator(ui::VKEY_DBE_SBCSCHAR, ui::EF_NONE))); 968 EXPECT_EQ(expect_id, manager_->GetCurrentInputMethod().id()); 969 EXPECT_EQ("us", xkeyboard_->last_layout_); 970 EXPECT_FALSE(manager_->SwitchInputMethod( 971 ui::Accelerator(ui::VKEY_DBE_DBCSCHAR, ui::EF_NONE))); 972 EXPECT_EQ(expect_id, manager_->GetCurrentInputMethod().id()); 973 EXPECT_EQ("us", xkeyboard_->last_layout_); 974 975 manager_->RemoveObserver(&observer); 976} 977 978TEST_F(InputMethodManagerImplTest, TestSwitchInputMethodWithJpLayout) { 979 // Enable "xkb:jp::jpn" and press Muhenkan/ZenkakuHankaku. 980 InitComponentExtension(); 981 982 ui::Accelerator keydown_accelerator(ui::VKEY_SPACE, ui::EF_CONTROL_DOWN); 983 keydown_accelerator.set_type(ui::ET_KEY_PRESSED); 984 ui::Accelerator keyup_accelerator(ui::VKEY_SPACE, ui::EF_CONTROL_DOWN); 985 keyup_accelerator.set_type(ui::ET_KEY_RELEASED); 986 987 std::vector<std::string> keyboard_layouts; 988 keyboard_layouts.push_back(XkbId("xkb:us::eng")); 989 manager_->EnableLoginLayouts("ja", keyboard_layouts); 990 EXPECT_EQ(2U, manager_->GetNumActiveInputMethods()); 991 EXPECT_EQ(XkbId("xkb:us::eng"), manager_->GetCurrentInputMethod().id()); 992 EXPECT_EQ("us", xkeyboard_->last_layout_); 993 EXPECT_TRUE(manager_->SwitchInputMethod( 994 ui::Accelerator(ui::VKEY_NONCONVERT, ui::EF_NONE))); 995 EXPECT_EQ(XkbId("xkb:jp::jpn"), manager_->GetCurrentInputMethod().id()); 996 EXPECT_EQ("jp", xkeyboard_->last_layout_); 997 EXPECT_TRUE(manager_->SwitchToPreviousInputMethod(keydown_accelerator)); 998 EXPECT_TRUE(manager_->SwitchToPreviousInputMethod(keyup_accelerator)); 999 EXPECT_EQ(XkbId("xkb:us::eng"), manager_->GetCurrentInputMethod().id()); 1000 EXPECT_EQ("us", xkeyboard_->last_layout_); 1001 EXPECT_TRUE(manager_->SwitchInputMethod( 1002 ui::Accelerator(ui::VKEY_DBE_SBCSCHAR, ui::EF_NONE))); 1003 EXPECT_EQ(XkbId("xkb:jp::jpn"), manager_->GetCurrentInputMethod().id()); 1004 EXPECT_EQ("jp", xkeyboard_->last_layout_); 1005 EXPECT_TRUE(manager_->SwitchToPreviousInputMethod(keydown_accelerator)); 1006 EXPECT_TRUE(manager_->SwitchToPreviousInputMethod(keyup_accelerator)); 1007 EXPECT_EQ(XkbId("xkb:us::eng"), manager_->GetCurrentInputMethod().id()); 1008 EXPECT_EQ("us", xkeyboard_->last_layout_); 1009 EXPECT_TRUE(manager_->SwitchInputMethod( 1010 ui::Accelerator(ui::VKEY_DBE_DBCSCHAR, ui::EF_NONE))); 1011 EXPECT_EQ(XkbId("xkb:jp::jpn"), manager_->GetCurrentInputMethod().id()); 1012 EXPECT_EQ("jp", xkeyboard_->last_layout_); 1013} 1014 1015TEST_F(InputMethodManagerImplTest, TestSwitchInputMethodWithJpIme) { 1016 InitComponentExtension(); 1017 manager_->SetState(InputMethodManager::STATE_BROWSER_SCREEN); 1018 std::vector<std::string> ids; 1019 ids.push_back(XkbId("xkb:jp::jpn")); 1020 ids.push_back(kNaclMozcJpId); 1021 EXPECT_TRUE(manager_->ReplaceEnabledInputMethods(ids)); 1022 EXPECT_EQ(XkbId("xkb:jp::jpn"), manager_->GetCurrentInputMethod().id()); 1023 EXPECT_EQ("jp", xkeyboard_->last_layout_); 1024 EXPECT_TRUE(manager_->SwitchInputMethod( 1025 ui::Accelerator(ui::VKEY_DBE_DBCSCHAR, ui::EF_NONE))); 1026 EXPECT_EQ(kNaclMozcJpId, manager_->GetCurrentInputMethod().id()); 1027 EXPECT_EQ("jp", xkeyboard_->last_layout_); 1028 EXPECT_TRUE(manager_->SwitchInputMethod( 1029 ui::Accelerator(ui::VKEY_DBE_DBCSCHAR, ui::EF_NONE))); 1030 EXPECT_EQ(XkbId("xkb:jp::jpn"), manager_->GetCurrentInputMethod().id()); 1031 EXPECT_EQ("jp", xkeyboard_->last_layout_); 1032 EXPECT_TRUE(manager_->SwitchInputMethod( 1033 ui::Accelerator(ui::VKEY_CONVERT, ui::EF_NONE))); 1034 EXPECT_EQ(kNaclMozcJpId, manager_->GetCurrentInputMethod().id()); 1035 EXPECT_EQ("jp", xkeyboard_->last_layout_); 1036 EXPECT_TRUE(manager_->SwitchInputMethod( 1037 ui::Accelerator(ui::VKEY_CONVERT, ui::EF_NONE))); 1038 EXPECT_EQ(kNaclMozcJpId, manager_->GetCurrentInputMethod().id()); 1039 EXPECT_EQ("jp", xkeyboard_->last_layout_); 1040 EXPECT_TRUE(manager_->SwitchInputMethod( 1041 ui::Accelerator(ui::VKEY_NONCONVERT, ui::EF_NONE))); 1042 EXPECT_EQ(XkbId("xkb:jp::jpn"), manager_->GetCurrentInputMethod().id()); 1043 EXPECT_EQ("jp", xkeyboard_->last_layout_); 1044 EXPECT_TRUE(manager_->SwitchInputMethod( 1045 ui::Accelerator(ui::VKEY_NONCONVERT, ui::EF_NONE))); 1046 EXPECT_EQ(XkbId("xkb:jp::jpn"), manager_->GetCurrentInputMethod().id()); 1047 EXPECT_EQ("jp", xkeyboard_->last_layout_); 1048 1049 // Add Dvorak. 1050 ids.push_back(XkbId("xkb:us:dvorak:eng")); 1051 EXPECT_TRUE(manager_->ReplaceEnabledInputMethods(ids)); 1052 EXPECT_EQ(XkbId("xkb:jp::jpn"), manager_->GetCurrentInputMethod().id()); 1053 EXPECT_EQ("jp", xkeyboard_->last_layout_); 1054 EXPECT_TRUE(manager_->SwitchInputMethod( 1055 ui::Accelerator(ui::VKEY_DBE_SBCSCHAR, ui::EF_NONE))); 1056 EXPECT_EQ(kNaclMozcJpId, manager_->GetCurrentInputMethod().id()); 1057 EXPECT_EQ("jp", xkeyboard_->last_layout_); 1058 EXPECT_TRUE(manager_->SwitchInputMethod( 1059 ui::Accelerator(ui::VKEY_DBE_SBCSCHAR, ui::EF_NONE))); 1060 EXPECT_EQ(XkbId("xkb:jp::jpn"), manager_->GetCurrentInputMethod().id()); 1061 EXPECT_EQ("jp", xkeyboard_->last_layout_); 1062} 1063 1064TEST_F(InputMethodManagerImplTest, TestAddRemoveExtensionInputMethods) { 1065 TestObserver observer; 1066 manager_->AddObserver(&observer); 1067 InitComponentExtension(); 1068 manager_->SetState(InputMethodManager::STATE_BROWSER_SCREEN); 1069 std::vector<std::string> ids; 1070 ids.push_back(XkbId("xkb:us:dvorak:eng")); 1071 EXPECT_TRUE(manager_->ReplaceEnabledInputMethods(ids)); 1072 EXPECT_EQ(1U, manager_->GetNumActiveInputMethods()); 1073 EXPECT_EQ(1, observer.input_method_changed_count_); 1074 EXPECT_EQ(XkbId(ids[0]), 1075 manager_->GetCurrentInputMethod().id()); 1076 EXPECT_EQ("us(dvorak)", xkeyboard_->last_layout_); 1077 1078 // Add two Extension IMEs. 1079 std::vector<std::string> layouts; 1080 layouts.push_back("us"); 1081 std::vector<std::string> languages; 1082 languages.push_back("en-US"); 1083 1084 const std::string ext1_id = 1085 extension_ime_util::GetInputMethodID("deadbeef", "engine_id"); 1086 const InputMethodDescriptor descriptor1(ext1_id, 1087 "deadbeef input method", 1088 "DB", 1089 layouts, 1090 languages, 1091 false, // is_login_keyboard 1092 GURL(), 1093 GURL()); 1094 MockInputMethodEngine engine(descriptor1); 1095 manager_->AddInputMethodExtension(ext1_id, &engine); 1096 1097 // Extension IMEs are not enabled by default. 1098 EXPECT_EQ(1U, manager_->GetNumActiveInputMethods()); 1099 1100 std::vector<std::string> extension_ime_ids; 1101 extension_ime_ids.push_back(ext1_id); 1102 manager_->SetEnabledExtensionImes(&extension_ime_ids); 1103 EXPECT_EQ(2U, manager_->GetNumActiveInputMethods()); 1104 1105 { 1106 scoped_ptr<InputMethodDescriptors> methods( 1107 manager_->GetActiveInputMethods()); 1108 ASSERT_EQ(2U, methods->size()); 1109 // Ext IMEs should be at the end of the list. 1110 EXPECT_EQ(ext1_id, methods->at(1).id()); 1111 } 1112 1113 const std::string ext2_id = 1114 extension_ime_util::GetInputMethodID("cafebabe", "engine_id"); 1115 const InputMethodDescriptor descriptor2(ext2_id, 1116 "cafebabe input method", 1117 "CB", 1118 layouts, 1119 languages, 1120 false, // is_login_keyboard 1121 GURL(), 1122 GURL()); 1123 MockInputMethodEngine engine2(descriptor2); 1124 manager_->AddInputMethodExtension(ext2_id, &engine2); 1125 EXPECT_EQ(2U, manager_->GetNumActiveInputMethods()); 1126 1127 extension_ime_ids.push_back(ext2_id); 1128 manager_->SetEnabledExtensionImes(&extension_ime_ids); 1129 EXPECT_EQ(3U, manager_->GetNumActiveInputMethods()); 1130 { 1131 scoped_ptr<InputMethodDescriptors> methods( 1132 manager_->GetActiveInputMethods()); 1133 ASSERT_EQ(3U, methods->size()); 1134 // Ext IMEs should be at the end of the list. 1135 EXPECT_EQ(ext1_id, methods->at(1).id()); 1136 EXPECT_EQ(ext2_id, methods->at(2).id()); 1137 } 1138 1139 // Remove them. 1140 manager_->RemoveInputMethodExtension(ext1_id); 1141 EXPECT_EQ(2U, manager_->GetNumActiveInputMethods()); 1142 manager_->RemoveInputMethodExtension(ext2_id); 1143 EXPECT_EQ(1U, manager_->GetNumActiveInputMethods()); 1144} 1145 1146TEST_F(InputMethodManagerImplTest, TestAddExtensionInputThenLockScreen) { 1147 TestObserver observer; 1148 InitComponentExtension(); 1149 manager_->AddObserver(&observer); 1150 manager_->SetState(InputMethodManager::STATE_BROWSER_SCREEN); 1151 std::vector<std::string> ids; 1152 ids.push_back(XkbId("xkb:us::eng")); 1153 EXPECT_TRUE(manager_->ReplaceEnabledInputMethods(ids)); 1154 EXPECT_EQ(1U, manager_->GetNumActiveInputMethods()); 1155 EXPECT_EQ(1, observer.input_method_changed_count_); 1156 EXPECT_EQ(XkbId(ids[0]), manager_->GetCurrentInputMethod().id()); 1157 EXPECT_EQ("us", xkeyboard_->last_layout_); 1158 1159 // Add an Extension IME. 1160 std::vector<std::string> layouts; 1161 layouts.push_back("us(dvorak)"); 1162 std::vector<std::string> languages; 1163 languages.push_back("en-US"); 1164 1165 const std::string ext_id = 1166 extension_ime_util::GetInputMethodID("deadbeef", "engine_id"); 1167 const InputMethodDescriptor descriptor(ext_id, 1168 "deadbeef input method", 1169 "DB", 1170 layouts, 1171 languages, 1172 false, // is_login_keyboard 1173 GURL(), 1174 GURL()); 1175 MockInputMethodEngine engine(descriptor); 1176 manager_->AddInputMethodExtension(ext_id, &engine); 1177 1178 // Extension IME is not enabled by default. 1179 EXPECT_EQ(1U, manager_->GetNumActiveInputMethods()); 1180 EXPECT_EQ(1, observer.input_method_changed_count_); 1181 1182 std::vector<std::string> extension_ime_ids; 1183 extension_ime_ids.push_back(ext_id); 1184 manager_->SetEnabledExtensionImes(&extension_ime_ids); 1185 EXPECT_EQ(2U, manager_->GetNumActiveInputMethods()); 1186 1187 // Switch to the IME. 1188 manager_->SwitchToNextInputMethod(); 1189 EXPECT_EQ(3, observer.input_method_changed_count_); 1190 EXPECT_EQ(ext_id, manager_->GetCurrentInputMethod().id()); 1191 EXPECT_EQ("us(dvorak)", xkeyboard_->last_layout_); 1192 1193 // Lock the screen. This is for crosbug.com/27049. 1194 manager_->SetState(InputMethodManager::STATE_LOCK_SCREEN); 1195 EXPECT_EQ(1U, manager_->GetNumActiveInputMethods()); // Qwerty. No Ext. IME 1196 EXPECT_EQ(XkbId("xkb:us::eng"), 1197 manager_->GetCurrentInputMethod().id()); 1198 EXPECT_EQ("us", xkeyboard_->last_layout_); 1199 1200 // Unlock the screen. 1201 manager_->SetState(InputMethodManager::STATE_BROWSER_SCREEN); 1202 EXPECT_EQ(2U, manager_->GetNumActiveInputMethods()); 1203 EXPECT_EQ(ext_id, manager_->GetCurrentInputMethod().id()); 1204 EXPECT_EQ("us(dvorak)", xkeyboard_->last_layout_); 1205 { 1206 // This is for crosbug.com/27052. 1207 scoped_ptr<InputMethodDescriptors> methods( 1208 manager_->GetActiveInputMethods()); 1209 ASSERT_EQ(2U, methods->size()); 1210 // Ext. IMEs should be at the end of the list. 1211 EXPECT_EQ(ext_id, methods->at(1).id()); 1212 } 1213 manager_->RemoveObserver(&observer); 1214} 1215 1216TEST_F(InputMethodManagerImplTest, 1217 ChangeInputMethodBeforeComponentExtensionInitialization_OneIME) { 1218 manager_->SetState(InputMethodManager::STATE_BROWSER_SCREEN); 1219 std::vector<std::string> ids; 1220 ids.push_back(kNaclMozcUsId); 1221 EXPECT_TRUE(manager_->ReplaceEnabledInputMethods(ids)); 1222 EXPECT_EQ(1U, manager_->GetNumActiveInputMethods()); 1223 manager_->ChangeInputMethod(kNaclMozcUsId); 1224 1225 InitComponentExtension(); 1226 EXPECT_EQ(kNaclMozcUsId, manager_->GetCurrentInputMethod().id()); 1227} 1228 1229TEST_F(InputMethodManagerImplTest, 1230 ChangeInputMethodBeforeComponentExtensionInitialization_TwoIME) { 1231 manager_->SetState(InputMethodManager::STATE_BROWSER_SCREEN); 1232 std::vector<std::string> ids; 1233 ids.push_back(kNaclMozcUsId); 1234 ids.push_back(kNaclMozcJpId); 1235 EXPECT_TRUE(manager_->ReplaceEnabledInputMethods(ids)); 1236 EXPECT_EQ(2U, manager_->GetNumActiveInputMethods()); 1237 manager_->ChangeInputMethod(kNaclMozcUsId); 1238 manager_->ChangeInputMethod(kNaclMozcJpId); 1239 1240 InitComponentExtension(); 1241 EXPECT_EQ(kNaclMozcJpId, manager_->GetCurrentInputMethod().id()); 1242} 1243 1244TEST_F(InputMethodManagerImplTest, 1245 ChangeInputMethodBeforeComponentExtensionInitialization_CompOneIME) { 1246 manager_->SetState(InputMethodManager::STATE_BROWSER_SCREEN); 1247 const std::string ext_id = extension_ime_util::GetComponentInputMethodID( 1248 ime_list_[1].id, 1249 ime_list_[1].engines[0].engine_id); 1250 std::vector<std::string> ids; 1251 ids.push_back(ext_id); 1252 EXPECT_TRUE(manager_->ReplaceEnabledInputMethods(ids)); 1253 EXPECT_EQ(1U, manager_->GetNumActiveInputMethods()); 1254 manager_->ChangeInputMethod(ext_id); 1255 1256 InitComponentExtension(); 1257 EXPECT_EQ(ext_id, manager_->GetCurrentInputMethod().id()); 1258} 1259 1260TEST_F(InputMethodManagerImplTest, 1261 ChangeInputMethodBeforeComponentExtensionInitialization_CompTwoIME) { 1262 manager_->SetState(InputMethodManager::STATE_BROWSER_SCREEN); 1263 const std::string ext_id1 = extension_ime_util::GetComponentInputMethodID( 1264 ime_list_[1].id, 1265 ime_list_[1].engines[0].engine_id); 1266 const std::string ext_id2 = extension_ime_util::GetComponentInputMethodID( 1267 ime_list_[2].id, 1268 ime_list_[2].engines[0].engine_id); 1269 std::vector<std::string> ids; 1270 ids.push_back(ext_id1); 1271 ids.push_back(ext_id2); 1272 EXPECT_TRUE(manager_->ReplaceEnabledInputMethods(ids)); 1273 EXPECT_EQ(2U, manager_->GetNumActiveInputMethods()); 1274 manager_->ChangeInputMethod(ext_id1); 1275 manager_->ChangeInputMethod(ext_id2); 1276 1277 InitComponentExtension(); 1278 EXPECT_EQ(ext_id2, manager_->GetCurrentInputMethod().id()); 1279} 1280 1281TEST_F(InputMethodManagerImplTest, 1282 ChangeInputMethod_ComponenteExtensionOneIME) { 1283 InitComponentExtension(); 1284 manager_->SetState(InputMethodManager::STATE_BROWSER_SCREEN); 1285 const std::string ext_id = extension_ime_util::GetComponentInputMethodID( 1286 ime_list_[1].id, 1287 ime_list_[1].engines[0].engine_id); 1288 std::vector<std::string> ids; 1289 ids.push_back(ext_id); 1290 EXPECT_TRUE(manager_->ReplaceEnabledInputMethods(ids)); 1291 EXPECT_EQ(1U, manager_->GetNumActiveInputMethods()); 1292 EXPECT_EQ(ext_id, manager_->GetCurrentInputMethod().id()); 1293} 1294 1295TEST_F(InputMethodManagerImplTest, 1296 ChangeInputMethod_ComponenteExtensionTwoIME) { 1297 InitComponentExtension(); 1298 manager_->SetState(InputMethodManager::STATE_BROWSER_SCREEN); 1299 const std::string ext_id1 = extension_ime_util::GetComponentInputMethodID( 1300 ime_list_[1].id, 1301 ime_list_[1].engines[0].engine_id); 1302 const std::string ext_id2 = extension_ime_util::GetComponentInputMethodID( 1303 ime_list_[2].id, 1304 ime_list_[2].engines[0].engine_id); 1305 std::vector<std::string> ids; 1306 ids.push_back(ext_id1); 1307 ids.push_back(ext_id2); 1308 EXPECT_TRUE(manager_->ReplaceEnabledInputMethods(ids)); 1309 EXPECT_EQ(2U, manager_->GetNumActiveInputMethods()); 1310 EXPECT_EQ(ext_id1, manager_->GetCurrentInputMethod().id()); 1311 manager_->ChangeInputMethod(ext_id2); 1312 EXPECT_EQ(ext_id2, manager_->GetCurrentInputMethod().id()); 1313} 1314 1315TEST_F(InputMethodManagerImplTest, MigrateXkbInputMethodTest_1) { 1316 extension_ime_util::ScopedUseExtensionKeyboardFlagForTesting 1317 scoped_flag(true); 1318 1319 std::vector<std::string> input_method_ids; 1320 input_method_ids.push_back("xkb:us::eng"); 1321 input_method_ids.push_back("xkb:fr::fra"); 1322 input_method_ids.push_back( 1323 std::string("_comp_ime_") + kXkbExtId + "xkb:us::eng"); 1324 input_method_ids.push_back("xkb:fr::fra"); 1325 input_method_ids.push_back( 1326 std::string("_comp_ime_") + kXkbExtId + "xkb:us::eng"); 1327 input_method_ids.push_back("_comp_ime_asdf_pinyin"); 1328 1329 manager_->MigrateXkbInputMethods(&input_method_ids); 1330 1331 ASSERT_EQ(3U, input_method_ids.size()); 1332 1333 EXPECT_EQ(std::string("_comp_ime_") + kXkbExtId + "xkb:us::eng", 1334 input_method_ids[0]); 1335 EXPECT_EQ(std::string("_comp_ime_") + kXkbExtId + "xkb:fr::fra", 1336 input_method_ids[1]); 1337 EXPECT_EQ("_comp_ime_asdf_pinyin", input_method_ids[2]); 1338} 1339 1340TEST_F(InputMethodManagerImplTest, MigrateXkbInputMethodTest_2) { 1341 extension_ime_util::ScopedUseExtensionKeyboardFlagForTesting 1342 scoped_flag(false); 1343 1344 std::vector<std::string> input_method_ids; 1345 input_method_ids.push_back("xkb:us::eng"); 1346 input_method_ids.push_back("xkb:fr::fra"); 1347 input_method_ids.push_back( 1348 std::string("_comp_ime_") + kXkbExtId + "xkb:us::eng"); 1349 input_method_ids.push_back("xkb:fr::fra"); 1350 input_method_ids.push_back( 1351 std::string("_comp_ime_") + kXkbExtId + "xkb:us::eng"); 1352 input_method_ids.push_back("_comp_ime_asdf_pinyin"); 1353 1354 manager_->MigrateXkbInputMethods(&input_method_ids); 1355 1356 ASSERT_EQ(3U, input_method_ids.size()); 1357 1358 EXPECT_EQ("xkb:us::eng", input_method_ids[0]); 1359 EXPECT_EQ("xkb:fr::fra", input_method_ids[1]); 1360 EXPECT_EQ("_comp_ime_asdf_pinyin", input_method_ids[2]); 1361} 1362 1363} // namespace input_method 1364} // namespace chromeos 1365