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

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: Cleanup. 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 072a3b2b8dac7e0f5986b41a6fab648adda4cd35..57b5428407360d594034e86c5c5a5c587d8005f5 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,7 +24,9 @@
#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/login/users/user_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"
@@ -56,10 +60,104 @@ bool InputMethodManagerImpl::MigrateInputMethods(
return util_.MigrateInputMethods(input_method_ids);
}
+InputMethodManagerImpl::State::State(InputMethodManagerImpl* manager,
+ Profile* profile)
+ : profile(profile), manager_(manager) {
+}
+
+InputMethodManagerImpl::State::~State() {
+}
+
+void InputMethodManagerImpl::State::InitFrom(const State& other) {
+ previous_input_method = other.previous_input_method;
+ current_input_method = other.current_input_method;
+
+ active_input_method_ids = other.active_input_method_ids;
+
+ enabled_extension_imes = other.enabled_extension_imes;
+ extra_input_methods = other.extra_input_methods;
+}
+
+bool InputMethodManagerImpl::State::IsActive() const {
+ return manager_->state_.get() == this;
+}
+
+std::string InputMethodManagerImpl::State::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";
+ }
+
+ return os.str();
+}
+
+scoped_refptr<InputMethodManager::State> InputMethodManagerImpl::CloneState(
+ const InputMethodManager::State* state) {
+ const State* impl_state = static_cast<const State*>(state);
+ scoped_refptr<State> new_state(new State(this, impl_state->profile));
+ new_state->InitFrom(*impl_state);
+ return scoped_refptr<InputMethodManager::State>(new_state.get());
+}
+
+void InputMethodManagerImpl::SetState(
+ scoped_refptr<InputMethodManager::State> state) {
+ DCHECK(state);
+ InputMethodManagerImpl::State* new_impl_state =
+ static_cast<InputMethodManagerImpl::State*>(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)
: delegate_(delegate.Pass()),
- state_(STATE_LOGIN_SCREEN),
+ ui_session_(STATE_LOGIN_SCREEN),
+ state_(NULL),
util_(delegate_.get()),
component_extension_ime_manager_(new ComponentExtensionIMEManager()),
weak_ptr_factory_(this) {
@@ -94,18 +192,14 @@ void InputMethodManagerImpl::RemoveCandidateWindowObserver(
candidate_window_observers_.RemoveObserver(observer);
}
-void InputMethodManagerImpl::SetState(State new_state) {
- const State old_state = state_;
- state_ = new_state;
- switch (state_) {
+void InputMethodManagerImpl::SetUISessionState(UISessionState new_ui_session) {
+ ui_session_ = new_ui_session;
+ switch (ui_session_) {
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())
@@ -121,27 +215,27 @@ InputMethodManagerImpl::GetSupportedInputMethods() const {
}
scoped_ptr<InputMethodDescriptors>
-InputMethodManagerImpl::GetActiveInputMethods() const {
+InputMethodManagerImpl::State::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());
@@ -150,43 +244,43 @@ InputMethodManagerImpl::GetActiveInputMethods() const {
}
const std::vector<std::string>&
-InputMethodManagerImpl::GetActiveInputMethodIds() const {
- return active_input_method_ids_;
+InputMethodManagerImpl::State::GetActiveInputMethodIds() const {
+ return active_input_method_ids;
}
-size_t InputMethodManagerImpl::GetNumActiveInputMethods() const {
- return active_input_method_ids_.size();
+size_t InputMethodManagerImpl::State::GetNumActiveInputMethods() const {
+ return active_input_method_ids.size();
}
-const InputMethodDescriptor* InputMethodManagerImpl::GetInputMethodFromId(
+const InputMethodDescriptor*
+InputMethodManagerImpl::State::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::State::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());
@@ -195,8 +289,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)
@@ -214,30 +308,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);
- // 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();
+ 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);
+ }
+}
+
+void InputMethodManagerImpl::State::EnableLockScreenLayouts() {
+ std::set<std::string> added_ids;
+
+ 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);
- // you can pass empty |initial_layout|.
- ChangeInputMethod(initial_layouts.empty() ? "" :
- extension_ime_util::GetInputMethodIDByEngineID(initial_layouts[0]));
+ // Re-check current_input_method.
+ ChangeInputMethod(current_input_method.id(), false);
}
// Adds new input method to given list.
-bool InputMethodManagerImpl::EnableInputMethodImpl(
+bool InputMethodManagerImpl::State::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;
}
@@ -249,75 +383,94 @@ bool InputMethodManagerImpl::EnableInputMethodImpl(
}
// Starts or stops the system input method framework as needed.
-void InputMethodManagerImpl::ReconfigureIMFramework() {
- LoadNecessaryComponentExtensions();
+void InputMethodManagerImpl::ReconfigureIMFramework(
+ InputMethodManagerImpl::State* 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.
- MaybeInitializeCandidateWindowController();
+ if (state_.get() == state)
+ MaybeInitializeCandidateWindowController();
}
-bool InputMethodManagerImpl::EnableInputMethod(
+bool InputMethodManagerImpl::State::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::State::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.
- std::vector<std::string> new_active_input_method_ids_filtered;
+ std::vector<std::string> new_active_input_method_idsfiltered;
Shu Chen 2014/08/13 16:15:33 why rename this?
Alexander Alekseev 2014/08/13 23:29:32 Fixed. This was a result of mass rename.
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);
+ &new_active_input_method_idsfiltered);
- if (new_active_input_method_ids_filtered.empty()) {
+ if (new_active_input_method_idsfiltered.empty()) {
DVLOG(1) << "ReplaceEnabledInputMethods: No valid input method ID";
return false;
}
- // Copy extension IDs to |new_active_input_method_ids_filtered|. We have to
+ // Copy extension IDs to |new_active_input_method_idsfiltered|. 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);
+ new_active_input_method_idsfiltered.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_idsfiltered);
+ 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::State::ChangeInputMethod(
const std::string& input_method_id,
bool show_message) {
- if (state_ == STATE_TERMINATING)
- return false;
+ bool notify_menu = false;
+ // 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;
+ }
+
+ // 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);
+}
+
+const InputMethodDescriptor* InputMethodManagerImpl::LookupInputMethod(
+ const std::string& input_method_id,
+ InputMethodManagerImpl::State* state) {
+ DCHECK(state);
std::string input_method_id_to_switch = input_method_id;
// Sanity check.
- if (!InputMethodIsActivated(input_method_id)) {
- scoped_ptr<InputMethodDescriptors> input_methods(GetActiveInputMethods());
+ 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()) {
@@ -327,13 +480,33 @@ bool InputMethodManagerImpl::ChangeInputMethodInternal(
}
}
- // Hide candidate window and info list.
+ 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();
- // 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) {
+ 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
@@ -343,22 +516,6 @@ bool InputMethodManagerImpl::ChangeInputMethodInternal(
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.
@@ -368,50 +525,51 @@ bool InputMethodManagerImpl::ChangeInputMethodInternal(
engine->Disable();
// Configure the next engine handler.
- // This must be after |current_input_method_| has been set to new input
+ // 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);
+ extension_ime_util::GetExtensionIDFromInputMethodID(descriptor.id());
const std::string& component_id =
- extension_ime_util::GetComponentIDByInputMethodID(
- input_method_id_to_switch);
+ 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(
- current_input_method_.GetPreferredKeyboardLayout())) {
+ descriptor.GetPreferredKeyboardLayout())) {
LOG(ERROR) << "Failed to change keyboard layout to "
- << current_input_method_.GetPreferredKeyboardLayout();
+ << descriptor.GetPreferredKeyboardLayout();
}
// Update input method indicators (e.g. "US", "DV") in Chrome windows.
FOR_EACH_OBSERVER(InputMethodManager::Observer,
observers_,
InputMethodChanged(this, show_message));
- return true;
}
-void InputMethodManagerImpl::LoadNecessaryComponentExtensions() {
- // Load component extensions but also update |active_input_method_ids_| as
+void InputMethodManagerImpl::LoadNecessaryComponentExtensions(
+ InputMethodManagerImpl::State* 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(active_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.
- active_input_method_ids_.push_back(unfiltered_input_method_ids[i]);
+ state->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]);
+ state->profile, unfiltered_input_method_ids[i]);
+ state->active_input_method_ids.push_back(unfiltered_input_method_ids[i]);
}
}
}
@@ -432,32 +590,25 @@ void InputMethodManagerImpl::ActivateInputMethodMenuItem(
DVLOG(1) << "ActivateInputMethodMenuItem: unknown key: " << key;
}
-void InputMethodManagerImpl::AddInputMethodExtension(
+void InputMethodManagerImpl::State::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();
@@ -466,101 +617,111 @@ 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::State::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);
+ 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);
-
- // 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);
Shu Chen 2014/08/13 16:15:33 why remove the check: if (state_ != STATE_TERMINAT
Alexander Alekseev 2014/08/13 23:29:32 The idea was to move these checks to IMM. But you'
}
-void InputMethodManagerImpl::GetInputMethodExtensions(
+void InputMethodManagerImpl::State::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::State::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;
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.
- 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 |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 |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::SetInputMethodLoginDefaultFromVPD(
- const std::string& locale, const std::string& oem_layout) {
+void InputMethodManagerImpl::State::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.
@@ -568,10 +729,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.
@@ -585,7 +746,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, ","));
@@ -596,13 +757,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::State::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()) {
@@ -614,75 +775,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::State::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::State::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::State::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;
}
@@ -716,12 +879,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()) {
@@ -730,29 +893,28 @@ 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::State::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::State::GetCurrentInputMethod()
+ const {
+ if (current_input_method.id().empty())
return InputMethodUtil::GetFallbackInputMethodDescriptor();
- return current_input_method_;
+ return current_input_method;
}
bool InputMethodManagerImpl::IsISOLevel5ShiftUsedByCurrentInputMethod() const {
@@ -777,13 +939,34 @@ ComponentExtensionIMEManager*
return component_extension_ime_manager_.get();
}
-void InputMethodManagerImpl::InitializeComponentExtension() {
+scoped_refptr<InputMethodManager::State>
+InputMethodManagerImpl::GetDefaultState(Profile* profile) {
+ scoped_refptr<InputMethodManagerImpl::State> state = default_states_[profile];
+ if (!state) {
+ // Profile can be NULL in tests.
+ state = new InputMethodManagerImpl::State(this, profile);
+ default_states_[profile] = state;
+ }
+ return scoped_refptr<InputMethodManager::State>(state.get());
+}
+
+void InputMethodManagerImpl::InitializeComponentExtension(Profile* profile) {
Shu Chen 2014/08/13 16:15:33 This method will be gone in cl: https://codereview
Alexander Alekseev 2014/08/13 23:29:32 This call happens after PostProfileInit for signin
scoped_ptr<ComponentExtensionIMEManagerDelegate> delegate(
new ComponentExtensionIMEManagerImpl());
component_extension_ime_manager_->Initialize(delegate.Pass());
util_.ResetInputMethods(
component_extension_ime_manager_->GetAllIMEAsInputMethodDescriptor());
+
+ scoped_refptr<State> state(
+ static_cast<State*>(GetDefaultState(profile).get()));
+ if (state->active_input_method_ids.size()) {
+ ReconfigureIMFramework(state.get());
+ if (state->IsActive())
+ ChangeInputMethodInternal(state->current_input_method,
+ false /* show_message */,
+ true /* notify_menu */);
+ }
}
void InputMethodManagerImpl::SetCandidateWindowControllerForTesting(
@@ -822,52 +1005,9 @@ 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(
+bool InputMethodManagerImpl::State::InputMethodIsActivated(
const std::string& input_method_id) {
- return Contains(active_input_method_ids_, input_method_id);
+ return Contains(active_input_method_ids, input_method_id);
}
void InputMethodManagerImpl::MaybeInitializeCandidateWindowController() {

Powered by Google App Engine
This is Rietveld 408576698