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

Side by Side 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/chromeos/input_method/input_method_manager_impl.h" 5 #include "chrome/browser/chromeos/input_method/input_method_manager_impl.h"
6 6
7 #include <algorithm> // std::find 7 #include <algorithm> // std::find
8 8
9 #include <sstream>
10
9 #include "ash/ime/input_method_menu_item.h" 11 #include "ash/ime/input_method_menu_item.h"
10 #include "ash/ime/input_method_menu_manager.h" 12 #include "ash/ime/input_method_menu_manager.h"
11 #include "base/basictypes.h" 13 #include "base/basictypes.h"
12 #include "base/bind.h" 14 #include "base/bind.h"
13 #include "base/location.h" 15 #include "base/location.h"
14 #include "base/memory/scoped_ptr.h" 16 #include "base/memory/scoped_ptr.h"
15 #include "base/prefs/pref_service.h" 17 #include "base/prefs/pref_service.h"
16 #include "base/strings/string_split.h" 18 #include "base/strings/string_split.h"
17 #include "base/strings/string_util.h" 19 #include "base/strings/string_util.h"
18 #include "base/strings/stringprintf.h" 20 #include "base/strings/stringprintf.h"
19 #include "base/sys_info.h" 21 #include "base/sys_info.h"
20 #include "chrome/browser/browser_process.h" 22 #include "chrome/browser/browser_process.h"
21 #include "chrome/browser/chromeos/input_method/candidate_window_controller.h" 23 #include "chrome/browser/chromeos/input_method/candidate_window_controller.h"
22 #include "chrome/browser/chromeos/input_method/component_extension_ime_manager_i mpl.h" 24 #include "chrome/browser/chromeos/input_method/component_extension_ime_manager_i mpl.h"
23 #include "chrome/browser/chromeos/input_method/input_method_engine.h" 25 #include "chrome/browser/chromeos/input_method/input_method_engine.h"
24 #include "chrome/browser/chromeos/language_preferences.h" 26 #include "chrome/browser/chromeos/language_preferences.h"
27 #include "chrome/browser/chromeos/login/session/user_session_manager.h"
28 #include "chrome/browser/chromeos/profiles/profile_helper.h"
25 #include "chrome/browser/profiles/profile_manager.h" 29 #include "chrome/browser/profiles/profile_manager.h"
26 #include "chrome/common/pref_names.h" 30 #include "chrome/common/pref_names.h"
27 #include "chromeos/ime/component_extension_ime_manager.h" 31 #include "chromeos/ime/component_extension_ime_manager.h"
28 #include "chromeos/ime/extension_ime_util.h" 32 #include "chromeos/ime/extension_ime_util.h"
29 #include "chromeos/ime/fake_ime_keyboard.h" 33 #include "chromeos/ime/fake_ime_keyboard.h"
30 #include "chromeos/ime/ime_keyboard.h" 34 #include "chromeos/ime/ime_keyboard.h"
31 #include "chromeos/ime/input_method_delegate.h" 35 #include "chromeos/ime/input_method_delegate.h"
36 #include "components/user_manager/user_manager.h"
32 #include "third_party/icu/source/common/unicode/uloc.h" 37 #include "third_party/icu/source/common/unicode/uloc.h"
33 #include "ui/base/accelerators/accelerator.h" 38 #include "ui/base/accelerators/accelerator.h"
34 39
35 namespace chromeos { 40 namespace chromeos {
36 namespace input_method { 41 namespace input_method {
37 42
38 namespace { 43 namespace {
39 44
40 bool Contains(const std::vector<std::string>& container, 45 bool Contains(const std::vector<std::string>& container,
41 const std::string& value) { 46 const std::string& value) {
42 return std::find(container.begin(), container.end(), value) != 47 return std::find(container.begin(), container.end(), value) !=
43 container.end(); 48 container.end();
44 } 49 }
45 50
46 } // namespace 51 } // namespace
47 52
48 bool InputMethodManagerImpl::IsLoginKeyboard( 53 // ------------------------ InputMethodManagerImpl::StateImpl
49 const std::string& layout) const { 54
50 return util_.IsLoginKeyboard(layout); 55 InputMethodManagerImpl::StateImpl::StateImpl(InputMethodManagerImpl* manager,
56 Profile* profile)
57 : profile(profile), manager_(manager) {
51 } 58 }
52 59
53 bool InputMethodManagerImpl::MigrateInputMethods( 60 InputMethodManagerImpl::StateImpl::~StateImpl() {
54 std::vector<std::string>* input_method_ids) {
55 return util_.MigrateInputMethods(input_method_ids);
56 } 61 }
57 62
58 InputMethodManagerImpl::InputMethodManagerImpl( 63 void InputMethodManagerImpl::StateImpl::InitFrom(const StateImpl& other) {
59 scoped_ptr<InputMethodDelegate> delegate, bool enable_extension_loading) 64 previous_input_method = other.previous_input_method;
60 : delegate_(delegate.Pass()), 65 current_input_method = other.current_input_method;
61 state_(STATE_LOGIN_SCREEN),
62 util_(delegate_.get()),
63 component_extension_ime_manager_(new ComponentExtensionIMEManager()),
64 enable_extension_loading_(enable_extension_loading) {
65 if (base::SysInfo::IsRunningOnChromeOS())
66 keyboard_.reset(ImeKeyboard::Create());
67 else
68 keyboard_.reset(new FakeImeKeyboard());
69 66
70 // Initializes the system IME list. 67 active_input_method_ids = other.active_input_method_ids;
71 scoped_ptr<ComponentExtensionIMEManagerDelegate> comp_delegate( 68
72 new ComponentExtensionIMEManagerImpl()); 69 pending_input_method_id = other.pending_input_method_id;
73 component_extension_ime_manager_->Initialize(comp_delegate.Pass()); 70
74 util_.ResetInputMethods( 71 enabled_extension_imes = other.enabled_extension_imes;
75 component_extension_ime_manager_->GetAllIMEAsInputMethodDescriptor()); 72 extra_input_methods = other.extra_input_methods;
76 } 73 }
77 74
78 InputMethodManagerImpl::~InputMethodManagerImpl() { 75 bool InputMethodManagerImpl::StateImpl::IsActive() const {
79 if (candidate_window_controller_.get()) 76 return manager_->state_.get() == this;
80 candidate_window_controller_->RemoveObserver(this);
81 } 77 }
82 78
83 void InputMethodManagerImpl::AddObserver( 79 std::string InputMethodManagerImpl::StateImpl::Dump() const {
84 InputMethodManager::Observer* observer) { 80 std::ostringstream os;
85 observers_.AddObserver(observer); 81
82 os << "################# "
83 << (profile ? profile->GetProfileName() : std::string("NULL"))
84 << " #################\n";
85
86 os << "previous_input_method: '"
87 << previous_input_method.GetPreferredKeyboardLayout() << "'\n";
88 os << "current_input_method: '"
89 << current_input_method.GetPreferredKeyboardLayout() << "'\n";
90 os << "active_input_method_ids (size=" << active_input_method_ids.size()
91 << "):";
92 for (size_t i = 0; i < active_input_method_ids.size(); ++i) {
93 os << " '" << active_input_method_ids[i] << "',";
94 }
95 os << "\n";
96 os << "enabled_extension_imes (size=" << enabled_extension_imes.size()
97 << "):";
98 for (size_t i = 0; i < enabled_extension_imes.size(); ++i) {
99 os << " '" << enabled_extension_imes[i] << "'\n";
100 }
101 os << "\n";
102 os << "extra_input_methods (size=" << extra_input_methods.size() << "):";
103 for (std::map<std::string, InputMethodDescriptor>::const_iterator it =
104 extra_input_methods.begin();
105 it != extra_input_methods.end();
106 ++it) {
107 os << " '" << it->first << "' => '" << it->second.id() << "',\n";
108 }
109 os << "pending_input_method_id: '" << pending_input_method_id << "'\n";
110
111 return os.str();
86 } 112 }
87 113
88 void InputMethodManagerImpl::AddCandidateWindowObserver( 114 scoped_refptr<InputMethodManager::State>
89 InputMethodManager::CandidateWindowObserver* observer) { 115 InputMethodManagerImpl::StateImpl::Clone() const {
90 candidate_window_observers_.AddObserver(observer); 116 scoped_refptr<StateImpl> new_state(new StateImpl(this->manager_, profile));
91 } 117 new_state->InitFrom(*this);
92 118 return scoped_refptr<InputMethodManager::State>(new_state.get());
93 void InputMethodManagerImpl::RemoveObserver(
94 InputMethodManager::Observer* observer) {
95 observers_.RemoveObserver(observer);
96 }
97
98 void InputMethodManagerImpl::RemoveCandidateWindowObserver(
99 InputMethodManager::CandidateWindowObserver* observer) {
100 candidate_window_observers_.RemoveObserver(observer);
101 }
102
103 InputMethodManager::State InputMethodManagerImpl::GetState() {
104 return state_;
105 }
106
107 void InputMethodManagerImpl::SetState(State new_state) {
108 const State old_state = state_;
109 state_ = new_state;
110 switch (state_) {
111 case STATE_LOGIN_SCREEN:
112 break;
113 case STATE_BROWSER_SCREEN:
114 if (old_state == STATE_LOCK_SCREEN)
115 OnScreenUnlocked();
116 break;
117 case STATE_LOCK_SCREEN:
118 OnScreenLocked();
119 break;
120 case STATE_TERMINATING: {
121 if (candidate_window_controller_.get())
122 candidate_window_controller_.reset();
123 break;
124 }
125 }
126 } 119 }
127 120
128 scoped_ptr<InputMethodDescriptors> 121 scoped_ptr<InputMethodDescriptors>
129 InputMethodManagerImpl::GetSupportedInputMethods() const { 122 InputMethodManagerImpl::StateImpl::GetActiveInputMethods() const {
130 return scoped_ptr<InputMethodDescriptors>(new InputMethodDescriptors).Pass();
131 }
132
133 scoped_ptr<InputMethodDescriptors>
134 InputMethodManagerImpl::GetActiveInputMethods() const {
135 scoped_ptr<InputMethodDescriptors> result(new InputMethodDescriptors); 123 scoped_ptr<InputMethodDescriptors> result(new InputMethodDescriptors);
136 // Build the active input method descriptors from the active input 124 // Build the active input method descriptors from the active input
137 // methods cache |active_input_method_ids_|. 125 // methods cache |active_input_method_ids|.
138 for (size_t i = 0; i < active_input_method_ids_.size(); ++i) { 126 for (size_t i = 0; i < active_input_method_ids.size(); ++i) {
139 const std::string& input_method_id = active_input_method_ids_[i]; 127 const std::string& input_method_id = active_input_method_ids[i];
140 const InputMethodDescriptor* descriptor = 128 const InputMethodDescriptor* descriptor =
141 util_.GetInputMethodDescriptorFromId(input_method_id); 129 manager_->util_.GetInputMethodDescriptorFromId(input_method_id);
142 if (descriptor) { 130 if (descriptor) {
143 result->push_back(*descriptor); 131 result->push_back(*descriptor);
144 } else { 132 } else {
145 std::map<std::string, InputMethodDescriptor>::const_iterator ix = 133 std::map<std::string, InputMethodDescriptor>::const_iterator ix =
146 extra_input_methods_.find(input_method_id); 134 extra_input_methods.find(input_method_id);
147 if (ix != extra_input_methods_.end()) 135 if (ix != extra_input_methods.end())
148 result->push_back(ix->second); 136 result->push_back(ix->second);
149 else 137 else
150 DVLOG(1) << "Descriptor is not found for: " << input_method_id; 138 DVLOG(1) << "Descriptor is not found for: " << input_method_id;
151 } 139 }
152 } 140 }
153 if (result->empty()) { 141 if (result->empty()) {
154 // Initially |active_input_method_ids_| is empty. browser_tests might take 142 // Initially |active_input_method_ids| is empty. browser_tests might take
155 // this path. 143 // this path.
156 result->push_back( 144 result->push_back(
157 InputMethodUtil::GetFallbackInputMethodDescriptor()); 145 InputMethodUtil::GetFallbackInputMethodDescriptor());
158 } 146 }
159 return result.Pass(); 147 return result.Pass();
160 } 148 }
161 149
162 const std::vector<std::string>& 150 const std::vector<std::string>&
163 InputMethodManagerImpl::GetActiveInputMethodIds() const { 151 InputMethodManagerImpl::StateImpl::GetActiveInputMethodIds() const {
164 return active_input_method_ids_; 152 return active_input_method_ids;
165 } 153 }
166 154
167 size_t InputMethodManagerImpl::GetNumActiveInputMethods() const { 155 size_t InputMethodManagerImpl::StateImpl::GetNumActiveInputMethods() const {
168 return active_input_method_ids_.size(); 156 return active_input_method_ids.size();
169 } 157 }
170 158
171 const InputMethodDescriptor* InputMethodManagerImpl::GetInputMethodFromId( 159 const InputMethodDescriptor*
160 InputMethodManagerImpl::StateImpl::GetInputMethodFromId(
172 const std::string& input_method_id) const { 161 const std::string& input_method_id) const {
173 const InputMethodDescriptor* ime = util_.GetInputMethodDescriptorFromId( 162 const InputMethodDescriptor* ime =
174 input_method_id); 163 manager_->util_.GetInputMethodDescriptorFromId(input_method_id);
175 if (!ime) { 164 if (!ime) {
176 std::map<std::string, InputMethodDescriptor>::const_iterator ix = 165 std::map<std::string, InputMethodDescriptor>::const_iterator ix =
177 extra_input_methods_.find(input_method_id); 166 extra_input_methods.find(input_method_id);
178 if (ix != extra_input_methods_.end()) 167 if (ix != extra_input_methods.end())
179 ime = &ix->second; 168 ime = &ix->second;
180 } 169 }
181 return ime; 170 return ime;
182 } 171 }
183 172
184 void InputMethodManagerImpl::EnableLoginLayouts( 173 void InputMethodManagerImpl::StateImpl::EnableLoginLayouts(
185 const std::string& language_code, 174 const std::string& language_code,
186 const std::vector<std::string>& initial_layouts) { 175 const std::vector<std::string>& initial_layouts) {
187 if (state_ == STATE_TERMINATING) 176 if (manager_->ui_session_ == STATE_TERMINATING)
188 return; 177 return;
189 178
190 // First, hardware keyboard layout should be shown. 179 // First, hardware keyboard layout should be shown.
191 std::vector<std::string> candidates = 180 std::vector<std::string> candidates =
192 util_.GetHardwareLoginInputMethodIds(); 181 manager_->util_.GetHardwareLoginInputMethodIds();
193 182
194 // Seocnd, locale based input method should be shown. 183 // Second, locale based input method should be shown.
195 // Add input methods associated with the language. 184 // Add input methods associated with the language.
196 std::vector<std::string> layouts_from_locale; 185 std::vector<std::string> layouts_from_locale;
197 util_.GetInputMethodIdsFromLanguageCode(language_code, 186 manager_->util_.GetInputMethodIdsFromLanguageCode(
198 kKeyboardLayoutsOnly, 187 language_code, kKeyboardLayoutsOnly, &layouts_from_locale);
199 &layouts_from_locale);
200 candidates.insert(candidates.end(), layouts_from_locale.begin(), 188 candidates.insert(candidates.end(), layouts_from_locale.begin(),
201 layouts_from_locale.end()); 189 layouts_from_locale.end());
202 190
203 std::vector<std::string> layouts; 191 std::vector<std::string> layouts;
204 // First, add the initial input method ID, if it's requested, to 192 // First, add the initial input method ID, if it's requested, to
205 // layouts, so it appears first on the list of active input 193 // layouts, so it appears first on the list of active input
206 // methods at the input language status menu. 194 // methods at the input language status menu.
207 for (size_t i = 0; i < initial_layouts.size(); ++i) { 195 for (size_t i = 0; i < initial_layouts.size(); ++i) {
208 if (util_.IsValidInputMethodId(initial_layouts[i])) { 196 if (manager_->util_.IsValidInputMethodId(initial_layouts[i])) {
209 if (IsLoginKeyboard(initial_layouts[i])) { 197 if (manager_->IsLoginKeyboard(initial_layouts[i])) {
210 layouts.push_back(initial_layouts[i]); 198 layouts.push_back(initial_layouts[i]);
211 } else { 199 } else {
212 DVLOG(1) 200 DVLOG(1)
213 << "EnableLoginLayouts: ignoring non-login initial keyboard layout:" 201 << "EnableLoginLayouts: ignoring non-login initial keyboard layout:"
214 << initial_layouts[i]; 202 << initial_layouts[i];
215 } 203 }
216 } else if (!initial_layouts[i].empty()) { 204 } else if (!initial_layouts[i].empty()) {
217 DVLOG(1) << "EnableLoginLayouts: ignoring non-keyboard or invalid ID: " 205 DVLOG(1) << "EnableLoginLayouts: ignoring non-keyboard or invalid ID: "
218 << initial_layouts[i]; 206 << initial_layouts[i];
219 } 207 }
220 } 208 }
221 209
222 // Add candidates to layouts, while skipping duplicates. 210 // Add candidates to layouts, while skipping duplicates.
223 for (size_t i = 0; i < candidates.size(); ++i) { 211 for (size_t i = 0; i < candidates.size(); ++i) {
224 const std::string& candidate = candidates[i]; 212 const std::string& candidate = candidates[i];
225 // Not efficient, but should be fine, as the two vectors are very 213 // Not efficient, but should be fine, as the two vectors are very
226 // short (2-5 items). 214 // short (2-5 items).
227 if (!Contains(layouts, candidate) && IsLoginKeyboard(candidate)) 215 if (!Contains(layouts, candidate) && manager_->IsLoginKeyboard(candidate))
228 layouts.push_back(candidate); 216 layouts.push_back(candidate);
229 } 217 }
230 218
231 MigrateInputMethods(&layouts); 219 manager_->MigrateInputMethods(&layouts);
232 active_input_method_ids_.swap(layouts); 220 active_input_method_ids.swap(layouts);
233 221
234 // Initialize candidate window controller and widgets such as 222 if (IsActive()) {
235 // candidate window, infolist and mode indicator. Note, mode 223 // Initialize candidate window controller and widgets such as
236 // indicator is used by only keyboard layout input methods. 224 // candidate window, infolist and mode indicator. Note, mode
237 if (active_input_method_ids_.size() > 1) 225 // indicator is used by only keyboard layout input methods.
238 MaybeInitializeCandidateWindowController(); 226 if (active_input_method_ids.size() > 1)
227 manager_->MaybeInitializeCandidateWindowController();
239 228
240 // you can pass empty |initial_layout|. 229 // you can pass empty |initial_layout|.
241 ChangeInputMethod(initial_layouts.empty() ? "" : 230 ChangeInputMethod(initial_layouts.empty()
242 extension_ime_util::GetInputMethodIDByEngineID(initial_layouts[0])); 231 ? std::string()
232 : extension_ime_util::GetInputMethodIDByEngineID(
233 initial_layouts[0]),
234 false);
235 }
236 }
237
238 void InputMethodManagerImpl::StateImpl::EnableLockScreenLayouts() {
239 std::set<std::string> added_ids;
240
241 const std::vector<std::string>& hardware_keyboard_ids =
242 manager_->util_.GetHardwareLoginInputMethodIds();
243
244 std::vector<std::string> new_active_input_method_ids;
245 for (size_t i = 0; i < active_input_method_ids.size(); ++i) {
246 const std::string& input_method_id = active_input_method_ids[i];
247 // Skip if it's not a keyboard layout. Drop input methods including
248 // extension ones.
249 if (!manager_->IsLoginKeyboard(input_method_id) ||
250 added_ids.count(input_method_id)) {
251 continue;
252 }
253 new_active_input_method_ids.push_back(input_method_id);
254 added_ids.insert(input_method_id);
255 }
256
257 // We'll add the hardware keyboard if it's not included in
258 // |active_input_method_ids| so that the user can always use the hardware
259 // keyboard on the screen locker.
260 for (size_t i = 0; i < hardware_keyboard_ids.size(); ++i) {
261 if (added_ids.count(hardware_keyboard_ids[i]))
262 continue;
263 new_active_input_method_ids.push_back(hardware_keyboard_ids[i]);
264 added_ids.insert(hardware_keyboard_ids[i]);
265 }
266
267 active_input_method_ids.swap(new_active_input_method_ids);
268
269 // Re-check current_input_method.
270 ChangeInputMethod(current_input_method.id(), false);
243 } 271 }
244 272
245 // Adds new input method to given list. 273 // Adds new input method to given list.
246 bool InputMethodManagerImpl::EnableInputMethodImpl( 274 bool InputMethodManagerImpl::StateImpl::EnableInputMethodImpl(
247 const std::string& input_method_id, 275 const std::string& input_method_id,
248 std::vector<std::string>* new_active_input_method_ids) const { 276 std::vector<std::string>* new_active_input_method_ids) const {
249 DCHECK(new_active_input_method_ids); 277 DCHECK(new_active_input_method_ids);
250 if (!util_.IsValidInputMethodId(input_method_id)) { 278 if (!manager_->util_.IsValidInputMethodId(input_method_id)) {
251 DVLOG(1) << "EnableInputMethod: Invalid ID: " << input_method_id; 279 DVLOG(1) << "EnableInputMethod: Invalid ID: " << input_method_id;
252 return false; 280 return false;
253 } 281 }
254 282
255 if (!Contains(*new_active_input_method_ids, input_method_id)) 283 if (!Contains(*new_active_input_method_ids, input_method_id))
256 new_active_input_method_ids->push_back(input_method_id); 284 new_active_input_method_ids->push_back(input_method_id);
257 285
258 return true; 286 return true;
259 } 287 }
260 288
261 // Starts or stops the system input method framework as needed. 289 bool InputMethodManagerImpl::StateImpl::EnableInputMethod(
262 void InputMethodManagerImpl::ReconfigureIMFramework() {
263 LoadNecessaryComponentExtensions();
264
265 // Initialize candidate window controller and widgets such as
266 // candidate window, infolist and mode indicator. Note, mode
267 // indicator is used by only keyboard layout input methods.
268 MaybeInitializeCandidateWindowController();
269 }
270
271 bool InputMethodManagerImpl::EnableInputMethod(
272 const std::string& input_method_id) { 290 const std::string& input_method_id) {
273 if (!EnableInputMethodImpl(input_method_id, &active_input_method_ids_)) 291 if (!EnableInputMethodImpl(input_method_id, &active_input_method_ids))
274 return false; 292 return false;
275 293
276 ReconfigureIMFramework(); 294 manager_->ReconfigureIMFramework(this);
277 return true; 295 return true;
278 } 296 }
279 297
280 bool InputMethodManagerImpl::ReplaceEnabledInputMethods( 298 bool InputMethodManagerImpl::StateImpl::ReplaceEnabledInputMethods(
281 const std::vector<std::string>& new_active_input_method_ids) { 299 const std::vector<std::string>& new_active_input_method_ids) {
282 if (state_ == STATE_TERMINATING) 300 if (manager_->ui_session_ == STATE_TERMINATING)
283 return false; 301 return false;
284 302
285 // Filter unknown or obsolete IDs. 303 // Filter unknown or obsolete IDs.
286 std::vector<std::string> new_active_input_method_ids_filtered; 304 std::vector<std::string> new_active_input_method_ids_filtered;
287 305
288 for (size_t i = 0; i < new_active_input_method_ids.size(); ++i) 306 for (size_t i = 0; i < new_active_input_method_ids.size(); ++i)
289 EnableInputMethodImpl(new_active_input_method_ids[i], 307 EnableInputMethodImpl(new_active_input_method_ids[i],
290 &new_active_input_method_ids_filtered); 308 &new_active_input_method_ids_filtered);
291 309
292 if (new_active_input_method_ids_filtered.empty()) { 310 if (new_active_input_method_ids_filtered.empty()) {
293 DVLOG(1) << "ReplaceEnabledInputMethods: No valid input method ID"; 311 DVLOG(1) << "ReplaceEnabledInputMethods: No valid input method ID";
294 return false; 312 return false;
295 } 313 }
296 314
297 // Copy extension IDs to |new_active_input_method_ids_filtered|. We have to 315 // Copy extension IDs to |new_active_input_method_ids_filtered|. We have to
298 // keep relative order of the extension input method IDs. 316 // keep relative order of the extension input method IDs.
299 for (size_t i = 0; i < active_input_method_ids_.size(); ++i) { 317 for (size_t i = 0; i < active_input_method_ids.size(); ++i) {
300 const std::string& input_method_id = active_input_method_ids_[i]; 318 const std::string& input_method_id = active_input_method_ids[i];
301 if (extension_ime_util::IsExtensionIME(input_method_id)) 319 if (extension_ime_util::IsExtensionIME(input_method_id))
302 new_active_input_method_ids_filtered.push_back(input_method_id); 320 new_active_input_method_ids_filtered.push_back(input_method_id);
303 } 321 }
304 active_input_method_ids_.swap(new_active_input_method_ids_filtered); 322 active_input_method_ids.swap(new_active_input_method_ids_filtered);
305 MigrateInputMethods(&active_input_method_ids_); 323 manager_->MigrateInputMethods(&active_input_method_ids);
306 324
307 ReconfigureIMFramework(); 325 manager_->ReconfigureIMFramework(this);
308 326
309 // If |current_input_method| is no longer in |active_input_method_ids_|, 327 // If |current_input_method| is no longer in |active_input_method_ids|,
310 // ChangeInputMethod() picks the first one in |active_input_method_ids_|. 328 // ChangeInputMethod() picks the first one in |active_input_method_ids|.
311 ChangeInputMethod(current_input_method_.id()); 329 ChangeInputMethod(current_input_method.id(), false);
312 return true; 330 return true;
313 } 331 }
314 332
315 void InputMethodManagerImpl::ChangeInputMethod( 333 void InputMethodManagerImpl::StateImpl::ChangeInputMethod(
316 const std::string& input_method_id) { 334 const std::string& input_method_id,
317 ChangeInputMethodInternal(input_method_id, false); 335 bool show_message) {
336 if (manager_->ui_session_ == STATE_TERMINATING)
337 return;
338
339 bool notify_menu = false;
340 // For 3rd party IME, when the user just logged in, SetEnabledExtensionImes
341 // happens after activating the 3rd party IME.
342 // So here to record the 3rd party IME to be activated, and activate it
343 // when SetEnabledExtensionImes happens later.
344 if (MethodAwaitsExtensionLoad(input_method_id))
345 pending_input_method_id = input_method_id;
346
347 // Always lookup input method, even if it is the same as
348 // |current_input_method| because If it is no longer in
349 // |active_input_method_ids|, pick the first one in
350 // |active_input_method_ids|.
351 const InputMethodDescriptor* descriptor =
352 manager_->LookupInputMethod(input_method_id, this);
353 if (descriptor->id() != current_input_method.id()) {
354 previous_input_method = current_input_method;
355 current_input_method = *descriptor;
356 notify_menu = true;
357 }
358
359 // Always change input method even if it is the same.
360 // TODO(komatsu): Revisit if this is neccessary.
361 if (IsActive())
362 manager_->ChangeInputMethodInternal(*descriptor, show_message, notify_menu);
318 } 363 }
319 364
320 bool InputMethodManagerImpl::ChangeInputMethodInternal( 365 bool InputMethodManagerImpl::StateImpl::MethodAwaitsExtensionLoad(
321 const std::string& input_method_id, 366 const std::string& input_method_id) const {
322 bool show_message) { 367 // For 3rd party IME, when the user just logged in, SetEnabledExtensionImes
323 if (state_ == STATE_TERMINATING) 368 // happens after activating the 3rd party IME.
324 return false; 369 // So here to record the 3rd party IME to be activated, and activate it
325 370 // when SetEnabledExtensionImes happens later.
326 std::string input_method_id_to_switch = input_method_id; 371 return !InputMethodIsActivated(input_method_id) &&
327 372 extension_ime_util::IsExtensionIME(input_method_id);
328 // Sanity check.
329 if (!InputMethodIsActivated(input_method_id)) {
330 // For 3rd party IME, when the user just logged in, SetEnabledExtensionImes
331 // happens after activating the 3rd party IME.
332 // So here to record the 3rd party IME to be activated, and activate it
333 // when SetEnabledExtensionImes happens later.
334 if (extension_ime_util::IsExtensionIME(input_method_id))
335 pending_input_method_id_ = input_method_id;
336
337 scoped_ptr<InputMethodDescriptors> input_methods(GetActiveInputMethods());
338 DCHECK(!input_methods->empty());
339 input_method_id_to_switch = input_methods->at(0).id();
340 if (!input_method_id.empty()) {
341 DVLOG(1) << "Can't change the current input method to "
342 << input_method_id << " since the engine is not enabled. "
343 << "Switch to " << input_method_id_to_switch << " instead.";
344 }
345 }
346
347 // Hide candidate window and info list.
348 if (candidate_window_controller_.get())
349 candidate_window_controller_->Hide();
350
351 // TODO(komatsu): Check if it is necessary to perform the above routine
352 // when the current input method is equal to |input_method_id_to_swich|.
353 if (current_input_method_.id() != input_method_id_to_switch) {
354 // Clear property list. Property list would be updated by
355 // extension IMEs via InputMethodEngine::(Set|Update)MenuItems.
356 // If the current input method is a keyboard layout, empty
357 // properties are sufficient.
358 const ash::ime::InputMethodMenuItemList empty_menu_item_list;
359 ash::ime::InputMethodMenuManager* input_method_menu_manager =
360 ash::ime::InputMethodMenuManager::GetInstance();
361 input_method_menu_manager->SetCurrentInputMethodMenuItemList(
362 empty_menu_item_list);
363
364 const InputMethodDescriptor* descriptor = NULL;
365 if (extension_ime_util::IsExtensionIME(input_method_id_to_switch)) {
366 DCHECK(extra_input_methods_.find(input_method_id_to_switch) !=
367 extra_input_methods_.end());
368 descriptor = &(extra_input_methods_[input_method_id_to_switch]);
369 } else {
370 descriptor =
371 util_.GetInputMethodDescriptorFromId(input_method_id_to_switch);
372 if (!descriptor)
373 LOG(ERROR) << "Unknown input method id: " << input_method_id_to_switch;
374 }
375 DCHECK(descriptor);
376
377 previous_input_method_ = current_input_method_;
378 current_input_method_ = *descriptor;
379 }
380
381 // Disable the current engine handler.
382 IMEEngineHandlerInterface* engine =
383 IMEBridge::Get()->GetCurrentEngineHandler();
384 if (engine)
385 engine->Disable();
386
387 // Configure the next engine handler.
388 // This must be after |current_input_method_| has been set to new input
389 // method, because engine's Enable() method needs to access it.
390 const std::string& extension_id =
391 extension_ime_util::GetExtensionIDFromInputMethodID(
392 input_method_id_to_switch);
393 const std::string& component_id =
394 extension_ime_util::GetComponentIDByInputMethodID(
395 input_method_id_to_switch);
396 engine = engine_map_[extension_id];
397 IMEBridge::Get()->SetCurrentEngineHandler(engine);
398 if (engine)
399 engine->Enable(component_id);
400
401 // Change the keyboard layout to a preferred layout for the input method.
402 if (!keyboard_->SetCurrentKeyboardLayoutByName(
403 current_input_method_.GetPreferredKeyboardLayout())) {
404 LOG(ERROR) << "Failed to change keyboard layout to "
405 << current_input_method_.GetPreferredKeyboardLayout();
406 }
407
408 // Update input method indicators (e.g. "US", "DV") in Chrome windows.
409 FOR_EACH_OBSERVER(InputMethodManager::Observer,
410 observers_,
411 InputMethodChanged(this, show_message));
412 return true;
413 } 373 }
414 374
415 void InputMethodManagerImpl::LoadNecessaryComponentExtensions() { 375 void InputMethodManagerImpl::StateImpl::AddInputMethodExtension(
416 // Load component extensions but also update |active_input_method_ids_| as
417 // some component extension IMEs may have been removed from the Chrome OS
418 // image. If specified component extension IME no longer exists, falling back
419 // to an existing IME.
420 std::vector<std::string> unfiltered_input_method_ids;
421 unfiltered_input_method_ids.swap(active_input_method_ids_);
422 for (size_t i = 0; i < unfiltered_input_method_ids.size(); ++i) {
423 if (!extension_ime_util::IsComponentExtensionIME(
424 unfiltered_input_method_ids[i])) {
425 // Legacy IMEs or xkb layouts are alwayes active.
426 active_input_method_ids_.push_back(unfiltered_input_method_ids[i]);
427 } else if (component_extension_ime_manager_->IsWhitelisted(
428 unfiltered_input_method_ids[i])) {
429 if (enable_extension_loading_)
430 component_extension_ime_manager_->LoadComponentExtensionIME(
431 unfiltered_input_method_ids[i]);
432 active_input_method_ids_.push_back(unfiltered_input_method_ids[i]);
433 }
434 }
435 }
436
437 void InputMethodManagerImpl::ActivateInputMethodMenuItem(
438 const std::string& key) {
439 DCHECK(!key.empty());
440
441 if (ash::ime::InputMethodMenuManager::GetInstance()->
442 HasInputMethodMenuItemForKey(key)) {
443 IMEEngineHandlerInterface* engine =
444 IMEBridge::Get()->GetCurrentEngineHandler();
445 if (engine)
446 engine->PropertyActivate(key);
447 return;
448 }
449
450 DVLOG(1) << "ActivateInputMethodMenuItem: unknown key: " << key;
451 }
452
453 void InputMethodManagerImpl::AddInputMethodExtension(
454 const std::string& extension_id, 376 const std::string& extension_id,
455 const InputMethodDescriptors& descriptors, 377 const InputMethodDescriptors& descriptors,
456 InputMethodEngineInterface* engine) { 378 InputMethodEngineInterface* engine) {
457 if (state_ == STATE_TERMINATING) 379 if (manager_->ui_session_ == STATE_TERMINATING)
458 return; 380 return;
459 381
460 DCHECK(engine); 382 DCHECK(engine);
461 383
462 engine_map_[extension_id] = engine; 384 manager_->engine_map_[extension_id] = engine;
463
464 if (extension_id == extension_ime_util::GetExtensionIDFromInputMethodID(
465 current_input_method_.id())) {
466 IMEBridge::Get()->SetCurrentEngineHandler(engine);
467 engine->Enable(extension_ime_util::GetComponentIDByInputMethodID(
468 current_input_method_.id()));
469 }
470 385
471 bool contain = false; 386 bool contain = false;
472 for (size_t i = 0; i < descriptors.size(); i++) { 387 for (size_t i = 0; i < descriptors.size(); i++) {
473 const InputMethodDescriptor& descriptor = descriptors[i]; 388 const InputMethodDescriptor& descriptor = descriptors[i];
474 const std::string& id = descriptor.id(); 389 const std::string& id = descriptor.id();
475 extra_input_methods_[id] = descriptor; 390 extra_input_methods[id] = descriptor;
476 if (Contains(enabled_extension_imes_, id)) { 391 if (Contains(enabled_extension_imes, id)) {
477 if (!Contains(active_input_method_ids_, id)) { 392 if (!Contains(active_input_method_ids, id)) {
478 active_input_method_ids_.push_back(id); 393 active_input_method_ids.push_back(id);
479 } else { 394 } else {
480 DVLOG(1) << "AddInputMethodExtension: already added: " << id << ", " 395 DVLOG(1) << "AddInputMethodExtension: already added: " << id << ", "
481 << descriptor.name(); 396 << descriptor.name();
482 } 397 }
483 contain = true; 398 contain = true;
484 } 399 }
485 } 400 }
486 401
487 // Ensure that the input method daemon is running. 402 if (IsActive()) {
488 if (contain) 403 if (extension_id == extension_ime_util::GetExtensionIDFromInputMethodID(
489 MaybeInitializeCandidateWindowController(); 404 current_input_method.id())) {
405 IMEBridge::Get()->SetCurrentEngineHandler(engine);
406 engine->Enable(extension_ime_util::GetComponentIDByInputMethodID(
407 current_input_method.id()));
408 }
409
410 // Ensure that the input method daemon is running.
411 if (contain)
412 manager_->MaybeInitializeCandidateWindowController();
413 }
490 } 414 }
491 415
492 void InputMethodManagerImpl::RemoveInputMethodExtension( 416 void InputMethodManagerImpl::StateImpl::RemoveInputMethodExtension(
493 const std::string& extension_id) { 417 const std::string& extension_id) {
494 // Remove the active input methods with |extension_id|. 418 // Remove the active input methods with |extension_id|.
495 std::vector<std::string> new_active_input_method_ids; 419 std::vector<std::string> new_active_input_method_ids;
496 for (size_t i = 0; i < active_input_method_ids_.size(); ++i) { 420 for (size_t i = 0; i < active_input_method_ids.size(); ++i) {
497 if (extension_id != extension_ime_util::GetExtensionIDFromInputMethodID( 421 if (extension_id != extension_ime_util::GetExtensionIDFromInputMethodID(
498 active_input_method_ids_[i])) 422 active_input_method_ids[i]))
499 new_active_input_method_ids.push_back(active_input_method_ids_[i]); 423 new_active_input_method_ids.push_back(active_input_method_ids[i]);
500 } 424 }
501 active_input_method_ids_.swap(new_active_input_method_ids); 425 active_input_method_ids.swap(new_active_input_method_ids);
502 426
503 // Remove the extra input methods with |extension_id|. 427 // Remove the extra input methods with |extension_id|.
504 std::map<std::string, InputMethodDescriptor> new_extra_input_methods; 428 std::map<std::string, InputMethodDescriptor> new_extra_input_methods;
505 for (std::map<std::string, InputMethodDescriptor>::iterator i = 429 for (std::map<std::string, InputMethodDescriptor>::iterator i =
506 extra_input_methods_.begin(); 430 extra_input_methods.begin();
507 i != extra_input_methods_.end(); 431 i != extra_input_methods.end();
508 ++i) { 432 ++i) {
509 if (extension_id != 433 if (extension_id !=
510 extension_ime_util::GetExtensionIDFromInputMethodID(i->first)) 434 extension_ime_util::GetExtensionIDFromInputMethodID(i->first))
511 new_extra_input_methods[i->first] = i->second; 435 new_extra_input_methods[i->first] = i->second;
512 } 436 }
513 extra_input_methods_.swap(new_extra_input_methods); 437 extra_input_methods.swap(new_extra_input_methods);
514 438
515 if (IMEBridge::Get()->GetCurrentEngineHandler() == engine_map_[extension_id]) 439 if (IsActive()) {
516 IMEBridge::Get()->SetCurrentEngineHandler(NULL); 440 if (IMEBridge::Get()->GetCurrentEngineHandler() ==
517 engine_map_.erase(extension_id); 441 manager_->engine_map_[extension_id]) {
442 IMEBridge::Get()->SetCurrentEngineHandler(NULL);
443 }
444 manager_->engine_map_.erase(extension_id);
445 }
518 446
519 // No need to switch input method when terminating. 447 // If |current_input_method| is no longer in |active_input_method_ids|,
520 if (state_ != STATE_TERMINATING) { 448 // switch to the first one in |active_input_method_ids|.
521 // If |current_input_method| is no longer in |active_input_method_ids_|, 449 ChangeInputMethod(current_input_method.id(), false);
522 // switch to the first one in |active_input_method_ids_|.
523 ChangeInputMethod(current_input_method_.id());
524 }
525 } 450 }
526 451
527 void InputMethodManagerImpl::GetInputMethodExtensions( 452 void InputMethodManagerImpl::StateImpl::GetInputMethodExtensions(
528 InputMethodDescriptors* result) { 453 InputMethodDescriptors* result) {
529 // Build the extension input method descriptors from the extra input 454 // Build the extension input method descriptors from the extra input
530 // methods cache |extra_input_methods_|. 455 // methods cache |extra_input_methods|.
531 std::map<std::string, InputMethodDescriptor>::iterator iter; 456 std::map<std::string, InputMethodDescriptor>::iterator iter;
532 for (iter = extra_input_methods_.begin(); iter != extra_input_methods_.end(); 457 for (iter = extra_input_methods.begin(); iter != extra_input_methods.end();
533 ++iter) { 458 ++iter) {
534 if (extension_ime_util::IsExtensionIME(iter->first)) 459 if (extension_ime_util::IsExtensionIME(iter->first))
535 result->push_back(iter->second); 460 result->push_back(iter->second);
536 } 461 }
537 } 462 }
538 463
539 void InputMethodManagerImpl::SetEnabledExtensionImes( 464 void InputMethodManagerImpl::StateImpl::SetEnabledExtensionImes(
540 std::vector<std::string>* ids) { 465 std::vector<std::string>* ids) {
541 enabled_extension_imes_.clear(); 466 enabled_extension_imes.clear();
542 enabled_extension_imes_.insert(enabled_extension_imes_.end(), 467 enabled_extension_imes.insert(
543 ids->begin(), 468 enabled_extension_imes.end(), ids->begin(), ids->end());
544 ids->end());
545
546 bool active_imes_changed = false; 469 bool active_imes_changed = false;
547 bool switch_to_pending = false; 470 bool switch_to_pending = false;
548 471
549 for (std::map<std::string, InputMethodDescriptor>::iterator extra_iter = 472 for (std::map<std::string, InputMethodDescriptor>::iterator extra_iter =
550 extra_input_methods_.begin(); extra_iter != extra_input_methods_.end(); 473 extra_input_methods.begin();
474 extra_iter != extra_input_methods.end();
551 ++extra_iter) { 475 ++extra_iter) {
552 if (extension_ime_util::IsComponentExtensionIME( 476 if (extension_ime_util::IsComponentExtensionIME(extra_iter->first))
553 extra_iter->first))
554 continue; // Do not filter component extension. 477 continue; // Do not filter component extension.
555 478
556 if (pending_input_method_id_ == extra_iter->first) 479 if (pending_input_method_id == extra_iter->first)
557 switch_to_pending = true; 480 switch_to_pending = true;
558 481
559 std::vector<std::string>::iterator active_iter = std::find( 482 std::vector<std::string>::iterator active_iter =
560 active_input_method_ids_.begin(), active_input_method_ids_.end(), 483 std::find(active_input_method_ids.begin(),
561 extra_iter->first); 484 active_input_method_ids.end(),
485 extra_iter->first);
562 486
563 bool active = active_iter != active_input_method_ids_.end(); 487 bool active = active_iter != active_input_method_ids.end();
564 bool enabled = Contains(enabled_extension_imes_, extra_iter->first); 488 bool enabled = Contains(enabled_extension_imes, extra_iter->first);
565 489
566 if (active && !enabled) 490 if (active && !enabled)
567 active_input_method_ids_.erase(active_iter); 491 active_input_method_ids.erase(active_iter);
568 492
569 if (!active && enabled) 493 if (!active && enabled)
570 active_input_method_ids_.push_back(extra_iter->first); 494 active_input_method_ids.push_back(extra_iter->first);
571 495
572 if (active == !enabled) 496 if (active == !enabled)
573 active_imes_changed = true; 497 active_imes_changed = true;
574 } 498 }
575 499
576 if (active_imes_changed) { 500 if (IsActive() && active_imes_changed) {
577 MaybeInitializeCandidateWindowController(); 501 manager_->MaybeInitializeCandidateWindowController();
578 502
579 if (switch_to_pending) { 503 if (switch_to_pending) {
580 ChangeInputMethod(pending_input_method_id_); 504 ChangeInputMethod(pending_input_method_id, false);
581 pending_input_method_id_.clear(); 505 pending_input_method_id.clear();
582 } else { 506 } else {
583 // If |current_input_method| is no longer in |active_input_method_ids_|, 507 // If |current_input_method| is no longer in |active_input_method_ids_|,
584 // switch to the first one in |active_input_method_ids_|. 508 // switch to the first one in |active_input_method_ids_|.
585 ChangeInputMethod(current_input_method_.id()); 509 ChangeInputMethod(current_input_method.id(), false);
586 } 510 }
587 } 511 }
588 } 512 }
589 513
590 void InputMethodManagerImpl::SetInputMethodLoginDefaultFromVPD( 514 void InputMethodManagerImpl::StateImpl::SetInputMethodLoginDefaultFromVPD(
591 const std::string& locale, const std::string& oem_layout) { 515 const std::string& locale,
516 const std::string& oem_layout) {
592 std::string layout; 517 std::string layout;
593 if (!oem_layout.empty()) { 518 if (!oem_layout.empty()) {
594 // If the OEM layout information is provided, use it. 519 // If the OEM layout information is provided, use it.
595 layout = oem_layout; 520 layout = oem_layout;
596 } else { 521 } else {
597 // Otherwise, determine the hardware keyboard from the locale. 522 // Otherwise, determine the hardware keyboard from the locale.
598 std::vector<std::string> input_method_ids; 523 std::vector<std::string> input_method_ids;
599 if (util_.GetInputMethodIdsFromLanguageCode( 524 if (manager_->util_.GetInputMethodIdsFromLanguageCode(
600 locale, 525 locale,
601 chromeos::input_method::kKeyboardLayoutsOnly, 526 chromeos::input_method::kKeyboardLayoutsOnly,
602 &input_method_ids)) { 527 &input_method_ids)) {
603 // The output list |input_method_ids| is sorted by popularity, hence 528 // The output list |input_method_ids| is sorted by popularity, hence
604 // input_method_ids[0] now contains the most popular keyboard layout 529 // input_method_ids[0] now contains the most popular keyboard layout
605 // for the given locale. 530 // for the given locale.
606 DCHECK_GE(input_method_ids.size(), 1U); 531 DCHECK_GE(input_method_ids.size(), 1U);
607 layout = input_method_ids[0]; 532 layout = input_method_ids[0];
608 } 533 }
609 } 534 }
610 535
611 if (layout.empty()) 536 if (layout.empty())
612 return; 537 return;
613 538
614 std::vector<std::string> layouts; 539 std::vector<std::string> layouts;
615 base::SplitString(layout, ',', &layouts); 540 base::SplitString(layout, ',', &layouts);
616 MigrateInputMethods(&layouts); 541 manager_->MigrateInputMethods(&layouts);
617 542
618 PrefService* prefs = g_browser_process->local_state(); 543 PrefService* prefs = g_browser_process->local_state();
619 prefs->SetString(prefs::kHardwareKeyboardLayout, JoinString(layouts, ",")); 544 prefs->SetString(prefs::kHardwareKeyboardLayout, JoinString(layouts, ","));
620 545
621 // This asks the file thread to save the prefs (i.e. doesn't block). 546 // This asks the file thread to save the prefs (i.e. doesn't block).
622 // The latest values of Local State reside in memory so we can safely 547 // The latest values of Local State reside in memory so we can safely
623 // get the value of kHardwareKeyboardLayout even if the data is not 548 // get the value of kHardwareKeyboardLayout even if the data is not
624 // yet saved to disk. 549 // yet saved to disk.
625 prefs->CommitPendingWrite(); 550 prefs->CommitPendingWrite();
626 551
627 util_.UpdateHardwareLayoutCache(); 552 manager_->util_.UpdateHardwareLayoutCache();
628 553
629 EnableLoginLayouts(locale, layouts); 554 EnableLoginLayouts(locale, layouts);
630 LoadNecessaryComponentExtensions(); 555 manager_->LoadNecessaryComponentExtensions(this);
631 } 556 }
632 557
633 void InputMethodManagerImpl::SetInputMethodLoginDefault() { 558 void InputMethodManagerImpl::StateImpl::SetInputMethodLoginDefault() {
634 // Set up keyboards. For example, when |locale| is "en-US", enable US qwerty 559 // Set up keyboards. For example, when |locale| is "en-US", enable US qwerty
635 // and US dvorak keyboard layouts. 560 // and US dvorak keyboard layouts.
636 if (g_browser_process && g_browser_process->local_state()) { 561 if (g_browser_process && g_browser_process->local_state()) {
637 const std::string locale = g_browser_process->GetApplicationLocale(); 562 const std::string locale = g_browser_process->GetApplicationLocale();
638 // If the preferred keyboard for the login screen has been saved, use it. 563 // If the preferred keyboard for the login screen has been saved, use it.
639 PrefService* prefs = g_browser_process->local_state(); 564 PrefService* prefs = g_browser_process->local_state();
640 std::string initial_input_method_id = 565 std::string initial_input_method_id =
641 prefs->GetString(chromeos::language_prefs::kPreferredKeyboardLayout); 566 prefs->GetString(chromeos::language_prefs::kPreferredKeyboardLayout);
642 std::vector<std::string> input_methods_to_be_enabled; 567 std::vector<std::string> input_methods_to_be_enabled;
643 if (initial_input_method_id.empty()) { 568 if (initial_input_method_id.empty()) {
644 // If kPreferredKeyboardLayout is not specified, use the hardware layout. 569 // If kPreferredKeyboardLayout is not specified, use the hardware layout.
645 input_methods_to_be_enabled = util_.GetHardwareLoginInputMethodIds(); 570 input_methods_to_be_enabled =
571 manager_->util_.GetHardwareLoginInputMethodIds();
646 } else { 572 } else {
647 input_methods_to_be_enabled.push_back(initial_input_method_id); 573 input_methods_to_be_enabled.push_back(initial_input_method_id);
648 } 574 }
649 EnableLoginLayouts(locale, input_methods_to_be_enabled); 575 EnableLoginLayouts(locale, input_methods_to_be_enabled);
650 LoadNecessaryComponentExtensions(); 576 manager_->LoadNecessaryComponentExtensions(this);
651 } 577 }
652 } 578 }
653 579
654 bool InputMethodManagerImpl::SwitchToNextInputMethod() { 580 bool InputMethodManagerImpl::StateImpl::SwitchToNextInputMethod() {
655 // Sanity checks. 581 // Sanity checks.
656 if (active_input_method_ids_.empty()) { 582 if (active_input_method_ids.empty()) {
657 DVLOG(1) << "active input method is empty"; 583 DVLOG(1) << "active input method is empty";
658 return false; 584 return false;
659 } 585 }
660 586
661 if (current_input_method_.id().empty()) { 587 if (current_input_method.id().empty()) {
662 DVLOG(1) << "current_input_method_ is unknown"; 588 DVLOG(1) << "current_input_method is unknown";
663 return false; 589 return false;
664 } 590 }
665 591
666 // Do not consume key event if there is only one input method is enabled. 592 // Do not consume key event if there is only one input method is enabled.
667 // Ctrl+Space or Alt+Shift may be used by other application. 593 // Ctrl+Space or Alt+Shift may be used by other application.
668 if (active_input_method_ids_.size() == 1) 594 if (active_input_method_ids.size() == 1)
669 return false; 595 return false;
670 596
671 // Find the next input method and switch to it. 597 // Find the next input method and switch to it.
672 SwitchToNextInputMethodInternal(active_input_method_ids_, 598 SwitchToNextInputMethodInternal(active_input_method_ids,
673 current_input_method_.id()); 599 current_input_method.id());
674 return true; 600 return true;
675 } 601 }
676 602
677 bool InputMethodManagerImpl::SwitchToPreviousInputMethod( 603 bool InputMethodManagerImpl::StateImpl::SwitchToPreviousInputMethod(
678 const ui::Accelerator& accelerator) { 604 const ui::Accelerator& accelerator) {
679 // Sanity check. 605 // Sanity check.
680 if (active_input_method_ids_.empty()) { 606 if (active_input_method_ids.empty()) {
681 DVLOG(1) << "active input method is empty"; 607 DVLOG(1) << "active input method is empty";
682 return false; 608 return false;
683 } 609 }
684 610
685 // Do not consume key event if there is only one input method is enabled. 611 // Do not consume key event if there is only one input method is enabled.
686 // Ctrl+Space or Alt+Shift may be used by other application. 612 // Ctrl+Space or Alt+Shift may be used by other application.
687 if (active_input_method_ids_.size() == 1) 613 if (active_input_method_ids.size() == 1)
688 return false; 614 return false;
689 615
690 if (accelerator.type() == ui::ET_KEY_RELEASED) 616 if (accelerator.type() == ui::ET_KEY_RELEASED)
691 return true; 617 return true;
692 618
693 if (previous_input_method_.id().empty() || 619 if (previous_input_method.id().empty() ||
694 previous_input_method_.id() == current_input_method_.id()) { 620 previous_input_method.id() == current_input_method.id()) {
695 return SwitchToNextInputMethod(); 621 return SwitchToNextInputMethod();
696 } 622 }
697 623
698 std::vector<std::string>::const_iterator iter = 624 std::vector<std::string>::const_iterator iter =
699 std::find(active_input_method_ids_.begin(), 625 std::find(active_input_method_ids.begin(),
700 active_input_method_ids_.end(), 626 active_input_method_ids.end(),
701 previous_input_method_.id()); 627 previous_input_method.id());
702 if (iter == active_input_method_ids_.end()) { 628 if (iter == active_input_method_ids.end()) {
703 // previous_input_method_ is not supported. 629 // previous_input_method is not supported.
704 return SwitchToNextInputMethod(); 630 return SwitchToNextInputMethod();
705 } 631 }
706 ChangeInputMethodInternal(*iter, true); 632 ChangeInputMethod(*iter, true);
633
707 return true; 634 return true;
708 } 635 }
709 636
710 bool InputMethodManagerImpl::SwitchInputMethod( 637 bool InputMethodManagerImpl::StateImpl::SwitchInputMethod(
711 const ui::Accelerator& accelerator) { 638 const ui::Accelerator& accelerator) {
712 // Sanity check. 639 // Sanity check.
713 if (active_input_method_ids_.empty()) { 640 if (active_input_method_ids.empty()) {
714 DVLOG(1) << "active input method is empty"; 641 DVLOG(1) << "active input method is empty";
715 return false; 642 return false;
716 } 643 }
717 644
718 // Get the list of input method ids for the |accelerator|. For example, get 645 // Get the list of input method ids for the |accelerator|. For example, get
719 // { "mozc-hangul", "xkb:kr:kr104:kor" } for ui::VKEY_DBE_SBCSCHAR. 646 // { "mozc-hangul", "xkb:kr:kr104:kor" } for ui::VKEY_DBE_SBCSCHAR.
720 std::vector<std::string> input_method_ids_to_switch; 647 std::vector<std::string> input_method_ids_to_switch;
721 switch (accelerator.key_code()) { 648 switch (accelerator.key_code()) {
722 case ui::VKEY_CONVERT: // Henkan key on JP106 keyboard 649 case ui::VKEY_CONVERT: // Henkan key on JP106 keyboard
723 input_method_ids_to_switch.push_back( 650 input_method_ids_to_switch.push_back(
(...skipping 13 matching lines...) Expand all
737 default: 664 default:
738 NOTREACHED(); 665 NOTREACHED();
739 break; 666 break;
740 } 667 }
741 if (input_method_ids_to_switch.empty()) { 668 if (input_method_ids_to_switch.empty()) {
742 DVLOG(1) << "Unexpected VKEY: " << accelerator.key_code(); 669 DVLOG(1) << "Unexpected VKEY: " << accelerator.key_code();
743 return false; 670 return false;
744 } 671 }
745 672
746 // Obtain the intersection of input_method_ids_to_switch and 673 // Obtain the intersection of input_method_ids_to_switch and
747 // active_input_method_ids_. The order of IDs in active_input_method_ids_ is 674 // active_input_method_ids. The order of IDs in active_input_method_ids is
748 // preserved. 675 // preserved.
749 std::vector<std::string> ids; 676 std::vector<std::string> ids;
750 for (size_t i = 0; i < input_method_ids_to_switch.size(); ++i) { 677 for (size_t i = 0; i < input_method_ids_to_switch.size(); ++i) {
751 const std::string& id = input_method_ids_to_switch[i]; 678 const std::string& id = input_method_ids_to_switch[i];
752 if (Contains(active_input_method_ids_, id)) 679 if (Contains(active_input_method_ids, id))
753 ids.push_back(id); 680 ids.push_back(id);
754 } 681 }
755 if (ids.empty()) { 682 if (ids.empty()) {
756 // No input method for the accelerator is active. For example, we should 683 // No input method for the accelerator is active. For example, we should
757 // just ignore VKEY_HANGUL when mozc-hangul is not active. 684 // just ignore VKEY_HANGUL when mozc-hangul is not active.
758 return false; 685 return false;
759 } 686 }
760 687
761 SwitchToNextInputMethodInternal(ids, current_input_method_.id()); 688 SwitchToNextInputMethodInternal(ids, current_input_method.id());
762 return true; // consume the accelerator. 689 return true; // consume the accelerator.
763 } 690 }
764 691
765 void InputMethodManagerImpl::SwitchToNextInputMethodInternal( 692 void InputMethodManagerImpl::StateImpl::SwitchToNextInputMethodInternal(
766 const std::vector<std::string>& input_method_ids, 693 const std::vector<std::string>& input_method_ids,
767 const std::string& current_input_method_id) { 694 const std::string& current_input_methodid) {
768 std::vector<std::string>::const_iterator iter = 695 std::vector<std::string>::const_iterator iter = std::find(
769 std::find(input_method_ids.begin(), 696 input_method_ids.begin(), input_method_ids.end(), current_input_methodid);
770 input_method_ids.end(),
771 current_input_method_id);
772 if (iter != input_method_ids.end()) 697 if (iter != input_method_ids.end())
773 ++iter; 698 ++iter;
774 if (iter == input_method_ids.end()) 699 if (iter == input_method_ids.end())
775 iter = input_method_ids.begin(); 700 iter = input_method_ids.begin();
776 ChangeInputMethodInternal(*iter, true); 701 ChangeInputMethod(*iter, true);
777 } 702 }
778 703
779 InputMethodDescriptor InputMethodManagerImpl::GetCurrentInputMethod() const { 704 InputMethodDescriptor InputMethodManagerImpl::StateImpl::GetCurrentInputMethod()
780 if (current_input_method_.id().empty()) 705 const {
706 if (current_input_method.id().empty())
781 return InputMethodUtil::GetFallbackInputMethodDescriptor(); 707 return InputMethodUtil::GetFallbackInputMethodDescriptor();
782 708
783 return current_input_method_; 709 return current_input_method;
710 }
711
712 bool InputMethodManagerImpl::StateImpl::InputMethodIsActivated(
713 const std::string& input_method_id) const {
714 return Contains(active_input_method_ids, input_method_id);
715 }
716
717 // ------------------------ InputMethodManagerImpl
718 bool InputMethodManagerImpl::IsLoginKeyboard(
719 const std::string& layout) const {
720 return util_.IsLoginKeyboard(layout);
721 }
722
723 bool InputMethodManagerImpl::MigrateInputMethods(
724 std::vector<std::string>* input_method_ids) {
725 return util_.MigrateInputMethods(input_method_ids);
726 }
727
728 // Starts or stops the system input method framework as needed.
729 void InputMethodManagerImpl::ReconfigureIMFramework(
730 InputMethodManagerImpl::StateImpl* state) {
731 LoadNecessaryComponentExtensions(state);
732
733 // Initialize candidate window controller and widgets such as
734 // candidate window, infolist and mode indicator. Note, mode
735 // indicator is used by only keyboard layout input methods.
736 if (state_.get() == state)
737 MaybeInitializeCandidateWindowController();
738 }
739
740 void InputMethodManagerImpl::SetState(
741 scoped_refptr<InputMethodManager::State> state) {
742 DCHECK(state);
743 InputMethodManagerImpl::StateImpl* new_impl_state =
744 static_cast<InputMethodManagerImpl::StateImpl*>(state.get());
745 const bool need_update_current_input_method =
746 (state_ ? state_->current_input_method.id() !=
747 new_impl_state->current_input_method.id()
748 : true);
749 state_ = new_impl_state;
750
751 if (state_ && state_->active_input_method_ids.size()) {
752 // Initialize candidate window controller and widgets such as
753 // candidate window, infolist and mode indicator. Note, mode
754 // indicator is used by only keyboard layout input methods.
755 MaybeInitializeCandidateWindowController();
756
757 if (need_update_current_input_method)
758 ChangeInputMethodInternal(state_->current_input_method,
759 false /* show_message */,
760 true /* notify_menu */);
761 }
762 }
763
764 scoped_refptr<InputMethodManager::State>
765 InputMethodManagerImpl::GetActiveIMEState() {
766 return scoped_refptr<InputMethodManager::State>(state_.get());
767 }
768
769 InputMethodManagerImpl::InputMethodManagerImpl(
770 scoped_ptr<InputMethodDelegate> delegate,
771 bool enable_extension_loading)
772 : delegate_(delegate.Pass()),
773 ui_session_(STATE_LOGIN_SCREEN),
774 state_(NULL),
775 util_(delegate_.get()),
776 component_extension_ime_manager_(new ComponentExtensionIMEManager()),
777 enable_extension_loading_(enable_extension_loading) {
778 if (base::SysInfo::IsRunningOnChromeOS())
779 keyboard_.reset(ImeKeyboard::Create());
780 else
781 keyboard_.reset(new FakeImeKeyboard());
782
783 // Initializes the system IME list.
784 scoped_ptr<ComponentExtensionIMEManagerDelegate> comp_delegate(
785 new ComponentExtensionIMEManagerImpl());
786 component_extension_ime_manager_->Initialize(comp_delegate.Pass());
787 util_.ResetInputMethods(
788 component_extension_ime_manager_->GetAllIMEAsInputMethodDescriptor());
789 }
790
791 InputMethodManagerImpl::~InputMethodManagerImpl() {
792 if (candidate_window_controller_.get())
793 candidate_window_controller_->RemoveObserver(this);
794 }
795
796 void InputMethodManagerImpl::AddObserver(
797 InputMethodManager::Observer* observer) {
798 observers_.AddObserver(observer);
799 }
800
801 void InputMethodManagerImpl::AddCandidateWindowObserver(
802 InputMethodManager::CandidateWindowObserver* observer) {
803 candidate_window_observers_.AddObserver(observer);
804 }
805
806 void InputMethodManagerImpl::RemoveObserver(
807 InputMethodManager::Observer* observer) {
808 observers_.RemoveObserver(observer);
809 }
810
811 void InputMethodManagerImpl::RemoveCandidateWindowObserver(
812 InputMethodManager::CandidateWindowObserver* observer) {
813 candidate_window_observers_.RemoveObserver(observer);
814 }
815
816 InputMethodManager::UISessionState InputMethodManagerImpl::GetUISessionState() {
817 return ui_session_;
818 }
819
820 void InputMethodManagerImpl::SetUISessionState(UISessionState new_ui_session) {
821 ui_session_ = new_ui_session;
822 switch (ui_session_) {
823 case STATE_LOGIN_SCREEN:
824 break;
825 case STATE_BROWSER_SCREEN:
826 break;
827 case STATE_LOCK_SCREEN:
828 break;
829 case STATE_TERMINATING: {
830 if (candidate_window_controller_.get())
831 candidate_window_controller_.reset();
832 break;
833 }
834 }
835 }
836
837 scoped_ptr<InputMethodDescriptors>
838 InputMethodManagerImpl::GetSupportedInputMethods() const {
839 return scoped_ptr<InputMethodDescriptors>(new InputMethodDescriptors).Pass();
840 }
841
842 const InputMethodDescriptor* InputMethodManagerImpl::LookupInputMethod(
843 const std::string& input_method_id,
844 InputMethodManagerImpl::StateImpl* state) {
845 DCHECK(state);
846
847 std::string input_method_id_to_switch = input_method_id;
848
849 // Sanity check
850 if (!state->InputMethodIsActivated(input_method_id)) {
851 scoped_ptr<InputMethodDescriptors> input_methods(
852 state->GetActiveInputMethods());
853 DCHECK(!input_methods->empty());
854 input_method_id_to_switch = input_methods->at(0).id();
855 if (!input_method_id.empty()) {
856 DVLOG(1) << "Can't change the current input method to "
857 << input_method_id << " since the engine is not enabled. "
858 << "Switch to " << input_method_id_to_switch << " instead.";
859 }
860 }
861
862 const InputMethodDescriptor* descriptor = NULL;
863 if (extension_ime_util::IsExtensionIME(input_method_id_to_switch)) {
864 DCHECK(state->extra_input_methods.find(input_method_id_to_switch) !=
865 state->extra_input_methods.end());
866 descriptor = &(state->extra_input_methods[input_method_id_to_switch]);
867 } else {
868 descriptor =
869 util_.GetInputMethodDescriptorFromId(input_method_id_to_switch);
870 if (!descriptor)
871 LOG(ERROR) << "Unknown input method id: " << input_method_id_to_switch;
872 }
873 DCHECK(descriptor);
874 return descriptor;
875 }
876
877 void InputMethodManagerImpl::ChangeInputMethodInternal(
878 const InputMethodDescriptor& descriptor,
879 bool show_message,
880 bool notify_menu) {
881 // No need to switch input method when terminating.
882 if (ui_session_ == STATE_TERMINATING)
883 return;
884
885 if (candidate_window_controller_.get())
886 candidate_window_controller_->Hide();
887
888 if (notify_menu) {
889 // Clear property list. Property list would be updated by
890 // extension IMEs via InputMethodEngine::(Set|Update)MenuItems.
891 // If the current input method is a keyboard layout, empty
892 // properties are sufficient.
893 const ash::ime::InputMethodMenuItemList empty_menu_item_list;
894 ash::ime::InputMethodMenuManager* input_method_menu_manager =
895 ash::ime::InputMethodMenuManager::GetInstance();
896 input_method_menu_manager->SetCurrentInputMethodMenuItemList(
897 empty_menu_item_list);
898 }
899
900 // Disable the current engine handler.
901 IMEEngineHandlerInterface* engine =
902 IMEBridge::Get()->GetCurrentEngineHandler();
903 if (engine)
904 engine->Disable();
905
906 // Configure the next engine handler.
907 // This must be after |current_input_method| has been set to new input
908 // method, because engine's Enable() method needs to access it.
909 const std::string& extension_id =
910 extension_ime_util::GetExtensionIDFromInputMethodID(descriptor.id());
911 const std::string& component_id =
912 extension_ime_util::GetComponentIDByInputMethodID(descriptor.id());
913 engine = engine_map_[extension_id];
914
915 IMEBridge::Get()->SetCurrentEngineHandler(engine);
916
917 if (engine)
918 engine->Enable(component_id);
919
920 // Change the keyboard layout to a preferred layout for the input method.
921 if (!keyboard_->SetCurrentKeyboardLayoutByName(
922 descriptor.GetPreferredKeyboardLayout())) {
923 LOG(ERROR) << "Failed to change keyboard layout to "
924 << descriptor.GetPreferredKeyboardLayout();
925 }
926
927 // Update input method indicators (e.g. "US", "DV") in Chrome windows.
928 FOR_EACH_OBSERVER(InputMethodManager::Observer,
929 observers_,
930 InputMethodChanged(this, show_message));
931 }
932
933 void InputMethodManagerImpl::LoadNecessaryComponentExtensions(
934 InputMethodManagerImpl::StateImpl* state) {
935 // Load component extensions but also update |active_input_method_ids| as
936 // some component extension IMEs may have been removed from the Chrome OS
937 // image. If specified component extension IME no longer exists, falling back
938 // to an existing IME.
939 DCHECK(state);
940 std::vector<std::string> unfiltered_input_method_ids;
941 unfiltered_input_method_ids.swap(state->active_input_method_ids);
942 for (size_t i = 0; i < unfiltered_input_method_ids.size(); ++i) {
943 if (!extension_ime_util::IsComponentExtensionIME(
944 unfiltered_input_method_ids[i])) {
945 // Legacy IMEs or xkb layouts are alwayes active.
946 state->active_input_method_ids.push_back(unfiltered_input_method_ids[i]);
947 } else if (component_extension_ime_manager_->IsWhitelisted(
948 unfiltered_input_method_ids[i])) {
949 if (enable_extension_loading_) {
950 component_extension_ime_manager_->LoadComponentExtensionIME(
951 state->profile, unfiltered_input_method_ids[i]);
952 }
953
954 state->active_input_method_ids.push_back(unfiltered_input_method_ids[i]);
955 }
956 }
957 }
958
959 void InputMethodManagerImpl::ActivateInputMethodMenuItem(
960 const std::string& key) {
961 DCHECK(!key.empty());
962
963 if (ash::ime::InputMethodMenuManager::GetInstance()->
964 HasInputMethodMenuItemForKey(key)) {
965 IMEEngineHandlerInterface* engine =
966 IMEBridge::Get()->GetCurrentEngineHandler();
967 if (engine)
968 engine->PropertyActivate(key);
969 return;
970 }
971
972 DVLOG(1) << "ActivateInputMethodMenuItem: unknown key: " << key;
784 } 973 }
785 974
786 bool InputMethodManagerImpl::IsISOLevel5ShiftUsedByCurrentInputMethod() const { 975 bool InputMethodManagerImpl::IsISOLevel5ShiftUsedByCurrentInputMethod() const {
787 return keyboard_->IsISOLevel5ShiftAvailable(); 976 return keyboard_->IsISOLevel5ShiftAvailable();
788 } 977 }
789 978
790 bool InputMethodManagerImpl::IsAltGrUsedByCurrentInputMethod() const { 979 bool InputMethodManagerImpl::IsAltGrUsedByCurrentInputMethod() const {
791 return keyboard_->IsAltGrAvailable(); 980 return keyboard_->IsAltGrAvailable();
792 } 981 }
793 982
794 ImeKeyboard* InputMethodManagerImpl::GetImeKeyboard() { 983 ImeKeyboard* InputMethodManagerImpl::GetImeKeyboard() {
795 return keyboard_.get(); 984 return keyboard_.get();
796 } 985 }
797 986
798 InputMethodUtil* InputMethodManagerImpl::GetInputMethodUtil() { 987 InputMethodUtil* InputMethodManagerImpl::GetInputMethodUtil() {
799 return &util_; 988 return &util_;
800 } 989 }
801 990
802 ComponentExtensionIMEManager* 991 ComponentExtensionIMEManager*
803 InputMethodManagerImpl::GetComponentExtensionIMEManager() { 992 InputMethodManagerImpl::GetComponentExtensionIMEManager() {
804 return component_extension_ime_manager_.get(); 993 return component_extension_ime_manager_.get();
805 } 994 }
806 995
996 scoped_refptr<InputMethodManager::State> InputMethodManagerImpl::CreateNewState(
997 Profile* profile) {
998 return scoped_refptr<InputMethodManager::State>(new StateImpl(this, profile));
999 }
1000
807 void InputMethodManagerImpl::SetCandidateWindowControllerForTesting( 1001 void InputMethodManagerImpl::SetCandidateWindowControllerForTesting(
808 CandidateWindowController* candidate_window_controller) { 1002 CandidateWindowController* candidate_window_controller) {
809 candidate_window_controller_.reset(candidate_window_controller); 1003 candidate_window_controller_.reset(candidate_window_controller);
810 candidate_window_controller_->AddObserver(this); 1004 candidate_window_controller_->AddObserver(this);
811 } 1005 }
812 1006
813 void InputMethodManagerImpl::SetImeKeyboardForTesting(ImeKeyboard* keyboard) { 1007 void InputMethodManagerImpl::SetImeKeyboardForTesting(ImeKeyboard* keyboard) {
814 keyboard_.reset(keyboard); 1008 keyboard_.reset(keyboard);
815 } 1009 }
816 1010
(...skipping 16 matching lines...) Expand all
833 candidate_window_observers_, 1027 candidate_window_observers_,
834 CandidateWindowOpened(this)); 1028 CandidateWindowOpened(this));
835 } 1029 }
836 1030
837 void InputMethodManagerImpl::CandidateWindowClosed() { 1031 void InputMethodManagerImpl::CandidateWindowClosed() {
838 FOR_EACH_OBSERVER(InputMethodManager::CandidateWindowObserver, 1032 FOR_EACH_OBSERVER(InputMethodManager::CandidateWindowObserver,
839 candidate_window_observers_, 1033 candidate_window_observers_,
840 CandidateWindowClosed(this)); 1034 CandidateWindowClosed(this));
841 } 1035 }
842 1036
843 void InputMethodManagerImpl::OnScreenLocked() {
844 saved_previous_input_method_ = previous_input_method_;
845 saved_current_input_method_ = current_input_method_;
846 saved_active_input_method_ids_ = active_input_method_ids_;
847
848 std::set<std::string> added_ids_;
849
850 const std::vector<std::string>& hardware_keyboard_ids =
851 util_.GetHardwareLoginInputMethodIds();
852
853 active_input_method_ids_.clear();
854 for (size_t i = 0; i < saved_active_input_method_ids_.size(); ++i) {
855 const std::string& input_method_id = saved_active_input_method_ids_[i];
856 // Skip if it's not a keyboard layout. Drop input methods including
857 // extension ones.
858 if (!IsLoginKeyboard(input_method_id) ||
859 added_ids_.find(input_method_id) != added_ids_.end())
860 continue;
861 active_input_method_ids_.push_back(input_method_id);
862 added_ids_.insert(input_method_id);
863 }
864
865 // We'll add the hardware keyboard if it's not included in
866 // |active_input_method_ids_| so that the user can always use the hardware
867 // keyboard on the screen locker.
868 for (size_t i = 0; i < hardware_keyboard_ids.size(); ++i) {
869 if (added_ids_.find(hardware_keyboard_ids[i]) == added_ids_.end()) {
870 active_input_method_ids_.push_back(hardware_keyboard_ids[i]);
871 added_ids_.insert(hardware_keyboard_ids[i]);
872 }
873 }
874
875 ChangeInputMethod(current_input_method_.id());
876 }
877
878 void InputMethodManagerImpl::OnScreenUnlocked() {
879 previous_input_method_ = saved_previous_input_method_;
880 current_input_method_ = saved_current_input_method_;
881 active_input_method_ids_ = saved_active_input_method_ids_;
882
883 ChangeInputMethod(current_input_method_.id());
884 }
885
886 bool InputMethodManagerImpl::InputMethodIsActivated(
887 const std::string& input_method_id) {
888 return Contains(active_input_method_ids_, input_method_id);
889 }
890
891 void InputMethodManagerImpl::MaybeInitializeCandidateWindowController() { 1037 void InputMethodManagerImpl::MaybeInitializeCandidateWindowController() {
892 if (candidate_window_controller_.get()) 1038 if (candidate_window_controller_.get())
893 return; 1039 return;
894 1040
895 candidate_window_controller_.reset( 1041 candidate_window_controller_.reset(
896 CandidateWindowController::CreateCandidateWindowController()); 1042 CandidateWindowController::CreateCandidateWindowController());
897 candidate_window_controller_->AddObserver(this); 1043 candidate_window_controller_->AddObserver(this);
898 } 1044 }
899 1045
900 } // namespace input_method 1046 } // namespace input_method
901 } // namespace chromeos 1047 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698