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 f6b906dd4d2caa67fb62704385c4476598796a77..144f26cb93a0a9038b477b4c501b5087402f527e 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,106 @@ bool InputMethodManagerImpl::MigrateInputMethods( |
return util_.MigrateInputMethods(input_method_ids); |
} |
+InputMethodManagerImpl::StateImpl::StateImpl(InputMethodManagerImpl* manager, |
+ Profile* profile) |
+ : profile(profile), manager_(manager) { |
+} |
+ |
+InputMethodManagerImpl::StateImpl::~StateImpl() { |
+} |
+ |
+void InputMethodManagerImpl::StateImpl::InitFrom(const StateImpl& other) { |
+ previous_input_method = other.previous_input_method; |
+ current_input_method = other.current_input_method; |
+ |
+ active_input_method_ids = other.active_input_method_ids; |
+ |
+ pending_input_method_id = other.pending_input_method_id; |
+ |
+ enabled_extension_imes = other.enabled_extension_imes; |
+ extra_input_methods = other.extra_input_methods; |
+} |
+ |
+bool InputMethodManagerImpl::StateImpl::IsActive() const { |
+ return manager_->state_.get() == this; |
+} |
+ |
+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_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()); |
+} |
+ |
+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()); |
+} |
Shu Chen
2014/08/14 15:26:57
nit: can you please sort the code for StateImpl to
Alexander Alekseev
2014/08/15 19:46:08
Done.
|
+ |
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()) { |
if (base::SysInfo::IsRunningOnChromeOS()) |
@@ -100,22 +200,18 @@ void InputMethodManagerImpl::RemoveCandidateWindowObserver( |
candidate_window_observers_.RemoveObserver(observer); |
} |
-InputMethodManager::State InputMethodManagerImpl::GetState() { |
- return state_; |
+InputMethodManager::UISessionState InputMethodManagerImpl::GetUISessionState() { |
+ return ui_session_; |
} |
-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()) |
@@ -131,27 +227,27 @@ InputMethodManagerImpl::GetSupportedInputMethods() const { |
} |
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 +256,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 +301,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 +320,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; |
+ |
+ const std::vector<std::string>& hardware_keyboard_ids = |
+ manager_->util_.GetHardwareLoginInputMethodIds(); |
- // you can pass empty |initial_layout|. |
- ChangeInputMethod(initial_layouts.empty() ? "" : |
- extension_ime_util::GetInputMethodIDByEngineID(initial_layouts[0])); |
+ 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; |
} |
@@ -259,27 +395,29 @@ bool InputMethodManagerImpl::EnableInputMethodImpl( |
} |
// Starts or stops the system input method framework as needed. |
-void InputMethodManagerImpl::ReconfigureIMFramework() { |
- LoadNecessaryComponentExtensions(); |
+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. |
- MaybeInitializeCandidateWindowController(); |
+ if (state_.get() == state) |
+ 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,45 +434,75 @@ 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); |
+void InputMethodManagerImpl::StateImpl::ChangeInputMethod( |
+ const std::string& input_method_id, |
+ bool show_message) { |
+ if (manager_->ui_session_ == STATE_TERMINATING) |
+ return; |
+ |
+ 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; |
+ } |
+ |
+ // 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); |
} |
-bool InputMethodManagerImpl::ChangeInputMethodInternal( |
+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); |
+} |
+ |
+const InputMethodDescriptor* InputMethodManagerImpl::LookupInputMethod( |
const std::string& input_method_id, |
- bool show_message) { |
- if (state_ == STATE_TERMINATING) |
- return false; |
+ InputMethodManagerImpl::StateImpl* state) { |
+ DCHECK(state); |
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()); |
+ // 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()) { |
@@ -344,13 +512,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 |
@@ -360,22 +548,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. |
@@ -385,50 +557,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::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(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]); |
} |
} |
} |
@@ -449,32 +622,25 @@ void InputMethodManagerImpl::ActivateInputMethodMenuItem( |
DVLOG(1) << "ActivateInputMethodMenuItem: unknown key: " << key; |
} |
-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(); |
@@ -483,111 +649,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); |
+ 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); |
} |
-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. |
@@ -595,10 +771,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. |
@@ -612,7 +788,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, ",")); |
@@ -623,13 +799,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()) { |
@@ -641,75 +817,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; |
} |
@@ -743,12 +921,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()) { |
@@ -757,29 +935,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::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::IsISOLevel5ShiftUsedByCurrentInputMethod() const { |
@@ -803,6 +980,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); |
@@ -839,52 +1021,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( |
- const std::string& input_method_id) { |
- return Contains(active_input_method_ids_, input_method_id); |
+bool InputMethodManagerImpl::StateImpl::InputMethodIsActivated( |
+ const std::string& input_method_id) const { |
+ return Contains(active_input_method_ids, input_method_id); |
} |
void InputMethodManagerImpl::MaybeInitializeCandidateWindowController() { |