Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(48)

Side by Side Diff: chrome/browser/chromeos/input_method/input_method_manager_impl.cc

Issue 419293002: IME refactoring: ChromeOS introduce input methods State. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Cleanup. Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 <sstream>
10
9 #include "ash/ime/input_method_menu_item.h" 11 #include "ash/ime/input_method_menu_item.h"
10 #include "ash/ime/input_method_menu_manager.h" 12 #include "ash/ime/input_method_menu_manager.h"
11 #include "base/basictypes.h" 13 #include "base/basictypes.h"
12 #include "base/bind.h" 14 #include "base/bind.h"
13 #include "base/location.h" 15 #include "base/location.h"
14 #include "base/memory/scoped_ptr.h" 16 #include "base/memory/scoped_ptr.h"
15 #include "base/prefs/pref_service.h" 17 #include "base/prefs/pref_service.h"
16 #include "base/strings/string_split.h" 18 #include "base/strings/string_split.h"
17 #include "base/strings/string_util.h" 19 #include "base/strings/string_util.h"
18 #include "base/strings/stringprintf.h" 20 #include "base/strings/stringprintf.h"
19 #include "base/sys_info.h" 21 #include "base/sys_info.h"
20 #include "chrome/browser/browser_process.h" 22 #include "chrome/browser/browser_process.h"
21 #include "chrome/browser/chromeos/input_method/candidate_window_controller.h" 23 #include "chrome/browser/chromeos/input_method/candidate_window_controller.h"
22 #include "chrome/browser/chromeos/input_method/component_extension_ime_manager_i mpl.h" 24 #include "chrome/browser/chromeos/input_method/component_extension_ime_manager_i mpl.h"
23 #include "chrome/browser/chromeos/input_method/input_method_engine.h" 25 #include "chrome/browser/chromeos/input_method/input_method_engine.h"
24 #include "chrome/browser/chromeos/language_preferences.h" 26 #include "chrome/browser/chromeos/language_preferences.h"
27 #include "chrome/browser/chromeos/login/session/user_session_manager.h"
25 #include "chrome/browser/chromeos/login/users/user_manager.h" 28 #include "chrome/browser/chromeos/login/users/user_manager.h"
29 #include "chrome/browser/chromeos/profiles/profile_helper.h"
26 #include "chrome/browser/profiles/profile_manager.h" 30 #include "chrome/browser/profiles/profile_manager.h"
27 #include "chrome/common/pref_names.h" 31 #include "chrome/common/pref_names.h"
28 #include "chromeos/ime/component_extension_ime_manager.h" 32 #include "chromeos/ime/component_extension_ime_manager.h"
29 #include "chromeos/ime/extension_ime_util.h" 33 #include "chromeos/ime/extension_ime_util.h"
30 #include "chromeos/ime/fake_ime_keyboard.h" 34 #include "chromeos/ime/fake_ime_keyboard.h"
31 #include "chromeos/ime/ime_keyboard.h" 35 #include "chromeos/ime/ime_keyboard.h"
32 #include "chromeos/ime/input_method_delegate.h" 36 #include "chromeos/ime/input_method_delegate.h"
33 #include "third_party/icu/source/common/unicode/uloc.h" 37 #include "third_party/icu/source/common/unicode/uloc.h"
34 #include "ui/base/accelerators/accelerator.h" 38 #include "ui/base/accelerators/accelerator.h"
35 39
(...skipping 13 matching lines...) Expand all
49 bool InputMethodManagerImpl::IsLoginKeyboard( 53 bool InputMethodManagerImpl::IsLoginKeyboard(
50 const std::string& layout) const { 54 const std::string& layout) const {
51 return util_.IsLoginKeyboard(layout); 55 return util_.IsLoginKeyboard(layout);
52 } 56 }
53 57
54 bool InputMethodManagerImpl::MigrateInputMethods( 58 bool InputMethodManagerImpl::MigrateInputMethods(
55 std::vector<std::string>* input_method_ids) { 59 std::vector<std::string>* input_method_ids) {
56 return util_.MigrateInputMethods(input_method_ids); 60 return util_.MigrateInputMethods(input_method_ids);
57 } 61 }
58 62
63 InputMethodManagerImpl::State::State(InputMethodManagerImpl* manager,
64 Profile* profile)
65 : profile(profile), manager_(manager) {
66 }
67
68 InputMethodManagerImpl::State::~State() {
69 }
70
71 void InputMethodManagerImpl::State::InitFrom(const State& other) {
72 previous_input_method = other.previous_input_method;
73 current_input_method = other.current_input_method;
74
75 active_input_method_ids = other.active_input_method_ids;
76
77 enabled_extension_imes = other.enabled_extension_imes;
78 extra_input_methods = other.extra_input_methods;
79 }
80
81 bool InputMethodManagerImpl::State::IsActive() const {
82 return manager_->state_.get() == this;
83 }
84
85 std::string InputMethodManagerImpl::State::Dump() const {
86 std::ostringstream os;
87
88 os << "################# "
89 << (profile ? profile->GetProfileName() : std::string("NULL"))
90 << " #################\n";
91
92 os << "previous_input_method: '"
93 << previous_input_method.GetPreferredKeyboardLayout() << "'\n";
94 os << "current_input_method: '"
95 << current_input_method.GetPreferredKeyboardLayout() << "'\n";
96 os << "active_input_method_ids (size=" << active_input_method_ids.size()
97 << "):";
98 for (size_t i = 0; i < active_input_method_ids.size(); ++i) {
99 os << " '" << active_input_method_ids[i] << "',";
100 }
101 os << "\n";
102 os << "enabled_extension_imes (size=" << enabled_extension_imes.size()
103 << "):";
104 for (size_t i = 0; i < enabled_extension_imes.size(); ++i) {
105 os << " '" << enabled_extension_imes[i] << "'\n";
106 }
107 os << "\n";
108 os << "extra_input_methods (size=" << extra_input_methods.size() << "):";
109 for (std::map<std::string, InputMethodDescriptor>::const_iterator it =
110 extra_input_methods.begin();
111 it != extra_input_methods.end();
112 ++it) {
113 os << " '" << it->first << "' => '" << it->second.id() << "',\n";
114 }
115
116 return os.str();
117 }
118
119 scoped_refptr<InputMethodManager::State> InputMethodManagerImpl::CloneState(
120 const InputMethodManager::State* state) {
121 const State* impl_state = static_cast<const State*>(state);
122 scoped_refptr<State> new_state(new State(this, impl_state->profile));
123 new_state->InitFrom(*impl_state);
124 return scoped_refptr<InputMethodManager::State>(new_state.get());
125 }
126
127 void InputMethodManagerImpl::SetState(
128 scoped_refptr<InputMethodManager::State> state) {
129 DCHECK(state);
130 InputMethodManagerImpl::State* new_impl_state =
131 static_cast<InputMethodManagerImpl::State*>(state.get());
132 const bool need_update_current_input_method =
133 (state_ ? state_->current_input_method.id() !=
134 new_impl_state->current_input_method.id()
135 : true);
136 state_ = new_impl_state;
137
138 if (state_ && state_->active_input_method_ids.size()) {
139 // Initialize candidate window controller and widgets such as
140 // candidate window, infolist and mode indicator. Note, mode
141 // indicator is used by only keyboard layout input methods.
142 MaybeInitializeCandidateWindowController();
143
144 if (need_update_current_input_method)
145 ChangeInputMethodInternal(state_->current_input_method,
146 false /* show_message */,
147 true /* notify_menu */);
148 }
149 }
150
151 scoped_refptr<InputMethodManager::State>
152 InputMethodManagerImpl::GetActiveIMEState() {
153 return scoped_refptr<InputMethodManager::State>(state_.get());
154 }
155
59 InputMethodManagerImpl::InputMethodManagerImpl( 156 InputMethodManagerImpl::InputMethodManagerImpl(
60 scoped_ptr<InputMethodDelegate> delegate) 157 scoped_ptr<InputMethodDelegate> delegate)
61 : delegate_(delegate.Pass()), 158 : delegate_(delegate.Pass()),
62 state_(STATE_LOGIN_SCREEN), 159 ui_session_(STATE_LOGIN_SCREEN),
160 state_(NULL),
63 util_(delegate_.get()), 161 util_(delegate_.get()),
64 component_extension_ime_manager_(new ComponentExtensionIMEManager()), 162 component_extension_ime_manager_(new ComponentExtensionIMEManager()),
65 weak_ptr_factory_(this) { 163 weak_ptr_factory_(this) {
66 if (base::SysInfo::IsRunningOnChromeOS()) 164 if (base::SysInfo::IsRunningOnChromeOS())
67 keyboard_.reset(ImeKeyboard::Create()); 165 keyboard_.reset(ImeKeyboard::Create());
68 else 166 else
69 keyboard_.reset(new FakeImeKeyboard()); 167 keyboard_.reset(new FakeImeKeyboard());
70 } 168 }
71 169
72 InputMethodManagerImpl::~InputMethodManagerImpl() { 170 InputMethodManagerImpl::~InputMethodManagerImpl() {
(...skipping 14 matching lines...) Expand all
87 void InputMethodManagerImpl::RemoveObserver( 185 void InputMethodManagerImpl::RemoveObserver(
88 InputMethodManager::Observer* observer) { 186 InputMethodManager::Observer* observer) {
89 observers_.RemoveObserver(observer); 187 observers_.RemoveObserver(observer);
90 } 188 }
91 189
92 void InputMethodManagerImpl::RemoveCandidateWindowObserver( 190 void InputMethodManagerImpl::RemoveCandidateWindowObserver(
93 InputMethodManager::CandidateWindowObserver* observer) { 191 InputMethodManager::CandidateWindowObserver* observer) {
94 candidate_window_observers_.RemoveObserver(observer); 192 candidate_window_observers_.RemoveObserver(observer);
95 } 193 }
96 194
97 void InputMethodManagerImpl::SetState(State new_state) { 195 void InputMethodManagerImpl::SetUISessionState(UISessionState new_ui_session) {
98 const State old_state = state_; 196 ui_session_ = new_ui_session;
99 state_ = new_state; 197 switch (ui_session_) {
100 switch (state_) {
101 case STATE_LOGIN_SCREEN: 198 case STATE_LOGIN_SCREEN:
102 break; 199 break;
103 case STATE_BROWSER_SCREEN: 200 case STATE_BROWSER_SCREEN:
104 if (old_state == STATE_LOCK_SCREEN)
105 OnScreenUnlocked();
106 break; 201 break;
107 case STATE_LOCK_SCREEN: 202 case STATE_LOCK_SCREEN:
108 OnScreenLocked();
109 break; 203 break;
110 case STATE_TERMINATING: { 204 case STATE_TERMINATING: {
111 if (candidate_window_controller_.get()) 205 if (candidate_window_controller_.get())
112 candidate_window_controller_.reset(); 206 candidate_window_controller_.reset();
113 break; 207 break;
114 } 208 }
115 } 209 }
116 } 210 }
117 211
118 scoped_ptr<InputMethodDescriptors> 212 scoped_ptr<InputMethodDescriptors>
119 InputMethodManagerImpl::GetSupportedInputMethods() const { 213 InputMethodManagerImpl::GetSupportedInputMethods() const {
120 return scoped_ptr<InputMethodDescriptors>(new InputMethodDescriptors).Pass(); 214 return scoped_ptr<InputMethodDescriptors>(new InputMethodDescriptors).Pass();
121 } 215 }
122 216
123 scoped_ptr<InputMethodDescriptors> 217 scoped_ptr<InputMethodDescriptors>
124 InputMethodManagerImpl::GetActiveInputMethods() const { 218 InputMethodManagerImpl::State::GetActiveInputMethods() const {
125 scoped_ptr<InputMethodDescriptors> result(new InputMethodDescriptors); 219 scoped_ptr<InputMethodDescriptors> result(new InputMethodDescriptors);
126 // Build the active input method descriptors from the active input 220 // Build the active input method descriptors from the active input
127 // methods cache |active_input_method_ids_|. 221 // methods cache |active_input_method_ids|.
128 for (size_t i = 0; i < active_input_method_ids_.size(); ++i) { 222 for (size_t i = 0; i < active_input_method_ids.size(); ++i) {
129 const std::string& input_method_id = active_input_method_ids_[i]; 223 const std::string& input_method_id = active_input_method_ids[i];
130 const InputMethodDescriptor* descriptor = 224 const InputMethodDescriptor* descriptor =
131 util_.GetInputMethodDescriptorFromId(input_method_id); 225 manager_->util_.GetInputMethodDescriptorFromId(input_method_id);
132 if (descriptor) { 226 if (descriptor) {
133 result->push_back(*descriptor); 227 result->push_back(*descriptor);
134 } else { 228 } else {
135 std::map<std::string, InputMethodDescriptor>::const_iterator ix = 229 std::map<std::string, InputMethodDescriptor>::const_iterator ix =
136 extra_input_methods_.find(input_method_id); 230 extra_input_methods.find(input_method_id);
137 if (ix != extra_input_methods_.end()) 231 if (ix != extra_input_methods.end())
138 result->push_back(ix->second); 232 result->push_back(ix->second);
139 else 233 else
140 DVLOG(1) << "Descriptor is not found for: " << input_method_id; 234 DVLOG(1) << "Descriptor is not found for: " << input_method_id;
141 } 235 }
142 } 236 }
143 if (result->empty()) { 237 if (result->empty()) {
144 // Initially |active_input_method_ids_| is empty. browser_tests might take 238 // Initially |active_input_method_ids| is empty. browser_tests might take
145 // this path. 239 // this path.
146 result->push_back( 240 result->push_back(
147 InputMethodUtil::GetFallbackInputMethodDescriptor()); 241 InputMethodUtil::GetFallbackInputMethodDescriptor());
148 } 242 }
149 return result.Pass(); 243 return result.Pass();
150 } 244 }
151 245
152 const std::vector<std::string>& 246 const std::vector<std::string>&
153 InputMethodManagerImpl::GetActiveInputMethodIds() const { 247 InputMethodManagerImpl::State::GetActiveInputMethodIds() const {
154 return active_input_method_ids_; 248 return active_input_method_ids;
155 } 249 }
156 250
157 size_t InputMethodManagerImpl::GetNumActiveInputMethods() const { 251 size_t InputMethodManagerImpl::State::GetNumActiveInputMethods() const {
158 return active_input_method_ids_.size(); 252 return active_input_method_ids.size();
159 } 253 }
160 254
161 const InputMethodDescriptor* InputMethodManagerImpl::GetInputMethodFromId( 255 const InputMethodDescriptor*
256 InputMethodManagerImpl::State::GetInputMethodFromId(
162 const std::string& input_method_id) const { 257 const std::string& input_method_id) const {
163 const InputMethodDescriptor* ime = util_.GetInputMethodDescriptorFromId( 258 const InputMethodDescriptor* ime =
164 input_method_id); 259 manager_->util_.GetInputMethodDescriptorFromId(input_method_id);
165 if (!ime) { 260 if (!ime) {
166 std::map<std::string, InputMethodDescriptor>::const_iterator ix = 261 std::map<std::string, InputMethodDescriptor>::const_iterator ix =
167 extra_input_methods_.find(input_method_id); 262 extra_input_methods.find(input_method_id);
168 if (ix != extra_input_methods_.end()) 263 if (ix != extra_input_methods.end())
169 ime = &ix->second; 264 ime = &ix->second;
170 } 265 }
171 return ime; 266 return ime;
172 } 267 }
173 268
174 void InputMethodManagerImpl::EnableLoginLayouts( 269 void InputMethodManagerImpl::State::EnableLoginLayouts(
175 const std::string& language_code, 270 const std::string& language_code,
176 const std::vector<std::string>& initial_layouts) { 271 const std::vector<std::string>& initial_layouts) {
177 if (state_ == STATE_TERMINATING) 272 if (manager_->ui_session_ == STATE_TERMINATING)
178 return; 273 return;
179 274
180 // First, hardware keyboard layout should be shown. 275 // First, hardware keyboard layout should be shown.
181 std::vector<std::string> candidates = 276 std::vector<std::string> candidates =
182 util_.GetHardwareLoginInputMethodIds(); 277 manager_->util_.GetHardwareLoginInputMethodIds();
183 278
184 // Seocnd, locale based input method should be shown. 279 // Second, locale based input method should be shown.
185 // Add input methods associated with the language. 280 // Add input methods associated with the language.
186 std::vector<std::string> layouts_from_locale; 281 std::vector<std::string> layouts_from_locale;
187 util_.GetInputMethodIdsFromLanguageCode(language_code, 282 manager_->util_.GetInputMethodIdsFromLanguageCode(
188 kKeyboardLayoutsOnly, 283 language_code, kKeyboardLayoutsOnly, &layouts_from_locale);
189 &layouts_from_locale);
190 candidates.insert(candidates.end(), layouts_from_locale.begin(), 284 candidates.insert(candidates.end(), layouts_from_locale.begin(),
191 layouts_from_locale.end()); 285 layouts_from_locale.end());
192 286
193 std::vector<std::string> layouts; 287 std::vector<std::string> layouts;
194 // First, add the initial input method ID, if it's requested, to 288 // First, add the initial input method ID, if it's requested, to
195 // layouts, so it appears first on the list of active input 289 // layouts, so it appears first on the list of active input
196 // methods at the input language status menu. 290 // methods at the input language status menu.
197 for (size_t i = 0; i < initial_layouts.size(); ++i) { 291 for (size_t i = 0; i < initial_layouts.size(); ++i) {
198 if (util_.IsValidInputMethodId(initial_layouts[i])) { 292 if (manager_->util_.IsValidInputMethodId(initial_layouts[i])) {
199 if (IsLoginKeyboard(initial_layouts[i])) { 293 if (manager_->IsLoginKeyboard(initial_layouts[i])) {
200 layouts.push_back(initial_layouts[i]); 294 layouts.push_back(initial_layouts[i]);
201 } else { 295 } else {
202 DVLOG(1) 296 DVLOG(1)
203 << "EnableLoginLayouts: ignoring non-login initial keyboard layout:" 297 << "EnableLoginLayouts: ignoring non-login initial keyboard layout:"
204 << initial_layouts[i]; 298 << initial_layouts[i];
205 } 299 }
206 } else if (!initial_layouts[i].empty()) { 300 } else if (!initial_layouts[i].empty()) {
207 DVLOG(1) << "EnableLoginLayouts: ignoring non-keyboard or invalid ID: " 301 DVLOG(1) << "EnableLoginLayouts: ignoring non-keyboard or invalid ID: "
208 << initial_layouts[i]; 302 << initial_layouts[i];
209 } 303 }
210 } 304 }
211 305
212 // Add candidates to layouts, while skipping duplicates. 306 // Add candidates to layouts, while skipping duplicates.
213 for (size_t i = 0; i < candidates.size(); ++i) { 307 for (size_t i = 0; i < candidates.size(); ++i) {
214 const std::string& candidate = candidates[i]; 308 const std::string& candidate = candidates[i];
215 // Not efficient, but should be fine, as the two vectors are very 309 // Not efficient, but should be fine, as the two vectors are very
216 // short (2-5 items). 310 // short (2-5 items).
217 if (!Contains(layouts, candidate) && IsLoginKeyboard(candidate)) 311 if (!Contains(layouts, candidate) && manager_->IsLoginKeyboard(candidate))
218 layouts.push_back(candidate); 312 layouts.push_back(candidate);
219 } 313 }
220 314
221 MigrateInputMethods(&layouts); 315 manager_->MigrateInputMethods(&layouts);
222 active_input_method_ids_.swap(layouts); 316 active_input_method_ids.swap(layouts);
223 317
224 // Initialize candidate window controller and widgets such as 318 if (IsActive()) {
225 // candidate window, infolist and mode indicator. Note, mode 319 // Initialize candidate window controller and widgets such as
226 // indicator is used by only keyboard layout input methods. 320 // candidate window, infolist and mode indicator. Note, mode
227 if (active_input_method_ids_.size() > 1) 321 // indicator is used by only keyboard layout input methods.
228 MaybeInitializeCandidateWindowController(); 322 if (active_input_method_ids.size() > 1)
323 manager_->MaybeInitializeCandidateWindowController();
229 324
230 // you can pass empty |initial_layout|. 325 // you can pass empty |initial_layout|.
231 ChangeInputMethod(initial_layouts.empty() ? "" : 326 ChangeInputMethod(initial_layouts.empty()
232 extension_ime_util::GetInputMethodIDByEngineID(initial_layouts[0])); 327 ? std::string()
328 : extension_ime_util::GetInputMethodIDByEngineID(
329 initial_layouts[0]),
330 false);
331 }
332 }
333
334 void InputMethodManagerImpl::State::EnableLockScreenLayouts() {
335 std::set<std::string> added_ids;
336
337 const std::vector<std::string>& hardware_keyboard_ids =
338 manager_->util_.GetHardwareLoginInputMethodIds();
339
340 std::vector<std::string> new_active_input_method_ids;
341 for (size_t i = 0; i < active_input_method_ids.size(); ++i) {
342 const std::string& input_method_id = active_input_method_ids[i];
343 // Skip if it's not a keyboard layout. Drop input methods including
344 // extension ones.
345 if (!manager_->IsLoginKeyboard(input_method_id) ||
346 added_ids.count(input_method_id)) {
347 continue;
348 }
349 new_active_input_method_ids.push_back(input_method_id);
350 added_ids.insert(input_method_id);
351 }
352
353 // We'll add the hardware keyboard if it's not included in
354 // |active_input_method_ids| so that the user can always use the hardware
355 // keyboard on the screen locker.
356 for (size_t i = 0; i < hardware_keyboard_ids.size(); ++i) {
357 if (added_ids.count(hardware_keyboard_ids[i]))
358 continue;
359 new_active_input_method_ids.push_back(hardware_keyboard_ids[i]);
360 added_ids.insert(hardware_keyboard_ids[i]);
361 }
362
363 active_input_method_ids.swap(new_active_input_method_ids);
364
365 // Re-check current_input_method.
366 ChangeInputMethod(current_input_method.id(), false);
233 } 367 }
234 368
235 // Adds new input method to given list. 369 // Adds new input method to given list.
236 bool InputMethodManagerImpl::EnableInputMethodImpl( 370 bool InputMethodManagerImpl::State::EnableInputMethodImpl(
237 const std::string& input_method_id, 371 const std::string& input_method_id,
238 std::vector<std::string>* new_active_input_method_ids) const { 372 std::vector<std::string>* new_active_input_method_ids) const {
239 DCHECK(new_active_input_method_ids); 373 DCHECK(new_active_input_method_ids);
240 if (!util_.IsValidInputMethodId(input_method_id)) { 374 if (!manager_->util_.IsValidInputMethodId(input_method_id)) {
241 DVLOG(1) << "EnableInputMethod: Invalid ID: " << input_method_id; 375 DVLOG(1) << "EnableInputMethod: Invalid ID: " << input_method_id;
242 return false; 376 return false;
243 } 377 }
244 378
245 if (!Contains(*new_active_input_method_ids, input_method_id)) 379 if (!Contains(*new_active_input_method_ids, input_method_id))
246 new_active_input_method_ids->push_back(input_method_id); 380 new_active_input_method_ids->push_back(input_method_id);
247 381
248 return true; 382 return true;
249 } 383 }
250 384
251 // Starts or stops the system input method framework as needed. 385 // Starts or stops the system input method framework as needed.
252 void InputMethodManagerImpl::ReconfigureIMFramework() { 386 void InputMethodManagerImpl::ReconfigureIMFramework(
253 LoadNecessaryComponentExtensions(); 387 InputMethodManagerImpl::State* state) {
388 LoadNecessaryComponentExtensions(state);
254 389
255 // Initialize candidate window controller and widgets such as 390 // Initialize candidate window controller and widgets such as
256 // candidate window, infolist and mode indicator. Note, mode 391 // candidate window, infolist and mode indicator. Note, mode
257 // indicator is used by only keyboard layout input methods. 392 // indicator is used by only keyboard layout input methods.
258 MaybeInitializeCandidateWindowController(); 393 if (state_.get() == state)
394 MaybeInitializeCandidateWindowController();
259 } 395 }
260 396
261 bool InputMethodManagerImpl::EnableInputMethod( 397 bool InputMethodManagerImpl::State::EnableInputMethod(
262 const std::string& input_method_id) { 398 const std::string& input_method_id) {
263 if (!EnableInputMethodImpl(input_method_id, &active_input_method_ids_)) 399 if (!EnableInputMethodImpl(input_method_id, &active_input_method_ids))
264 return false; 400 return false;
265 401
266 ReconfigureIMFramework(); 402 manager_->ReconfigureIMFramework(this);
267 return true; 403 return true;
268 } 404 }
269 405
270 bool InputMethodManagerImpl::ReplaceEnabledInputMethods( 406 bool InputMethodManagerImpl::State::ReplaceEnabledInputMethods(
271 const std::vector<std::string>& new_active_input_method_ids) { 407 const std::vector<std::string>& new_active_input_method_ids) {
272 if (state_ == STATE_TERMINATING) 408 if (manager_->ui_session_ == STATE_TERMINATING)
273 return false; 409 return false;
274 410
275 // Filter unknown or obsolete IDs. 411 // Filter unknown or obsolete IDs.
276 std::vector<std::string> new_active_input_method_ids_filtered; 412 std::vector<std::string> new_active_input_method_idsfiltered;
Shu Chen 2014/08/13 16:15:33 why rename this?
Alexander Alekseev 2014/08/13 23:29:32 Fixed. This was a result of mass rename.
277 413
278 for (size_t i = 0; i < new_active_input_method_ids.size(); ++i) 414 for (size_t i = 0; i < new_active_input_method_ids.size(); ++i)
279 EnableInputMethodImpl(new_active_input_method_ids[i], 415 EnableInputMethodImpl(new_active_input_method_ids[i],
280 &new_active_input_method_ids_filtered); 416 &new_active_input_method_idsfiltered);
281 417
282 if (new_active_input_method_ids_filtered.empty()) { 418 if (new_active_input_method_idsfiltered.empty()) {
283 DVLOG(1) << "ReplaceEnabledInputMethods: No valid input method ID"; 419 DVLOG(1) << "ReplaceEnabledInputMethods: No valid input method ID";
284 return false; 420 return false;
285 } 421 }
286 422
287 // Copy extension IDs to |new_active_input_method_ids_filtered|. We have to 423 // Copy extension IDs to |new_active_input_method_idsfiltered|. We have to
288 // keep relative order of the extension input method IDs. 424 // keep relative order of the extension input method IDs.
289 for (size_t i = 0; i < active_input_method_ids_.size(); ++i) { 425 for (size_t i = 0; i < active_input_method_ids.size(); ++i) {
290 const std::string& input_method_id = active_input_method_ids_[i]; 426 const std::string& input_method_id = active_input_method_ids[i];
291 if (extension_ime_util::IsExtensionIME(input_method_id)) 427 if (extension_ime_util::IsExtensionIME(input_method_id))
292 new_active_input_method_ids_filtered.push_back(input_method_id); 428 new_active_input_method_idsfiltered.push_back(input_method_id);
293 } 429 }
294 active_input_method_ids_.swap(new_active_input_method_ids_filtered); 430 active_input_method_ids.swap(new_active_input_method_idsfiltered);
295 MigrateInputMethods(&active_input_method_ids_); 431 manager_->MigrateInputMethods(&active_input_method_ids);
296 432
297 ReconfigureIMFramework(); 433 manager_->ReconfigureIMFramework(this);
298 434
299 // If |current_input_method| is no longer in |active_input_method_ids_|, 435 // If |current_input_method| is no longer in |active_input_method_ids|,
300 // ChangeInputMethod() picks the first one in |active_input_method_ids_|. 436 // ChangeInputMethod() picks the first one in |active_input_method_ids|.
301 ChangeInputMethod(current_input_method_.id()); 437 ChangeInputMethod(current_input_method.id(), false);
302 return true; 438 return true;
303 } 439 }
304 440
305 void InputMethodManagerImpl::ChangeInputMethod( 441 void InputMethodManagerImpl::State::ChangeInputMethod(
306 const std::string& input_method_id) { 442 const std::string& input_method_id,
307 ChangeInputMethodInternal(input_method_id, false); 443 bool show_message) {
444 bool notify_menu = false;
445 // Always lookup input method, even if it is the same as
446 // |current_input_method| because If it is no longer in
447 // |active_input_method_ids|, pick the first one in
448 // |active_input_method_ids|.
449 const InputMethodDescriptor* descriptor =
450 manager_->LookupInputMethod(input_method_id, this);
451 if (descriptor->id() != current_input_method.id()) {
452 previous_input_method = current_input_method;
453 current_input_method = *descriptor;
454 notify_menu = true;
455 }
456
457 // Always change input method even if it is the same.
458 // TODO(komatsu): Revisit if this is neccessary.
459 if (IsActive())
460 manager_->ChangeInputMethodInternal(*descriptor, show_message, notify_menu);
308 } 461 }
309 462
310 bool InputMethodManagerImpl::ChangeInputMethodInternal( 463 const InputMethodDescriptor* InputMethodManagerImpl::LookupInputMethod(
311 const std::string& input_method_id, 464 const std::string& input_method_id,
312 bool show_message) { 465 InputMethodManagerImpl::State* state) {
313 if (state_ == STATE_TERMINATING) 466 DCHECK(state);
314 return false;
315 467
316 std::string input_method_id_to_switch = input_method_id; 468 std::string input_method_id_to_switch = input_method_id;
317 469
318 // Sanity check. 470 // Sanity check.
319 if (!InputMethodIsActivated(input_method_id)) { 471 if (!state->InputMethodIsActivated(input_method_id)) {
320 scoped_ptr<InputMethodDescriptors> input_methods(GetActiveInputMethods()); 472 scoped_ptr<InputMethodDescriptors> input_methods(
473 state->GetActiveInputMethods());
321 DCHECK(!input_methods->empty()); 474 DCHECK(!input_methods->empty());
322 input_method_id_to_switch = input_methods->at(0).id(); 475 input_method_id_to_switch = input_methods->at(0).id();
323 if (!input_method_id.empty()) { 476 if (!input_method_id.empty()) {
324 DVLOG(1) << "Can't change the current input method to " 477 DVLOG(1) << "Can't change the current input method to "
325 << input_method_id << " since the engine is not enabled. " 478 << input_method_id << " since the engine is not enabled. "
326 << "Switch to " << input_method_id_to_switch << " instead."; 479 << "Switch to " << input_method_id_to_switch << " instead.";
327 } 480 }
328 } 481 }
329 482
330 // Hide candidate window and info list. 483 const InputMethodDescriptor* descriptor = NULL;
484 if (extension_ime_util::IsExtensionIME(input_method_id_to_switch)) {
485 DCHECK(state->extra_input_methods.find(input_method_id_to_switch) !=
486 state->extra_input_methods.end());
487 descriptor = &(state->extra_input_methods[input_method_id_to_switch]);
488 } else {
489 descriptor =
490 util_.GetInputMethodDescriptorFromId(input_method_id_to_switch);
491 if (!descriptor)
492 LOG(ERROR) << "Unknown input method id: " << input_method_id_to_switch;
493 }
494 DCHECK(descriptor);
495 return descriptor;
496 }
497
498 void InputMethodManagerImpl::ChangeInputMethodInternal(
499 const InputMethodDescriptor& descriptor,
500 bool show_message,
501 bool notify_menu) {
502 // No need to switch input method when terminating.
503 if (ui_session_ == STATE_TERMINATING)
504 return;
505
331 if (candidate_window_controller_.get()) 506 if (candidate_window_controller_.get())
332 candidate_window_controller_->Hide(); 507 candidate_window_controller_->Hide();
333 508
334 // TODO(komatsu): Check if it is necessary to perform the above routine 509 if (notify_menu) {
335 // when the current input method is equal to |input_method_id_to_swich|.
336 if (current_input_method_.id() != input_method_id_to_switch) {
337 // Clear property list. Property list would be updated by 510 // Clear property list. Property list would be updated by
338 // extension IMEs via InputMethodEngine::(Set|Update)MenuItems. 511 // extension IMEs via InputMethodEngine::(Set|Update)MenuItems.
339 // If the current input method is a keyboard layout, empty 512 // If the current input method is a keyboard layout, empty
340 // properties are sufficient. 513 // properties are sufficient.
341 const ash::ime::InputMethodMenuItemList empty_menu_item_list; 514 const ash::ime::InputMethodMenuItemList empty_menu_item_list;
342 ash::ime::InputMethodMenuManager* input_method_menu_manager = 515 ash::ime::InputMethodMenuManager* input_method_menu_manager =
343 ash::ime::InputMethodMenuManager::GetInstance(); 516 ash::ime::InputMethodMenuManager::GetInstance();
344 input_method_menu_manager->SetCurrentInputMethodMenuItemList( 517 input_method_menu_manager->SetCurrentInputMethodMenuItemList(
345 empty_menu_item_list); 518 empty_menu_item_list);
346
347 const InputMethodDescriptor* descriptor = NULL;
348 if (extension_ime_util::IsExtensionIME(input_method_id_to_switch)) {
349 DCHECK(extra_input_methods_.find(input_method_id_to_switch) !=
350 extra_input_methods_.end());
351 descriptor = &(extra_input_methods_[input_method_id_to_switch]);
352 } else {
353 descriptor =
354 util_.GetInputMethodDescriptorFromId(input_method_id_to_switch);
355 if (!descriptor)
356 LOG(ERROR) << "Unknown input method id: " << input_method_id_to_switch;
357 }
358 DCHECK(descriptor);
359
360 previous_input_method_ = current_input_method_;
361 current_input_method_ = *descriptor;
362 } 519 }
363 520
364 // Disable the current engine handler. 521 // Disable the current engine handler.
365 IMEEngineHandlerInterface* engine = 522 IMEEngineHandlerInterface* engine =
366 IMEBridge::Get()->GetCurrentEngineHandler(); 523 IMEBridge::Get()->GetCurrentEngineHandler();
367 if (engine) 524 if (engine)
368 engine->Disable(); 525 engine->Disable();
369 526
370 // Configure the next engine handler. 527 // Configure the next engine handler.
371 // This must be after |current_input_method_| has been set to new input 528 // This must be after |current_input_method| has been set to new input
372 // method, because engine's Enable() method needs to access it. 529 // method, because engine's Enable() method needs to access it.
373 const std::string& extension_id = 530 const std::string& extension_id =
374 extension_ime_util::GetExtensionIDFromInputMethodID( 531 extension_ime_util::GetExtensionIDFromInputMethodID(descriptor.id());
375 input_method_id_to_switch);
376 const std::string& component_id = 532 const std::string& component_id =
377 extension_ime_util::GetComponentIDByInputMethodID( 533 extension_ime_util::GetComponentIDByInputMethodID(descriptor.id());
378 input_method_id_to_switch);
379 engine = engine_map_[extension_id]; 534 engine = engine_map_[extension_id];
535
380 IMEBridge::Get()->SetCurrentEngineHandler(engine); 536 IMEBridge::Get()->SetCurrentEngineHandler(engine);
537
381 if (engine) 538 if (engine)
382 engine->Enable(component_id); 539 engine->Enable(component_id);
383 540
384 // Change the keyboard layout to a preferred layout for the input method. 541 // Change the keyboard layout to a preferred layout for the input method.
385 if (!keyboard_->SetCurrentKeyboardLayoutByName( 542 if (!keyboard_->SetCurrentKeyboardLayoutByName(
386 current_input_method_.GetPreferredKeyboardLayout())) { 543 descriptor.GetPreferredKeyboardLayout())) {
387 LOG(ERROR) << "Failed to change keyboard layout to " 544 LOG(ERROR) << "Failed to change keyboard layout to "
388 << current_input_method_.GetPreferredKeyboardLayout(); 545 << descriptor.GetPreferredKeyboardLayout();
389 } 546 }
390 547
391 // Update input method indicators (e.g. "US", "DV") in Chrome windows. 548 // Update input method indicators (e.g. "US", "DV") in Chrome windows.
392 FOR_EACH_OBSERVER(InputMethodManager::Observer, 549 FOR_EACH_OBSERVER(InputMethodManager::Observer,
393 observers_, 550 observers_,
394 InputMethodChanged(this, show_message)); 551 InputMethodChanged(this, show_message));
395 return true;
396 } 552 }
397 553
398 void InputMethodManagerImpl::LoadNecessaryComponentExtensions() { 554 void InputMethodManagerImpl::LoadNecessaryComponentExtensions(
399 // Load component extensions but also update |active_input_method_ids_| as 555 InputMethodManagerImpl::State* state) {
556 // Load component extensions but also update |active_input_method_ids| as
400 // some component extension IMEs may have been removed from the Chrome OS 557 // some component extension IMEs may have been removed from the Chrome OS
401 // image. If specified component extension IME no longer exists, falling back 558 // image. If specified component extension IME no longer exists, falling back
402 // to an existing IME. 559 // to an existing IME.
560 DCHECK(state);
403 std::vector<std::string> unfiltered_input_method_ids; 561 std::vector<std::string> unfiltered_input_method_ids;
404 unfiltered_input_method_ids.swap(active_input_method_ids_); 562 unfiltered_input_method_ids.swap(state->active_input_method_ids);
405 for (size_t i = 0; i < unfiltered_input_method_ids.size(); ++i) { 563 for (size_t i = 0; i < unfiltered_input_method_ids.size(); ++i) {
406 if (!extension_ime_util::IsComponentExtensionIME( 564 if (!extension_ime_util::IsComponentExtensionIME(
407 unfiltered_input_method_ids[i])) { 565 unfiltered_input_method_ids[i])) {
408 // Legacy IMEs or xkb layouts are alwayes active. 566 // Legacy IMEs or xkb layouts are alwayes active.
409 active_input_method_ids_.push_back(unfiltered_input_method_ids[i]); 567 state->active_input_method_ids.push_back(unfiltered_input_method_ids[i]);
410 } else if (component_extension_ime_manager_->IsWhitelisted( 568 } else if (component_extension_ime_manager_->IsWhitelisted(
411 unfiltered_input_method_ids[i])) { 569 unfiltered_input_method_ids[i])) {
412 component_extension_ime_manager_->LoadComponentExtensionIME( 570 component_extension_ime_manager_->LoadComponentExtensionIME(
413 unfiltered_input_method_ids[i]); 571 state->profile, unfiltered_input_method_ids[i]);
414 active_input_method_ids_.push_back(unfiltered_input_method_ids[i]); 572 state->active_input_method_ids.push_back(unfiltered_input_method_ids[i]);
415 } 573 }
416 } 574 }
417 } 575 }
418 576
419 void InputMethodManagerImpl::ActivateInputMethodMenuItem( 577 void InputMethodManagerImpl::ActivateInputMethodMenuItem(
420 const std::string& key) { 578 const std::string& key) {
421 DCHECK(!key.empty()); 579 DCHECK(!key.empty());
422 580
423 if (ash::ime::InputMethodMenuManager::GetInstance()-> 581 if (ash::ime::InputMethodMenuManager::GetInstance()->
424 HasInputMethodMenuItemForKey(key)) { 582 HasInputMethodMenuItemForKey(key)) {
425 IMEEngineHandlerInterface* engine = 583 IMEEngineHandlerInterface* engine =
426 IMEBridge::Get()->GetCurrentEngineHandler(); 584 IMEBridge::Get()->GetCurrentEngineHandler();
427 if (engine) 585 if (engine)
428 engine->PropertyActivate(key); 586 engine->PropertyActivate(key);
429 return; 587 return;
430 } 588 }
431 589
432 DVLOG(1) << "ActivateInputMethodMenuItem: unknown key: " << key; 590 DVLOG(1) << "ActivateInputMethodMenuItem: unknown key: " << key;
433 } 591 }
434 592
435 void InputMethodManagerImpl::AddInputMethodExtension( 593 void InputMethodManagerImpl::State::AddInputMethodExtension(
436 const std::string& extension_id, 594 const std::string& extension_id,
437 const InputMethodDescriptors& descriptors, 595 const InputMethodDescriptors& descriptors,
438 InputMethodEngineInterface* engine) { 596 InputMethodEngineInterface* engine) {
439 if (state_ == STATE_TERMINATING) 597 if (manager_->ui_session_ == STATE_TERMINATING)
440 return; 598 return;
441 599
442 DCHECK(engine); 600 DCHECK(engine);
443 601
444 engine_map_[extension_id] = engine; 602 manager_->engine_map_[extension_id] = engine;
445
446 if (extension_id == extension_ime_util::GetExtensionIDFromInputMethodID(
447 current_input_method_.id())) {
448 IMEBridge::Get()->SetCurrentEngineHandler(engine);
449 engine->Enable(extension_ime_util::GetComponentIDByInputMethodID(
450 current_input_method_.id()));
451 }
452 603
453 bool contain = false; 604 bool contain = false;
454 for (size_t i = 0; i < descriptors.size(); i++) { 605 for (size_t i = 0; i < descriptors.size(); i++) {
455 const InputMethodDescriptor& descriptor = descriptors[i]; 606 const InputMethodDescriptor& descriptor = descriptors[i];
456 const std::string& id = descriptor.id(); 607 const std::string& id = descriptor.id();
457 extra_input_methods_[id] = descriptor; 608 extra_input_methods[id] = descriptor;
458 if (Contains(enabled_extension_imes_, id)) { 609 if (Contains(enabled_extension_imes, id)) {
459 if (!Contains(active_input_method_ids_, id)) { 610 if (!Contains(active_input_method_ids, id)) {
460 active_input_method_ids_.push_back(id); 611 active_input_method_ids.push_back(id);
461 } else { 612 } else {
462 DVLOG(1) << "AddInputMethodExtension: already added: " << id << ", " 613 DVLOG(1) << "AddInputMethodExtension: already added: " << id << ", "
463 << descriptor.name(); 614 << descriptor.name();
464 } 615 }
465 contain = true; 616 contain = true;
466 } 617 }
467 } 618 }
468 619
469 // Ensure that the input method daemon is running. 620 if (IsActive()) {
470 if (contain) 621 if (extension_id == extension_ime_util::GetExtensionIDFromInputMethodID(
471 MaybeInitializeCandidateWindowController(); 622 current_input_method.id())) {
623 IMEBridge::Get()->SetCurrentEngineHandler(engine);
624 engine->Enable(extension_ime_util::GetComponentIDByInputMethodID(
625 current_input_method.id()));
626 }
627
628 // Ensure that the input method daemon is running.
629 if (contain)
630 manager_->MaybeInitializeCandidateWindowController();
631 }
472 } 632 }
473 633
474 void InputMethodManagerImpl::RemoveInputMethodExtension( 634 void InputMethodManagerImpl::State::RemoveInputMethodExtension(
475 const std::string& extension_id) { 635 const std::string& extension_id) {
476 // Remove the active input methods with |extension_id|. 636 // Remove the active input methods with |extension_id|.
477 std::vector<std::string> new_active_input_method_ids; 637 std::vector<std::string> new_active_input_method_ids;
478 for (size_t i = 0; i < active_input_method_ids_.size(); ++i) { 638 for (size_t i = 0; i < active_input_method_ids.size(); ++i) {
479 if (extension_id != extension_ime_util::GetExtensionIDFromInputMethodID( 639 if (extension_id != extension_ime_util::GetExtensionIDFromInputMethodID(
480 active_input_method_ids_[i])) 640 active_input_method_ids[i]))
481 new_active_input_method_ids.push_back(active_input_method_ids_[i]); 641 new_active_input_method_ids.push_back(active_input_method_ids[i]);
482 } 642 }
483 active_input_method_ids_.swap(new_active_input_method_ids); 643 active_input_method_ids.swap(new_active_input_method_ids);
484 644
485 // Remove the extra input methods with |extension_id|. 645 // Remove the extra input methods with |extension_id|.
486 std::map<std::string, InputMethodDescriptor> new_extra_input_methods; 646 std::map<std::string, InputMethodDescriptor> new_extra_input_methods;
487 for (std::map<std::string, InputMethodDescriptor>::iterator i = 647 for (std::map<std::string, InputMethodDescriptor>::iterator i =
488 extra_input_methods_.begin(); 648 extra_input_methods.begin();
489 i != extra_input_methods_.end(); 649 i != extra_input_methods.end();
490 ++i) { 650 ++i) {
491 if (extension_id != 651 if (extension_id !=
492 extension_ime_util::GetExtensionIDFromInputMethodID(i->first)) 652 extension_ime_util::GetExtensionIDFromInputMethodID(i->first))
493 new_extra_input_methods[i->first] = i->second; 653 new_extra_input_methods[i->first] = i->second;
494 } 654 }
495 extra_input_methods_.swap(new_extra_input_methods); 655 extra_input_methods.swap(new_extra_input_methods);
496 656
497 if (IMEBridge::Get()->GetCurrentEngineHandler() == engine_map_[extension_id]) 657 if (IsActive()) {
498 IMEBridge::Get()->SetCurrentEngineHandler(NULL); 658 if (IMEBridge::Get()->GetCurrentEngineHandler() ==
499 engine_map_.erase(extension_id); 659 manager_->engine_map_[extension_id]) {
660 IMEBridge::Get()->SetCurrentEngineHandler(NULL);
661 }
662 manager_->engine_map_.erase(extension_id);
663 }
500 664
501 // No need to switch input method when terminating. 665 // If |current_input_method| is no longer in |active_input_method_ids|,
502 if (state_ != STATE_TERMINATING) { 666 // switch to the first one in |active_input_method_ids|.
503 // If |current_input_method| is no longer in |active_input_method_ids_|, 667 ChangeInputMethod(current_input_method.id(), false);
Shu Chen 2014/08/13 16:15:33 why remove the check: if (state_ != STATE_TERMINAT
Alexander Alekseev 2014/08/13 23:29:32 The idea was to move these checks to IMM. But you'
504 // switch to the first one in |active_input_method_ids_|.
505 ChangeInputMethod(current_input_method_.id());
506 }
507 } 668 }
508 669
509 void InputMethodManagerImpl::GetInputMethodExtensions( 670 void InputMethodManagerImpl::State::GetInputMethodExtensions(
510 InputMethodDescriptors* result) { 671 InputMethodDescriptors* result) {
511 // Build the extension input method descriptors from the extra input 672 // Build the extension input method descriptors from the extra input
512 // methods cache |extra_input_methods_|. 673 // methods cache |extra_input_methods|.
513 std::map<std::string, InputMethodDescriptor>::iterator iter; 674 std::map<std::string, InputMethodDescriptor>::iterator iter;
514 for (iter = extra_input_methods_.begin(); iter != extra_input_methods_.end(); 675 for (iter = extra_input_methods.begin(); iter != extra_input_methods.end();
515 ++iter) { 676 ++iter) {
516 if (extension_ime_util::IsExtensionIME(iter->first)) 677 if (extension_ime_util::IsExtensionIME(iter->first))
517 result->push_back(iter->second); 678 result->push_back(iter->second);
518 } 679 }
519 } 680 }
520 681
521 void InputMethodManagerImpl::SetEnabledExtensionImes( 682 void InputMethodManagerImpl::State::SetEnabledExtensionImes(
522 std::vector<std::string>* ids) { 683 std::vector<std::string>* ids) {
523 enabled_extension_imes_.clear(); 684 enabled_extension_imes.clear();
524 enabled_extension_imes_.insert(enabled_extension_imes_.end(), 685 enabled_extension_imes.insert(
525 ids->begin(), 686 enabled_extension_imes.end(), ids->begin(), ids->end());
526 ids->end());
527
528 bool active_imes_changed = false; 687 bool active_imes_changed = false;
529 688
530 for (std::map<std::string, InputMethodDescriptor>::iterator extra_iter = 689 for (std::map<std::string, InputMethodDescriptor>::iterator extra_iter =
531 extra_input_methods_.begin(); extra_iter != extra_input_methods_.end(); 690 extra_input_methods.begin();
691 extra_iter != extra_input_methods.end();
532 ++extra_iter) { 692 ++extra_iter) {
533 if (extension_ime_util::IsComponentExtensionIME( 693 if (extension_ime_util::IsComponentExtensionIME(extra_iter->first))
534 extra_iter->first))
535 continue; // Do not filter component extension. 694 continue; // Do not filter component extension.
536 std::vector<std::string>::iterator active_iter = std::find( 695 std::vector<std::string>::iterator active_iter =
537 active_input_method_ids_.begin(), active_input_method_ids_.end(), 696 std::find(active_input_method_ids.begin(),
538 extra_iter->first); 697 active_input_method_ids.end(),
698 extra_iter->first);
539 699
540 bool active = active_iter != active_input_method_ids_.end(); 700 bool active = active_iter != active_input_method_ids.end();
541 bool enabled = Contains(enabled_extension_imes_, extra_iter->first); 701 bool enabled = Contains(enabled_extension_imes, extra_iter->first);
542 702
543 if (active && !enabled) 703 if (active && !enabled)
544 active_input_method_ids_.erase(active_iter); 704 active_input_method_ids.erase(active_iter);
545 705
546 if (!active && enabled) 706 if (!active && enabled)
547 active_input_method_ids_.push_back(extra_iter->first); 707 active_input_method_ids.push_back(extra_iter->first);
548 708
549 if (active == !enabled) 709 if (active == !enabled)
550 active_imes_changed = true; 710 active_imes_changed = true;
551 } 711 }
552 712
553 if (active_imes_changed) { 713 if (IsActive() && active_imes_changed) {
554 MaybeInitializeCandidateWindowController(); 714 manager_->MaybeInitializeCandidateWindowController();
555 715
556 // If |current_input_method| is no longer in |active_input_method_ids_|, 716 // If |current_input_method| is no longer in |active_input_method_ids|,
557 // switch to the first one in |active_input_method_ids_|. 717 // switch to the first one in |active_input_method_ids|.
558 ChangeInputMethod(current_input_method_.id()); 718 ChangeInputMethod(current_input_method.id(), false);
559 } 719 }
560 } 720 }
561 721
562 void InputMethodManagerImpl::SetInputMethodLoginDefaultFromVPD( 722 void InputMethodManagerImpl::State::SetInputMethodLoginDefaultFromVPD(
563 const std::string& locale, const std::string& oem_layout) { 723 const std::string& locale,
724 const std::string& oem_layout) {
564 std::string layout; 725 std::string layout;
565 if (!oem_layout.empty()) { 726 if (!oem_layout.empty()) {
566 // If the OEM layout information is provided, use it. 727 // If the OEM layout information is provided, use it.
567 layout = oem_layout; 728 layout = oem_layout;
568 } else { 729 } else {
569 // Otherwise, determine the hardware keyboard from the locale. 730 // Otherwise, determine the hardware keyboard from the locale.
570 std::vector<std::string> input_method_ids; 731 std::vector<std::string> input_method_ids;
571 if (util_.GetInputMethodIdsFromLanguageCode( 732 if (manager_->util_.GetInputMethodIdsFromLanguageCode(
572 locale, 733 locale,
573 chromeos::input_method::kKeyboardLayoutsOnly, 734 chromeos::input_method::kKeyboardLayoutsOnly,
574 &input_method_ids)) { 735 &input_method_ids)) {
575 // The output list |input_method_ids| is sorted by popularity, hence 736 // The output list |input_method_ids| is sorted by popularity, hence
576 // input_method_ids[0] now contains the most popular keyboard layout 737 // input_method_ids[0] now contains the most popular keyboard layout
577 // for the given locale. 738 // for the given locale.
578 DCHECK_GE(input_method_ids.size(), 1U); 739 DCHECK_GE(input_method_ids.size(), 1U);
579 layout = input_method_ids[0]; 740 layout = input_method_ids[0];
580 } 741 }
581 } 742 }
582 743
583 if (layout.empty()) 744 if (layout.empty())
584 return; 745 return;
585 746
586 std::vector<std::string> layouts; 747 std::vector<std::string> layouts;
587 base::SplitString(layout, ',', &layouts); 748 base::SplitString(layout, ',', &layouts);
588 MigrateInputMethods(&layouts); 749 manager_->MigrateInputMethods(&layouts);
589 750
590 PrefService* prefs = g_browser_process->local_state(); 751 PrefService* prefs = g_browser_process->local_state();
591 prefs->SetString(prefs::kHardwareKeyboardLayout, JoinString(layouts, ",")); 752 prefs->SetString(prefs::kHardwareKeyboardLayout, JoinString(layouts, ","));
592 753
593 // This asks the file thread to save the prefs (i.e. doesn't block). 754 // This asks the file thread to save the prefs (i.e. doesn't block).
594 // The latest values of Local State reside in memory so we can safely 755 // The latest values of Local State reside in memory so we can safely
595 // get the value of kHardwareKeyboardLayout even if the data is not 756 // get the value of kHardwareKeyboardLayout even if the data is not
596 // yet saved to disk. 757 // yet saved to disk.
597 prefs->CommitPendingWrite(); 758 prefs->CommitPendingWrite();
598 759
599 util_.UpdateHardwareLayoutCache(); 760 manager_->util_.UpdateHardwareLayoutCache();
600 761
601 EnableLoginLayouts(locale, layouts); 762 EnableLoginLayouts(locale, layouts);
602 LoadNecessaryComponentExtensions(); 763 manager_->LoadNecessaryComponentExtensions(this);
603 } 764 }
604 765
605 void InputMethodManagerImpl::SetInputMethodLoginDefault() { 766 void InputMethodManagerImpl::State::SetInputMethodLoginDefault() {
606 // Set up keyboards. For example, when |locale| is "en-US", enable US qwerty 767 // Set up keyboards. For example, when |locale| is "en-US", enable US qwerty
607 // and US dvorak keyboard layouts. 768 // and US dvorak keyboard layouts.
608 if (g_browser_process && g_browser_process->local_state()) { 769 if (g_browser_process && g_browser_process->local_state()) {
609 const std::string locale = g_browser_process->GetApplicationLocale(); 770 const std::string locale = g_browser_process->GetApplicationLocale();
610 // If the preferred keyboard for the login screen has been saved, use it. 771 // If the preferred keyboard for the login screen has been saved, use it.
611 PrefService* prefs = g_browser_process->local_state(); 772 PrefService* prefs = g_browser_process->local_state();
612 std::string initial_input_method_id = 773 std::string initial_input_method_id =
613 prefs->GetString(chromeos::language_prefs::kPreferredKeyboardLayout); 774 prefs->GetString(chromeos::language_prefs::kPreferredKeyboardLayout);
614 std::vector<std::string> input_methods_to_be_enabled; 775 std::vector<std::string> input_methods_to_be_enabled;
615 if (initial_input_method_id.empty()) { 776 if (initial_input_method_id.empty()) {
616 // If kPreferredKeyboardLayout is not specified, use the hardware layout. 777 // If kPreferredKeyboardLayout is not specified, use the hardware layout.
617 input_methods_to_be_enabled = util_.GetHardwareLoginInputMethodIds(); 778 input_methods_to_be_enabled =
779 manager_->util_.GetHardwareLoginInputMethodIds();
618 } else { 780 } else {
619 input_methods_to_be_enabled.push_back(initial_input_method_id); 781 input_methods_to_be_enabled.push_back(initial_input_method_id);
620 } 782 }
621 EnableLoginLayouts(locale, input_methods_to_be_enabled); 783 EnableLoginLayouts(locale, input_methods_to_be_enabled);
622 LoadNecessaryComponentExtensions(); 784 manager_->LoadNecessaryComponentExtensions(this);
623 } 785 }
624 } 786 }
625 787
626 bool InputMethodManagerImpl::SwitchToNextInputMethod() { 788 bool InputMethodManagerImpl::State::SwitchToNextInputMethod() {
627 // Sanity checks. 789 // Sanity checks.
628 if (active_input_method_ids_.empty()) { 790 if (active_input_method_ids.empty()) {
629 DVLOG(1) << "active input method is empty"; 791 DVLOG(1) << "active input method is empty";
630 return false; 792 return false;
631 } 793 }
632 794
633 if (current_input_method_.id().empty()) { 795 if (current_input_method.id().empty()) {
634 DVLOG(1) << "current_input_method_ is unknown"; 796 DVLOG(1) << "current_input_method is unknown";
635 return false; 797 return false;
636 } 798 }
637 799
638 // Do not consume key event if there is only one input method is enabled. 800 // Do not consume key event if there is only one input method is enabled.
639 // Ctrl+Space or Alt+Shift may be used by other application. 801 // Ctrl+Space or Alt+Shift may be used by other application.
640 if (active_input_method_ids_.size() == 1) 802 if (active_input_method_ids.size() == 1)
641 return false; 803 return false;
642 804
643 // Find the next input method and switch to it. 805 // Find the next input method and switch to it.
644 SwitchToNextInputMethodInternal(active_input_method_ids_, 806 SwitchToNextInputMethodInternal(active_input_method_ids,
645 current_input_method_.id()); 807 current_input_method.id());
646 return true; 808 return true;
647 } 809 }
648 810
649 bool InputMethodManagerImpl::SwitchToPreviousInputMethod( 811 bool InputMethodManagerImpl::State::SwitchToPreviousInputMethod(
650 const ui::Accelerator& accelerator) { 812 const ui::Accelerator& accelerator) {
651 // Sanity check. 813 // Sanity check.
652 if (active_input_method_ids_.empty()) { 814 if (active_input_method_ids.empty()) {
653 DVLOG(1) << "active input method is empty"; 815 DVLOG(1) << "active input method is empty";
654 return false; 816 return false;
655 } 817 }
656 818
657 // Do not consume key event if there is only one input method is enabled. 819 // Do not consume key event if there is only one input method is enabled.
658 // Ctrl+Space or Alt+Shift may be used by other application. 820 // Ctrl+Space or Alt+Shift may be used by other application.
659 if (active_input_method_ids_.size() == 1) 821 if (active_input_method_ids.size() == 1)
660 return false; 822 return false;
661 823
662 if (accelerator.type() == ui::ET_KEY_RELEASED) 824 if (accelerator.type() == ui::ET_KEY_RELEASED)
663 return true; 825 return true;
664 826
665 if (previous_input_method_.id().empty() || 827 if (previous_input_method.id().empty() ||
666 previous_input_method_.id() == current_input_method_.id()) { 828 previous_input_method.id() == current_input_method.id()) {
667 return SwitchToNextInputMethod(); 829 return SwitchToNextInputMethod();
668 } 830 }
669 831
670 std::vector<std::string>::const_iterator iter = 832 std::vector<std::string>::const_iterator iter =
671 std::find(active_input_method_ids_.begin(), 833 std::find(active_input_method_ids.begin(),
672 active_input_method_ids_.end(), 834 active_input_method_ids.end(),
673 previous_input_method_.id()); 835 previous_input_method.id());
674 if (iter == active_input_method_ids_.end()) { 836 if (iter == active_input_method_ids.end()) {
675 // previous_input_method_ is not supported. 837 // previous_input_method is not supported.
676 return SwitchToNextInputMethod(); 838 return SwitchToNextInputMethod();
677 } 839 }
678 ChangeInputMethodInternal(*iter, true); 840 ChangeInputMethod(*iter, true);
841
679 return true; 842 return true;
680 } 843 }
681 844
682 bool InputMethodManagerImpl::SwitchInputMethod( 845 bool InputMethodManagerImpl::State::SwitchInputMethod(
683 const ui::Accelerator& accelerator) { 846 const ui::Accelerator& accelerator) {
684 // Sanity check. 847 // Sanity check.
685 if (active_input_method_ids_.empty()) { 848 if (active_input_method_ids.empty()) {
686 DVLOG(1) << "active input method is empty"; 849 DVLOG(1) << "active input method is empty";
687 return false; 850 return false;
688 } 851 }
689 852
690 // Get the list of input method ids for the |accelerator|. For example, get 853 // Get the list of input method ids for the |accelerator|. For example, get
691 // { "mozc-hangul", "xkb:kr:kr104:kor" } for ui::VKEY_DBE_SBCSCHAR. 854 // { "mozc-hangul", "xkb:kr:kr104:kor" } for ui::VKEY_DBE_SBCSCHAR.
692 std::vector<std::string> input_method_ids_to_switch; 855 std::vector<std::string> input_method_ids_to_switch;
693 switch (accelerator.key_code()) { 856 switch (accelerator.key_code()) {
694 case ui::VKEY_CONVERT: // Henkan key on JP106 keyboard 857 case ui::VKEY_CONVERT: // Henkan key on JP106 keyboard
695 input_method_ids_to_switch.push_back( 858 input_method_ids_to_switch.push_back(
(...skipping 13 matching lines...) Expand all
709 default: 872 default:
710 NOTREACHED(); 873 NOTREACHED();
711 break; 874 break;
712 } 875 }
713 if (input_method_ids_to_switch.empty()) { 876 if (input_method_ids_to_switch.empty()) {
714 DVLOG(1) << "Unexpected VKEY: " << accelerator.key_code(); 877 DVLOG(1) << "Unexpected VKEY: " << accelerator.key_code();
715 return false; 878 return false;
716 } 879 }
717 880
718 // Obtain the intersection of input_method_ids_to_switch and 881 // Obtain the intersection of input_method_ids_to_switch and
719 // active_input_method_ids_. The order of IDs in active_input_method_ids_ is 882 // active_input_method_ids. The order of IDs in active_input_method_ids is
720 // preserved. 883 // preserved.
721 std::vector<std::string> ids; 884 std::vector<std::string> ids;
722 for (size_t i = 0; i < input_method_ids_to_switch.size(); ++i) { 885 for (size_t i = 0; i < input_method_ids_to_switch.size(); ++i) {
723 const std::string& id = input_method_ids_to_switch[i]; 886 const std::string& id = input_method_ids_to_switch[i];
724 if (Contains(active_input_method_ids_, id)) 887 if (Contains(active_input_method_ids, id))
725 ids.push_back(id); 888 ids.push_back(id);
726 } 889 }
727 if (ids.empty()) { 890 if (ids.empty()) {
728 // No input method for the accelerator is active. For example, we should 891 // No input method for the accelerator is active. For example, we should
729 // just ignore VKEY_HANGUL when mozc-hangul is not active. 892 // just ignore VKEY_HANGUL when mozc-hangul is not active.
730 return false; 893 return false;
731 } 894 }
732 895
733 SwitchToNextInputMethodInternal(ids, current_input_method_.id()); 896 SwitchToNextInputMethodInternal(ids, current_input_method.id());
734 return true; // consume the accelerator. 897 return true; // consume the accelerator.
735 } 898 }
736 899
737 void InputMethodManagerImpl::SwitchToNextInputMethodInternal( 900 void InputMethodManagerImpl::State::SwitchToNextInputMethodInternal(
738 const std::vector<std::string>& input_method_ids, 901 const std::vector<std::string>& input_method_ids,
739 const std::string& current_input_method_id) { 902 const std::string& current_input_methodid) {
740 std::vector<std::string>::const_iterator iter = 903 std::vector<std::string>::const_iterator iter = std::find(
741 std::find(input_method_ids.begin(), 904 input_method_ids.begin(), input_method_ids.end(), current_input_methodid);
742 input_method_ids.end(),
743 current_input_method_id);
744 if (iter != input_method_ids.end()) 905 if (iter != input_method_ids.end())
745 ++iter; 906 ++iter;
746 if (iter == input_method_ids.end()) 907 if (iter == input_method_ids.end())
747 iter = input_method_ids.begin(); 908 iter = input_method_ids.begin();
748 ChangeInputMethodInternal(*iter, true); 909 ChangeInputMethod(*iter, true);
749 } 910 }
750 911
751 InputMethodDescriptor InputMethodManagerImpl::GetCurrentInputMethod() const { 912 InputMethodDescriptor InputMethodManagerImpl::State::GetCurrentInputMethod()
752 if (current_input_method_.id().empty()) 913 const {
914 if (current_input_method.id().empty())
753 return InputMethodUtil::GetFallbackInputMethodDescriptor(); 915 return InputMethodUtil::GetFallbackInputMethodDescriptor();
754 916
755 return current_input_method_; 917 return current_input_method;
756 } 918 }
757 919
758 bool InputMethodManagerImpl::IsISOLevel5ShiftUsedByCurrentInputMethod() const { 920 bool InputMethodManagerImpl::IsISOLevel5ShiftUsedByCurrentInputMethod() const {
759 return keyboard_->IsISOLevel5ShiftAvailable(); 921 return keyboard_->IsISOLevel5ShiftAvailable();
760 } 922 }
761 923
762 bool InputMethodManagerImpl::IsAltGrUsedByCurrentInputMethod() const { 924 bool InputMethodManagerImpl::IsAltGrUsedByCurrentInputMethod() const {
763 return keyboard_->IsAltGrAvailable(); 925 return keyboard_->IsAltGrAvailable();
764 } 926 }
765 927
766 ImeKeyboard* InputMethodManagerImpl::GetImeKeyboard() { 928 ImeKeyboard* InputMethodManagerImpl::GetImeKeyboard() {
767 return keyboard_.get(); 929 return keyboard_.get();
768 } 930 }
769 931
770 InputMethodUtil* InputMethodManagerImpl::GetInputMethodUtil() { 932 InputMethodUtil* InputMethodManagerImpl::GetInputMethodUtil() {
771 return &util_; 933 return &util_;
772 } 934 }
773 935
774 ComponentExtensionIMEManager* 936 ComponentExtensionIMEManager*
775 InputMethodManagerImpl::GetComponentExtensionIMEManager() { 937 InputMethodManagerImpl::GetComponentExtensionIMEManager() {
776 DCHECK(thread_checker_.CalledOnValidThread()); 938 DCHECK(thread_checker_.CalledOnValidThread());
777 return component_extension_ime_manager_.get(); 939 return component_extension_ime_manager_.get();
778 } 940 }
779 941
780 void InputMethodManagerImpl::InitializeComponentExtension() { 942 scoped_refptr<InputMethodManager::State>
943 InputMethodManagerImpl::GetDefaultState(Profile* profile) {
944 scoped_refptr<InputMethodManagerImpl::State> state = default_states_[profile];
945 if (!state) {
946 // Profile can be NULL in tests.
947 state = new InputMethodManagerImpl::State(this, profile);
948 default_states_[profile] = state;
949 }
950 return scoped_refptr<InputMethodManager::State>(state.get());
951 }
952
953 void InputMethodManagerImpl::InitializeComponentExtension(Profile* profile) {
Shu Chen 2014/08/13 16:15:33 This method will be gone in cl: https://codereview
Alexander Alekseev 2014/08/13 23:29:32 This call happens after PostProfileInit for signin
781 scoped_ptr<ComponentExtensionIMEManagerDelegate> delegate( 954 scoped_ptr<ComponentExtensionIMEManagerDelegate> delegate(
782 new ComponentExtensionIMEManagerImpl()); 955 new ComponentExtensionIMEManagerImpl());
783 component_extension_ime_manager_->Initialize(delegate.Pass()); 956 component_extension_ime_manager_->Initialize(delegate.Pass());
784 957
785 util_.ResetInputMethods( 958 util_.ResetInputMethods(
786 component_extension_ime_manager_->GetAllIMEAsInputMethodDescriptor()); 959 component_extension_ime_manager_->GetAllIMEAsInputMethodDescriptor());
960
961 scoped_refptr<State> state(
962 static_cast<State*>(GetDefaultState(profile).get()));
963 if (state->active_input_method_ids.size()) {
964 ReconfigureIMFramework(state.get());
965 if (state->IsActive())
966 ChangeInputMethodInternal(state->current_input_method,
967 false /* show_message */,
968 true /* notify_menu */);
969 }
787 } 970 }
788 971
789 void InputMethodManagerImpl::SetCandidateWindowControllerForTesting( 972 void InputMethodManagerImpl::SetCandidateWindowControllerForTesting(
790 CandidateWindowController* candidate_window_controller) { 973 CandidateWindowController* candidate_window_controller) {
791 candidate_window_controller_.reset(candidate_window_controller); 974 candidate_window_controller_.reset(candidate_window_controller);
792 candidate_window_controller_->AddObserver(this); 975 candidate_window_controller_->AddObserver(this);
793 } 976 }
794 977
795 void InputMethodManagerImpl::SetImeKeyboardForTesting(ImeKeyboard* keyboard) { 978 void InputMethodManagerImpl::SetImeKeyboardForTesting(ImeKeyboard* keyboard) {
796 keyboard_.reset(keyboard); 979 keyboard_.reset(keyboard);
(...skipping 18 matching lines...) Expand all
815 candidate_window_observers_, 998 candidate_window_observers_,
816 CandidateWindowOpened(this)); 999 CandidateWindowOpened(this));
817 } 1000 }
818 1001
819 void InputMethodManagerImpl::CandidateWindowClosed() { 1002 void InputMethodManagerImpl::CandidateWindowClosed() {
820 FOR_EACH_OBSERVER(InputMethodManager::CandidateWindowObserver, 1003 FOR_EACH_OBSERVER(InputMethodManager::CandidateWindowObserver,
821 candidate_window_observers_, 1004 candidate_window_observers_,
822 CandidateWindowClosed(this)); 1005 CandidateWindowClosed(this));
823 } 1006 }
824 1007
825 void InputMethodManagerImpl::OnScreenLocked() { 1008 bool InputMethodManagerImpl::State::InputMethodIsActivated(
826 saved_previous_input_method_ = previous_input_method_;
827 saved_current_input_method_ = current_input_method_;
828 saved_active_input_method_ids_ = active_input_method_ids_;
829
830 std::set<std::string> added_ids_;
831
832 const std::vector<std::string>& hardware_keyboard_ids =
833 util_.GetHardwareLoginInputMethodIds();
834
835 active_input_method_ids_.clear();
836 for (size_t i = 0; i < saved_active_input_method_ids_.size(); ++i) {
837 const std::string& input_method_id = saved_active_input_method_ids_[i];
838 // Skip if it's not a keyboard layout. Drop input methods including
839 // extension ones.
840 if (!IsLoginKeyboard(input_method_id) ||
841 added_ids_.find(input_method_id) != added_ids_.end())
842 continue;
843 active_input_method_ids_.push_back(input_method_id);
844 added_ids_.insert(input_method_id);
845 }
846
847 // We'll add the hardware keyboard if it's not included in
848 // |active_input_method_ids_| so that the user can always use the hardware
849 // keyboard on the screen locker.
850 for (size_t i = 0; i < hardware_keyboard_ids.size(); ++i) {
851 if (added_ids_.find(hardware_keyboard_ids[i]) == added_ids_.end()) {
852 active_input_method_ids_.push_back(hardware_keyboard_ids[i]);
853 added_ids_.insert(hardware_keyboard_ids[i]);
854 }
855 }
856
857 ChangeInputMethod(current_input_method_.id());
858 }
859
860 void InputMethodManagerImpl::OnScreenUnlocked() {
861 previous_input_method_ = saved_previous_input_method_;
862 current_input_method_ = saved_current_input_method_;
863 active_input_method_ids_ = saved_active_input_method_ids_;
864
865 ChangeInputMethod(current_input_method_.id());
866 }
867
868 bool InputMethodManagerImpl::InputMethodIsActivated(
869 const std::string& input_method_id) { 1009 const std::string& input_method_id) {
870 return Contains(active_input_method_ids_, input_method_id); 1010 return Contains(active_input_method_ids, input_method_id);
871 } 1011 }
872 1012
873 void InputMethodManagerImpl::MaybeInitializeCandidateWindowController() { 1013 void InputMethodManagerImpl::MaybeInitializeCandidateWindowController() {
874 if (candidate_window_controller_.get()) 1014 if (candidate_window_controller_.get())
875 return; 1015 return;
876 1016
877 candidate_window_controller_.reset( 1017 candidate_window_controller_.reset(
878 CandidateWindowController::CreateCandidateWindowController()); 1018 CandidateWindowController::CreateCandidateWindowController());
879 candidate_window_controller_->AddObserver(this); 1019 candidate_window_controller_->AddObserver(this);
880 } 1020 }
881 1021
882 } // namespace input_method 1022 } // namespace input_method
883 } // namespace chromeos 1023 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698