This source file includes following definitions.
- Contains
- IsLoginKeyboard
- MigrateXkbInputMethods
- weak_ptr_factory_
- AddObserver
- AddCandidateWindowObserver
- RemoveObserver
- RemoveCandidateWindowObserver
- SetState
- GetSupportedInputMethods
- GetActiveInputMethods
- GetActiveInputMethodIds
- GetNumActiveInputMethods
- GetInputMethodFromId
- EnableLoginLayouts
- EnableInputMethodImpl
- ReconfigureIMFramework
- EnableInputMethod
- ReplaceEnabledInputMethods
- ChangeInputMethod
- ChangeInputMethodInternal
- OnComponentExtensionInitialized
- LoadNecessaryComponentExtensions
- ActivateInputMethodMenuItem
- AddInputMethodExtension
- RemoveInputMethodExtension
- GetInputMethodExtensions
- SetEnabledExtensionImes
- SetInputMethodLoginDefault
- SwitchToNextInputMethod
- SwitchToPreviousInputMethod
- SwitchInputMethod
- SwitchToNextInputMethodInternal
- GetCurrentInputMethod
- IsISOLevel5ShiftUsedByCurrentInputMethod
- IsAltGrUsedByCurrentInputMethod
- GetXKeyboard
- GetInputMethodUtil
- GetComponentExtensionIMEManager
- InitializeComponentExtension
- Init
- SetCandidateWindowControllerForTesting
- SetXKeyboardForTesting
- InitializeComponentExtensionForTesting
- CandidateClicked
- CandidateWindowOpened
- CandidateWindowClosed
- OnScreenLocked
- OnScreenUnlocked
- InputMethodIsActivated
- MaybeInitializeCandidateWindowController
#include "chrome/browser/chromeos/input_method/input_method_manager_impl.h"
#include <algorithm>
#include "ash/ime/input_method_menu_item.h"
#include "ash/ime/input_method_menu_manager.h"
#include "base/basictypes.h"
#include "base/bind.h"
#include "base/location.h"
#include "base/memory/scoped_ptr.h"
#include "base/prefs/pref_service.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/sys_info.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chromeos/input_method/candidate_window_controller.h"
#include "chrome/browser/chromeos/input_method/component_extension_ime_manager_impl.h"
#include "chrome/browser/chromeos/input_method/input_method_engine.h"
#include "chrome/browser/chromeos/language_preferences.h"
#include "chromeos/ime/component_extension_ime_manager.h"
#include "chromeos/ime/extension_ime_util.h"
#include "chromeos/ime/fake_xkeyboard.h"
#include "chromeos/ime/input_method_delegate.h"
#include "chromeos/ime/xkeyboard.h"
#include "third_party/icu/source/common/unicode/uloc.h"
#include "ui/base/accelerators/accelerator.h"
namespace chromeos {
namespace input_method {
namespace {
const char nacl_mozc_jp_id[] =
"_comp_ime_fpfbhcjppmaeaijcidgiibchfbnhbeljnacl_mozc_jp";
bool Contains(const std::vector<std::string>& container,
const std::string& value) {
return std::find(container.begin(), container.end(), value) !=
container.end();
}
}
bool InputMethodManagerImpl::IsLoginKeyboard(
const std::string& layout) const {
return util_.IsLoginKeyboard(layout);
}
bool InputMethodManagerImpl::MigrateXkbInputMethods(
std::vector<std::string>* input_method_ids) {
return util_.MigrateXkbInputMethods(input_method_ids);
}
InputMethodManagerImpl::InputMethodManagerImpl(
scoped_ptr<InputMethodDelegate> delegate)
: delegate_(delegate.Pass()),
state_(STATE_LOGIN_SCREEN),
util_(delegate_.get(), GetSupportedInputMethods()),
component_extension_ime_manager_(new ComponentExtensionIMEManager()),
weak_ptr_factory_(this) {
}
InputMethodManagerImpl::~InputMethodManagerImpl() {
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: {
if (candidate_window_controller_.get())
candidate_window_controller_.reset();
break;
}
}
}
scoped_ptr<InputMethodDescriptors>
InputMethodManagerImpl::GetSupportedInputMethods() const {
scoped_ptr<InputMethodDescriptors> whitelist_imes =
whitelist_.GetSupportedInputMethods();
if (!extension_ime_util::UseWrappedExtensionKeyboardLayouts())
return whitelist_imes.Pass();
return scoped_ptr<InputMethodDescriptors>(new InputMethodDescriptors).Pass();
}
scoped_ptr<InputMethodDescriptors>
InputMethodManagerImpl::GetActiveInputMethods() const {
scoped_ptr<InputMethodDescriptors> result(new InputMethodDescriptors);
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
DVLOG(1) << "Descriptor is not found for: " << input_method_id;
}
}
if (result->empty()) {
result->push_back(
InputMethodUtil::GetFallbackInputMethodDescriptor());
}
return result.Pass();
}
const std::vector<std::string>&
InputMethodManagerImpl::GetActiveInputMethodIds() const {
return active_input_method_ids_;
}
size_t InputMethodManagerImpl::GetNumActiveInputMethods() const {
return active_input_method_ids_.size();
}
const InputMethodDescriptor* InputMethodManagerImpl::GetInputMethodFromId(
const std::string& input_method_id) const {
const InputMethodDescriptor* ime = util_.GetInputMethodDescriptorFromId(
input_method_id);
if (!ime) {
std::map<std::string, InputMethodDescriptor>::const_iterator ix =
extra_input_methods_.find(input_method_id);
if (ix != extra_input_methods_.end())
ime = &ix->second;
}
return ime;
}
void InputMethodManagerImpl::EnableLoginLayouts(
const std::string& language_code,
const std::vector<std::string>& initial_layouts) {
if (state_ == STATE_TERMINATING)
return;
std::vector<std::string> candidates =
util_.GetHardwareLoginInputMethodIds();
std::vector<std::string> layouts_from_locale;
util_.GetInputMethodIdsFromLanguageCode(language_code,
kKeyboardLayoutsOnly,
&layouts_from_locale);
candidates.insert(candidates.end(), layouts_from_locale.begin(),
layouts_from_locale.end());
std::vector<std::string> layouts;
for (size_t i = 0; i < initial_layouts.size(); ++i) {
if (util_.IsValidInputMethodId(initial_layouts[i])) {
if (IsLoginKeyboard(initial_layouts[i])) {
layouts.push_back(initial_layouts[i]);
} else {
DVLOG(1)
<< "EnableLoginLayouts: ignoring non-login initial keyboard layout:"
<< initial_layouts[i];
}
} else if (!initial_layouts[i].empty()) {
DVLOG(1) << "EnableLoginLayouts: ignoring non-keyboard or invalid ID: "
<< initial_layouts[i];
}
}
for (size_t i = 0; i < candidates.size(); ++i) {
const std::string& candidate = candidates[i];
if (!Contains(layouts, candidate) && IsLoginKeyboard(candidate))
layouts.push_back(candidate);
}
MigrateXkbInputMethods(&layouts);
active_input_method_ids_.swap(layouts);
if (active_input_method_ids_.size() > 1)
MaybeInitializeCandidateWindowController();
ChangeInputMethod(initial_layouts.empty() ? "" :
extension_ime_util::GetInputMethodIDByKeyboardLayout(
initial_layouts[0]));
}
bool InputMethodManagerImpl::EnableInputMethodImpl(
const std::string& input_method_id,
std::vector<std::string>* new_active_input_method_ids) const {
DCHECK(new_active_input_method_ids);
if (!util_.IsValidInputMethodId(input_method_id)) {
DVLOG(1) << "EnableInputMethod: Invalid ID: " << input_method_id;
return false;
}
if (!Contains(*new_active_input_method_ids, input_method_id))
new_active_input_method_ids->push_back(input_method_id);
return true;
}
void InputMethodManagerImpl::ReconfigureIMFramework() {
LoadNecessaryComponentExtensions();
MaybeInitializeCandidateWindowController();
}
bool InputMethodManagerImpl::EnableInputMethod(
const std::string& input_method_id) {
if (!EnableInputMethodImpl(input_method_id, &active_input_method_ids_))
return false;
ReconfigureIMFramework();
return true;
}
bool InputMethodManagerImpl::ReplaceEnabledInputMethods(
const std::vector<std::string>& new_active_input_method_ids) {
if (state_ == STATE_TERMINATING)
return false;
std::vector<std::string> new_active_input_method_ids_filtered;
for (size_t i = 0; i < new_active_input_method_ids.size(); ++i)
EnableInputMethodImpl(new_active_input_method_ids[i],
&new_active_input_method_ids_filtered);
if (new_active_input_method_ids_filtered.empty()) {
DVLOG(1) << "ReplaceEnabledInputMethods: No valid input method ID";
return false;
}
for (size_t i = 0; i < active_input_method_ids_.size(); ++i) {
const std::string& input_method_id = active_input_method_ids_[i];
if (extension_ime_util::IsExtensionIME(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);
MigrateXkbInputMethods(&active_input_method_ids_);
ReconfigureIMFramework();
ChangeInputMethod(current_input_method_.id());
return true;
}
void InputMethodManagerImpl::ChangeInputMethod(
const std::string& input_method_id) {
ChangeInputMethodInternal(input_method_id, false);
}
bool InputMethodManagerImpl::ChangeInputMethodInternal(
const std::string& input_method_id,
bool show_message) {
if (state_ == STATE_TERMINATING)
return false;
std::string input_method_id_to_switch = input_method_id;
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()) {
DVLOG(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 (!component_extension_ime_manager_->IsInitialized() &&
(!InputMethodUtil::IsKeyboardLayout(input_method_id_to_switch) ||
extension_ime_util::IsKeyboardLayoutExtension(
input_method_id_to_switch))) {
pending_input_method_ = input_method_id_to_switch;
return false;
}
pending_input_method_.clear();
if (candidate_window_controller_.get())
candidate_window_controller_->Hide();
IMEEngineHandlerInterface* engine =
IMEBridge::Get()->GetCurrentEngineHandler();
if (engine)
engine->Disable();
if (InputMethodUtil::IsKeyboardLayout(input_method_id_to_switch) &&
!extension_ime_util::IsKeyboardLayoutExtension(
input_method_id_to_switch)) {
IMEBridge::Get()->SetCurrentEngineHandler(NULL);
} else {
IMEEngineHandlerInterface* next_engine =
IMEBridge::Get()->SetCurrentEngineHandlerById(
input_method_id_to_switch);
if (next_engine)
next_engine->Enable();
}
if (current_input_method_.id() != input_method_id_to_switch) {
const ash::ime::InputMethodMenuItemList empty_menu_item_list;
ash::ime::InputMethodMenuManager* input_method_menu_manager =
ash::ime::InputMethodMenuManager::GetInstance();
input_method_menu_manager->SetCurrentInputMethodMenuItemList(
empty_menu_item_list);
const InputMethodDescriptor* descriptor = NULL;
if (extension_ime_util::IsExtensionIME(input_method_id_to_switch)) {
DCHECK(extra_input_methods_.find(input_method_id_to_switch) !=
extra_input_methods_.end());
descriptor = &(extra_input_methods_[input_method_id_to_switch]);
} else {
descriptor =
util_.GetInputMethodDescriptorFromId(input_method_id_to_switch);
}
DCHECK(descriptor);
previous_input_method_ = current_input_method_;
current_input_method_ = *descriptor;
}
if (!xkeyboard_->SetCurrentKeyboardLayoutByName(
current_input_method_.GetPreferredKeyboardLayout())) {
LOG(ERROR) << "Failed to change keyboard layout to "
<< current_input_method_.GetPreferredKeyboardLayout();
}
FOR_EACH_OBSERVER(InputMethodManager::Observer,
observers_,
InputMethodChanged(this, show_message));
return true;
}
void InputMethodManagerImpl::OnComponentExtensionInitialized(
scoped_ptr<ComponentExtensionIMEManagerDelegate> delegate) {
DCHECK(thread_checker_.CalledOnValidThread());
component_extension_ime_manager_->Initialize(delegate.Pass());
util_.SetComponentExtensions(
component_extension_ime_manager_->GetAllIMEAsInputMethodDescriptor());
LoadNecessaryComponentExtensions();
if (!pending_input_method_.empty())
ChangeInputMethodInternal(pending_input_method_, false);
}
void InputMethodManagerImpl::LoadNecessaryComponentExtensions() {
if (!component_extension_ime_manager_->IsInitialized())
return;
std::vector<std::string> unfiltered_input_method_ids;
unfiltered_input_method_ids.swap(active_input_method_ids_);
for (size_t i = 0; i < unfiltered_input_method_ids.size(); ++i) {
if (!extension_ime_util::IsComponentExtensionIME(
unfiltered_input_method_ids[i])) {
active_input_method_ids_.push_back(unfiltered_input_method_ids[i]);
} else if (component_extension_ime_manager_->IsWhitelisted(
unfiltered_input_method_ids[i])) {
component_extension_ime_manager_->LoadComponentExtensionIME(
unfiltered_input_method_ids[i]);
active_input_method_ids_.push_back(unfiltered_input_method_ids[i]);
}
}
component_extension_ime_manager_->NotifyInitialized();
}
void InputMethodManagerImpl::ActivateInputMethodMenuItem(
const std::string& key) {
DCHECK(!key.empty());
if (ash::ime::InputMethodMenuManager::GetInstance()->
HasInputMethodMenuItemForKey(key)) {
IMEEngineHandlerInterface* engine =
IMEBridge::Get()->GetCurrentEngineHandler();
if (engine)
engine->PropertyActivate(key);
return;
}
DVLOG(1) << "ActivateInputMethodMenuItem: unknown key: " << key;
}
void InputMethodManagerImpl::AddInputMethodExtension(
const std::string& id,
InputMethodEngineInterface* engine) {
if (state_ == STATE_TERMINATING)
return;
if (!extension_ime_util::IsExtensionIME(id) &&
!extension_ime_util::IsComponentExtensionIME(id)) {
DVLOG(1) << id << " is not a valid extension input method ID.";
return;
}
DCHECK(engine);
const InputMethodDescriptor& descriptor = engine->GetDescriptor();
extra_input_methods_[id] = descriptor;
if (Contains(enabled_extension_imes_, id) &&
!extension_ime_util::IsComponentExtensionIME(id)) {
if (!Contains(active_input_method_ids_, id)) {
active_input_method_ids_.push_back(id);
} else {
DVLOG(1) << "AddInputMethodExtension: alread added: "
<< id << ", " << descriptor.name();
}
MaybeInitializeCandidateWindowController();
}
IMEBridge::Get()->SetEngineHandler(id, engine);
}
void InputMethodManagerImpl::RemoveInputMethodExtension(const std::string& id) {
if (!extension_ime_util::IsExtensionIME(id))
DVLOG(1) << id << " is not a valid extension input method ID.";
std::vector<std::string>::iterator i = std::find(
active_input_method_ids_.begin(), active_input_method_ids_.end(), id);
if (i != active_input_method_ids_.end())
active_input_method_ids_.erase(i);
extra_input_methods_.erase(id);
ChangeInputMethod(current_input_method_.id());
if (IMEBridge::Get()->GetCurrentEngineHandler() ==
IMEBridge::Get()->GetEngineHandler(id))
IMEBridge::Get()->SetCurrentEngineHandler(NULL);
}
void InputMethodManagerImpl::GetInputMethodExtensions(
InputMethodDescriptors* result) {
std::map<std::string, InputMethodDescriptor>::iterator iter;
for (iter = extra_input_methods_.begin(); iter != extra_input_methods_.end();
++iter) {
if (extension_ime_util::IsExtensionIME(iter->first))
result->push_back(iter->second);
}
}
void InputMethodManagerImpl::SetEnabledExtensionImes(
std::vector<std::string>* ids) {
enabled_extension_imes_.clear();
enabled_extension_imes_.insert(enabled_extension_imes_.end(),
ids->begin(),
ids->end());
bool active_imes_changed = false;
for (std::map<std::string, InputMethodDescriptor>::iterator extra_iter =
extra_input_methods_.begin(); extra_iter != extra_input_methods_.end();
++extra_iter) {
if (extension_ime_util::IsComponentExtensionIME(
extra_iter->first))
continue;
std::vector<std::string>::iterator active_iter = std::find(
active_input_method_ids_.begin(), active_input_method_ids_.end(),
extra_iter->first);
bool active = active_iter != active_input_method_ids_.end();
bool enabled = Contains(enabled_extension_imes_, extra_iter->first);
if (active && !enabled)
active_input_method_ids_.erase(active_iter);
if (!active && enabled)
active_input_method_ids_.push_back(extra_iter->first);
if (active == !enabled)
active_imes_changed = true;
}
if (active_imes_changed) {
MaybeInitializeCandidateWindowController();
ChangeInputMethod(current_input_method_.id());
}
}
void InputMethodManagerImpl::SetInputMethodLoginDefault() {
if (g_browser_process && g_browser_process->local_state()) {
const std::string locale = g_browser_process->GetApplicationLocale();
PrefService* prefs = g_browser_process->local_state();
std::string initial_input_method_id =
prefs->GetString(chromeos::language_prefs::kPreferredKeyboardLayout);
std::vector<std::string> input_methods_to_be_enabled;
if (initial_input_method_id.empty()) {
input_methods_to_be_enabled = util_.GetHardwareLoginInputMethodIds();
} else {
input_methods_to_be_enabled.push_back(initial_input_method_id);
}
EnableLoginLayouts(locale, input_methods_to_be_enabled);
}
}
bool InputMethodManagerImpl::SwitchToNextInputMethod() {
if (active_input_method_ids_.empty()) {
DVLOG(1) << "active input method is empty";
return false;
}
if (current_input_method_.id().empty()) {
DVLOG(1) << "current_input_method_ is unknown";
return false;
}
if (active_input_method_ids_.size() == 1)
return false;
SwitchToNextInputMethodInternal(active_input_method_ids_,
current_input_method_.id());
return true;
}
bool InputMethodManagerImpl::SwitchToPreviousInputMethod(
const ui::Accelerator& accelerator) {
if (active_input_method_ids_.empty()) {
DVLOG(1) << "active input method is empty";
return false;
}
if (active_input_method_ids_.size() == 1)
return false;
if (accelerator.type() == ui::ET_KEY_RELEASED)
return true;
if (previous_input_method_.id().empty() ||
previous_input_method_.id() == current_input_method_.id()) {
return SwitchToNextInputMethod();
}
std::vector<std::string>::const_iterator iter =
std::find(active_input_method_ids_.begin(),
active_input_method_ids_.end(),
previous_input_method_.id());
if (iter == active_input_method_ids_.end()) {
return SwitchToNextInputMethod();
}
ChangeInputMethodInternal(*iter, true);
return true;
}
bool InputMethodManagerImpl::SwitchInputMethod(
const ui::Accelerator& accelerator) {
if (active_input_method_ids_.empty()) {
DVLOG(1) << "active input method is empty";
return false;
}
std::vector<std::string> input_method_ids_to_switch;
switch (accelerator.key_code()) {
case ui::VKEY_CONVERT:
input_method_ids_to_switch.push_back(nacl_mozc_jp_id);
break;
case ui::VKEY_NONCONVERT:
input_method_ids_to_switch.push_back("xkb:jp::jpn");
break;
case ui::VKEY_DBE_SBCSCHAR:
case ui::VKEY_DBE_DBCSCHAR:
input_method_ids_to_switch.push_back(nacl_mozc_jp_id);
input_method_ids_to_switch.push_back("xkb:jp::jpn");
break;
default:
NOTREACHED();
break;
}
if (input_method_ids_to_switch.empty()) {
DVLOG(1) << "Unexpected VKEY: " << accelerator.key_code();
return false;
}
MigrateXkbInputMethods(&input_method_ids_to_switch);
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()) {
return false;
}
SwitchToNextInputMethodInternal(ids, current_input_method_.id());
return true;
}
void InputMethodManagerImpl::SwitchToNextInputMethodInternal(
const std::vector<std::string>& input_method_ids,
const std::string& current_input_method_id) {
std::vector<std::string>::const_iterator iter =
std::find(input_method_ids.begin(),
input_method_ids.end(),
current_input_method_id);
if (iter != input_method_ids.end())
++iter;
if (iter == input_method_ids.end())
iter = input_method_ids.begin();
ChangeInputMethodInternal(*iter, true);
}
InputMethodDescriptor InputMethodManagerImpl::GetCurrentInputMethod() const {
if (current_input_method_.id().empty())
return InputMethodUtil::GetFallbackInputMethodDescriptor();
return current_input_method_;
}
bool InputMethodManagerImpl::IsISOLevel5ShiftUsedByCurrentInputMethod() const {
return xkeyboard_->IsISOLevel5ShiftAvailable();
}
bool InputMethodManagerImpl::IsAltGrUsedByCurrentInputMethod() const {
return xkeyboard_->IsAltGrAvailable();
}
XKeyboard* InputMethodManagerImpl::GetXKeyboard() {
return xkeyboard_.get();
}
InputMethodUtil* InputMethodManagerImpl::GetInputMethodUtil() {
return &util_;
}
ComponentExtensionIMEManager*
InputMethodManagerImpl::GetComponentExtensionIMEManager() {
DCHECK(thread_checker_.CalledOnValidThread());
return component_extension_ime_manager_.get();
}
void InputMethodManagerImpl::InitializeComponentExtension() {
ComponentExtensionIMEManagerImpl* impl =
new ComponentExtensionIMEManagerImpl();
scoped_ptr<ComponentExtensionIMEManagerDelegate> delegate(impl);
impl->InitializeAsync(base::Bind(
&InputMethodManagerImpl::OnComponentExtensionInitialized,
weak_ptr_factory_.GetWeakPtr(),
base::Passed(&delegate)));
}
void InputMethodManagerImpl::Init(base::SequencedTaskRunner* ui_task_runner) {
DCHECK(thread_checker_.CalledOnValidThread());
if (base::SysInfo::IsRunningOnChromeOS())
xkeyboard_.reset(XKeyboard::Create());
else
xkeyboard_.reset(new FakeXKeyboard());
ui_task_runner->PostTask(
FROM_HERE,
base::Bind(&InputMethodManagerImpl::InitializeComponentExtension,
weak_ptr_factory_.GetWeakPtr()));
}
void InputMethodManagerImpl::SetCandidateWindowControllerForTesting(
CandidateWindowController* candidate_window_controller) {
candidate_window_controller_.reset(candidate_window_controller);
candidate_window_controller_->AddObserver(this);
}
void InputMethodManagerImpl::SetXKeyboardForTesting(XKeyboard* xkeyboard) {
xkeyboard_.reset(xkeyboard);
}
void InputMethodManagerImpl::InitializeComponentExtensionForTesting(
scoped_ptr<ComponentExtensionIMEManagerDelegate> delegate) {
OnComponentExtensionInitialized(delegate.Pass());
}
void InputMethodManagerImpl::CandidateClicked(int index) {
IMEEngineHandlerInterface* engine =
IMEBridge::Get()->GetCurrentEngineHandler();
if (engine)
engine->CandidateClicked(index);
}
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_;
std::set<std::string> added_ids_;
const std::vector<std::string>& hardware_keyboard_ids =
util_.GetHardwareLoginInputMethodIds();
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];
if (!IsLoginKeyboard(input_method_id) ||
added_ids_.find(input_method_id) != added_ids_.end())
continue;
active_input_method_ids_.push_back(input_method_id);
added_ids_.insert(input_method_id);
}
for (size_t i = 0; i < hardware_keyboard_ids.size(); ++i) {
if (added_ids_.find(hardware_keyboard_ids[i]) == added_ids_.end()) {
active_input_method_ids_.push_back(hardware_keyboard_ids[i]);
added_ids_.insert(hardware_keyboard_ids[i]);
}
}
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);
}
void InputMethodManagerImpl::MaybeInitializeCandidateWindowController() {
if (candidate_window_controller_.get())
return;
candidate_window_controller_.reset(
CandidateWindowController::CreateCandidateWindowController());
candidate_window_controller_->AddObserver(this);
}
}
}