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