| 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..34a5410134b7ec3612867f082892d53dffc32f18
|
| --- /dev/null
|
| +++ b/chrome/browser/chromeos/input_method/input_method_manager_impl.cc
|
| @@ -0,0 +1,613 @@
|
| +// 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() {
|
| + return whitelist_.GetSupportedInputMethods();
|
| +}
|
| +
|
| +InputMethodDescriptors* InputMethodManagerImpl::GetActiveInputMethods() {
|
| + 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 reletive 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 {
|
| + 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
|
|
|