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"
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"
38 namespace input_method
{
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())
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
{
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_
;
88 DISALLOW_COPY_AND_ASSIGN(TestObserver
);
91 class TestCandidateWindowObserver
92 : public InputMethodManager::CandidateWindowObserver
{
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_
;
112 DISALLOW_COPY_AND_ASSIGN(TestCandidateWindowObserver
);
116 class InputMethodManagerImplTest
: public BrowserWithTestWindowTest
{
118 InputMethodManagerImplTest()
120 candidate_window_controller_(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();
148 BrowserWithTestWindowTest::SetUp();
151 void TearDown() override
{
152 BrowserWithTestWindowTest::TearDown();
154 ui::ShutdownInputMethodForTesting();
157 candidate_window_controller_
= NULL
;
161 profile_manager_
.reset();
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
),
187 mock_engine_handler_
.get());
188 manager_
->GetActiveIMEState()->AddInputMethodExtension(
189 ImeIdFromEngineId(kExt2Engine1Id
),
191 mock_engine_handler_
.get());
192 manager_
->InitializeComponentExtensionForTesting(delegate
.Pass());
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_
;
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
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
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(
449 manager_
->GetActiveIMEState()->EnableLoginLayouts(
451 manager_
->GetInputMethodUtil()->GetHardwareLoginInputMethodIds());
454 manager_
->GetActiveIMEState()->GetNumActiveInputMethods()); // 5 + French
455 // The physical layout is Japanese.
456 manager_
->GetInputMethodUtil()->SetHardwareKeyboardLayoutForTesting(
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(
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(
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());
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
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_
);
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_
);
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_
);
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_
);
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_
);
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_
);
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
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_
);
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_
);
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_
);
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_
);
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
);
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
);
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_
);
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());
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",
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
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_
);
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",
1167 false, // is_login_keyboard
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",
1199 false, // is_login_keyboard
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());
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",
1255 false, // is_login_keyboard
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_
);
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
);
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());
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(
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());
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(
1332 ime_list_
[1].engines
[0].engine_id
);
1333 const std::string ext_id2
= extension_ime_util::GetComponentInputMethodID(
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());
1342 manager_
->GetActiveIMEState()->GetCurrentInputMethod().id());
1343 manager_
->GetActiveIMEState()->ChangeInputMethod(ext_id2
,
1344 false /* show_message */);
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