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) { | |
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 : should_hide_properties_(true), | |
46 ignore_hotkeys_(false), | |
47 state_(STATE_LOGIN_SCREEN), | |
48 util_(GetSupportedInputMethods()) { | |
49 } | |
50 | |
51 InputMethodManagerImpl::~InputMethodManagerImpl() { | |
52 if (ibus_controller_.get()) | |
53 ibus_controller_->RemoveObserver(this); | |
54 if (candidate_window_controller_.get()) | |
55 candidate_window_controller_->RemoveObserver(this); | |
56 } | |
57 | |
58 void InputMethodManagerImpl::AddObserver( | |
59 InputMethodManager::Observer* observer) { | |
60 observers_.AddObserver(observer); | |
61 } | |
62 | |
63 void InputMethodManagerImpl::AddCandidateWindowObserver( | |
64 InputMethodManager::CandidateWindowObserver* observer) { | |
65 candidate_window_observers_.AddObserver(observer); | |
66 } | |
67 | |
68 void InputMethodManagerImpl::RemoveObserver( | |
69 InputMethodManager::Observer* observer) { | |
70 observers_.RemoveObserver(observer); | |
71 } | |
72 | |
73 void InputMethodManagerImpl::RemoveCandidateWindowObserver( | |
74 InputMethodManager::CandidateWindowObserver* observer) { | |
75 candidate_window_observers_.RemoveObserver(observer); | |
76 } | |
77 | |
78 void InputMethodManagerImpl::SetState(State new_state) { | |
79 const State old_state = state_; | |
80 state_ = new_state; | |
81 switch (state_) { | |
82 case STATE_LOGIN_SCREEN: | |
83 break; | |
84 case STATE_BROWSER_SCREEN: | |
85 if (old_state == STATE_LOCK_SCREEN) | |
86 OnScreenUnlocked(); | |
87 break; | |
88 case STATE_LOCK_SCREEN: | |
89 OnScreenLocked(); | |
90 break; | |
91 case STATE_TERMINATING: | |
92 ibus_controller_->Stop(); | |
93 browser_state_monitor_.reset(); // For crbug.com/120183. | |
94 candidate_window_controller_.reset(); | |
95 break; | |
96 } | |
97 } | |
98 | |
99 InputMethodDescriptors* InputMethodManagerImpl::GetSupportedInputMethods() { | |
100 return whitelist_.GetSupportedInputMethods(); | |
101 } | |
102 | |
103 InputMethodDescriptors* InputMethodManagerImpl::GetActiveInputMethods() { | |
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 reletive order of the extension input method IDs. | |
Seigo Nonaka
2012/04/13 04:03:14
typo? relative
Yusuke Sato
2012/04/13 08:00:45
Done.
| |
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(active_input_method_ids_); | |
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 should_hide_properties_ = true; | |
253 FOR_EACH_OBSERVER(InputMethodManager::Observer, | |
254 observers_, | |
255 InputMethodPropertyChanged(this)); | |
256 } else { | |
257 ibus_controller_->ChangeInputMethod(input_method_id_to_switch); | |
258 } | |
259 | |
260 if (current_input_method_.id() != input_method_id_to_switch) { | |
261 const InputMethodDescriptor* descriptor = NULL; | |
262 if (!InputMethodUtil::IsExtensionInputMethod(input_method_id_to_switch)) { | |
263 descriptor = | |
264 util_.GetInputMethodDescriptorFromId(input_method_id_to_switch); | |
265 } else { | |
266 std::map<std::string, InputMethodDescriptor>::const_iterator i = | |
267 extra_input_methods_.find(input_method_id_to_switch); | |
268 DCHECK(i != extra_input_methods_.end()); | |
269 descriptor = &(i->second); | |
270 } | |
271 DCHECK(descriptor); | |
272 | |
273 previous_input_method_ = current_input_method_; | |
274 current_input_method_ = *descriptor; | |
275 | |
276 // Change the keyboard layout to a preferred layout for the input method. | |
277 if (!xkeyboard_->SetCurrentKeyboardLayoutByName( | |
278 current_input_method_.keyboard_layout())) { | |
279 LOG(ERROR) << "Failed to change keyboard layout to " | |
280 << current_input_method_.keyboard_layout(); | |
281 } | |
282 } | |
283 | |
284 // Update input method indicators (e.g. "US", "DV") in Chrome windows. | |
285 FOR_EACH_OBSERVER(InputMethodManager::Observer, | |
286 observers_, | |
287 InputMethodChanged(this)); | |
288 } | |
289 | |
290 void InputMethodManagerImpl::ActivateInputMethodProperty( | |
291 const std::string& key) { | |
292 DCHECK(!key.empty()); | |
293 ibus_controller_->ActivateInputMethodProperty(key); | |
294 } | |
295 | |
296 void InputMethodManagerImpl::AddInputMethodExtension( | |
297 const std::string& id, | |
298 const std::string& name, | |
299 const std::vector<std::string>& layouts, | |
300 const std::string& language) { | |
301 if (state_ == STATE_TERMINATING) | |
302 return; | |
303 | |
304 if (!InputMethodUtil::IsExtensionInputMethod(id)) { | |
305 LOG(ERROR) << id << " is not a valid extension input method ID."; | |
306 return; | |
307 } | |
308 | |
309 const std::string virtual_layouts = JoinString(layouts, ','); | |
310 extra_input_methods_[id] = InputMethodDescriptor( | |
311 whitelist_, id, name, virtual_layouts, language); | |
312 | |
313 if (!Contains(active_input_method_ids_, id)) { | |
314 active_input_method_ids_.push_back(id); | |
315 } else { | |
316 LOG(ERROR) << "AddInputMethodExtension: alread added: " | |
317 << id << ", " << name; | |
318 // Call Start() anyway, just in case. | |
319 } | |
320 | |
321 // Ensure that the input method daemon is running. | |
322 MaybeInitializeCandidateWindowController(); | |
323 ibus_controller_->Start(active_input_method_ids_); | |
324 } | |
325 | |
326 void InputMethodManagerImpl::RemoveInputMethodExtension(const std::string& id) { | |
327 if (!InputMethodUtil::IsExtensionInputMethod(id)) | |
328 LOG(ERROR) << id << " is not a valid extension input method ID."; | |
329 | |
330 std::vector<std::string>::iterator i = Find(active_input_method_ids_, id); | |
331 if (i != active_input_method_ids_.end()) | |
332 active_input_method_ids_.erase(i); | |
333 extra_input_methods_.erase(id); | |
334 | |
335 if (ContainOnlyKeyboardLayout(active_input_method_ids_)) { | |
336 // Do NOT call ibus_controller_->Stop(); here to work around a crash issue | |
337 // at crosbug.com/27051. | |
338 // TODO(yusukes): We can safely call Stop(); here once crosbug.com/26443 | |
339 // is implemented. | |
340 } | |
341 | |
342 // If |current_input_method| is no longer in |active_input_method_ids_|, | |
343 // switch to the first one in |active_input_method_ids_|. | |
344 ChangeInputMethod(current_input_method_.id()); | |
345 } | |
346 | |
347 void InputMethodManagerImpl::EnableHotkeys() { | |
348 ignore_hotkeys_ = false; | |
349 } | |
350 | |
351 void InputMethodManagerImpl::DisableHotkeys() { | |
352 ignore_hotkeys_ = true; | |
353 } | |
354 | |
355 bool InputMethodManagerImpl::SwitchToNextInputMethod() { | |
356 if (ignore_hotkeys_) | |
357 return false; | |
358 | |
359 // Sanity checks. | |
360 if (active_input_method_ids_.empty()) { | |
361 LOG(ERROR) << "active input method is empty"; | |
362 return false; | |
363 } | |
364 if (current_input_method_.id().empty()) { | |
365 LOG(ERROR) << "current_input_method_ is unknown"; | |
366 return false; | |
367 } | |
368 | |
369 // Find the next input method. | |
370 std::vector<std::string>::const_iterator iter = | |
371 Find(active_input_method_ids_, current_input_method_.id()); | |
372 if (iter != active_input_method_ids_.end()) | |
373 ++iter; | |
374 if (iter == active_input_method_ids_.end()) | |
375 iter = active_input_method_ids_.begin(); | |
376 ChangeInputMethod(*iter); | |
377 return true; | |
378 } | |
379 | |
380 bool InputMethodManagerImpl::SwitchToPreviousInputMethod() { | |
381 if (ignore_hotkeys_) | |
382 return false; | |
383 | |
384 // Sanity check. | |
385 if (active_input_method_ids_.empty()) { | |
386 LOG(ERROR) << "active input method is empty"; | |
387 return false; | |
388 } | |
389 | |
390 if (previous_input_method_.id().empty() || | |
391 previous_input_method_.id() == current_input_method_.id()) { | |
392 return SwitchToNextInputMethod(); | |
393 } | |
394 | |
395 std::vector<std::string>::const_iterator iter = | |
396 Find(active_input_method_ids_, previous_input_method_.id()); | |
397 if (iter == active_input_method_ids_.end()) { | |
398 // previous_input_method_ is not supported. | |
399 return SwitchToNextInputMethod(); | |
400 } | |
401 ChangeInputMethod(*iter); | |
402 return true; | |
403 } | |
404 | |
405 bool InputMethodManagerImpl::SwitchInputMethod( | |
406 const ui::Accelerator& accelerator) { | |
407 if (ignore_hotkeys_) | |
408 return false; | |
409 | |
410 // Sanity check. | |
411 if (active_input_method_ids_.empty()) { | |
412 LOG(ERROR) << "active input method is empty"; | |
413 return false; | |
414 } | |
415 | |
416 // Get the list of input method ids for the |accelerator|. For example, get | |
417 // { "mozc-hangul", "xkb:kr:kr104:kor" } for ui::VKEY_DBE_SBCSCHAR. | |
418 std::vector<std::string> input_method_ids_to_switch; | |
419 switch (accelerator.key_code()) { | |
420 case ui::VKEY_CONVERT: // Henkan key on JP106 keyboard | |
421 input_method_ids_to_switch.push_back("mozc-jp"); | |
422 break; | |
423 case ui::VKEY_NONCONVERT: // Muhenkan key on JP106 keyboard | |
424 input_method_ids_to_switch.push_back("xkb:jp::jpn"); | |
425 break; | |
426 case ui::VKEY_DBE_SBCSCHAR: // ZenkakuHankaku key on JP106 keyboard | |
427 case ui::VKEY_DBE_DBCSCHAR: | |
428 input_method_ids_to_switch.push_back("mozc-jp"); | |
429 input_method_ids_to_switch.push_back("xkb:jp::jpn"); | |
430 break; | |
431 case ui::VKEY_HANGUL: // Hangul (or right Alt) key on Korean keyboard | |
432 case ui::VKEY_SPACE: // Shift+Space | |
433 input_method_ids_to_switch.push_back("mozc-hangul"); | |
434 input_method_ids_to_switch.push_back("xkb:kr:kr104:kor"); | |
435 break; | |
436 default: | |
437 NOTREACHED(); | |
438 break; | |
439 } | |
440 if (input_method_ids_to_switch.empty()) { | |
441 LOG(ERROR) << "Unexpected VKEY: " << accelerator.key_code(); | |
442 return false; | |
443 } | |
444 | |
445 // Obtain the intersection of input_method_ids_to_switch and | |
446 // active_input_method_ids_. The order of IDs in active_input_method_ids_ is | |
447 // preserved. | |
448 std::vector<std::string> ids; | |
449 for (size_t i = 0; i < input_method_ids_to_switch.size(); ++i) { | |
450 const std::string& id = input_method_ids_to_switch[i]; | |
451 if (Contains(active_input_method_ids_, id)) | |
452 ids.push_back(id); | |
453 } | |
454 if (ids.empty()) { | |
455 // No input method for the accelerator is active. For example, we should | |
456 // just ignore VKEY_HANGUL when mozc-hangul is not active. | |
457 return false; | |
458 } | |
459 | |
460 // If |current_input_method_| is not in ids, switch to ids[0]. If | |
461 // |current_input_method_| is ids[N], switch to ids[N+1]. | |
462 std::vector<std::string>::const_iterator iter = | |
463 Find(ids, current_input_method_.id()); | |
464 if (iter != ids.end()) | |
465 ++iter; | |
466 if (iter == ids.end()) | |
467 iter = ids.begin(); | |
468 ChangeInputMethod(*iter); | |
469 return true; // consume the accelerator. | |
470 } | |
471 | |
472 InputMethodDescriptor InputMethodManagerImpl::GetCurrentInputMethod() const { | |
473 if (current_input_method_.id().empty()) | |
474 return InputMethodDescriptor::GetFallbackInputMethodDescriptor(); | |
475 return current_input_method_; | |
476 } | |
477 | |
478 InputMethodPropertyList | |
479 InputMethodManagerImpl::GetCurrentInputMethodProperties() const { | |
480 if (should_hide_properties_ || | |
481 // This check is necessary since an IME property (e.g. for Pinyin) might | |
482 // be sent from ibus-daemon AFTER the current input method is switched | |
483 // to XKB. | |
484 InputMethodUtil::IsKeyboardLayout(GetCurrentInputMethod().id())) { | |
485 return InputMethodPropertyList(); | |
486 } | |
487 return ibus_controller_->GetCurrentProperties(); | |
488 } | |
489 | |
490 XKeyboard* InputMethodManagerImpl::GetXKeyboard() { | |
491 return xkeyboard_.get(); | |
492 } | |
493 | |
494 InputMethodUtil* InputMethodManagerImpl::GetInputMethodUtil() { | |
495 return &util_; | |
496 } | |
497 | |
498 void InputMethodManagerImpl::Init() { | |
499 DCHECK(!ibus_controller_.get()); | |
500 | |
501 browser_state_monitor_.reset(new BrowserStateMonitor(this)); | |
502 ibus_controller_.reset(IBusController::Create()); | |
503 xkeyboard_.reset(XKeyboard::Create(util_)); | |
504 ibus_controller_->AddObserver(this); | |
505 } | |
506 | |
507 void InputMethodManagerImpl::SetIBusControllerForTesting( | |
508 IBusController* ibus_controller) { | |
509 ibus_controller_.reset(ibus_controller); | |
510 ibus_controller_->AddObserver(this); | |
511 } | |
512 | |
513 void InputMethodManagerImpl::SetCandidateWindowControllerForTesting( | |
514 CandidateWindowController* candidate_window_controller) { | |
515 candidate_window_controller_.reset(candidate_window_controller); | |
516 candidate_window_controller_->Init(); | |
517 candidate_window_controller_->AddObserver(this); | |
518 } | |
519 | |
520 void InputMethodManagerImpl::SetXKeyboardForTesting(XKeyboard* xkeyboard) { | |
521 xkeyboard_.reset(xkeyboard); | |
522 } | |
523 | |
524 void InputMethodManagerImpl::PropertyChanged() { | |
525 should_hide_properties_ = ibus_controller_->GetCurrentProperties().empty(); | |
526 FOR_EACH_OBSERVER(InputMethodManager::Observer, | |
527 observers_, | |
528 InputMethodPropertyChanged(this)); | |
529 } | |
530 | |
531 void InputMethodManagerImpl::CandidateWindowOpened() { | |
532 FOR_EACH_OBSERVER(InputMethodManager::CandidateWindowObserver, | |
533 candidate_window_observers_, | |
534 CandidateWindowOpened(this)); | |
535 } | |
536 | |
537 void InputMethodManagerImpl::CandidateWindowClosed() { | |
538 FOR_EACH_OBSERVER(InputMethodManager::CandidateWindowObserver, | |
539 candidate_window_observers_, | |
540 CandidateWindowClosed(this)); | |
541 } | |
542 | |
543 void InputMethodManagerImpl::OnScreenLocked() { | |
544 saved_previous_input_method_ = previous_input_method_; | |
545 saved_current_input_method_ = current_input_method_; | |
546 saved_active_input_method_ids_ = active_input_method_ids_; | |
547 | |
548 const std::string hardware_keyboard_id = util_.GetHardwareInputMethodId(); | |
549 // We'll add the hardware keyboard if it's not included in | |
550 // |active_input_method_list| so that the user can always use the hardware | |
551 // keyboard on the screen locker. | |
552 bool should_add_hardware_keyboard = true; | |
553 | |
554 active_input_method_ids_.clear(); | |
555 for (size_t i = 0; i < saved_active_input_method_ids_.size(); ++i) { | |
556 const std::string& input_method_id = saved_active_input_method_ids_[i]; | |
557 // Skip if it's not a keyboard layout. Drop input methods including | |
558 // extension ones. | |
559 if (!InputMethodUtil::IsKeyboardLayout(input_method_id)) | |
560 continue; | |
561 active_input_method_ids_.push_back(input_method_id); | |
562 if (input_method_id == hardware_keyboard_id) | |
563 should_add_hardware_keyboard = false; | |
564 } | |
565 if (should_add_hardware_keyboard) | |
566 active_input_method_ids_.push_back(hardware_keyboard_id); | |
567 | |
568 ChangeInputMethod(current_input_method_.id()); | |
569 } | |
570 | |
571 void InputMethodManagerImpl::OnScreenUnlocked() { | |
572 previous_input_method_ = saved_previous_input_method_; | |
573 current_input_method_ = saved_current_input_method_; | |
574 active_input_method_ids_ = saved_active_input_method_ids_; | |
575 | |
576 ChangeInputMethod(current_input_method_.id()); | |
577 } | |
578 | |
579 bool InputMethodManagerImpl::InputMethodIsActivated( | |
580 const std::string& input_method_id) { | |
581 return Contains(active_input_method_ids_, input_method_id); | |
582 } | |
583 | |
584 bool InputMethodManagerImpl::ContainOnlyKeyboardLayout( | |
585 const std::vector<std::string>& value) { | |
586 for (size_t i = 0; i < value.size(); ++i) { | |
587 if (!InputMethodUtil::IsKeyboardLayout(value[i])) | |
588 return false; | |
589 } | |
590 return true; | |
591 } | |
592 | |
593 void InputMethodManagerImpl::MaybeInitializeCandidateWindowController() { | |
594 #if !defined(USE_VIRTUAL_KEYBOARD) | |
595 if (candidate_window_controller_.get()) | |
596 return; | |
597 | |
598 candidate_window_controller_.reset( | |
599 CandidateWindowController::CreateCandidateWindowController()); | |
600 if (candidate_window_controller_->Init()) | |
601 candidate_window_controller_->AddObserver(this); | |
602 else | |
603 LOG(WARNING) << "Failed to initialize the candidate window controller"; | |
604 #endif | |
605 } | |
606 | |
607 // static | |
608 InputMethodManagerImpl* InputMethodManagerImpl::GetInstanceForTesting() { | |
609 return new InputMethodManagerImpl; | |
610 } | |
611 | |
612 } // namespace input_method | |
613 } // namespace chromeos | |
OLD | NEW |