OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/chromeos/input_method/input_method_manager_impl.h" | 5 #include "chrome/browser/chromeos/input_method/input_method_manager_impl.h" |
6 | 6 |
7 #include <algorithm> // std::find | 7 #include <algorithm> // std::find |
8 | 8 |
9 #include "ash/ime/input_method_menu_item.h" | 9 #include "ash/ime/input_method_menu_item.h" |
10 #include "ash/ime/input_method_menu_manager.h" | 10 #include "ash/ime/input_method_menu_manager.h" |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
53 | 53 |
54 bool InputMethodManagerImpl::MigrateInputMethods( | 54 bool InputMethodManagerImpl::MigrateInputMethods( |
55 std::vector<std::string>* input_method_ids) { | 55 std::vector<std::string>* input_method_ids) { |
56 return util_.MigrateInputMethods(input_method_ids); | 56 return util_.MigrateInputMethods(input_method_ids); |
57 } | 57 } |
58 | 58 |
59 InputMethodManagerImpl::InputMethodManagerImpl( | 59 InputMethodManagerImpl::InputMethodManagerImpl( |
60 scoped_ptr<InputMethodDelegate> delegate) | 60 scoped_ptr<InputMethodDelegate> delegate) |
61 : delegate_(delegate.Pass()), | 61 : delegate_(delegate.Pass()), |
62 state_(STATE_LOGIN_SCREEN), | 62 state_(STATE_LOGIN_SCREEN), |
63 util_(delegate_.get(), whitelist_.GetSupportedInputMethods()), | 63 util_(delegate_.get()), |
64 component_extension_ime_manager_(new ComponentExtensionIMEManager()), | 64 component_extension_ime_manager_(new ComponentExtensionIMEManager()), |
65 weak_ptr_factory_(this) { | 65 weak_ptr_factory_(this) { |
| 66 if (base::SysInfo::IsRunningOnChromeOS()) |
| 67 keyboard_.reset(ImeKeyboard::Create()); |
| 68 else |
| 69 keyboard_.reset(new FakeImeKeyboard()); |
66 } | 70 } |
67 | 71 |
68 InputMethodManagerImpl::~InputMethodManagerImpl() { | 72 InputMethodManagerImpl::~InputMethodManagerImpl() { |
69 if (candidate_window_controller_.get()) | 73 if (candidate_window_controller_.get()) |
70 candidate_window_controller_->RemoveObserver(this); | 74 candidate_window_controller_->RemoveObserver(this); |
71 } | 75 } |
72 | 76 |
73 void InputMethodManagerImpl::AddObserver( | 77 void InputMethodManagerImpl::AddObserver( |
74 InputMethodManager::Observer* observer) { | 78 InputMethodManager::Observer* observer) { |
75 observers_.AddObserver(observer); | 79 observers_.AddObserver(observer); |
(...skipping 30 matching lines...) Expand all Loading... |
106 case STATE_TERMINATING: { | 110 case STATE_TERMINATING: { |
107 if (candidate_window_controller_.get()) | 111 if (candidate_window_controller_.get()) |
108 candidate_window_controller_.reset(); | 112 candidate_window_controller_.reset(); |
109 break; | 113 break; |
110 } | 114 } |
111 } | 115 } |
112 } | 116 } |
113 | 117 |
114 scoped_ptr<InputMethodDescriptors> | 118 scoped_ptr<InputMethodDescriptors> |
115 InputMethodManagerImpl::GetSupportedInputMethods() const { | 119 InputMethodManagerImpl::GetSupportedInputMethods() const { |
116 if (!IsXkbComponentExtensionAvailable()) | |
117 return whitelist_.GetSupportedInputMethods().Pass(); | |
118 return scoped_ptr<InputMethodDescriptors>(new InputMethodDescriptors).Pass(); | 120 return scoped_ptr<InputMethodDescriptors>(new InputMethodDescriptors).Pass(); |
119 } | 121 } |
120 | 122 |
121 scoped_ptr<InputMethodDescriptors> | 123 scoped_ptr<InputMethodDescriptors> |
122 InputMethodManagerImpl::GetActiveInputMethods() const { | 124 InputMethodManagerImpl::GetActiveInputMethods() const { |
123 scoped_ptr<InputMethodDescriptors> result(new InputMethodDescriptors); | 125 scoped_ptr<InputMethodDescriptors> result(new InputMethodDescriptors); |
124 // Build the active input method descriptors from the active input | 126 // Build the active input method descriptors from the active input |
125 // methods cache |active_input_method_ids_|. | 127 // methods cache |active_input_method_ids_|. |
126 for (size_t i = 0; i < active_input_method_ids_.size(); ++i) { | 128 for (size_t i = 0; i < active_input_method_ids_.size(); ++i) { |
127 const std::string& input_method_id = active_input_method_ids_[i]; | 129 const std::string& input_method_id = active_input_method_ids_[i]; |
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
318 scoped_ptr<InputMethodDescriptors> input_methods(GetActiveInputMethods()); | 320 scoped_ptr<InputMethodDescriptors> input_methods(GetActiveInputMethods()); |
319 DCHECK(!input_methods->empty()); | 321 DCHECK(!input_methods->empty()); |
320 input_method_id_to_switch = input_methods->at(0).id(); | 322 input_method_id_to_switch = input_methods->at(0).id(); |
321 if (!input_method_id.empty()) { | 323 if (!input_method_id.empty()) { |
322 DVLOG(1) << "Can't change the current input method to " | 324 DVLOG(1) << "Can't change the current input method to " |
323 << input_method_id << " since the engine is not enabled. " | 325 << input_method_id << " since the engine is not enabled. " |
324 << "Switch to " << input_method_id_to_switch << " instead."; | 326 << "Switch to " << input_method_id_to_switch << " instead."; |
325 } | 327 } |
326 } | 328 } |
327 | 329 |
328 if (!component_extension_ime_manager_->IsInitialized() && | |
329 !InputMethodUtil::IsKeyboardLayout(input_method_id_to_switch)) { | |
330 // We can't change input method before the initialization of | |
331 // component extension ime manager. ChangeInputMethod will be | |
332 // called with |pending_input_method_| when the initialization is | |
333 // done. | |
334 pending_input_method_ = input_method_id_to_switch; | |
335 return false; | |
336 } | |
337 pending_input_method_.clear(); | |
338 | |
339 // Hide candidate window and info list. | 330 // Hide candidate window and info list. |
340 if (candidate_window_controller_.get()) | 331 if (candidate_window_controller_.get()) |
341 candidate_window_controller_->Hide(); | 332 candidate_window_controller_->Hide(); |
342 | 333 |
343 // Disable the current engine handler. | 334 // Disable the current engine handler. |
344 IMEEngineHandlerInterface* engine = | 335 IMEEngineHandlerInterface* engine = |
345 IMEBridge::Get()->GetCurrentEngineHandler(); | 336 IMEBridge::Get()->GetCurrentEngineHandler(); |
346 if (engine) | 337 if (engine) |
347 engine->Disable(); | 338 engine->Disable(); |
348 | 339 |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
397 << current_input_method_.GetPreferredKeyboardLayout(); | 388 << current_input_method_.GetPreferredKeyboardLayout(); |
398 } | 389 } |
399 | 390 |
400 // Update input method indicators (e.g. "US", "DV") in Chrome windows. | 391 // Update input method indicators (e.g. "US", "DV") in Chrome windows. |
401 FOR_EACH_OBSERVER(InputMethodManager::Observer, | 392 FOR_EACH_OBSERVER(InputMethodManager::Observer, |
402 observers_, | 393 observers_, |
403 InputMethodChanged(this, show_message)); | 394 InputMethodChanged(this, show_message)); |
404 return true; | 395 return true; |
405 } | 396 } |
406 | 397 |
407 bool InputMethodManagerImpl::IsXkbComponentExtensionAvailable() const { | |
408 if (!component_extension_ime_manager_->IsInitialized()) | |
409 return false; | |
410 InputMethodDescriptors imes = | |
411 component_extension_ime_manager_->GetAllIMEAsInputMethodDescriptor(); | |
412 for (size_t i = 0; i < imes.size(); ++i) { | |
413 if (StartsWithASCII(extension_ime_util::MaybeGetLegacyXkbId( | |
414 imes[i].id()), "xkb:", true)) | |
415 return true; | |
416 } | |
417 return false; | |
418 } | |
419 | |
420 void InputMethodManagerImpl::OnComponentExtensionInitialized( | |
421 scoped_ptr<ComponentExtensionIMEManagerDelegate> delegate) { | |
422 DCHECK(thread_checker_.CalledOnValidThread()); | |
423 component_extension_ime_manager_->Initialize(delegate.Pass()); | |
424 InputMethodDescriptors imes = | |
425 component_extension_ime_manager_->GetAllIMEAsInputMethodDescriptor(); | |
426 // In case of XKB extension is not available (e.g. linux_chromeos), don't | |
427 // reset the input methods in InputMethodUtil, Instead append input methods. | |
428 if (IsXkbComponentExtensionAvailable()) | |
429 util_.ResetInputMethods(imes); | |
430 else | |
431 util_.AppendInputMethods(imes); | |
432 | |
433 LoadNecessaryComponentExtensions(); | |
434 | |
435 if (!pending_input_method_.empty()) | |
436 ChangeInputMethodInternal(pending_input_method_, false); | |
437 } | |
438 | |
439 void InputMethodManagerImpl::LoadNecessaryComponentExtensions() { | 398 void InputMethodManagerImpl::LoadNecessaryComponentExtensions() { |
440 if (!component_extension_ime_manager_->IsInitialized()) | |
441 return; | |
442 // Load component extensions but also update |active_input_method_ids_| as | 399 // Load component extensions but also update |active_input_method_ids_| as |
443 // some component extension IMEs may have been removed from the Chrome OS | 400 // some component extension IMEs may have been removed from the Chrome OS |
444 // image. If specified component extension IME no longer exists, falling back | 401 // image. If specified component extension IME no longer exists, falling back |
445 // to an existing IME. | 402 // to an existing IME. |
446 std::vector<std::string> unfiltered_input_method_ids; | 403 std::vector<std::string> unfiltered_input_method_ids; |
447 unfiltered_input_method_ids.swap(active_input_method_ids_); | 404 unfiltered_input_method_ids.swap(active_input_method_ids_); |
448 for (size_t i = 0; i < unfiltered_input_method_ids.size(); ++i) { | 405 for (size_t i = 0; i < unfiltered_input_method_ids.size(); ++i) { |
449 if (!extension_ime_util::IsComponentExtensionIME( | 406 if (!extension_ime_util::IsComponentExtensionIME( |
450 unfiltered_input_method_ids[i])) { | 407 unfiltered_input_method_ids[i])) { |
451 // Legacy IMEs or xkb layouts are alwayes active. | 408 // Legacy IMEs or xkb layouts are alwayes active. |
452 active_input_method_ids_.push_back(unfiltered_input_method_ids[i]); | 409 active_input_method_ids_.push_back(unfiltered_input_method_ids[i]); |
453 } else if (component_extension_ime_manager_->IsWhitelisted( | 410 } else if (component_extension_ime_manager_->IsWhitelisted( |
454 unfiltered_input_method_ids[i])) { | 411 unfiltered_input_method_ids[i])) { |
455 component_extension_ime_manager_->LoadComponentExtensionIME( | 412 component_extension_ime_manager_->LoadComponentExtensionIME( |
456 unfiltered_input_method_ids[i]); | 413 unfiltered_input_method_ids[i]); |
457 active_input_method_ids_.push_back(unfiltered_input_method_ids[i]); | 414 active_input_method_ids_.push_back(unfiltered_input_method_ids[i]); |
458 } | 415 } |
459 } | 416 } |
460 // TODO(shuchen): move this call in ComponentExtensionIMEManager. | |
461 component_extension_ime_manager_->NotifyInitialized(); | |
462 } | 417 } |
463 | 418 |
464 void InputMethodManagerImpl::ActivateInputMethodMenuItem( | 419 void InputMethodManagerImpl::ActivateInputMethodMenuItem( |
465 const std::string& key) { | 420 const std::string& key) { |
466 DCHECK(!key.empty()); | 421 DCHECK(!key.empty()); |
467 | 422 |
468 if (ash::ime::InputMethodMenuManager::GetInstance()-> | 423 if (ash::ime::InputMethodMenuManager::GetInstance()-> |
469 HasInputMethodMenuItemForKey(key)) { | 424 HasInputMethodMenuItemForKey(key)) { |
470 IMEEngineHandlerInterface* engine = | 425 IMEEngineHandlerInterface* engine = |
471 IMEBridge::Get()->GetCurrentEngineHandler(); | 426 IMEBridge::Get()->GetCurrentEngineHandler(); |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
623 | 578 |
624 // This asks the file thread to save the prefs (i.e. doesn't block). | 579 // This asks the file thread to save the prefs (i.e. doesn't block). |
625 // The latest values of Local State reside in memory so we can safely | 580 // The latest values of Local State reside in memory so we can safely |
626 // get the value of kHardwareKeyboardLayout even if the data is not | 581 // get the value of kHardwareKeyboardLayout even if the data is not |
627 // yet saved to disk. | 582 // yet saved to disk. |
628 prefs->CommitPendingWrite(); | 583 prefs->CommitPendingWrite(); |
629 | 584 |
630 util_.UpdateHardwareLayoutCache(); | 585 util_.UpdateHardwareLayoutCache(); |
631 | 586 |
632 EnableLoginLayouts(locale, layouts); | 587 EnableLoginLayouts(locale, layouts); |
| 588 LoadNecessaryComponentExtensions(); |
633 } | 589 } |
634 | 590 |
635 void InputMethodManagerImpl::SetInputMethodLoginDefault() { | 591 void InputMethodManagerImpl::SetInputMethodLoginDefault() { |
636 // Set up keyboards. For example, when |locale| is "en-US", enable US qwerty | 592 // Set up keyboards. For example, when |locale| is "en-US", enable US qwerty |
637 // and US dvorak keyboard layouts. | 593 // and US dvorak keyboard layouts. |
638 if (g_browser_process && g_browser_process->local_state()) { | 594 if (g_browser_process && g_browser_process->local_state()) { |
639 const std::string locale = g_browser_process->GetApplicationLocale(); | 595 const std::string locale = g_browser_process->GetApplicationLocale(); |
640 // If the preferred keyboard for the login screen has been saved, use it. | 596 // If the preferred keyboard for the login screen has been saved, use it. |
641 PrefService* prefs = g_browser_process->local_state(); | 597 PrefService* prefs = g_browser_process->local_state(); |
642 std::string initial_input_method_id = | 598 std::string initial_input_method_id = |
643 prefs->GetString(chromeos::language_prefs::kPreferredKeyboardLayout); | 599 prefs->GetString(chromeos::language_prefs::kPreferredKeyboardLayout); |
644 std::vector<std::string> input_methods_to_be_enabled; | 600 std::vector<std::string> input_methods_to_be_enabled; |
645 if (initial_input_method_id.empty()) { | 601 if (initial_input_method_id.empty()) { |
646 // If kPreferredKeyboardLayout is not specified, use the hardware layout. | 602 // If kPreferredKeyboardLayout is not specified, use the hardware layout. |
647 input_methods_to_be_enabled = util_.GetHardwareLoginInputMethodIds(); | 603 input_methods_to_be_enabled = util_.GetHardwareLoginInputMethodIds(); |
648 } else { | 604 } else { |
649 input_methods_to_be_enabled.push_back(initial_input_method_id); | 605 input_methods_to_be_enabled.push_back(initial_input_method_id); |
650 } | 606 } |
651 EnableLoginLayouts(locale, input_methods_to_be_enabled); | 607 EnableLoginLayouts(locale, input_methods_to_be_enabled); |
| 608 LoadNecessaryComponentExtensions(); |
652 } | 609 } |
653 } | 610 } |
654 | 611 |
655 bool InputMethodManagerImpl::SwitchToNextInputMethod() { | 612 bool InputMethodManagerImpl::SwitchToNextInputMethod() { |
656 // Sanity checks. | 613 // Sanity checks. |
657 if (active_input_method_ids_.empty()) { | 614 if (active_input_method_ids_.empty()) { |
658 DVLOG(1) << "active input method is empty"; | 615 DVLOG(1) << "active input method is empty"; |
659 return false; | 616 return false; |
660 } | 617 } |
661 | 618 |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
800 return &util_; | 757 return &util_; |
801 } | 758 } |
802 | 759 |
803 ComponentExtensionIMEManager* | 760 ComponentExtensionIMEManager* |
804 InputMethodManagerImpl::GetComponentExtensionIMEManager() { | 761 InputMethodManagerImpl::GetComponentExtensionIMEManager() { |
805 DCHECK(thread_checker_.CalledOnValidThread()); | 762 DCHECK(thread_checker_.CalledOnValidThread()); |
806 return component_extension_ime_manager_.get(); | 763 return component_extension_ime_manager_.get(); |
807 } | 764 } |
808 | 765 |
809 void InputMethodManagerImpl::InitializeComponentExtension() { | 766 void InputMethodManagerImpl::InitializeComponentExtension() { |
810 ComponentExtensionIMEManagerImpl* impl = | 767 scoped_ptr<ComponentExtensionIMEManagerDelegate> delegate( |
811 new ComponentExtensionIMEManagerImpl(); | 768 new ComponentExtensionIMEManagerImpl()); |
812 scoped_ptr<ComponentExtensionIMEManagerDelegate> delegate(impl); | 769 component_extension_ime_manager_->Initialize(delegate.Pass()); |
813 impl->InitializeAsync(base::Bind( | |
814 &InputMethodManagerImpl::OnComponentExtensionInitialized, | |
815 weak_ptr_factory_.GetWeakPtr(), | |
816 base::Passed(&delegate))); | |
817 } | |
818 | 770 |
819 void InputMethodManagerImpl::Init(base::SequencedTaskRunner* ui_task_runner) { | 771 util_.ResetInputMethods( |
820 DCHECK(thread_checker_.CalledOnValidThread()); | 772 component_extension_ime_manager_->GetAllIMEAsInputMethodDescriptor()); |
821 | |
822 if (base::SysInfo::IsRunningOnChromeOS()) | |
823 keyboard_.reset(ImeKeyboard::Create()); | |
824 else | |
825 keyboard_.reset(new FakeImeKeyboard()); | |
826 | |
827 // We can't call impl->Initialize here, because file thread is not available | |
828 // at this moment. | |
829 ui_task_runner->PostTask( | |
830 FROM_HERE, | |
831 base::Bind(&InputMethodManagerImpl::InitializeComponentExtension, | |
832 weak_ptr_factory_.GetWeakPtr())); | |
833 } | 773 } |
834 | 774 |
835 void InputMethodManagerImpl::SetCandidateWindowControllerForTesting( | 775 void InputMethodManagerImpl::SetCandidateWindowControllerForTesting( |
836 CandidateWindowController* candidate_window_controller) { | 776 CandidateWindowController* candidate_window_controller) { |
837 candidate_window_controller_.reset(candidate_window_controller); | 777 candidate_window_controller_.reset(candidate_window_controller); |
838 candidate_window_controller_->AddObserver(this); | 778 candidate_window_controller_->AddObserver(this); |
839 } | 779 } |
840 | 780 |
841 void InputMethodManagerImpl::SetImeKeyboardForTesting(ImeKeyboard* keyboard) { | 781 void InputMethodManagerImpl::SetImeKeyboardForTesting(ImeKeyboard* keyboard) { |
842 keyboard_.reset(keyboard); | 782 keyboard_.reset(keyboard); |
843 } | 783 } |
844 | 784 |
845 void InputMethodManagerImpl::InitializeComponentExtensionForTesting( | 785 void InputMethodManagerImpl::InitializeComponentExtensionForTesting( |
846 scoped_ptr<ComponentExtensionIMEManagerDelegate> delegate) { | 786 scoped_ptr<ComponentExtensionIMEManagerDelegate> delegate) { |
847 OnComponentExtensionInitialized(delegate.Pass()); | 787 component_extension_ime_manager_->Initialize(delegate.Pass()); |
| 788 util_.ResetInputMethods( |
| 789 component_extension_ime_manager_->GetAllIMEAsInputMethodDescriptor()); |
848 } | 790 } |
849 | 791 |
850 void InputMethodManagerImpl::CandidateClicked(int index) { | 792 void InputMethodManagerImpl::CandidateClicked(int index) { |
851 IMEEngineHandlerInterface* engine = | 793 IMEEngineHandlerInterface* engine = |
852 IMEBridge::Get()->GetCurrentEngineHandler(); | 794 IMEBridge::Get()->GetCurrentEngineHandler(); |
853 if (engine) | 795 if (engine) |
854 engine->CandidateClicked(index); | 796 engine->CandidateClicked(index); |
855 } | 797 } |
856 | 798 |
857 void InputMethodManagerImpl::CandidateWindowOpened() { | 799 void InputMethodManagerImpl::CandidateWindowOpened() { |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
922 CandidateWindowController::CreateCandidateWindowController()); | 864 CandidateWindowController::CreateCandidateWindowController()); |
923 candidate_window_controller_->AddObserver(this); | 865 candidate_window_controller_->AddObserver(this); |
924 } | 866 } |
925 | 867 |
926 Profile* InputMethodManagerImpl::GetProfile() const { | 868 Profile* InputMethodManagerImpl::GetProfile() const { |
927 return ProfileManager::GetActiveUserProfile(); | 869 return ProfileManager::GetActiveUserProfile(); |
928 } | 870 } |
929 | 871 |
930 } // namespace input_method | 872 } // namespace input_method |
931 } // namespace chromeos | 873 } // namespace chromeos |
OLD | NEW |