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