Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(446)

Unified Diff: chrome/browser/chromeos/input_method/input_method_manager_impl.cc

Issue 419293002: IME refactoring: ChromeOS introduce input methods State. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Unit test fixed. Re-sorted methods of StateImpl and IMM. Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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
index 87518b91185ff9ec288c436f90c1cc5e35fec7f8..6679b587b585e7ee94a2b4cd2f762fc3db7d809d 100644
--- a/chrome/browser/chromeos/input_method/input_method_manager_impl.cc
+++ b/chrome/browser/chromeos/input_method/input_method_manager_impl.cc
@@ -6,6 +6,8 @@
#include <algorithm> // std::find
+#include <sstream>
+
#include "ash/ime/input_method_menu_item.h"
#include "ash/ime/input_method_menu_manager.h"
#include "base/basictypes.h"
@@ -22,6 +24,8 @@
#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 "chrome/browser/chromeos/login/session/user_session_manager.h"
+#include "chrome/browser/chromeos/profiles/profile_helper.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/common/pref_names.h"
#include "chromeos/ime/component_extension_ime_manager.h"
@@ -29,6 +33,7 @@
#include "chromeos/ime/fake_ime_keyboard.h"
#include "chromeos/ime/ime_keyboard.h"
#include "chromeos/ime/input_method_delegate.h"
+#include "components/user_manager/user_manager.h"
#include "third_party/icu/source/common/unicode/uloc.h"
#include "ui/base/accelerators/accelerator.h"
@@ -45,113 +50,96 @@ bool Contains(const std::vector<std::string>& container,
} // namespace
-bool InputMethodManagerImpl::IsLoginKeyboard(
- const std::string& layout) const {
- return util_.IsLoginKeyboard(layout);
-}
+// ------------------------ InputMethodManagerImpl::StateImpl
-bool InputMethodManagerImpl::MigrateInputMethods(
- std::vector<std::string>* input_method_ids) {
- return util_.MigrateInputMethods(input_method_ids);
+InputMethodManagerImpl::StateImpl::StateImpl(InputMethodManagerImpl* manager,
+ Profile* profile)
+ : profile(profile), manager_(manager) {
}
-InputMethodManagerImpl::InputMethodManagerImpl(
- scoped_ptr<InputMethodDelegate> delegate, bool enable_extension_loading)
- : delegate_(delegate.Pass()),
- state_(STATE_LOGIN_SCREEN),
- util_(delegate_.get()),
- component_extension_ime_manager_(new ComponentExtensionIMEManager()),
- enable_extension_loading_(enable_extension_loading) {
- if (base::SysInfo::IsRunningOnChromeOS())
- keyboard_.reset(ImeKeyboard::Create());
- else
- keyboard_.reset(new FakeImeKeyboard());
-
- // Initializes the system IME list.
- scoped_ptr<ComponentExtensionIMEManagerDelegate> comp_delegate(
- new ComponentExtensionIMEManagerImpl());
- component_extension_ime_manager_->Initialize(comp_delegate.Pass());
- util_.ResetInputMethods(
- component_extension_ime_manager_->GetAllIMEAsInputMethodDescriptor());
+InputMethodManagerImpl::StateImpl::~StateImpl() {
}
-InputMethodManagerImpl::~InputMethodManagerImpl() {
- if (candidate_window_controller_.get())
- candidate_window_controller_->RemoveObserver(this);
-}
+void InputMethodManagerImpl::StateImpl::InitFrom(const StateImpl& other) {
+ previous_input_method = other.previous_input_method;
+ current_input_method = other.current_input_method;
-void InputMethodManagerImpl::AddObserver(
- InputMethodManager::Observer* observer) {
- observers_.AddObserver(observer);
-}
+ active_input_method_ids = other.active_input_method_ids;
-void InputMethodManagerImpl::AddCandidateWindowObserver(
- InputMethodManager::CandidateWindowObserver* observer) {
- candidate_window_observers_.AddObserver(observer);
-}
+ pending_input_method_id = other.pending_input_method_id;
-void InputMethodManagerImpl::RemoveObserver(
- InputMethodManager::Observer* observer) {
- observers_.RemoveObserver(observer);
+ enabled_extension_imes = other.enabled_extension_imes;
+ extra_input_methods = other.extra_input_methods;
}
-void InputMethodManagerImpl::RemoveCandidateWindowObserver(
- InputMethodManager::CandidateWindowObserver* observer) {
- candidate_window_observers_.RemoveObserver(observer);
+bool InputMethodManagerImpl::StateImpl::IsActive() const {
+ return manager_->state_.get() == this;
}
-InputMethodManager::State InputMethodManagerImpl::GetState() {
- return state_;
-}
-
-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;
- }
+std::string InputMethodManagerImpl::StateImpl::Dump() const {
+ std::ostringstream os;
+
+ os << "################# "
+ << (profile ? profile->GetProfileName() : std::string("NULL"))
+ << " #################\n";
+
+ os << "previous_input_method: '"
+ << previous_input_method.GetPreferredKeyboardLayout() << "'\n";
+ os << "current_input_method: '"
+ << current_input_method.GetPreferredKeyboardLayout() << "'\n";
+ os << "active_input_method_ids (size=" << active_input_method_ids.size()
+ << "):";
+ for (size_t i = 0; i < active_input_method_ids.size(); ++i) {
+ os << " '" << active_input_method_ids[i] << "',";
}
+ os << "\n";
+ os << "enabled_extension_imes (size=" << enabled_extension_imes.size()
+ << "):";
+ for (size_t i = 0; i < enabled_extension_imes.size(); ++i) {
+ os << " '" << enabled_extension_imes[i] << "'\n";
+ }
+ os << "\n";
+ os << "extra_input_methods (size=" << extra_input_methods.size() << "):";
+ for (std::map<std::string, InputMethodDescriptor>::const_iterator it =
+ extra_input_methods.begin();
+ it != extra_input_methods.end();
+ ++it) {
+ os << " '" << it->first << "' => '" << it->second.id() << "',\n";
+ }
+ os << "pending_input_method_id: '" << pending_input_method_id << "'\n";
+
+ return os.str();
}
-scoped_ptr<InputMethodDescriptors>
-InputMethodManagerImpl::GetSupportedInputMethods() const {
- return scoped_ptr<InputMethodDescriptors>(new InputMethodDescriptors).Pass();
+scoped_refptr<InputMethodManager::State>
+InputMethodManagerImpl::StateImpl::Clone() const {
+ scoped_refptr<StateImpl> new_state(new StateImpl(this->manager_, profile));
+ new_state->InitFrom(*this);
+ return scoped_refptr<InputMethodManager::State>(new_state.get());
}
scoped_ptr<InputMethodDescriptors>
-InputMethodManagerImpl::GetActiveInputMethods() const {
+InputMethodManagerImpl::StateImpl::GetActiveInputMethods() const {
scoped_ptr<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];
+ // 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);
+ manager_->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())
+ 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()) {
- // Initially |active_input_method_ids_| is empty. browser_tests might take
+ // Initially |active_input_method_ids| is empty. browser_tests might take
// this path.
result->push_back(
InputMethodUtil::GetFallbackInputMethodDescriptor());
@@ -160,43 +148,43 @@ InputMethodManagerImpl::GetActiveInputMethods() const {
}
const std::vector<std::string>&
-InputMethodManagerImpl::GetActiveInputMethodIds() const {
- return active_input_method_ids_;
+InputMethodManagerImpl::StateImpl::GetActiveInputMethodIds() const {
+ return active_input_method_ids;
}
-size_t InputMethodManagerImpl::GetNumActiveInputMethods() const {
- return active_input_method_ids_.size();
+size_t InputMethodManagerImpl::StateImpl::GetNumActiveInputMethods() const {
+ return active_input_method_ids.size();
}
-const InputMethodDescriptor* InputMethodManagerImpl::GetInputMethodFromId(
+const InputMethodDescriptor*
+InputMethodManagerImpl::StateImpl::GetInputMethodFromId(
const std::string& input_method_id) const {
- const InputMethodDescriptor* ime = util_.GetInputMethodDescriptorFromId(
- input_method_id);
+ const InputMethodDescriptor* ime =
+ manager_->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())
+ extra_input_methods.find(input_method_id);
+ if (ix != extra_input_methods.end())
ime = &ix->second;
}
return ime;
}
-void InputMethodManagerImpl::EnableLoginLayouts(
+void InputMethodManagerImpl::StateImpl::EnableLoginLayouts(
const std::string& language_code,
const std::vector<std::string>& initial_layouts) {
- if (state_ == STATE_TERMINATING)
+ if (manager_->ui_session_ == STATE_TERMINATING)
return;
// First, hardware keyboard layout should be shown.
std::vector<std::string> candidates =
- util_.GetHardwareLoginInputMethodIds();
+ manager_->util_.GetHardwareLoginInputMethodIds();
- // Seocnd, locale based input method should be shown.
+ // Second, locale based input method should be shown.
// Add input methods associated with the language.
std::vector<std::string> layouts_from_locale;
- util_.GetInputMethodIdsFromLanguageCode(language_code,
- kKeyboardLayoutsOnly,
- &layouts_from_locale);
+ manager_->util_.GetInputMethodIdsFromLanguageCode(
+ language_code, kKeyboardLayoutsOnly, &layouts_from_locale);
candidates.insert(candidates.end(), layouts_from_locale.begin(),
layouts_from_locale.end());
@@ -205,8 +193,8 @@ void InputMethodManagerImpl::EnableLoginLayouts(
// layouts, so it appears first on the list of active input
// methods at the input language status menu.
for (size_t i = 0; i < initial_layouts.size(); ++i) {
- if (util_.IsValidInputMethodId(initial_layouts[i])) {
- if (IsLoginKeyboard(initial_layouts[i])) {
+ if (manager_->util_.IsValidInputMethodId(initial_layouts[i])) {
+ if (manager_->IsLoginKeyboard(initial_layouts[i])) {
layouts.push_back(initial_layouts[i]);
} else {
DVLOG(1)
@@ -224,30 +212,70 @@ void InputMethodManagerImpl::EnableLoginLayouts(
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) && IsLoginKeyboard(candidate))
+ if (!Contains(layouts, candidate) && manager_->IsLoginKeyboard(candidate))
layouts.push_back(candidate);
}
- MigrateInputMethods(&layouts);
- active_input_method_ids_.swap(layouts);
+ manager_->MigrateInputMethods(&layouts);
+ active_input_method_ids.swap(layouts);
+
+ if (IsActive()) {
+ // Initialize candidate window controller and widgets such as
+ // candidate window, infolist and mode indicator. Note, mode
+ // indicator is used by only keyboard layout input methods.
+ if (active_input_method_ids.size() > 1)
+ manager_->MaybeInitializeCandidateWindowController();
+
+ // you can pass empty |initial_layout|.
+ ChangeInputMethod(initial_layouts.empty()
+ ? std::string()
+ : extension_ime_util::GetInputMethodIDByEngineID(
+ initial_layouts[0]),
+ false);
+ }
+}
- // Initialize candidate window controller and widgets such as
- // candidate window, infolist and mode indicator. Note, mode
- // indicator is used by only keyboard layout input methods.
- if (active_input_method_ids_.size() > 1)
- MaybeInitializeCandidateWindowController();
+void InputMethodManagerImpl::StateImpl::EnableLockScreenLayouts() {
+ std::set<std::string> added_ids;
- // you can pass empty |initial_layout|.
- ChangeInputMethod(initial_layouts.empty() ? "" :
- extension_ime_util::GetInputMethodIDByEngineID(initial_layouts[0]));
+ const std::vector<std::string>& hardware_keyboard_ids =
+ manager_->util_.GetHardwareLoginInputMethodIds();
+
+ std::vector<std::string> new_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];
+ // Skip if it's not a keyboard layout. Drop input methods including
+ // extension ones.
+ if (!manager_->IsLoginKeyboard(input_method_id) ||
+ added_ids.count(input_method_id)) {
+ continue;
+ }
+ new_active_input_method_ids.push_back(input_method_id);
+ added_ids.insert(input_method_id);
+ }
+
+ // We'll add the hardware keyboard if it's not included in
+ // |active_input_method_ids| so that the user can always use the hardware
+ // keyboard on the screen locker.
+ for (size_t i = 0; i < hardware_keyboard_ids.size(); ++i) {
+ if (added_ids.count(hardware_keyboard_ids[i]))
+ continue;
+ new_active_input_method_ids.push_back(hardware_keyboard_ids[i]);
+ added_ids.insert(hardware_keyboard_ids[i]);
+ }
+
+ active_input_method_ids.swap(new_active_input_method_ids);
+
+ // Re-check current_input_method.
+ ChangeInputMethod(current_input_method.id(), false);
}
// Adds new input method to given list.
-bool InputMethodManagerImpl::EnableInputMethodImpl(
+bool InputMethodManagerImpl::StateImpl::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)) {
+ if (!manager_->util_.IsValidInputMethodId(input_method_id)) {
DVLOG(1) << "EnableInputMethod: Invalid ID: " << input_method_id;
return false;
}
@@ -258,28 +286,18 @@ bool InputMethodManagerImpl::EnableInputMethodImpl(
return true;
}
-// Starts or stops the system input method framework as needed.
-void InputMethodManagerImpl::ReconfigureIMFramework() {
- LoadNecessaryComponentExtensions();
-
- // Initialize candidate window controller and widgets such as
- // candidate window, infolist and mode indicator. Note, mode
- // indicator is used by only keyboard layout input methods.
- MaybeInitializeCandidateWindowController();
-}
-
-bool InputMethodManagerImpl::EnableInputMethod(
+bool InputMethodManagerImpl::StateImpl::EnableInputMethod(
const std::string& input_method_id) {
- if (!EnableInputMethodImpl(input_method_id, &active_input_method_ids_))
+ if (!EnableInputMethodImpl(input_method_id, &active_input_method_ids))
return false;
- ReconfigureIMFramework();
+ manager_->ReconfigureIMFramework(this);
return true;
}
-bool InputMethodManagerImpl::ReplaceEnabledInputMethods(
+bool InputMethodManagerImpl::StateImpl::ReplaceEnabledInputMethods(
const std::vector<std::string>& new_active_input_method_ids) {
- if (state_ == STATE_TERMINATING)
+ if (manager_->ui_session_ == STATE_TERMINATING)
return false;
// Filter unknown or obsolete IDs.
@@ -296,186 +314,83 @@ bool InputMethodManagerImpl::ReplaceEnabledInputMethods(
// 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];
+ 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);
- MigrateInputMethods(&active_input_method_ids_);
+ active_input_method_ids.swap(new_active_input_method_ids_filtered);
+ manager_->MigrateInputMethods(&active_input_method_ids);
- ReconfigureIMFramework();
+ manager_->ReconfigureIMFramework(this);
- // 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());
+ // 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(), false);
return true;
}
-void InputMethodManagerImpl::ChangeInputMethod(
- const std::string& input_method_id) {
- ChangeInputMethodInternal(input_method_id, false);
-}
-
-bool InputMethodManagerImpl::ChangeInputMethodInternal(
+void InputMethodManagerImpl::StateImpl::ChangeInputMethod(
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;
-
- // Sanity check.
- if (!InputMethodIsActivated(input_method_id)) {
- // For 3rd party IME, when the user just logged in, SetEnabledExtensionImes
- // happens after activating the 3rd party IME.
- // So here to record the 3rd party IME to be activated, and activate it
- // when SetEnabledExtensionImes happens later.
- if (extension_ime_util::IsExtensionIME(input_method_id))
- pending_input_method_id_ = 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.";
- }
- }
-
- // Hide candidate window and info list.
- if (candidate_window_controller_.get())
- candidate_window_controller_->Hide();
-
- // TODO(komatsu): Check if it is necessary to perform the above routine
- // when the current input method is equal to |input_method_id_to_swich|.
- if (current_input_method_.id() != input_method_id_to_switch) {
- // Clear property list. Property list would be updated by
- // extension IMEs via InputMethodEngine::(Set|Update)MenuItems.
- // If the current input method is a keyboard layout, empty
- // properties are sufficient.
- 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);
- if (!descriptor)
- LOG(ERROR) << "Unknown input method id: " << input_method_id_to_switch;
- }
- DCHECK(descriptor);
-
- previous_input_method_ = current_input_method_;
- current_input_method_ = *descriptor;
- }
-
- // Disable the current engine handler.
- IMEEngineHandlerInterface* engine =
- IMEBridge::Get()->GetCurrentEngineHandler();
- if (engine)
- engine->Disable();
-
- // Configure the next engine handler.
- // This must be after |current_input_method_| has been set to new input
- // method, because engine's Enable() method needs to access it.
- const std::string& extension_id =
- extension_ime_util::GetExtensionIDFromInputMethodID(
- input_method_id_to_switch);
- const std::string& component_id =
- extension_ime_util::GetComponentIDByInputMethodID(
- input_method_id_to_switch);
- engine = engine_map_[extension_id];
- IMEBridge::Get()->SetCurrentEngineHandler(engine);
- if (engine)
- engine->Enable(component_id);
+ if (manager_->ui_session_ == STATE_TERMINATING)
+ return;
- // Change the keyboard layout to a preferred layout for the input method.
- if (!keyboard_->SetCurrentKeyboardLayoutByName(
- current_input_method_.GetPreferredKeyboardLayout())) {
- LOG(ERROR) << "Failed to change keyboard layout to "
- << current_input_method_.GetPreferredKeyboardLayout();
+ bool notify_menu = false;
+ // For 3rd party IME, when the user just logged in, SetEnabledExtensionImes
+ // happens after activating the 3rd party IME.
+ // So here to record the 3rd party IME to be activated, and activate it
+ // when SetEnabledExtensionImes happens later.
+ if (MethodAwaitsExtensionLoad(input_method_id))
+ pending_input_method_id = input_method_id;
+
+ // Always lookup input method, even if it is the same as
+ // |current_input_method| because If it is no longer in
+ // |active_input_method_ids|, pick the first one in
+ // |active_input_method_ids|.
+ const InputMethodDescriptor* descriptor =
+ manager_->LookupInputMethod(input_method_id, this);
+ if (descriptor->id() != current_input_method.id()) {
+ previous_input_method = current_input_method;
+ current_input_method = *descriptor;
+ notify_menu = true;
}
- // Update input method indicators (e.g. "US", "DV") in Chrome windows.
- FOR_EACH_OBSERVER(InputMethodManager::Observer,
- observers_,
- InputMethodChanged(this, show_message));
- return true;
+ // Always change input method even if it is the same.
+ // TODO(komatsu): Revisit if this is neccessary.
+ if (IsActive())
+ manager_->ChangeInputMethodInternal(*descriptor, show_message, notify_menu);
}
-void InputMethodManagerImpl::LoadNecessaryComponentExtensions() {
- // Load component extensions but also update |active_input_method_ids_| as
- // some component extension IMEs may have been removed from the Chrome OS
- // image. If specified component extension IME no longer exists, falling back
- // to an existing IME.
- 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])) {
- // Legacy IMEs or xkb layouts are alwayes active.
- active_input_method_ids_.push_back(unfiltered_input_method_ids[i]);
- } else if (component_extension_ime_manager_->IsWhitelisted(
- unfiltered_input_method_ids[i])) {
- if (enable_extension_loading_)
- component_extension_ime_manager_->LoadComponentExtensionIME(
- unfiltered_input_method_ids[i]);
- active_input_method_ids_.push_back(unfiltered_input_method_ids[i]);
- }
- }
-}
-
-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;
+bool InputMethodManagerImpl::StateImpl::MethodAwaitsExtensionLoad(
+ const std::string& input_method_id) const {
+ // For 3rd party IME, when the user just logged in, SetEnabledExtensionImes
+ // happens after activating the 3rd party IME.
+ // So here to record the 3rd party IME to be activated, and activate it
+ // when SetEnabledExtensionImes happens later.
+ return !InputMethodIsActivated(input_method_id) &&
+ extension_ime_util::IsExtensionIME(input_method_id);
}
-void InputMethodManagerImpl::AddInputMethodExtension(
+void InputMethodManagerImpl::StateImpl::AddInputMethodExtension(
const std::string& extension_id,
const InputMethodDescriptors& descriptors,
InputMethodEngineInterface* engine) {
- if (state_ == STATE_TERMINATING)
+ if (manager_->ui_session_ == STATE_TERMINATING)
return;
DCHECK(engine);
- engine_map_[extension_id] = engine;
-
- if (extension_id == extension_ime_util::GetExtensionIDFromInputMethodID(
- current_input_method_.id())) {
- IMEBridge::Get()->SetCurrentEngineHandler(engine);
- engine->Enable(extension_ime_util::GetComponentIDByInputMethodID(
- current_input_method_.id()));
- }
+ manager_->engine_map_[extension_id] = engine;
bool contain = false;
for (size_t i = 0; i < descriptors.size(); i++) {
const InputMethodDescriptor& descriptor = descriptors[i];
const std::string& id = descriptor.id();
- extra_input_methods_[id] = descriptor;
- if (Contains(enabled_extension_imes_, id)) {
- if (!Contains(active_input_method_ids_, id)) {
- active_input_method_ids_.push_back(id);
+ extra_input_methods[id] = descriptor;
+ if (Contains(enabled_extension_imes, id)) {
+ if (!Contains(active_input_method_ids, id)) {
+ active_input_method_ids.push_back(id);
} else {
DVLOG(1) << "AddInputMethodExtension: already added: " << id << ", "
<< descriptor.name();
@@ -484,111 +399,121 @@ void InputMethodManagerImpl::AddInputMethodExtension(
}
}
- // Ensure that the input method daemon is running.
- if (contain)
- MaybeInitializeCandidateWindowController();
+ if (IsActive()) {
+ if (extension_id == extension_ime_util::GetExtensionIDFromInputMethodID(
+ current_input_method.id())) {
+ IMEBridge::Get()->SetCurrentEngineHandler(engine);
+ engine->Enable(extension_ime_util::GetComponentIDByInputMethodID(
+ current_input_method.id()));
+ }
+
+ // Ensure that the input method daemon is running.
+ if (contain)
+ manager_->MaybeInitializeCandidateWindowController();
+ }
}
-void InputMethodManagerImpl::RemoveInputMethodExtension(
+void InputMethodManagerImpl::StateImpl::RemoveInputMethodExtension(
const std::string& extension_id) {
// Remove the active input methods with |extension_id|.
std::vector<std::string> new_active_input_method_ids;
- for (size_t i = 0; i < active_input_method_ids_.size(); ++i) {
+ for (size_t i = 0; i < active_input_method_ids.size(); ++i) {
if (extension_id != extension_ime_util::GetExtensionIDFromInputMethodID(
- active_input_method_ids_[i]))
- new_active_input_method_ids.push_back(active_input_method_ids_[i]);
+ active_input_method_ids[i]))
+ new_active_input_method_ids.push_back(active_input_method_ids[i]);
}
- active_input_method_ids_.swap(new_active_input_method_ids);
+ active_input_method_ids.swap(new_active_input_method_ids);
// Remove the extra input methods with |extension_id|.
std::map<std::string, InputMethodDescriptor> new_extra_input_methods;
for (std::map<std::string, InputMethodDescriptor>::iterator i =
- extra_input_methods_.begin();
- i != extra_input_methods_.end();
+ extra_input_methods.begin();
+ i != extra_input_methods.end();
++i) {
if (extension_id !=
extension_ime_util::GetExtensionIDFromInputMethodID(i->first))
new_extra_input_methods[i->first] = i->second;
}
- extra_input_methods_.swap(new_extra_input_methods);
-
- if (IMEBridge::Get()->GetCurrentEngineHandler() == engine_map_[extension_id])
- IMEBridge::Get()->SetCurrentEngineHandler(NULL);
- engine_map_.erase(extension_id);
+ extra_input_methods.swap(new_extra_input_methods);
- // No need to switch input method when terminating.
- if (state_ != STATE_TERMINATING) {
- // 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());
+ if (IsActive()) {
+ if (IMEBridge::Get()->GetCurrentEngineHandler() ==
+ manager_->engine_map_[extension_id]) {
+ IMEBridge::Get()->SetCurrentEngineHandler(NULL);
+ }
+ manager_->engine_map_.erase(extension_id);
}
+
+ // 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(), false);
}
-void InputMethodManagerImpl::GetInputMethodExtensions(
+void InputMethodManagerImpl::StateImpl::GetInputMethodExtensions(
InputMethodDescriptors* result) {
// Build the extension input method descriptors from the extra input
- // methods cache |extra_input_methods_|.
+ // methods cache |extra_input_methods|.
std::map<std::string, InputMethodDescriptor>::iterator iter;
- for (iter = extra_input_methods_.begin(); iter != extra_input_methods_.end();
+ 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(
+void InputMethodManagerImpl::StateImpl::SetEnabledExtensionImes(
std::vector<std::string>* ids) {
- enabled_extension_imes_.clear();
- enabled_extension_imes_.insert(enabled_extension_imes_.end(),
- ids->begin(),
- ids->end());
-
+ enabled_extension_imes.clear();
+ enabled_extension_imes.insert(
+ enabled_extension_imes.end(), ids->begin(), ids->end());
bool active_imes_changed = false;
bool switch_to_pending = false;
for (std::map<std::string, InputMethodDescriptor>::iterator extra_iter =
- extra_input_methods_.begin(); extra_iter != extra_input_methods_.end();
+ extra_input_methods.begin();
+ extra_iter != extra_input_methods.end();
++extra_iter) {
- if (extension_ime_util::IsComponentExtensionIME(
- extra_iter->first))
+ if (extension_ime_util::IsComponentExtensionIME(extra_iter->first))
continue; // Do not filter component extension.
- if (pending_input_method_id_ == extra_iter->first)
+ if (pending_input_method_id == extra_iter->first)
switch_to_pending = true;
- std::vector<std::string>::iterator active_iter = std::find(
- active_input_method_ids_.begin(), active_input_method_ids_.end(),
- extra_iter->first);
+ 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);
+ 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);
+ active_input_method_ids.erase(active_iter);
if (!active && enabled)
- active_input_method_ids_.push_back(extra_iter->first);
+ active_input_method_ids.push_back(extra_iter->first);
if (active == !enabled)
active_imes_changed = true;
}
- if (active_imes_changed) {
- MaybeInitializeCandidateWindowController();
+ if (IsActive() && active_imes_changed) {
+ manager_->MaybeInitializeCandidateWindowController();
if (switch_to_pending) {
- ChangeInputMethod(pending_input_method_id_);
- pending_input_method_id_.clear();
+ ChangeInputMethod(pending_input_method_id, false);
+ pending_input_method_id.clear();
} else {
// 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());
+ ChangeInputMethod(current_input_method.id(), false);
}
}
}
-void InputMethodManagerImpl::SetInputMethodLoginDefaultFromVPD(
- const std::string& locale, const std::string& oem_layout) {
+void InputMethodManagerImpl::StateImpl::SetInputMethodLoginDefaultFromVPD(
+ const std::string& locale,
+ const std::string& oem_layout) {
std::string layout;
if (!oem_layout.empty()) {
// If the OEM layout information is provided, use it.
@@ -596,10 +521,10 @@ void InputMethodManagerImpl::SetInputMethodLoginDefaultFromVPD(
} else {
// Otherwise, determine the hardware keyboard from the locale.
std::vector<std::string> input_method_ids;
- if (util_.GetInputMethodIdsFromLanguageCode(
- locale,
- chromeos::input_method::kKeyboardLayoutsOnly,
- &input_method_ids)) {
+ if (manager_->util_.GetInputMethodIdsFromLanguageCode(
+ locale,
+ chromeos::input_method::kKeyboardLayoutsOnly,
+ &input_method_ids)) {
// The output list |input_method_ids| is sorted by popularity, hence
// input_method_ids[0] now contains the most popular keyboard layout
// for the given locale.
@@ -613,7 +538,7 @@ void InputMethodManagerImpl::SetInputMethodLoginDefaultFromVPD(
std::vector<std::string> layouts;
base::SplitString(layout, ',', &layouts);
- MigrateInputMethods(&layouts);
+ manager_->MigrateInputMethods(&layouts);
PrefService* prefs = g_browser_process->local_state();
prefs->SetString(prefs::kHardwareKeyboardLayout, JoinString(layouts, ","));
@@ -624,13 +549,13 @@ void InputMethodManagerImpl::SetInputMethodLoginDefaultFromVPD(
// yet saved to disk.
prefs->CommitPendingWrite();
- util_.UpdateHardwareLayoutCache();
+ manager_->util_.UpdateHardwareLayoutCache();
EnableLoginLayouts(locale, layouts);
- LoadNecessaryComponentExtensions();
+ manager_->LoadNecessaryComponentExtensions(this);
}
-void InputMethodManagerImpl::SetInputMethodLoginDefault() {
+void InputMethodManagerImpl::StateImpl::SetInputMethodLoginDefault() {
// Set up keyboards. For example, when |locale| is "en-US", enable US qwerty
// and US dvorak keyboard layouts.
if (g_browser_process && g_browser_process->local_state()) {
@@ -642,75 +567,77 @@ void InputMethodManagerImpl::SetInputMethodLoginDefault() {
std::vector<std::string> input_methods_to_be_enabled;
if (initial_input_method_id.empty()) {
// If kPreferredKeyboardLayout is not specified, use the hardware layout.
- input_methods_to_be_enabled = util_.GetHardwareLoginInputMethodIds();
+ input_methods_to_be_enabled =
+ manager_->util_.GetHardwareLoginInputMethodIds();
} else {
input_methods_to_be_enabled.push_back(initial_input_method_id);
}
EnableLoginLayouts(locale, input_methods_to_be_enabled);
- LoadNecessaryComponentExtensions();
+ manager_->LoadNecessaryComponentExtensions(this);
}
}
-bool InputMethodManagerImpl::SwitchToNextInputMethod() {
+bool InputMethodManagerImpl::StateImpl::SwitchToNextInputMethod() {
// Sanity checks.
- if (active_input_method_ids_.empty()) {
+ 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";
+ if (current_input_method.id().empty()) {
+ DVLOG(1) << "current_input_method is unknown";
return false;
}
// Do not consume key event if there is only one input method is enabled.
// Ctrl+Space or Alt+Shift may be used by other application.
- if (active_input_method_ids_.size() == 1)
+ if (active_input_method_ids.size() == 1)
return false;
// Find the next input method and switch to it.
- SwitchToNextInputMethodInternal(active_input_method_ids_,
- current_input_method_.id());
+ SwitchToNextInputMethodInternal(active_input_method_ids,
+ current_input_method.id());
return true;
}
-bool InputMethodManagerImpl::SwitchToPreviousInputMethod(
+bool InputMethodManagerImpl::StateImpl::SwitchToPreviousInputMethod(
const ui::Accelerator& accelerator) {
// Sanity check.
- if (active_input_method_ids_.empty()) {
+ if (active_input_method_ids.empty()) {
DVLOG(1) << "active input method is empty";
return false;
}
// Do not consume key event if there is only one input method is enabled.
// Ctrl+Space or Alt+Shift may be used by other application.
- if (active_input_method_ids_.size() == 1)
+ 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()) {
+ 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()) {
- // previous_input_method_ is not supported.
+ std::find(active_input_method_ids.begin(),
+ active_input_method_ids.end(),
+ previous_input_method.id());
+ if (iter == active_input_method_ids.end()) {
+ // previous_input_method is not supported.
return SwitchToNextInputMethod();
}
- ChangeInputMethodInternal(*iter, true);
+ ChangeInputMethod(*iter, true);
+
return true;
}
-bool InputMethodManagerImpl::SwitchInputMethod(
+bool InputMethodManagerImpl::StateImpl::SwitchInputMethod(
const ui::Accelerator& accelerator) {
// Sanity check.
- if (active_input_method_ids_.empty()) {
+ if (active_input_method_ids.empty()) {
DVLOG(1) << "active input method is empty";
return false;
}
@@ -744,12 +671,12 @@ bool InputMethodManagerImpl::SwitchInputMethod(
}
// Obtain the intersection of input_method_ids_to_switch and
- // active_input_method_ids_. The order of IDs in active_input_method_ids_ is
+ // 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))
+ if (Contains(active_input_method_ids, id))
ids.push_back(id);
}
if (ids.empty()) {
@@ -758,29 +685,291 @@ bool InputMethodManagerImpl::SwitchInputMethod(
return false;
}
- SwitchToNextInputMethodInternal(ids, current_input_method_.id());
+ SwitchToNextInputMethodInternal(ids, current_input_method.id());
return true; // consume the accelerator.
}
-void InputMethodManagerImpl::SwitchToNextInputMethodInternal(
+void InputMethodManagerImpl::StateImpl::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);
+ const std::string& current_input_methodid) {
+ std::vector<std::string>::const_iterator iter = std::find(
+ input_method_ids.begin(), input_method_ids.end(), current_input_methodid);
if (iter != input_method_ids.end())
++iter;
if (iter == input_method_ids.end())
iter = input_method_ids.begin();
- ChangeInputMethodInternal(*iter, true);
+ ChangeInputMethod(*iter, true);
}
-InputMethodDescriptor InputMethodManagerImpl::GetCurrentInputMethod() const {
- if (current_input_method_.id().empty())
+InputMethodDescriptor InputMethodManagerImpl::StateImpl::GetCurrentInputMethod()
+ const {
+ if (current_input_method.id().empty())
return InputMethodUtil::GetFallbackInputMethodDescriptor();
- return current_input_method_;
+ return current_input_method;
+}
+
+bool InputMethodManagerImpl::StateImpl::InputMethodIsActivated(
+ const std::string& input_method_id) const {
+ return Contains(active_input_method_ids, input_method_id);
+}
+
+// ------------------------ InputMethodManagerImpl
+bool InputMethodManagerImpl::IsLoginKeyboard(
+ const std::string& layout) const {
+ return util_.IsLoginKeyboard(layout);
+}
+
+bool InputMethodManagerImpl::MigrateInputMethods(
+ std::vector<std::string>* input_method_ids) {
+ return util_.MigrateInputMethods(input_method_ids);
+}
+
+// Starts or stops the system input method framework as needed.
+void InputMethodManagerImpl::ReconfigureIMFramework(
+ InputMethodManagerImpl::StateImpl* state) {
+ LoadNecessaryComponentExtensions(state);
+
+ // Initialize candidate window controller and widgets such as
+ // candidate window, infolist and mode indicator. Note, mode
+ // indicator is used by only keyboard layout input methods.
+ if (state_.get() == state)
+ MaybeInitializeCandidateWindowController();
+}
+
+void InputMethodManagerImpl::SetState(
+ scoped_refptr<InputMethodManager::State> state) {
+ DCHECK(state);
+ InputMethodManagerImpl::StateImpl* new_impl_state =
+ static_cast<InputMethodManagerImpl::StateImpl*>(state.get());
+ const bool need_update_current_input_method =
+ (state_ ? state_->current_input_method.id() !=
+ new_impl_state->current_input_method.id()
+ : true);
+ state_ = new_impl_state;
+
+ if (state_ && state_->active_input_method_ids.size()) {
+ // Initialize candidate window controller and widgets such as
+ // candidate window, infolist and mode indicator. Note, mode
+ // indicator is used by only keyboard layout input methods.
+ MaybeInitializeCandidateWindowController();
+
+ if (need_update_current_input_method)
+ ChangeInputMethodInternal(state_->current_input_method,
+ false /* show_message */,
+ true /* notify_menu */);
+ }
+}
+
+scoped_refptr<InputMethodManager::State>
+InputMethodManagerImpl::GetActiveIMEState() {
+ return scoped_refptr<InputMethodManager::State>(state_.get());
+}
+
+InputMethodManagerImpl::InputMethodManagerImpl(
+ scoped_ptr<InputMethodDelegate> delegate,
+ bool enable_extension_loading)
+ : delegate_(delegate.Pass()),
+ ui_session_(STATE_LOGIN_SCREEN),
+ state_(NULL),
+ util_(delegate_.get()),
+ component_extension_ime_manager_(new ComponentExtensionIMEManager()),
+ enable_extension_loading_(enable_extension_loading) {
+ if (base::SysInfo::IsRunningOnChromeOS())
+ keyboard_.reset(ImeKeyboard::Create());
+ else
+ keyboard_.reset(new FakeImeKeyboard());
+
+ // Initializes the system IME list.
+ scoped_ptr<ComponentExtensionIMEManagerDelegate> comp_delegate(
+ new ComponentExtensionIMEManagerImpl());
+ component_extension_ime_manager_->Initialize(comp_delegate.Pass());
+ util_.ResetInputMethods(
+ component_extension_ime_manager_->GetAllIMEAsInputMethodDescriptor());
+}
+
+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);
+}
+
+InputMethodManager::UISessionState InputMethodManagerImpl::GetUISessionState() {
+ return ui_session_;
+}
+
+void InputMethodManagerImpl::SetUISessionState(UISessionState new_ui_session) {
+ ui_session_ = new_ui_session;
+ switch (ui_session_) {
+ case STATE_LOGIN_SCREEN:
+ break;
+ case STATE_BROWSER_SCREEN:
+ break;
+ case STATE_LOCK_SCREEN:
+ break;
+ case STATE_TERMINATING: {
+ if (candidate_window_controller_.get())
+ candidate_window_controller_.reset();
+ break;
+ }
+ }
+}
+
+scoped_ptr<InputMethodDescriptors>
+InputMethodManagerImpl::GetSupportedInputMethods() const {
+ return scoped_ptr<InputMethodDescriptors>(new InputMethodDescriptors).Pass();
+}
+
+const InputMethodDescriptor* InputMethodManagerImpl::LookupInputMethod(
+ const std::string& input_method_id,
+ InputMethodManagerImpl::StateImpl* state) {
+ DCHECK(state);
+
+ std::string input_method_id_to_switch = input_method_id;
+
+ // Sanity check
+ if (!state->InputMethodIsActivated(input_method_id)) {
+ scoped_ptr<InputMethodDescriptors> input_methods(
+ state->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.";
+ }
+ }
+
+ const InputMethodDescriptor* descriptor = NULL;
+ if (extension_ime_util::IsExtensionIME(input_method_id_to_switch)) {
+ DCHECK(state->extra_input_methods.find(input_method_id_to_switch) !=
+ state->extra_input_methods.end());
+ descriptor = &(state->extra_input_methods[input_method_id_to_switch]);
+ } else {
+ descriptor =
+ util_.GetInputMethodDescriptorFromId(input_method_id_to_switch);
+ if (!descriptor)
+ LOG(ERROR) << "Unknown input method id: " << input_method_id_to_switch;
+ }
+ DCHECK(descriptor);
+ return descriptor;
+}
+
+void InputMethodManagerImpl::ChangeInputMethodInternal(
+ const InputMethodDescriptor& descriptor,
+ bool show_message,
+ bool notify_menu) {
+ // No need to switch input method when terminating.
+ if (ui_session_ == STATE_TERMINATING)
+ return;
+
+ if (candidate_window_controller_.get())
+ candidate_window_controller_->Hide();
+
+ if (notify_menu) {
+ // Clear property list. Property list would be updated by
+ // extension IMEs via InputMethodEngine::(Set|Update)MenuItems.
+ // If the current input method is a keyboard layout, empty
+ // properties are sufficient.
+ 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);
+ }
+
+ // Disable the current engine handler.
+ IMEEngineHandlerInterface* engine =
+ IMEBridge::Get()->GetCurrentEngineHandler();
+ if (engine)
+ engine->Disable();
+
+ // Configure the next engine handler.
+ // This must be after |current_input_method| has been set to new input
+ // method, because engine's Enable() method needs to access it.
+ const std::string& extension_id =
+ extension_ime_util::GetExtensionIDFromInputMethodID(descriptor.id());
+ const std::string& component_id =
+ extension_ime_util::GetComponentIDByInputMethodID(descriptor.id());
+ engine = engine_map_[extension_id];
+
+ IMEBridge::Get()->SetCurrentEngineHandler(engine);
+
+ if (engine)
+ engine->Enable(component_id);
+
+ // Change the keyboard layout to a preferred layout for the input method.
+ if (!keyboard_->SetCurrentKeyboardLayoutByName(
+ descriptor.GetPreferredKeyboardLayout())) {
+ LOG(ERROR) << "Failed to change keyboard layout to "
+ << descriptor.GetPreferredKeyboardLayout();
+ }
+
+ // Update input method indicators (e.g. "US", "DV") in Chrome windows.
+ FOR_EACH_OBSERVER(InputMethodManager::Observer,
+ observers_,
+ InputMethodChanged(this, show_message));
+}
+
+void InputMethodManagerImpl::LoadNecessaryComponentExtensions(
+ InputMethodManagerImpl::StateImpl* state) {
+ // Load component extensions but also update |active_input_method_ids| as
+ // some component extension IMEs may have been removed from the Chrome OS
+ // image. If specified component extension IME no longer exists, falling back
+ // to an existing IME.
+ DCHECK(state);
+ std::vector<std::string> unfiltered_input_method_ids;
+ unfiltered_input_method_ids.swap(state->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])) {
+ // Legacy IMEs or xkb layouts are alwayes active.
+ state->active_input_method_ids.push_back(unfiltered_input_method_ids[i]);
+ } else if (component_extension_ime_manager_->IsWhitelisted(
+ unfiltered_input_method_ids[i])) {
+ if (enable_extension_loading_) {
+ component_extension_ime_manager_->LoadComponentExtensionIME(
+ state->profile, unfiltered_input_method_ids[i]);
+ }
+
+ state->active_input_method_ids.push_back(unfiltered_input_method_ids[i]);
+ }
+ }
+}
+
+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;
}
bool InputMethodManagerImpl::IsISOLevel5ShiftUsedByCurrentInputMethod() const {
@@ -804,6 +993,11 @@ ComponentExtensionIMEManager*
return component_extension_ime_manager_.get();
}
+scoped_refptr<InputMethodManager::State> InputMethodManagerImpl::CreateNewState(
+ Profile* profile) {
+ return scoped_refptr<InputMethodManager::State>(new StateImpl(this, profile));
+}
+
void InputMethodManagerImpl::SetCandidateWindowControllerForTesting(
CandidateWindowController* candidate_window_controller) {
candidate_window_controller_.reset(candidate_window_controller);
@@ -840,54 +1034,6 @@ void InputMethodManagerImpl::CandidateWindowClosed() {
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];
- // Skip if it's not a keyboard layout. Drop input methods including
- // extension ones.
- 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);
- }
-
- // We'll add the hardware keyboard if it's not included in
- // |active_input_method_ids_| so that the user can always use the hardware
- // keyboard on the screen locker.
- 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;

Powered by Google App Engine
This is Rietveld 408576698