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