OLD | NEW |
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 "base/basictypes.h" | 9 #include "base/basictypes.h" |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 21 matching lines...) Expand all Loading... |
32 | 32 |
33 const char nacl_mozc_jp_id[] = | 33 const char nacl_mozc_jp_id[] = |
34 "_comp_ime_fpfbhcjppmaeaijcidgiibchfbnhbeljnacl_mozc_jp"; | 34 "_comp_ime_fpfbhcjppmaeaijcidgiibchfbnhbeljnacl_mozc_jp"; |
35 | 35 |
36 bool Contains(const std::vector<std::string>& container, | 36 bool Contains(const std::vector<std::string>& container, |
37 const std::string& value) { | 37 const std::string& value) { |
38 return std::find(container.begin(), container.end(), value) != | 38 return std::find(container.begin(), container.end(), value) != |
39 container.end(); | 39 container.end(); |
40 } | 40 } |
41 | 41 |
| 42 void UniquifyVectorWithKeepingOrder(std::vector<std::string>* v) { |
| 43 DCHECK(v); |
| 44 std::set<std::string> added_value; |
| 45 size_t output_pos = 0; |
| 46 for (size_t i = 0; i < v->size(); ++i) { |
| 47 if ((*v)[i].empty()) |
| 48 continue; |
| 49 if (added_value.find((*v)[i]) == added_value.end()) { |
| 50 (*v)[output_pos++] = (*v)[i]; |
| 51 added_value.insert((*v)[i]); |
| 52 } |
| 53 } |
| 54 v->resize(output_pos); |
| 55 } |
| 56 |
42 } // namespace | 57 } // namespace |
43 | 58 |
44 bool InputMethodManagerImpl::IsLoginKeyboard( | 59 bool InputMethodManagerImpl::IsLoginKeyboard( |
45 const std::string& layout) const { | 60 const std::string& layout) const { |
46 return util_.IsLoginKeyboard(layout); | 61 return util_.IsLoginKeyboard(layout); |
47 } | 62 } |
48 | 63 |
49 InputMethodManagerImpl::InputMethodManagerImpl( | 64 InputMethodManagerImpl::InputMethodManagerImpl( |
50 scoped_ptr<InputMethodDelegate> delegate) | 65 scoped_ptr<InputMethodDelegate> delegate) |
51 : delegate_(delegate.Pass()), | 66 : delegate_(delegate.Pass()), |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
152 std::map<std::string, InputMethodDescriptor>::const_iterator ix = | 167 std::map<std::string, InputMethodDescriptor>::const_iterator ix = |
153 extra_input_methods_.find(input_method_id); | 168 extra_input_methods_.find(input_method_id); |
154 if (ix != extra_input_methods_.end()) | 169 if (ix != extra_input_methods_.end()) |
155 ime = &ix->second; | 170 ime = &ix->second; |
156 } | 171 } |
157 return ime; | 172 return ime; |
158 } | 173 } |
159 | 174 |
160 void InputMethodManagerImpl::EnableLoginLayouts( | 175 void InputMethodManagerImpl::EnableLoginLayouts( |
161 const std::string& language_code, | 176 const std::string& language_code, |
162 const std::string& initial_layout) { | 177 const std::vector<std::string>& initial_layouts) { |
163 if (state_ == STATE_TERMINATING) | 178 if (state_ == STATE_TERMINATING) |
164 return; | 179 return; |
165 | 180 |
166 std::vector<std::string> candidates; | 181 // First, hardware keyboard layout should be shown. |
| 182 std::vector<std::string> candidates = |
| 183 util_.GetHardwareLoginInputMethodIds(); |
| 184 |
| 185 // Seocnd, locale based input method should be shown. |
167 // Add input methods associated with the language. | 186 // Add input methods associated with the language. |
| 187 std::vector<std::string> layouts_from_locale; |
168 util_.GetInputMethodIdsFromLanguageCode(language_code, | 188 util_.GetInputMethodIdsFromLanguageCode(language_code, |
169 kKeyboardLayoutsOnly, | 189 kKeyboardLayoutsOnly, |
170 &candidates); | 190 &layouts_from_locale); |
171 // Add the hardware keyboard as well. We should always add this so users | 191 candidates.insert(candidates.end(), layouts_from_locale.begin(), |
172 // can use the hardware keyboard on the login screen and the screen locker. | 192 layouts_from_locale.end()); |
173 candidates.push_back(util_.GetHardwareLoginInputMethodId()); | |
174 | 193 |
175 std::vector<std::string> layouts; | 194 std::vector<std::string> layouts; |
176 // First, add the initial input method ID, if it's requested, to | 195 // First, add the initial input method ID, if it's requested, to |
177 // layouts, so it appears first on the list of active input | 196 // layouts, so it appears first on the list of active input |
178 // methods at the input language status menu. | 197 // methods at the input language status menu. |
179 if (util_.IsValidInputMethodId(initial_layout)) { | 198 for (size_t i = 0; i < initial_layouts.size(); ++i) { |
180 if (!IsLoginKeyboard(initial_layout)) { | 199 if (util_.IsValidInputMethodId(initial_layouts[i])) { |
181 DVLOG(1) | 200 if (!IsLoginKeyboard(initial_layouts[i])) { |
182 << "EnableLoginLayouts: ignoring non-login initial keyboard layout:" | 201 DVLOG(1) |
183 << initial_layout; | 202 << "EnableLoginLayouts: ignoring non-login initial keyboard layout:" |
184 } else { | 203 << initial_layouts[i]; |
185 layouts.push_back(initial_layout); | 204 } else { |
| 205 layouts.push_back(initial_layouts[i]); |
| 206 } |
| 207 } else if (!initial_layouts[i].empty()) { |
| 208 DVLOG(1) << "EnableLoginLayouts: ignoring non-keyboard or invalid ID: " |
| 209 << initial_layouts[i]; |
186 } | 210 } |
187 } else if (!initial_layout.empty()) { | |
188 DVLOG(1) << "EnableLoginLayouts: ignoring non-keyboard or invalid ID: " | |
189 << initial_layout; | |
190 } | 211 } |
191 | 212 |
192 // Add candidates to layouts, while skipping duplicates. | 213 // Add candidates to layouts, while skipping duplicates. |
193 for (size_t i = 0; i < candidates.size(); ++i) { | 214 for (size_t i = 0; i < candidates.size(); ++i) { |
194 const std::string& candidate = candidates[i]; | 215 const std::string& candidate = candidates[i]; |
195 // Not efficient, but should be fine, as the two vectors are very | 216 // Not efficient, but should be fine, as the two vectors are very |
196 // short (2-5 items). | 217 // short (2-5 items). |
197 if (!Contains(layouts, candidate) && IsLoginKeyboard(candidate)) | 218 if (!Contains(layouts, candidate) && IsLoginKeyboard(candidate)) |
198 layouts.push_back(candidate); | 219 layouts.push_back(candidate); |
199 } | 220 } |
200 | 221 |
201 active_input_method_ids_.swap(layouts); | 222 active_input_method_ids_.swap(layouts); |
202 | 223 |
203 // Initialize candidate window controller and widgets such as | 224 // Initialize candidate window controller and widgets such as |
204 // candidate window, infolist and mode indicator. Note, mode | 225 // candidate window, infolist and mode indicator. Note, mode |
205 // indicator is used by only keyboard layout input methods. | 226 // indicator is used by only keyboard layout input methods. |
206 if (active_input_method_ids_.size() > 1) | 227 if (active_input_method_ids_.size() > 1) |
207 MaybeInitializeCandidateWindowController(); | 228 MaybeInitializeCandidateWindowController(); |
208 | 229 |
209 ChangeInputMethod(initial_layout); // you can pass empty |initial_layout|. | 230 // you can pass empty |initial_layout|. |
| 231 ChangeInputMethod(initial_layouts.empty() ? "" : initial_layouts[0]); |
210 } | 232 } |
211 | 233 |
212 // Adds new input method to given list. | 234 // Adds new input method to given list. |
213 bool InputMethodManagerImpl::EnableInputMethodImpl( | 235 bool InputMethodManagerImpl::EnableInputMethodImpl( |
214 const std::string& input_method_id, | 236 const std::string& input_method_id, |
215 std::vector<std::string>* new_active_input_method_ids) const { | 237 std::vector<std::string>* new_active_input_method_ids) const { |
216 DCHECK(new_active_input_method_ids); | 238 DCHECK(new_active_input_method_ids); |
217 if (!util_.IsValidInputMethodId(input_method_id)) { | 239 if (!util_.IsValidInputMethodId(input_method_id)) { |
218 DVLOG(1) << "EnableInputMethod: Invalid ID: " << input_method_id; | 240 DVLOG(1) << "EnableInputMethod: Invalid ID: " << input_method_id; |
219 return false; | 241 return false; |
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
532 | 554 |
533 if (active_imes_changed) { | 555 if (active_imes_changed) { |
534 MaybeInitializeCandidateWindowController(); | 556 MaybeInitializeCandidateWindowController(); |
535 | 557 |
536 // If |current_input_method| is no longer in |active_input_method_ids_|, | 558 // If |current_input_method| is no longer in |active_input_method_ids_|, |
537 // switch to the first one in |active_input_method_ids_|. | 559 // switch to the first one in |active_input_method_ids_|. |
538 ChangeInputMethod(current_input_method_.id()); | 560 ChangeInputMethod(current_input_method_.id()); |
539 } | 561 } |
540 } | 562 } |
541 | 563 |
542 void InputMethodManagerImpl::SetInputMethodDefault() { | 564 void InputMethodManagerImpl::SetInputMethodLoginDefault() { |
543 // Set up keyboards. For example, when |locale| is "en-US", enable US qwerty | 565 // Set up keyboards. For example, when |locale| is "en-US", enable US qwerty |
544 // and US dvorak keyboard layouts. | 566 // and US dvorak keyboard layouts. |
545 if (g_browser_process && g_browser_process->local_state()) { | 567 if (g_browser_process && g_browser_process->local_state()) { |
546 const std::string locale = g_browser_process->GetApplicationLocale(); | 568 const std::string locale = g_browser_process->GetApplicationLocale(); |
547 // If the preferred keyboard for the login screen has been saved, use it. | 569 // If the preferred keyboard for the login screen has been saved, use it. |
548 PrefService* prefs = g_browser_process->local_state(); | 570 PrefService* prefs = g_browser_process->local_state(); |
549 std::string initial_input_method_id = | 571 std::string initial_input_method_id = |
550 prefs->GetString(chromeos::language_prefs::kPreferredKeyboardLayout); | 572 prefs->GetString(chromeos::language_prefs::kPreferredKeyboardLayout); |
| 573 std::vector<std::string> input_methods_to_be_enabled; |
551 if (initial_input_method_id.empty()) { | 574 if (initial_input_method_id.empty()) { |
552 // If kPreferredKeyboardLayout is not specified, use the hardware layout. | 575 // If kPreferredKeyboardLayout is not specified, use the hardware layout. |
553 initial_input_method_id = | 576 input_methods_to_be_enabled = util_.GetHardwareLoginInputMethodIds(); |
554 GetInputMethodUtil()->GetHardwareInputMethodId(); | 577 } else { |
| 578 input_methods_to_be_enabled.push_back(initial_input_method_id); |
555 } | 579 } |
556 EnableLoginLayouts(locale, initial_input_method_id); | 580 EnableLoginLayouts(locale, input_methods_to_be_enabled); |
557 } | 581 } |
558 } | 582 } |
559 | 583 |
560 bool InputMethodManagerImpl::SwitchToNextInputMethod() { | 584 bool InputMethodManagerImpl::SwitchToNextInputMethod() { |
561 // Sanity checks. | 585 // Sanity checks. |
562 if (active_input_method_ids_.empty()) { | 586 if (active_input_method_ids_.empty()) { |
563 DVLOG(1) << "active input method is empty"; | 587 DVLOG(1) << "active input method is empty"; |
564 return false; | 588 return false; |
565 } | 589 } |
566 | 590 |
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
775 FOR_EACH_OBSERVER(InputMethodManager::CandidateWindowObserver, | 799 FOR_EACH_OBSERVER(InputMethodManager::CandidateWindowObserver, |
776 candidate_window_observers_, | 800 candidate_window_observers_, |
777 CandidateWindowClosed(this)); | 801 CandidateWindowClosed(this)); |
778 } | 802 } |
779 | 803 |
780 void InputMethodManagerImpl::OnScreenLocked() { | 804 void InputMethodManagerImpl::OnScreenLocked() { |
781 saved_previous_input_method_ = previous_input_method_; | 805 saved_previous_input_method_ = previous_input_method_; |
782 saved_current_input_method_ = current_input_method_; | 806 saved_current_input_method_ = current_input_method_; |
783 saved_active_input_method_ids_ = active_input_method_ids_; | 807 saved_active_input_method_ids_ = active_input_method_ids_; |
784 | 808 |
785 const std::string hardware_keyboard_id = util_.GetHardwareInputMethodId(); | 809 const std::vector<std::string>& hardware_keyboard_ids = |
786 // We'll add the hardware keyboard if it's not included in | 810 util_.GetHardwareLoginInputMethodIds(); |
787 // |active_input_method_list| so that the user can always use the hardware | |
788 // keyboard on the screen locker. | |
789 bool should_add_hardware_keyboard = true; | |
790 | 811 |
791 active_input_method_ids_.clear(); | 812 active_input_method_ids_.clear(); |
792 for (size_t i = 0; i < saved_active_input_method_ids_.size(); ++i) { | 813 for (size_t i = 0; i < saved_active_input_method_ids_.size(); ++i) { |
793 const std::string& input_method_id = saved_active_input_method_ids_[i]; | 814 const std::string& input_method_id = saved_active_input_method_ids_[i]; |
794 // Skip if it's not a keyboard layout. Drop input methods including | 815 // Skip if it's not a keyboard layout. Drop input methods including |
795 // extension ones. | 816 // extension ones. |
796 if (!IsLoginKeyboard(input_method_id)) | 817 if (!IsLoginKeyboard(input_method_id)) |
797 continue; | 818 continue; |
798 active_input_method_ids_.push_back(input_method_id); | 819 active_input_method_ids_.push_back(input_method_id); |
799 if (input_method_id == hardware_keyboard_id) | |
800 should_add_hardware_keyboard = false; | |
801 } | 820 } |
802 if (should_add_hardware_keyboard) | 821 |
803 active_input_method_ids_.push_back(hardware_keyboard_id); | 822 // We'll add the hardware keyboard if it's not included in |
| 823 // |active_input_method_ids_| so that the user can always use the hardware |
| 824 // keyboard on the screen locker. |
| 825 active_input_method_ids_.insert(active_input_method_ids_.end(), |
| 826 hardware_keyboard_ids.begin(), |
| 827 hardware_keyboard_ids.end()); |
| 828 |
| 829 UniquifyVectorWithKeepingOrder(&active_input_method_ids_); |
804 | 830 |
805 ChangeInputMethod(current_input_method_.id()); | 831 ChangeInputMethod(current_input_method_.id()); |
806 } | 832 } |
807 | 833 |
808 void InputMethodManagerImpl::OnScreenUnlocked() { | 834 void InputMethodManagerImpl::OnScreenUnlocked() { |
809 previous_input_method_ = saved_previous_input_method_; | 835 previous_input_method_ = saved_previous_input_method_; |
810 current_input_method_ = saved_current_input_method_; | 836 current_input_method_ = saved_current_input_method_; |
811 active_input_method_ids_ = saved_active_input_method_ids_; | 837 active_input_method_ids_ = saved_active_input_method_ids_; |
812 | 838 |
813 ChangeInputMethod(current_input_method_.id()); | 839 ChangeInputMethod(current_input_method_.id()); |
(...skipping 17 matching lines...) Expand all Loading... |
831 if (candidate_window_controller_.get()) | 857 if (candidate_window_controller_.get()) |
832 return; | 858 return; |
833 | 859 |
834 candidate_window_controller_.reset( | 860 candidate_window_controller_.reset( |
835 CandidateWindowController::CreateCandidateWindowController()); | 861 CandidateWindowController::CreateCandidateWindowController()); |
836 candidate_window_controller_->AddObserver(this); | 862 candidate_window_controller_->AddObserver(this); |
837 } | 863 } |
838 | 864 |
839 } // namespace input_method | 865 } // namespace input_method |
840 } // namespace chromeos | 866 } // namespace chromeos |
OLD | NEW |