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 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
154 std::map<std::string, InputMethodDescriptor>::const_iterator ix = | 154 std::map<std::string, InputMethodDescriptor>::const_iterator ix = |
155 extra_input_methods_.find(input_method_id); | 155 extra_input_methods_.find(input_method_id); |
156 if (ix != extra_input_methods_.end()) | 156 if (ix != extra_input_methods_.end()) |
157 ime = &ix->second; | 157 ime = &ix->second; |
158 } | 158 } |
159 return ime; | 159 return ime; |
160 } | 160 } |
161 | 161 |
162 void InputMethodManagerImpl::EnableLoginLayouts( | 162 void InputMethodManagerImpl::EnableLoginLayouts( |
163 const std::string& language_code, | 163 const std::string& language_code, |
164 const std::string& initial_layout) { | 164 const std::vector<std::string>& initial_layouts) { |
165 if (state_ == STATE_TERMINATING) | 165 if (state_ == STATE_TERMINATING) |
166 return; | 166 return; |
167 | 167 |
168 std::vector<std::string> candidates; | 168 // First, hardware keyboard layout should be shown. |
| 169 std::vector<std::string> candidates = |
| 170 util_.GetHardwareLoginInputMethodIds(); |
| 171 |
| 172 // Seocnd, locale based input method should be shown. |
169 // Add input methods associated with the language. | 173 // Add input methods associated with the language. |
| 174 std::vector<std::string> layouts_from_locale; |
170 util_.GetInputMethodIdsFromLanguageCode(language_code, | 175 util_.GetInputMethodIdsFromLanguageCode(language_code, |
171 kKeyboardLayoutsOnly, | 176 kKeyboardLayoutsOnly, |
172 &candidates); | 177 &layouts_from_locale); |
173 // Add the hardware keyboard as well. We should always add this so users | 178 candidates.insert(candidates.end(), layouts_from_locale.begin(), |
174 // can use the hardware keyboard on the login screen and the screen locker. | 179 layouts_from_locale.end()); |
175 candidates.push_back(util_.GetHardwareLoginInputMethodId()); | |
176 | 180 |
177 std::vector<std::string> layouts; | 181 std::vector<std::string> layouts; |
178 // First, add the initial input method ID, if it's requested, to | 182 // First, add the initial input method ID, if it's requested, to |
179 // layouts, so it appears first on the list of active input | 183 // layouts, so it appears first on the list of active input |
180 // methods at the input language status menu. | 184 // methods at the input language status menu. |
181 if (util_.IsValidInputMethodId(initial_layout)) { | 185 for (size_t i = 0; i < initial_layouts.size(); ++i) { |
182 if (!IsLoginKeyboard(initial_layout)) { | 186 if (util_.IsValidInputMethodId(initial_layouts[i])) { |
183 DVLOG(1) | 187 if (IsLoginKeyboard(initial_layouts[i])) { |
184 << "EnableLoginLayouts: ignoring non-login initial keyboard layout:" | 188 layouts.push_back(initial_layouts[i]); |
185 << initial_layout; | 189 } else { |
186 } else { | 190 DVLOG(1) |
187 layouts.push_back(initial_layout); | 191 << "EnableLoginLayouts: ignoring non-login initial keyboard layout:" |
| 192 << initial_layouts[i]; |
| 193 } |
| 194 } else if (!initial_layouts[i].empty()) { |
| 195 DVLOG(1) << "EnableLoginLayouts: ignoring non-keyboard or invalid ID: " |
| 196 << initial_layouts[i]; |
188 } | 197 } |
189 } else if (!initial_layout.empty()) { | |
190 DVLOG(1) << "EnableLoginLayouts: ignoring non-keyboard or invalid ID: " | |
191 << initial_layout; | |
192 } | 198 } |
193 | 199 |
194 // Add candidates to layouts, while skipping duplicates. | 200 // Add candidates to layouts, while skipping duplicates. |
195 for (size_t i = 0; i < candidates.size(); ++i) { | 201 for (size_t i = 0; i < candidates.size(); ++i) { |
196 const std::string& candidate = candidates[i]; | 202 const std::string& candidate = candidates[i]; |
197 // Not efficient, but should be fine, as the two vectors are very | 203 // Not efficient, but should be fine, as the two vectors are very |
198 // short (2-5 items). | 204 // short (2-5 items). |
199 if (!Contains(layouts, candidate) && IsLoginKeyboard(candidate)) | 205 if (!Contains(layouts, candidate) && IsLoginKeyboard(candidate)) |
200 layouts.push_back(candidate); | 206 layouts.push_back(candidate); |
201 } | 207 } |
202 | 208 |
203 active_input_method_ids_.swap(layouts); | 209 active_input_method_ids_.swap(layouts); |
204 | 210 |
205 // Initialize candidate window controller and widgets such as | 211 // Initialize candidate window controller and widgets such as |
206 // candidate window, infolist and mode indicator. Note, mode | 212 // candidate window, infolist and mode indicator. Note, mode |
207 // indicator is used by only keyboard layout input methods. | 213 // indicator is used by only keyboard layout input methods. |
208 if (active_input_method_ids_.size() > 1) | 214 if (active_input_method_ids_.size() > 1) |
209 MaybeInitializeCandidateWindowController(); | 215 MaybeInitializeCandidateWindowController(); |
210 | 216 |
211 ChangeInputMethod(initial_layout); // you can pass empty |initial_layout|. | 217 // you can pass empty |initial_layout|. |
| 218 ChangeInputMethod(initial_layouts.empty() ? "" : initial_layouts[0]); |
212 } | 219 } |
213 | 220 |
214 // Adds new input method to given list. | 221 // Adds new input method to given list. |
215 bool InputMethodManagerImpl::EnableInputMethodImpl( | 222 bool InputMethodManagerImpl::EnableInputMethodImpl( |
216 const std::string& input_method_id, | 223 const std::string& input_method_id, |
217 std::vector<std::string>* new_active_input_method_ids) const { | 224 std::vector<std::string>* new_active_input_method_ids) const { |
218 DCHECK(new_active_input_method_ids); | 225 DCHECK(new_active_input_method_ids); |
219 if (!util_.IsValidInputMethodId(input_method_id)) { | 226 if (!util_.IsValidInputMethodId(input_method_id)) { |
220 DVLOG(1) << "EnableInputMethod: Invalid ID: " << input_method_id; | 227 DVLOG(1) << "EnableInputMethod: Invalid ID: " << input_method_id; |
221 return false; | 228 return false; |
(...skipping 22 matching lines...) Expand all Loading... |
244 | 251 |
245 bool InputMethodManagerImpl::EnableInputMethod( | 252 bool InputMethodManagerImpl::EnableInputMethod( |
246 const std::string& input_method_id) { | 253 const std::string& input_method_id) { |
247 if (!EnableInputMethodImpl(input_method_id, &active_input_method_ids_)) | 254 if (!EnableInputMethodImpl(input_method_id, &active_input_method_ids_)) |
248 return false; | 255 return false; |
249 | 256 |
250 ReconfigureIMFramework(); | 257 ReconfigureIMFramework(); |
251 return true; | 258 return true; |
252 } | 259 } |
253 | 260 |
254 bool InputMethodManagerImpl::EnableInputMethods( | 261 bool InputMethodManagerImpl::ReplaceEnabledInputMethods( |
255 const std::vector<std::string>& new_active_input_method_ids) { | 262 const std::vector<std::string>& new_active_input_method_ids) { |
256 if (state_ == STATE_TERMINATING) | 263 if (state_ == STATE_TERMINATING) |
257 return false; | 264 return false; |
258 | 265 |
259 // Filter unknown or obsolete IDs. | 266 // Filter unknown or obsolete IDs. |
260 std::vector<std::string> new_active_input_method_ids_filtered; | 267 std::vector<std::string> new_active_input_method_ids_filtered; |
261 | 268 |
262 for (size_t i = 0; i < new_active_input_method_ids.size(); ++i) | 269 for (size_t i = 0; i < new_active_input_method_ids.size(); ++i) |
263 EnableInputMethodImpl(new_active_input_method_ids[i], | 270 EnableInputMethodImpl(new_active_input_method_ids[i], |
264 &new_active_input_method_ids_filtered); | 271 &new_active_input_method_ids_filtered); |
265 | 272 |
266 if (new_active_input_method_ids_filtered.empty()) { | 273 if (new_active_input_method_ids_filtered.empty()) { |
267 DVLOG(1) << "EnableInputMethods: No valid input method ID"; | 274 DVLOG(1) << "ReplaceEnabledInputMethods: No valid input method ID"; |
268 return false; | 275 return false; |
269 } | 276 } |
270 | 277 |
271 // Copy extension IDs to |new_active_input_method_ids_filtered|. We have to | 278 // Copy extension IDs to |new_active_input_method_ids_filtered|. We have to |
272 // keep relative order of the extension input method IDs. | 279 // keep relative order of the extension input method IDs. |
273 for (size_t i = 0; i < active_input_method_ids_.size(); ++i) { | 280 for (size_t i = 0; i < active_input_method_ids_.size(); ++i) { |
274 const std::string& input_method_id = active_input_method_ids_[i]; | 281 const std::string& input_method_id = active_input_method_ids_[i]; |
275 if (extension_ime_util::IsExtensionIME(input_method_id)) | 282 if (extension_ime_util::IsExtensionIME(input_method_id)) |
276 new_active_input_method_ids_filtered.push_back(input_method_id); | 283 new_active_input_method_ids_filtered.push_back(input_method_id); |
277 } | 284 } |
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
534 | 541 |
535 if (active_imes_changed) { | 542 if (active_imes_changed) { |
536 MaybeInitializeCandidateWindowController(); | 543 MaybeInitializeCandidateWindowController(); |
537 | 544 |
538 // If |current_input_method| is no longer in |active_input_method_ids_|, | 545 // If |current_input_method| is no longer in |active_input_method_ids_|, |
539 // switch to the first one in |active_input_method_ids_|. | 546 // switch to the first one in |active_input_method_ids_|. |
540 ChangeInputMethod(current_input_method_.id()); | 547 ChangeInputMethod(current_input_method_.id()); |
541 } | 548 } |
542 } | 549 } |
543 | 550 |
544 void InputMethodManagerImpl::SetInputMethodDefault() { | 551 void InputMethodManagerImpl::SetInputMethodLoginDefault() { |
545 // Set up keyboards. For example, when |locale| is "en-US", enable US qwerty | 552 // Set up keyboards. For example, when |locale| is "en-US", enable US qwerty |
546 // and US dvorak keyboard layouts. | 553 // and US dvorak keyboard layouts. |
547 if (g_browser_process && g_browser_process->local_state()) { | 554 if (g_browser_process && g_browser_process->local_state()) { |
548 const std::string locale = g_browser_process->GetApplicationLocale(); | 555 const std::string locale = g_browser_process->GetApplicationLocale(); |
549 // If the preferred keyboard for the login screen has been saved, use it. | 556 // If the preferred keyboard for the login screen has been saved, use it. |
550 PrefService* prefs = g_browser_process->local_state(); | 557 PrefService* prefs = g_browser_process->local_state(); |
551 std::string initial_input_method_id = | 558 std::string initial_input_method_id = |
552 prefs->GetString(chromeos::language_prefs::kPreferredKeyboardLayout); | 559 prefs->GetString(chromeos::language_prefs::kPreferredKeyboardLayout); |
| 560 std::vector<std::string> input_methods_to_be_enabled; |
553 if (initial_input_method_id.empty()) { | 561 if (initial_input_method_id.empty()) { |
554 // If kPreferredKeyboardLayout is not specified, use the hardware layout. | 562 // If kPreferredKeyboardLayout is not specified, use the hardware layout. |
555 initial_input_method_id = | 563 input_methods_to_be_enabled = util_.GetHardwareLoginInputMethodIds(); |
556 GetInputMethodUtil()->GetHardwareInputMethodId(); | 564 } else { |
| 565 input_methods_to_be_enabled.push_back(initial_input_method_id); |
557 } | 566 } |
558 EnableLoginLayouts(locale, initial_input_method_id); | 567 EnableLoginLayouts(locale, input_methods_to_be_enabled); |
559 } | 568 } |
560 } | 569 } |
561 | 570 |
562 bool InputMethodManagerImpl::SwitchToNextInputMethod() { | 571 bool InputMethodManagerImpl::SwitchToNextInputMethod() { |
563 // Sanity checks. | 572 // Sanity checks. |
564 if (active_input_method_ids_.empty()) { | 573 if (active_input_method_ids_.empty()) { |
565 DVLOG(1) << "active input method is empty"; | 574 DVLOG(1) << "active input method is empty"; |
566 return false; | 575 return false; |
567 } | 576 } |
568 | 577 |
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
780 FOR_EACH_OBSERVER(InputMethodManager::CandidateWindowObserver, | 789 FOR_EACH_OBSERVER(InputMethodManager::CandidateWindowObserver, |
781 candidate_window_observers_, | 790 candidate_window_observers_, |
782 CandidateWindowClosed(this)); | 791 CandidateWindowClosed(this)); |
783 } | 792 } |
784 | 793 |
785 void InputMethodManagerImpl::OnScreenLocked() { | 794 void InputMethodManagerImpl::OnScreenLocked() { |
786 saved_previous_input_method_ = previous_input_method_; | 795 saved_previous_input_method_ = previous_input_method_; |
787 saved_current_input_method_ = current_input_method_; | 796 saved_current_input_method_ = current_input_method_; |
788 saved_active_input_method_ids_ = active_input_method_ids_; | 797 saved_active_input_method_ids_ = active_input_method_ids_; |
789 | 798 |
790 const std::string hardware_keyboard_id = util_.GetHardwareInputMethodId(); | 799 std::set<std::string> added_ids_; |
791 // We'll add the hardware keyboard if it's not included in | 800 |
792 // |active_input_method_list| so that the user can always use the hardware | 801 const std::vector<std::string>& hardware_keyboard_ids = |
793 // keyboard on the screen locker. | 802 util_.GetHardwareLoginInputMethodIds(); |
794 bool should_add_hardware_keyboard = true; | |
795 | 803 |
796 active_input_method_ids_.clear(); | 804 active_input_method_ids_.clear(); |
797 for (size_t i = 0; i < saved_active_input_method_ids_.size(); ++i) { | 805 for (size_t i = 0; i < saved_active_input_method_ids_.size(); ++i) { |
798 const std::string& input_method_id = saved_active_input_method_ids_[i]; | 806 const std::string& input_method_id = saved_active_input_method_ids_[i]; |
799 // Skip if it's not a keyboard layout. Drop input methods including | 807 // Skip if it's not a keyboard layout. Drop input methods including |
800 // extension ones. | 808 // extension ones. |
801 if (!IsLoginKeyboard(input_method_id)) | 809 if (!IsLoginKeyboard(input_method_id) || |
| 810 added_ids_.find(input_method_id) != added_ids_.end()) |
802 continue; | 811 continue; |
803 active_input_method_ids_.push_back(input_method_id); | 812 active_input_method_ids_.push_back(input_method_id); |
804 if (input_method_id == hardware_keyboard_id) | 813 added_ids_.insert(input_method_id); |
805 should_add_hardware_keyboard = false; | |
806 } | 814 } |
807 if (should_add_hardware_keyboard) | 815 |
808 active_input_method_ids_.push_back(hardware_keyboard_id); | 816 // We'll add the hardware keyboard if it's not included in |
| 817 // |active_input_method_ids_| so that the user can always use the hardware |
| 818 // keyboard on the screen locker. |
| 819 for (size_t i = 0; i < hardware_keyboard_ids.size(); ++i) { |
| 820 if (added_ids_.find(hardware_keyboard_ids[i]) == added_ids_.end()) { |
| 821 active_input_method_ids_.push_back(hardware_keyboard_ids[i]); |
| 822 added_ids_.insert(hardware_keyboard_ids[i]); |
| 823 } |
| 824 } |
809 | 825 |
810 ChangeInputMethod(current_input_method_.id()); | 826 ChangeInputMethod(current_input_method_.id()); |
811 } | 827 } |
812 | 828 |
813 void InputMethodManagerImpl::OnScreenUnlocked() { | 829 void InputMethodManagerImpl::OnScreenUnlocked() { |
814 previous_input_method_ = saved_previous_input_method_; | 830 previous_input_method_ = saved_previous_input_method_; |
815 current_input_method_ = saved_current_input_method_; | 831 current_input_method_ = saved_current_input_method_; |
816 active_input_method_ids_ = saved_active_input_method_ids_; | 832 active_input_method_ids_ = saved_active_input_method_ids_; |
817 | 833 |
818 ChangeInputMethod(current_input_method_.id()); | 834 ChangeInputMethod(current_input_method_.id()); |
(...skipping 17 matching lines...) Expand all Loading... |
836 if (candidate_window_controller_.get()) | 852 if (candidate_window_controller_.get()) |
837 return; | 853 return; |
838 | 854 |
839 candidate_window_controller_.reset( | 855 candidate_window_controller_.reset( |
840 CandidateWindowController::CreateCandidateWindowController()); | 856 CandidateWindowController::CreateCandidateWindowController()); |
841 candidate_window_controller_->AddObserver(this); | 857 candidate_window_controller_->AddObserver(this); |
842 } | 858 } |
843 | 859 |
844 } // namespace input_method | 860 } // namespace input_method |
845 } // namespace chromeos | 861 } // namespace chromeos |
OLD | NEW |