Index: chrome/browser/chromeos/input_method/input_method_manager_impl.cc |
diff --git a/chrome/browser/chromeos/input_method/input_method_manager_impl.cc b/chrome/browser/chromeos/input_method/input_method_manager_impl.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..fb16b3a0a1b67d385a02579d5c82efc8a9578609 |
--- /dev/null |
+++ b/chrome/browser/chromeos/input_method/input_method_manager_impl.cc |
@@ -0,0 +1,614 @@ |
+// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "chrome/browser/chromeos/input_method/input_method_manager_impl.h" |
+ |
+#include <algorithm> // std::find |
+ |
+#include "base/basictypes.h" |
+#include "base/memory/scoped_ptr.h" |
+#include "base/string_util.h" |
+#include "base/stringprintf.h" |
+#include "chrome/browser/chromeos/input_method/browser_state_monitor.h" |
+#include "chrome/browser/chromeos/input_method/candidate_window.h" |
+#include "chrome/browser/chromeos/input_method/input_method_util.h" |
+#include "chrome/browser/chromeos/input_method/xkeyboard.h" |
+#include "chrome/browser/chromeos/language_preferences.h" |
+#include "ui/base/accelerators/accelerator.h" |
+#include "unicode/uloc.h" |
+ |
+namespace chromeos { |
+namespace input_method { |
+ |
+namespace { |
+ |
+template<typename T> |
+typename T::iterator Find(T& container, const typename T::value_type& value) { |
+ return std::find(container.begin(), container.end(), value); |
+} |
+ |
+template<typename T> |
+typename T::const_iterator Find(const T& container, |
+ const typename T::value_type& value) { |
+ return std::find(container.begin(), container.end(), value); |
+} |
+ |
+template<typename T> |
+bool Contains(const T& container, const typename T::value_type& value) { |
+ return Find(container, value) != container.end(); |
+} |
+ |
+} // namespace |
+ |
+InputMethodManagerImpl::InputMethodManagerImpl() |
+ : should_hide_properties_(true), |
+ ignore_hotkeys_(false), |
+ state_(STATE_LOGIN_SCREEN), |
+ util_(GetSupportedInputMethods()) { |
+} |
+ |
+InputMethodManagerImpl::~InputMethodManagerImpl() { |
+ if (ibus_controller_.get()) |
+ ibus_controller_->RemoveObserver(this); |
+ if (candidate_window_controller_.get()) |
+ candidate_window_controller_->RemoveObserver(this); |
+} |
+ |
+void InputMethodManagerImpl::AddObserver( |
+ InputMethodManager::Observer* observer) { |
+ observers_.AddObserver(observer); |
+} |
+ |
+void InputMethodManagerImpl::AddCandidateWindowObserver( |
+ InputMethodManager::CandidateWindowObserver* observer) { |
+ candidate_window_observers_.AddObserver(observer); |
+} |
+ |
+void InputMethodManagerImpl::RemoveObserver( |
+ InputMethodManager::Observer* observer) { |
+ observers_.RemoveObserver(observer); |
+} |
+ |
+void InputMethodManagerImpl::RemoveCandidateWindowObserver( |
+ InputMethodManager::CandidateWindowObserver* observer) { |
+ candidate_window_observers_.RemoveObserver(observer); |
+} |
+ |
+void InputMethodManagerImpl::SetState(State new_state) { |
+ const State old_state = state_; |
+ state_ = new_state; |
+ switch (state_) { |
+ case STATE_LOGIN_SCREEN: |
+ break; |
+ case STATE_BROWSER_SCREEN: |
+ if (old_state == STATE_LOCK_SCREEN) |
+ OnScreenUnlocked(); |
+ break; |
+ case STATE_LOCK_SCREEN: |
+ OnScreenLocked(); |
+ break; |
+ case STATE_TERMINATING: |
+ ibus_controller_->Stop(); |
+ browser_state_monitor_.reset(); // For crbug.com/120183. |
+ candidate_window_controller_.reset(); |
+ break; |
+ } |
+} |
+ |
+InputMethodDescriptors* |
+InputMethodManagerImpl::GetSupportedInputMethods() const { |
+ return whitelist_.GetSupportedInputMethods(); |
+} |
+ |
+InputMethodDescriptors* InputMethodManagerImpl::GetActiveInputMethods() const { |
+ InputMethodDescriptors* result = new InputMethodDescriptors; |
+ // Build the active input method descriptors from the active input |
+ // methods cache |active_input_method_ids_|. |
+ for (size_t i = 0; i < active_input_method_ids_.size(); ++i) { |
+ const std::string& input_method_id = active_input_method_ids_[i]; |
+ const InputMethodDescriptor* descriptor = |
+ util_.GetInputMethodDescriptorFromId(input_method_id); |
+ if (descriptor) { |
+ result->push_back(*descriptor); |
+ } else { |
+ std::map<std::string, InputMethodDescriptor>::const_iterator ix = |
+ extra_input_methods_.find(input_method_id); |
+ if (ix != extra_input_methods_.end()) |
+ result->push_back(ix->second); |
+ else |
+ LOG(ERROR) << "Descriptor is not found for: " << input_method_id; |
+ } |
+ } |
+ if (result->empty()) { |
+ // Initially |active_input_method_ids_| is empty. browser_tests might take |
+ // this path. |
+ result->push_back( |
+ InputMethodDescriptor::GetFallbackInputMethodDescriptor()); |
+ } |
+ return result; |
+} |
+ |
+size_t InputMethodManagerImpl::GetNumActiveInputMethods() const { |
+ return active_input_method_ids_.size(); |
+} |
+ |
+void InputMethodManagerImpl::EnableLayouts(const std::string& language_code, |
+ const std::string& initial_layout) { |
+ if (state_ == STATE_TERMINATING) |
+ return; |
+ |
+ std::vector<std::string> candidates; |
+ // Add input methods associated with the language. |
+ util_.GetInputMethodIdsFromLanguageCode(language_code, |
+ kKeyboardLayoutsOnly, |
+ &candidates); |
+ // Add the hardware keyboard as well. We should always add this so users |
+ // can use the hardware keyboard on the login screen and the screen locker. |
+ candidates.push_back(util_.GetHardwareInputMethodId()); |
+ |
+ std::vector<std::string> layouts; |
+ // First, add the initial input method ID, if it's requested, to |
+ // layouts, so it appears first on the list of active input |
+ // methods at the input language status menu. |
+ if (util_.IsValidInputMethodId(initial_layout) && |
+ InputMethodUtil::IsKeyboardLayout(initial_layout)) { |
+ layouts.push_back(initial_layout); |
+ } else if (!initial_layout.empty()) { |
+ LOG(ERROR) << "EnableLayouts: ignoring non-keyboard or invalid ID: " |
+ << initial_layout; |
+ } |
+ |
+ // Add candidates to layouts, while skipping duplicates. |
+ for (size_t i = 0; i < candidates.size(); ++i) { |
+ const std::string& candidate = candidates[i]; |
+ // Not efficient, but should be fine, as the two vectors are very |
+ // short (2-5 items). |
+ if (!Contains(layouts, candidate)) |
+ layouts.push_back(candidate); |
+ } |
+ |
+ active_input_method_ids_.swap(layouts); |
+ ChangeInputMethod(initial_layout); // you can pass empty |initial_layout|. |
+} |
+ |
+bool InputMethodManagerImpl::EnableInputMethods( |
+ const std::vector<std::string>& new_active_input_method_ids) { |
+ if (state_ == STATE_TERMINATING) |
+ return false; |
+ |
+ // Filter unknown or obsolete IDs. |
+ std::vector<std::string> new_active_input_method_ids_filtered; |
+ |
+ for (size_t i = 0; i < new_active_input_method_ids.size(); ++i) { |
+ const std::string& input_method_id = new_active_input_method_ids[i]; |
+ if (util_.IsValidInputMethodId(input_method_id)) |
+ new_active_input_method_ids_filtered.push_back(input_method_id); |
+ else |
+ LOG(ERROR) << "EnableInputMethods: Invalid ID: " << input_method_id; |
+ } |
+ |
+ if (new_active_input_method_ids_filtered.empty()) { |
+ LOG(ERROR) << "EnableInputMethods: No valid input method ID"; |
+ return false; |
+ } |
+ |
+ // Copy extension IDs to |new_active_input_method_ids_filtered|. We have to |
+ // keep relative order of the extension input method IDs. |
+ for (size_t i = 0; i < active_input_method_ids_.size(); ++i) { |
+ const std::string& input_method_id = active_input_method_ids_[i]; |
+ if (InputMethodUtil::IsExtensionInputMethod(input_method_id)) |
+ new_active_input_method_ids_filtered.push_back(input_method_id); |
+ } |
+ active_input_method_ids_.swap(new_active_input_method_ids_filtered); |
+ |
+ if (ContainOnlyKeyboardLayout(active_input_method_ids_)) { |
+ // Do NOT call ibus_controller_->Stop(); here to work around a crash issue |
+ // at crosbug.com/27051. |
+ // TODO(yusukes): We can safely call Stop(); here once crosbug.com/26443 |
+ // is implemented. |
+ } else { |
+ MaybeInitializeCandidateWindowController(); |
+ ibus_controller_->Start(active_input_method_ids_); |
+ } |
+ |
+ // If |current_input_method| is no longer in |active_input_method_ids_|, |
+ // ChangeInputMethod() picks the first one in |active_input_method_ids_|. |
+ ChangeInputMethod(current_input_method_.id()); |
+ return true; |
+} |
+ |
+bool InputMethodManagerImpl::SetInputMethodConfig( |
+ const std::string& section, |
+ const std::string& config_name, |
+ const InputMethodConfigValue& value) { |
+ DCHECK(section != language_prefs::kGeneralSectionName || |
+ config_name != language_prefs::kPreloadEnginesConfigName); |
+ |
+ if (state_ == STATE_TERMINATING) |
+ return false; |
+ return ibus_controller_->SetInputMethodConfig(section, config_name, value); |
+} |
+ |
+void InputMethodManagerImpl::ChangeInputMethod( |
+ const std::string& input_method_id) { |
+ if (state_ == STATE_TERMINATING) |
+ return; |
+ |
+ std::string input_method_id_to_switch = input_method_id; |
+ |
+ // Sanity check. |
+ if (!InputMethodIsActivated(input_method_id)) { |
+ scoped_ptr<InputMethodDescriptors> input_methods(GetActiveInputMethods()); |
+ DCHECK(!input_methods->empty()); |
+ input_method_id_to_switch = input_methods->at(0).id(); |
+ if (!input_method_id.empty()) { |
+ VLOG(1) << "Can't change the current input method to " |
+ << input_method_id << " since the engine is not enabled. " |
+ << "Switch to " << input_method_id_to_switch << " instead."; |
+ } |
+ } |
+ |
+ if (InputMethodUtil::IsKeyboardLayout(input_method_id_to_switch)) { |
+ should_hide_properties_ = true; |
+ FOR_EACH_OBSERVER(InputMethodManager::Observer, |
+ observers_, |
+ InputMethodPropertyChanged(this)); |
+ } else { |
Seigo Nonaka
2012/04/13 09:44:22
I'm not sure about should_hide_properties_ variabl
Yusuke Sato
2012/04/16 02:11:25
probably it's possible to remove should_hide_prope
Yusuke Sato
2012/04/16 05:54:31
Removed the variable. Slightly modified IBusContro
|
+ ibus_controller_->ChangeInputMethod(input_method_id_to_switch); |
+ } |
+ |
+ if (current_input_method_.id() != input_method_id_to_switch) { |
+ const InputMethodDescriptor* descriptor = NULL; |
+ if (!InputMethodUtil::IsExtensionInputMethod(input_method_id_to_switch)) { |
+ descriptor = |
+ util_.GetInputMethodDescriptorFromId(input_method_id_to_switch); |
+ } else { |
+ std::map<std::string, InputMethodDescriptor>::const_iterator i = |
+ extra_input_methods_.find(input_method_id_to_switch); |
+ DCHECK(i != extra_input_methods_.end()); |
+ descriptor = &(i->second); |
+ } |
+ DCHECK(descriptor); |
+ |
+ previous_input_method_ = current_input_method_; |
+ current_input_method_ = *descriptor; |
+ |
+ // Change the keyboard layout to a preferred layout for the input method. |
+ if (!xkeyboard_->SetCurrentKeyboardLayoutByName( |
+ current_input_method_.keyboard_layout())) { |
+ LOG(ERROR) << "Failed to change keyboard layout to " |
+ << current_input_method_.keyboard_layout(); |
+ } |
+ } |
+ |
+ // Update input method indicators (e.g. "US", "DV") in Chrome windows. |
+ FOR_EACH_OBSERVER(InputMethodManager::Observer, |
+ observers_, |
+ InputMethodChanged(this)); |
+} |
+ |
+void InputMethodManagerImpl::ActivateInputMethodProperty( |
+ const std::string& key) { |
+ DCHECK(!key.empty()); |
+ ibus_controller_->ActivateInputMethodProperty(key); |
+} |
+ |
+void InputMethodManagerImpl::AddInputMethodExtension( |
+ const std::string& id, |
+ const std::string& name, |
+ const std::vector<std::string>& layouts, |
+ const std::string& language) { |
+ if (state_ == STATE_TERMINATING) |
+ return; |
+ |
+ if (!InputMethodUtil::IsExtensionInputMethod(id)) { |
+ LOG(ERROR) << id << " is not a valid extension input method ID."; |
+ return; |
+ } |
+ |
+ const std::string virtual_layouts = JoinString(layouts, ','); |
+ extra_input_methods_[id] = InputMethodDescriptor( |
+ whitelist_, id, name, virtual_layouts, language); |
+ |
+ if (!Contains(active_input_method_ids_, id)) { |
+ active_input_method_ids_.push_back(id); |
+ } else { |
+ LOG(ERROR) << "AddInputMethodExtension: alread added: " |
+ << id << ", " << name; |
+ // Call Start() anyway, just in case. |
+ } |
+ |
+ // Ensure that the input method daemon is running. |
+ MaybeInitializeCandidateWindowController(); |
+ ibus_controller_->Start(active_input_method_ids_); |
+} |
+ |
+void InputMethodManagerImpl::RemoveInputMethodExtension(const std::string& id) { |
+ if (!InputMethodUtil::IsExtensionInputMethod(id)) |
+ LOG(ERROR) << id << " is not a valid extension input method ID."; |
+ |
+ std::vector<std::string>::iterator i = Find(active_input_method_ids_, id); |
+ if (i != active_input_method_ids_.end()) |
+ active_input_method_ids_.erase(i); |
+ extra_input_methods_.erase(id); |
+ |
+ if (ContainOnlyKeyboardLayout(active_input_method_ids_)) { |
+ // Do NOT call ibus_controller_->Stop(); here to work around a crash issue |
+ // at crosbug.com/27051. |
+ // TODO(yusukes): We can safely call Stop(); here once crosbug.com/26443 |
+ // is implemented. |
+ } |
+ |
+ // If |current_input_method| is no longer in |active_input_method_ids_|, |
+ // switch to the first one in |active_input_method_ids_|. |
+ ChangeInputMethod(current_input_method_.id()); |
+} |
+ |
+void InputMethodManagerImpl::EnableHotkeys() { |
+ ignore_hotkeys_ = false; |
+} |
+ |
+void InputMethodManagerImpl::DisableHotkeys() { |
+ ignore_hotkeys_ = true; |
+} |
+ |
+bool InputMethodManagerImpl::SwitchToNextInputMethod() { |
+ if (ignore_hotkeys_) |
+ return false; |
+ |
+ // Sanity checks. |
+ if (active_input_method_ids_.empty()) { |
+ LOG(ERROR) << "active input method is empty"; |
+ return false; |
+ } |
+ if (current_input_method_.id().empty()) { |
+ LOG(ERROR) << "current_input_method_ is unknown"; |
+ return false; |
+ } |
+ |
+ // Find the next input method. |
+ std::vector<std::string>::const_iterator iter = |
+ Find(active_input_method_ids_, current_input_method_.id()); |
+ if (iter != active_input_method_ids_.end()) |
+ ++iter; |
+ if (iter == active_input_method_ids_.end()) |
+ iter = active_input_method_ids_.begin(); |
+ ChangeInputMethod(*iter); |
+ return true; |
+} |
+ |
+bool InputMethodManagerImpl::SwitchToPreviousInputMethod() { |
+ if (ignore_hotkeys_) |
+ return false; |
+ |
+ // Sanity check. |
+ if (active_input_method_ids_.empty()) { |
+ LOG(ERROR) << "active input method is empty"; |
+ return false; |
+ } |
+ |
+ if (previous_input_method_.id().empty() || |
+ previous_input_method_.id() == current_input_method_.id()) { |
+ return SwitchToNextInputMethod(); |
+ } |
+ |
+ std::vector<std::string>::const_iterator iter = |
+ Find(active_input_method_ids_, previous_input_method_.id()); |
+ if (iter == active_input_method_ids_.end()) { |
+ // previous_input_method_ is not supported. |
+ return SwitchToNextInputMethod(); |
+ } |
+ ChangeInputMethod(*iter); |
+ return true; |
+} |
+ |
+bool InputMethodManagerImpl::SwitchInputMethod( |
+ const ui::Accelerator& accelerator) { |
+ if (ignore_hotkeys_) |
+ return false; |
+ |
+ // Sanity check. |
+ if (active_input_method_ids_.empty()) { |
+ LOG(ERROR) << "active input method is empty"; |
+ return false; |
+ } |
+ |
+ // Get the list of input method ids for the |accelerator|. For example, get |
+ // { "mozc-hangul", "xkb:kr:kr104:kor" } for ui::VKEY_DBE_SBCSCHAR. |
+ std::vector<std::string> input_method_ids_to_switch; |
+ switch (accelerator.key_code()) { |
+ case ui::VKEY_CONVERT: // Henkan key on JP106 keyboard |
+ input_method_ids_to_switch.push_back("mozc-jp"); |
+ break; |
+ case ui::VKEY_NONCONVERT: // Muhenkan key on JP106 keyboard |
+ input_method_ids_to_switch.push_back("xkb:jp::jpn"); |
+ break; |
+ case ui::VKEY_DBE_SBCSCHAR: // ZenkakuHankaku key on JP106 keyboard |
+ case ui::VKEY_DBE_DBCSCHAR: |
+ input_method_ids_to_switch.push_back("mozc-jp"); |
+ input_method_ids_to_switch.push_back("xkb:jp::jpn"); |
+ break; |
+ case ui::VKEY_HANGUL: // Hangul (or right Alt) key on Korean keyboard |
+ case ui::VKEY_SPACE: // Shift+Space |
+ input_method_ids_to_switch.push_back("mozc-hangul"); |
+ input_method_ids_to_switch.push_back("xkb:kr:kr104:kor"); |
+ break; |
+ default: |
+ NOTREACHED(); |
+ break; |
+ } |
+ if (input_method_ids_to_switch.empty()) { |
+ LOG(ERROR) << "Unexpected VKEY: " << accelerator.key_code(); |
+ return false; |
+ } |
+ |
+ // Obtain the intersection of input_method_ids_to_switch and |
+ // active_input_method_ids_. The order of IDs in active_input_method_ids_ is |
+ // preserved. |
+ std::vector<std::string> ids; |
+ for (size_t i = 0; i < input_method_ids_to_switch.size(); ++i) { |
+ const std::string& id = input_method_ids_to_switch[i]; |
+ if (Contains(active_input_method_ids_, id)) |
+ ids.push_back(id); |
+ } |
+ if (ids.empty()) { |
+ // No input method for the accelerator is active. For example, we should |
+ // just ignore VKEY_HANGUL when mozc-hangul is not active. |
+ return false; |
+ } |
+ |
+ // If |current_input_method_| is not in ids, switch to ids[0]. If |
+ // |current_input_method_| is ids[N], switch to ids[N+1]. |
+ std::vector<std::string>::const_iterator iter = |
+ Find(ids, current_input_method_.id()); |
+ if (iter != ids.end()) |
+ ++iter; |
+ if (iter == ids.end()) |
+ iter = ids.begin(); |
+ ChangeInputMethod(*iter); |
+ return true; // consume the accelerator. |
+} |
+ |
+InputMethodDescriptor InputMethodManagerImpl::GetCurrentInputMethod() const { |
+ if (current_input_method_.id().empty()) |
+ return InputMethodDescriptor::GetFallbackInputMethodDescriptor(); |
+ return current_input_method_; |
+} |
+ |
+InputMethodPropertyList |
+InputMethodManagerImpl::GetCurrentInputMethodProperties() const { |
+ if (should_hide_properties_ || |
+ // This check is necessary since an IME property (e.g. for Pinyin) might |
+ // be sent from ibus-daemon AFTER the current input method is switched |
+ // to XKB. |
+ InputMethodUtil::IsKeyboardLayout(GetCurrentInputMethod().id())) { |
+ return InputMethodPropertyList(); |
+ } |
+ return ibus_controller_->GetCurrentProperties(); |
+} |
+ |
+XKeyboard* InputMethodManagerImpl::GetXKeyboard() { |
+ return xkeyboard_.get(); |
+} |
+ |
+InputMethodUtil* InputMethodManagerImpl::GetInputMethodUtil() { |
+ return &util_; |
+} |
+ |
+void InputMethodManagerImpl::Init() { |
+ DCHECK(!ibus_controller_.get()); |
+ |
+ browser_state_monitor_.reset(new BrowserStateMonitor(this)); |
+ ibus_controller_.reset(IBusController::Create()); |
+ xkeyboard_.reset(XKeyboard::Create(util_)); |
+ ibus_controller_->AddObserver(this); |
+} |
+ |
+void InputMethodManagerImpl::SetIBusControllerForTesting( |
+ IBusController* ibus_controller) { |
+ ibus_controller_.reset(ibus_controller); |
+ ibus_controller_->AddObserver(this); |
+} |
+ |
+void InputMethodManagerImpl::SetCandidateWindowControllerForTesting( |
+ CandidateWindowController* candidate_window_controller) { |
+ candidate_window_controller_.reset(candidate_window_controller); |
+ candidate_window_controller_->Init(); |
+ candidate_window_controller_->AddObserver(this); |
+} |
+ |
+void InputMethodManagerImpl::SetXKeyboardForTesting(XKeyboard* xkeyboard) { |
+ xkeyboard_.reset(xkeyboard); |
+} |
+ |
+void InputMethodManagerImpl::PropertyChanged() { |
+ should_hide_properties_ = ibus_controller_->GetCurrentProperties().empty(); |
+ FOR_EACH_OBSERVER(InputMethodManager::Observer, |
+ observers_, |
+ InputMethodPropertyChanged(this)); |
+} |
+ |
+void InputMethodManagerImpl::CandidateWindowOpened() { |
+ FOR_EACH_OBSERVER(InputMethodManager::CandidateWindowObserver, |
+ candidate_window_observers_, |
+ CandidateWindowOpened(this)); |
+} |
+ |
+void InputMethodManagerImpl::CandidateWindowClosed() { |
+ FOR_EACH_OBSERVER(InputMethodManager::CandidateWindowObserver, |
+ candidate_window_observers_, |
+ CandidateWindowClosed(this)); |
+} |
+ |
+void InputMethodManagerImpl::OnScreenLocked() { |
+ saved_previous_input_method_ = previous_input_method_; |
+ saved_current_input_method_ = current_input_method_; |
+ saved_active_input_method_ids_ = active_input_method_ids_; |
+ |
+ const std::string hardware_keyboard_id = util_.GetHardwareInputMethodId(); |
+ // We'll add the hardware keyboard if it's not included in |
+ // |active_input_method_list| so that the user can always use the hardware |
+ // keyboard on the screen locker. |
+ bool should_add_hardware_keyboard = true; |
+ |
+ active_input_method_ids_.clear(); |
+ for (size_t i = 0; i < saved_active_input_method_ids_.size(); ++i) { |
+ const std::string& input_method_id = saved_active_input_method_ids_[i]; |
+ // Skip if it's not a keyboard layout. Drop input methods including |
+ // extension ones. |
+ if (!InputMethodUtil::IsKeyboardLayout(input_method_id)) |
+ continue; |
+ active_input_method_ids_.push_back(input_method_id); |
+ if (input_method_id == hardware_keyboard_id) |
+ should_add_hardware_keyboard = false; |
+ } |
+ if (should_add_hardware_keyboard) |
+ active_input_method_ids_.push_back(hardware_keyboard_id); |
+ |
+ ChangeInputMethod(current_input_method_.id()); |
+} |
+ |
+void InputMethodManagerImpl::OnScreenUnlocked() { |
+ previous_input_method_ = saved_previous_input_method_; |
+ current_input_method_ = saved_current_input_method_; |
+ active_input_method_ids_ = saved_active_input_method_ids_; |
+ |
+ ChangeInputMethod(current_input_method_.id()); |
+} |
+ |
+bool InputMethodManagerImpl::InputMethodIsActivated( |
+ const std::string& input_method_id) { |
+ return Contains(active_input_method_ids_, input_method_id); |
+} |
+ |
+bool InputMethodManagerImpl::ContainOnlyKeyboardLayout( |
+ const std::vector<std::string>& value) { |
+ for (size_t i = 0; i < value.size(); ++i) { |
+ if (!InputMethodUtil::IsKeyboardLayout(value[i])) |
+ return false; |
+ } |
+ return true; |
+} |
+ |
+void InputMethodManagerImpl::MaybeInitializeCandidateWindowController() { |
+#if !defined(USE_VIRTUAL_KEYBOARD) |
+ if (candidate_window_controller_.get()) |
+ return; |
+ |
+ candidate_window_controller_.reset( |
+ CandidateWindowController::CreateCandidateWindowController()); |
+ if (candidate_window_controller_->Init()) |
+ candidate_window_controller_->AddObserver(this); |
+ else |
+ LOG(WARNING) << "Failed to initialize the candidate window controller"; |
+#endif |
+} |
+ |
+// static |
+InputMethodManagerImpl* InputMethodManagerImpl::GetInstanceForTesting() { |
+ return new InputMethodManagerImpl; |
+} |
+ |
+} // namespace input_method |
+} // namespace chromeos |