OLD | NEW |
---|---|
(Empty) | |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 #include "chrome/browser/chromeos/input_method/input_method_manager_impl.h" | |
6 | |
7 #include <algorithm> // std::find | |
8 | |
9 #include "base/basictypes.h" | |
10 #include "base/memory/scoped_ptr.h" | |
11 #include "base/string_util.h" | |
12 #include "base/stringprintf.h" | |
13 #include "chrome/browser/chromeos/input_method/browser_state_monitor.h" | |
14 #include "chrome/browser/chromeos/input_method/candidate_window.h" | |
15 #include "chrome/browser/chromeos/input_method/input_method_util.h" | |
16 #include "chrome/browser/chromeos/input_method/xkeyboard.h" | |
17 #include "chrome/browser/chromeos/language_preferences.h" | |
18 #include "ui/base/accelerators/accelerator.h" | |
19 #include "unicode/uloc.h" | |
20 | |
21 namespace chromeos { | |
22 namespace input_method { | |
23 | |
24 namespace { | |
25 | |
26 template<typename T> | |
27 typename T::iterator Find(T& container, const typename T::value_type& value) { | |
Zachary Kuznia
2012/04/17 01:26:36
Why define these wrappers? It doesn't seem to add
Yusuke Sato
2012/04/17 02:23:32
I defined them just because I didn't want to type
| |
28 return std::find(container.begin(), container.end(), value); | |
29 } | |
30 | |
31 template<typename T> | |
32 typename T::const_iterator Find(const T& container, | |
33 const typename T::value_type& value) { | |
34 return std::find(container.begin(), container.end(), value); | |
35 } | |
36 | |
37 template<typename T> | |
38 bool Contains(const T& container, const typename T::value_type& value) { | |
39 return Find(container, value) != container.end(); | |
40 } | |
41 | |
42 } // namespace | |
43 | |
44 InputMethodManagerImpl::InputMethodManagerImpl() | |
45 : ignore_hotkeys_(false), | |
46 state_(STATE_LOGIN_SCREEN), | |
47 util_(GetSupportedInputMethods()) { | |
48 } | |
49 | |
50 InputMethodManagerImpl::~InputMethodManagerImpl() { | |
51 if (ibus_controller_.get()) | |
52 ibus_controller_->RemoveObserver(this); | |
53 if (candidate_window_controller_.get()) | |
54 candidate_window_controller_->RemoveObserver(this); | |
55 } | |
56 | |
57 void InputMethodManagerImpl::AddObserver( | |
58 InputMethodManager::Observer* observer) { | |
59 observers_.AddObserver(observer); | |
60 } | |
61 | |
62 void InputMethodManagerImpl::AddCandidateWindowObserver( | |
63 InputMethodManager::CandidateWindowObserver* observer) { | |
64 candidate_window_observers_.AddObserver(observer); | |
65 } | |
66 | |
67 void InputMethodManagerImpl::RemoveObserver( | |
68 InputMethodManager::Observer* observer) { | |
69 observers_.RemoveObserver(observer); | |
70 } | |
71 | |
72 void InputMethodManagerImpl::RemoveCandidateWindowObserver( | |
73 InputMethodManager::CandidateWindowObserver* observer) { | |
74 candidate_window_observers_.RemoveObserver(observer); | |
75 } | |
76 | |
77 void InputMethodManagerImpl::SetState(State new_state) { | |
78 const State old_state = state_; | |
79 state_ = new_state; | |
80 switch (state_) { | |
81 case STATE_LOGIN_SCREEN: | |
82 break; | |
83 case STATE_BROWSER_SCREEN: | |
84 if (old_state == STATE_LOCK_SCREEN) | |
85 OnScreenUnlocked(); | |
86 break; | |
87 case STATE_LOCK_SCREEN: | |
88 OnScreenLocked(); | |
89 break; | |
90 case STATE_TERMINATING: | |
91 ibus_controller_->Stop(); | |
92 browser_state_monitor_.reset(); // For crbug.com/120183. | |
93 candidate_window_controller_.reset(); | |
94 break; | |
95 } | |
96 } | |
97 | |
98 InputMethodDescriptors* | |
99 InputMethodManagerImpl::GetSupportedInputMethods() const { | |
100 return whitelist_.GetSupportedInputMethods(); | |
101 } | |
102 | |
103 InputMethodDescriptors* InputMethodManagerImpl::GetActiveInputMethods() const { | |
104 InputMethodDescriptors* result = new InputMethodDescriptors; | |
105 // Build the active input method descriptors from the active input | |
106 // methods cache |active_input_method_ids_|. | |
107 for (size_t i = 0; i < active_input_method_ids_.size(); ++i) { | |
108 const std::string& input_method_id = active_input_method_ids_[i]; | |
109 const InputMethodDescriptor* descriptor = | |
110 util_.GetInputMethodDescriptorFromId(input_method_id); | |
111 if (descriptor) { | |
112 result->push_back(*descriptor); | |
113 } else { | |
114 std::map<std::string, InputMethodDescriptor>::const_iterator ix = | |
115 extra_input_methods_.find(input_method_id); | |
116 if (ix != extra_input_methods_.end()) | |
117 result->push_back(ix->second); | |
118 else | |
119 LOG(ERROR) << "Descriptor is not found for: " << input_method_id; | |
120 } | |
121 } | |
122 if (result->empty()) { | |
123 // Initially |active_input_method_ids_| is empty. browser_tests might take | |
124 // this path. | |
125 result->push_back( | |
126 InputMethodDescriptor::GetFallbackInputMethodDescriptor()); | |
127 } | |
128 return result; | |
129 } | |
130 | |
131 size_t InputMethodManagerImpl::GetNumActiveInputMethods() const { | |
132 return active_input_method_ids_.size(); | |
133 } | |
134 | |
135 void InputMethodManagerImpl::EnableLayouts(const std::string& language_code, | |
136 const std::string& initial_layout) { | |
137 if (state_ == STATE_TERMINATING) | |
138 return; | |
139 | |
140 std::vector<std::string> candidates; | |
141 // Add input methods associated with the language. | |
142 util_.GetInputMethodIdsFromLanguageCode(language_code, | |
143 kKeyboardLayoutsOnly, | |
144 &candidates); | |
145 // Add the hardware keyboard as well. We should always add this so users | |
146 // can use the hardware keyboard on the login screen and the screen locker. | |
147 candidates.push_back(util_.GetHardwareInputMethodId()); | |
148 | |
149 std::vector<std::string> layouts; | |
150 // First, add the initial input method ID, if it's requested, to | |
151 // layouts, so it appears first on the list of active input | |
152 // methods at the input language status menu. | |
153 if (util_.IsValidInputMethodId(initial_layout) && | |
154 InputMethodUtil::IsKeyboardLayout(initial_layout)) { | |
155 layouts.push_back(initial_layout); | |
156 } else if (!initial_layout.empty()) { | |
157 LOG(ERROR) << "EnableLayouts: ignoring non-keyboard or invalid ID: " | |
158 << initial_layout; | |
159 } | |
160 | |
161 // Add candidates to layouts, while skipping duplicates. | |
162 for (size_t i = 0; i < candidates.size(); ++i) { | |
163 const std::string& candidate = candidates[i]; | |
164 // Not efficient, but should be fine, as the two vectors are very | |
165 // short (2-5 items). | |
166 if (!Contains(layouts, candidate)) | |
167 layouts.push_back(candidate); | |
168 } | |
169 | |
170 active_input_method_ids_.swap(layouts); | |
171 ChangeInputMethod(initial_layout); // you can pass empty |initial_layout|. | |
172 } | |
173 | |
174 bool InputMethodManagerImpl::EnableInputMethods( | |
175 const std::vector<std::string>& new_active_input_method_ids) { | |
176 if (state_ == STATE_TERMINATING) | |
177 return false; | |
178 | |
179 // Filter unknown or obsolete IDs. | |
180 std::vector<std::string> new_active_input_method_ids_filtered; | |
181 | |
182 for (size_t i = 0; i < new_active_input_method_ids.size(); ++i) { | |
183 const std::string& input_method_id = new_active_input_method_ids[i]; | |
184 if (util_.IsValidInputMethodId(input_method_id)) | |
185 new_active_input_method_ids_filtered.push_back(input_method_id); | |
186 else | |
187 LOG(ERROR) << "EnableInputMethods: Invalid ID: " << input_method_id; | |
188 } | |
189 | |
190 if (new_active_input_method_ids_filtered.empty()) { | |
191 LOG(ERROR) << "EnableInputMethods: No valid input method ID"; | |
192 return false; | |
193 } | |
194 | |
195 // Copy extension IDs to |new_active_input_method_ids_filtered|. We have to | |
196 // keep relative order of the extension input method IDs. | |
197 for (size_t i = 0; i < active_input_method_ids_.size(); ++i) { | |
198 const std::string& input_method_id = active_input_method_ids_[i]; | |
199 if (InputMethodUtil::IsExtensionInputMethod(input_method_id)) | |
200 new_active_input_method_ids_filtered.push_back(input_method_id); | |
201 } | |
202 active_input_method_ids_.swap(new_active_input_method_ids_filtered); | |
203 | |
204 if (ContainOnlyKeyboardLayout(active_input_method_ids_)) { | |
205 // Do NOT call ibus_controller_->Stop(); here to work around a crash issue | |
206 // at crosbug.com/27051. | |
207 // TODO(yusukes): We can safely call Stop(); here once crosbug.com/26443 | |
208 // is implemented. | |
209 } else { | |
210 MaybeInitializeCandidateWindowController(); | |
211 ibus_controller_->Start(); | |
212 } | |
213 | |
214 // If |current_input_method| is no longer in |active_input_method_ids_|, | |
215 // ChangeInputMethod() picks the first one in |active_input_method_ids_|. | |
216 ChangeInputMethod(current_input_method_.id()); | |
217 return true; | |
218 } | |
219 | |
220 bool InputMethodManagerImpl::SetInputMethodConfig( | |
221 const std::string& section, | |
222 const std::string& config_name, | |
223 const InputMethodConfigValue& value) { | |
224 DCHECK(section != language_prefs::kGeneralSectionName || | |
225 config_name != language_prefs::kPreloadEnginesConfigName); | |
226 | |
227 if (state_ == STATE_TERMINATING) | |
228 return false; | |
229 return ibus_controller_->SetInputMethodConfig(section, config_name, value); | |
230 } | |
231 | |
232 void InputMethodManagerImpl::ChangeInputMethod( | |
233 const std::string& input_method_id) { | |
234 if (state_ == STATE_TERMINATING) | |
235 return; | |
236 | |
237 std::string input_method_id_to_switch = input_method_id; | |
238 | |
239 // Sanity check. | |
240 if (!InputMethodIsActivated(input_method_id)) { | |
241 scoped_ptr<InputMethodDescriptors> input_methods(GetActiveInputMethods()); | |
242 DCHECK(!input_methods->empty()); | |
243 input_method_id_to_switch = input_methods->at(0).id(); | |
244 if (!input_method_id.empty()) { | |
245 VLOG(1) << "Can't change the current input method to " | |
246 << input_method_id << " since the engine is not enabled. " | |
247 << "Switch to " << input_method_id_to_switch << " instead."; | |
248 } | |
249 } | |
250 | |
251 if (InputMethodUtil::IsKeyboardLayout(input_method_id_to_switch)) { | |
252 FOR_EACH_OBSERVER(InputMethodManager::Observer, | |
253 observers_, | |
254 InputMethodPropertyChanged(this)); | |
255 } else { | |
256 ibus_controller_->ChangeInputMethod(input_method_id_to_switch); | |
257 } | |
258 | |
259 if (current_input_method_.id() != input_method_id_to_switch) { | |
260 const InputMethodDescriptor* descriptor = NULL; | |
261 if (!InputMethodUtil::IsExtensionInputMethod(input_method_id_to_switch)) { | |
262 descriptor = | |
263 util_.GetInputMethodDescriptorFromId(input_method_id_to_switch); | |
264 } else { | |
265 std::map<std::string, InputMethodDescriptor>::const_iterator i = | |
266 extra_input_methods_.find(input_method_id_to_switch); | |
267 DCHECK(i != extra_input_methods_.end()); | |
268 descriptor = &(i->second); | |
269 } | |
270 DCHECK(descriptor); | |
271 | |
272 previous_input_method_ = current_input_method_; | |
273 current_input_method_ = *descriptor; | |
274 | |
275 // Change the keyboard layout to a preferred layout for the input method. | |
276 if (!xkeyboard_->SetCurrentKeyboardLayoutByName( | |
277 current_input_method_.keyboard_layout())) { | |
278 LOG(ERROR) << "Failed to change keyboard layout to " | |
279 << current_input_method_.keyboard_layout(); | |
280 } | |
281 } | |
282 | |
283 // Update input method indicators (e.g. "US", "DV") in Chrome windows. | |
284 FOR_EACH_OBSERVER(InputMethodManager::Observer, | |
285 observers_, | |
286 InputMethodChanged(this)); | |
287 } | |
288 | |
289 void InputMethodManagerImpl::ActivateInputMethodProperty( | |
290 const std::string& key) { | |
291 DCHECK(!key.empty()); | |
292 ibus_controller_->ActivateInputMethodProperty(key); | |
293 } | |
294 | |
295 void InputMethodManagerImpl::AddInputMethodExtension( | |
296 const std::string& id, | |
297 const std::string& name, | |
298 const std::vector<std::string>& layouts, | |
299 const std::string& language) { | |
300 if (state_ == STATE_TERMINATING) | |
301 return; | |
302 | |
303 if (!InputMethodUtil::IsExtensionInputMethod(id)) { | |
304 LOG(ERROR) << id << " is not a valid extension input method ID."; | |
305 return; | |
306 } | |
307 | |
308 const std::string virtual_layouts = JoinString(layouts, ','); | |
309 extra_input_methods_[id] = InputMethodDescriptor( | |
310 whitelist_, id, name, virtual_layouts, language); | |
311 | |
312 if (!Contains(active_input_method_ids_, id)) { | |
313 active_input_method_ids_.push_back(id); | |
314 } else { | |
315 LOG(ERROR) << "AddInputMethodExtension: alread added: " | |
316 << id << ", " << name; | |
317 // Call Start() anyway, just in case. | |
318 } | |
319 | |
320 // Ensure that the input method daemon is running. | |
321 MaybeInitializeCandidateWindowController(); | |
322 ibus_controller_->Start(); | |
323 } | |
324 | |
325 void InputMethodManagerImpl::RemoveInputMethodExtension(const std::string& id) { | |
326 if (!InputMethodUtil::IsExtensionInputMethod(id)) | |
327 LOG(ERROR) << id << " is not a valid extension input method ID."; | |
328 | |
329 std::vector<std::string>::iterator i = Find(active_input_method_ids_, id); | |
330 if (i != active_input_method_ids_.end()) | |
331 active_input_method_ids_.erase(i); | |
332 extra_input_methods_.erase(id); | |
333 | |
334 if (ContainOnlyKeyboardLayout(active_input_method_ids_)) { | |
335 // Do NOT call ibus_controller_->Stop(); here to work around a crash issue | |
336 // at crosbug.com/27051. | |
337 // TODO(yusukes): We can safely call Stop(); here once crosbug.com/26443 | |
338 // is implemented. | |
339 } | |
340 | |
341 // If |current_input_method| is no longer in |active_input_method_ids_|, | |
342 // switch to the first one in |active_input_method_ids_|. | |
343 ChangeInputMethod(current_input_method_.id()); | |
344 } | |
345 | |
346 void InputMethodManagerImpl::EnableHotkeys() { | |
347 ignore_hotkeys_ = false; | |
348 } | |
349 | |
350 void InputMethodManagerImpl::DisableHotkeys() { | |
351 ignore_hotkeys_ = true; | |
352 } | |
353 | |
354 bool InputMethodManagerImpl::SwitchToNextInputMethod() { | |
355 if (ignore_hotkeys_) | |
356 return false; | |
357 | |
358 // Sanity checks. | |
359 if (active_input_method_ids_.empty()) { | |
360 LOG(ERROR) << "active input method is empty"; | |
361 return false; | |
362 } | |
363 if (current_input_method_.id().empty()) { | |
364 LOG(ERROR) << "current_input_method_ is unknown"; | |
365 return false; | |
366 } | |
367 | |
368 // Find the next input method. | |
369 std::vector<std::string>::const_iterator iter = | |
370 Find(active_input_method_ids_, current_input_method_.id()); | |
371 if (iter != active_input_method_ids_.end()) | |
372 ++iter; | |
373 if (iter == active_input_method_ids_.end()) | |
374 iter = active_input_method_ids_.begin(); | |
kinaba
2012/04/16 10:22:53
Shall we factor out the pattern of above 6 lines?
Yusuke Sato
2012/04/16 11:25:43
Done.
| |
375 ChangeInputMethod(*iter); | |
376 return true; | |
377 } | |
378 | |
379 bool InputMethodManagerImpl::SwitchToPreviousInputMethod() { | |
380 if (ignore_hotkeys_) | |
381 return false; | |
382 | |
383 // Sanity check. | |
384 if (active_input_method_ids_.empty()) { | |
385 LOG(ERROR) << "active input method is empty"; | |
386 return false; | |
387 } | |
388 | |
389 if (previous_input_method_.id().empty() || | |
390 previous_input_method_.id() == current_input_method_.id()) { | |
391 return SwitchToNextInputMethod(); | |
392 } | |
393 | |
394 std::vector<std::string>::const_iterator iter = | |
395 Find(active_input_method_ids_, previous_input_method_.id()); | |
396 if (iter == active_input_method_ids_.end()) { | |
397 // previous_input_method_ is not supported. | |
398 return SwitchToNextInputMethod(); | |
399 } | |
400 ChangeInputMethod(*iter); | |
401 return true; | |
402 } | |
403 | |
404 bool InputMethodManagerImpl::SwitchInputMethod( | |
405 const ui::Accelerator& accelerator) { | |
406 if (ignore_hotkeys_) | |
407 return false; | |
408 | |
409 // Sanity check. | |
410 if (active_input_method_ids_.empty()) { | |
411 LOG(ERROR) << "active input method is empty"; | |
412 return false; | |
413 } | |
414 | |
415 // Get the list of input method ids for the |accelerator|. For example, get | |
416 // { "mozc-hangul", "xkb:kr:kr104:kor" } for ui::VKEY_DBE_SBCSCHAR. | |
417 std::vector<std::string> input_method_ids_to_switch; | |
418 switch (accelerator.key_code()) { | |
419 case ui::VKEY_CONVERT: // Henkan key on JP106 keyboard | |
420 input_method_ids_to_switch.push_back("mozc-jp"); | |
421 break; | |
422 case ui::VKEY_NONCONVERT: // Muhenkan key on JP106 keyboard | |
423 input_method_ids_to_switch.push_back("xkb:jp::jpn"); | |
424 break; | |
425 case ui::VKEY_DBE_SBCSCHAR: // ZenkakuHankaku key on JP106 keyboard | |
426 case ui::VKEY_DBE_DBCSCHAR: | |
427 input_method_ids_to_switch.push_back("mozc-jp"); | |
428 input_method_ids_to_switch.push_back("xkb:jp::jpn"); | |
429 break; | |
430 case ui::VKEY_HANGUL: // Hangul (or right Alt) key on Korean keyboard | |
431 case ui::VKEY_SPACE: // Shift+Space | |
432 input_method_ids_to_switch.push_back("mozc-hangul"); | |
433 input_method_ids_to_switch.push_back("xkb:kr:kr104:kor"); | |
434 break; | |
435 default: | |
436 NOTREACHED(); | |
437 break; | |
438 } | |
439 if (input_method_ids_to_switch.empty()) { | |
440 LOG(ERROR) << "Unexpected VKEY: " << accelerator.key_code(); | |
441 return false; | |
442 } | |
443 | |
444 // Obtain the intersection of input_method_ids_to_switch and | |
445 // active_input_method_ids_. The order of IDs in active_input_method_ids_ is | |
446 // preserved. | |
447 std::vector<std::string> ids; | |
448 for (size_t i = 0; i < input_method_ids_to_switch.size(); ++i) { | |
449 const std::string& id = input_method_ids_to_switch[i]; | |
450 if (Contains(active_input_method_ids_, id)) | |
451 ids.push_back(id); | |
452 } | |
453 if (ids.empty()) { | |
454 // No input method for the accelerator is active. For example, we should | |
455 // just ignore VKEY_HANGUL when mozc-hangul is not active. | |
456 return false; | |
457 } | |
458 | |
459 // If |current_input_method_| is not in ids, switch to ids[0]. If | |
460 // |current_input_method_| is ids[N], switch to ids[N+1]. | |
461 std::vector<std::string>::const_iterator iter = | |
462 Find(ids, current_input_method_.id()); | |
463 if (iter != ids.end()) | |
464 ++iter; | |
465 if (iter == ids.end()) | |
466 iter = ids.begin(); | |
467 ChangeInputMethod(*iter); | |
468 return true; // consume the accelerator. | |
469 } | |
470 | |
471 InputMethodDescriptor InputMethodManagerImpl::GetCurrentInputMethod() const { | |
472 if (current_input_method_.id().empty()) | |
473 return InputMethodDescriptor::GetFallbackInputMethodDescriptor(); | |
474 return current_input_method_; | |
475 } | |
476 | |
477 InputMethodPropertyList | |
478 InputMethodManagerImpl::GetCurrentInputMethodProperties() const { | |
479 // This check is necessary since an IME property (e.g. for Pinyin) might be | |
480 // sent from ibus-daemon AFTER the current input method is switched to XKB. | |
481 if (InputMethodUtil::IsKeyboardLayout(GetCurrentInputMethod().id())) | |
482 return InputMethodPropertyList(); | |
483 return ibus_controller_->GetCurrentProperties(); | |
484 } | |
485 | |
486 XKeyboard* InputMethodManagerImpl::GetXKeyboard() { | |
487 return xkeyboard_.get(); | |
488 } | |
489 | |
490 InputMethodUtil* InputMethodManagerImpl::GetInputMethodUtil() { | |
491 return &util_; | |
492 } | |
493 | |
494 void InputMethodManagerImpl::Init() { | |
495 DCHECK(!ibus_controller_.get()); | |
496 | |
497 browser_state_monitor_.reset(new BrowserStateMonitor(this)); | |
498 ibus_controller_.reset(IBusController::Create()); | |
499 xkeyboard_.reset(XKeyboard::Create(util_)); | |
500 ibus_controller_->AddObserver(this); | |
501 } | |
502 | |
503 void InputMethodManagerImpl::SetIBusControllerForTesting( | |
504 IBusController* ibus_controller) { | |
505 ibus_controller_.reset(ibus_controller); | |
506 ibus_controller_->AddObserver(this); | |
507 } | |
508 | |
509 void InputMethodManagerImpl::SetCandidateWindowControllerForTesting( | |
510 CandidateWindowController* candidate_window_controller) { | |
511 candidate_window_controller_.reset(candidate_window_controller); | |
512 candidate_window_controller_->Init(); | |
513 candidate_window_controller_->AddObserver(this); | |
514 } | |
515 | |
516 void InputMethodManagerImpl::SetXKeyboardForTesting(XKeyboard* xkeyboard) { | |
517 xkeyboard_.reset(xkeyboard); | |
518 } | |
519 | |
520 void InputMethodManagerImpl::PropertyChanged() { | |
521 FOR_EACH_OBSERVER(InputMethodManager::Observer, | |
522 observers_, | |
523 InputMethodPropertyChanged(this)); | |
524 } | |
525 | |
526 void InputMethodManagerImpl::CandidateWindowOpened() { | |
527 FOR_EACH_OBSERVER(InputMethodManager::CandidateWindowObserver, | |
528 candidate_window_observers_, | |
529 CandidateWindowOpened(this)); | |
530 } | |
531 | |
532 void InputMethodManagerImpl::CandidateWindowClosed() { | |
533 FOR_EACH_OBSERVER(InputMethodManager::CandidateWindowObserver, | |
534 candidate_window_observers_, | |
535 CandidateWindowClosed(this)); | |
536 } | |
537 | |
538 void InputMethodManagerImpl::OnScreenLocked() { | |
539 saved_previous_input_method_ = previous_input_method_; | |
540 saved_current_input_method_ = current_input_method_; | |
541 saved_active_input_method_ids_ = active_input_method_ids_; | |
542 | |
543 const std::string hardware_keyboard_id = util_.GetHardwareInputMethodId(); | |
544 // We'll add the hardware keyboard if it's not included in | |
545 // |active_input_method_list| so that the user can always use the hardware | |
546 // keyboard on the screen locker. | |
547 bool should_add_hardware_keyboard = true; | |
548 | |
549 active_input_method_ids_.clear(); | |
550 for (size_t i = 0; i < saved_active_input_method_ids_.size(); ++i) { | |
551 const std::string& input_method_id = saved_active_input_method_ids_[i]; | |
552 // Skip if it's not a keyboard layout. Drop input methods including | |
553 // extension ones. | |
554 if (!InputMethodUtil::IsKeyboardLayout(input_method_id)) | |
555 continue; | |
556 active_input_method_ids_.push_back(input_method_id); | |
557 if (input_method_id == hardware_keyboard_id) | |
558 should_add_hardware_keyboard = false; | |
559 } | |
560 if (should_add_hardware_keyboard) | |
561 active_input_method_ids_.push_back(hardware_keyboard_id); | |
562 | |
563 ChangeInputMethod(current_input_method_.id()); | |
564 } | |
565 | |
566 void InputMethodManagerImpl::OnScreenUnlocked() { | |
567 previous_input_method_ = saved_previous_input_method_; | |
568 current_input_method_ = saved_current_input_method_; | |
569 active_input_method_ids_ = saved_active_input_method_ids_; | |
570 | |
571 ChangeInputMethod(current_input_method_.id()); | |
572 } | |
573 | |
574 bool InputMethodManagerImpl::InputMethodIsActivated( | |
575 const std::string& input_method_id) { | |
576 return Contains(active_input_method_ids_, input_method_id); | |
577 } | |
578 | |
579 bool InputMethodManagerImpl::ContainOnlyKeyboardLayout( | |
580 const std::vector<std::string>& value) { | |
581 for (size_t i = 0; i < value.size(); ++i) { | |
582 if (!InputMethodUtil::IsKeyboardLayout(value[i])) | |
583 return false; | |
584 } | |
585 return true; | |
586 } | |
587 | |
588 void InputMethodManagerImpl::MaybeInitializeCandidateWindowController() { | |
589 #if !defined(USE_VIRTUAL_KEYBOARD) | |
590 if (candidate_window_controller_.get()) | |
591 return; | |
592 | |
593 candidate_window_controller_.reset( | |
594 CandidateWindowController::CreateCandidateWindowController()); | |
595 if (candidate_window_controller_->Init()) | |
596 candidate_window_controller_->AddObserver(this); | |
597 else | |
598 LOG(WARNING) << "Failed to initialize the candidate window controller"; | |
599 #endif | |
600 } | |
601 | |
602 // static | |
603 InputMethodManagerImpl* InputMethodManagerImpl::GetInstanceForTesting() { | |
604 return new InputMethodManagerImpl; | |
605 } | |
606 | |
607 } // namespace input_method | |
608 } // namespace chromeos | |
OLD | NEW |