| 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 |