Chromium Code Reviews| 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 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 101 const char* keyboard_id; | 101 const char* keyboard_id; |
| 102 const char* ime_id; | 102 const char* ime_id; |
| 103 } kMigrationHangulKeyboardToInputMethodID[] = { | 103 } kMigrationHangulKeyboardToInputMethodID[] = { |
| 104 { "2", "_comp_ime_bdgdidmhaijohebebipajioienkglgfohangul_2set" }, | 104 { "2", "_comp_ime_bdgdidmhaijohebebipajioienkglgfohangul_2set" }, |
| 105 { "3f", "_comp_ime_bdgdidmhaijohebebipajioienkglgfohangul_3setfinal" }, | 105 { "3f", "_comp_ime_bdgdidmhaijohebebipajioienkglgfohangul_3setfinal" }, |
| 106 { "39", "_comp_ime_bdgdidmhaijohebebipajioienkglgfohangul_3set390" }, | 106 { "39", "_comp_ime_bdgdidmhaijohebebipajioienkglgfohangul_3set390" }, |
| 107 { "3s", "_comp_ime_bdgdidmhaijohebebipajioienkglgfohangul_3setnoshift" }, | 107 { "3s", "_comp_ime_bdgdidmhaijohebebipajioienkglgfohangul_3setnoshift" }, |
| 108 { "ro", "_comp_ime_bdgdidmhaijohebebipajioienkglgfohangul_romaja" }, | 108 { "ro", "_comp_ime_bdgdidmhaijohebebipajioienkglgfohangul_romaja" }, |
| 109 }; | 109 }; |
| 110 | 110 |
| 111 static bool ContainsTwoLetterLanguageCode( | |
| 112 const std::vector<InputMethodManagerImpl::TwoLetterLanguageCode>& all, | |
| 113 const std::string& lang) { | |
| 114 if (lang.size() < 2) { | |
| 115 return false; | |
| 116 } | |
| 117 return std::binary_search( | |
| 118 all.begin(), | |
| 119 all.end(), | |
| 120 InputMethodManagerImpl::TwoLetterLanguageCode(lang.c_str())); | |
| 121 } | |
| 122 | |
| 123 // A list of languages having full 26 latin letter set on keyboard. | |
| 124 // (If all input methods of a given language can be used at login screen.) | |
| 125 const char* kFullLatinKeyboardLanguageList[] = { | |
|
Seigo Nonaka
2013/07/11 09:43:56
Please notice that there is "xkb:jp::jpn" keyboard
Alexander Alekseev
2013/07/12 20:10:49
That's a good point. I've been waiting for somethi
| |
| 126 "ca", // Catalan | |
| 127 "cs", // Czech | |
| 128 "da", // Danish | |
| 129 "de", // German | |
| 130 "en", // English | |
| 131 "es", // Spanish | |
| 132 "et", // Estonian | |
| 133 "fi", // Finnish | |
| 134 "fr", // French | |
| 135 "hr", // Croatian | |
| 136 "hu", // Hungarian | |
| 137 "is", // Icelandic | |
| 138 "it", // Italian | |
| 139 "lt", // Lithuanian | |
| 140 "lv", // Latvian | |
| 141 "nb", // Norwegian (Bokmal) | |
| 142 "nl", // Dutch | |
| 143 "pl", // Polish | |
| 144 "pt", // Portuguese | |
| 145 "ro", // Romanian | |
| 146 "sk", // Slovak | |
| 147 "sl", // Slovenian | |
| 148 "sv", // Swedish | |
| 149 "tr", // Turkish | |
| 150 }; | |
| 151 | |
| 111 } // namespace | 152 } // namespace |
| 112 | 153 |
| 154 // Note, that language may be longer than 2 letters. Like "en-US". | |
| 155 // but ContainsTwoLetterLanguageCode() compares only 2 first letters. | |
| 156 bool InputMethodManagerImpl::IsLanguageFullLatinKeyboard( | |
| 157 const std::string& lang) const { | |
| 158 return ContainsTwoLetterLanguageCode(full_latin_keyboard_languages_, lang); | |
| 159 } | |
| 160 | |
| 161 InputMethodManagerImpl::TwoLetterLanguageCode::TwoLetterLanguageCode( | |
| 162 const char* lang) | |
| 163 : val(base::ToLowerASCII(lang[0]) * 256 + base::ToLowerASCII(lang[1])) {} | |
| 164 | |
| 113 InputMethodManagerImpl::InputMethodManagerImpl( | 165 InputMethodManagerImpl::InputMethodManagerImpl( |
| 114 scoped_ptr<InputMethodDelegate> delegate) | 166 scoped_ptr<InputMethodDelegate> delegate) |
| 115 : delegate_(delegate.Pass()), | 167 : delegate_(delegate.Pass()), |
| 116 state_(STATE_LOGIN_SCREEN), | 168 state_(STATE_LOGIN_SCREEN), |
| 117 util_(delegate_.get(), GetSupportedInputMethods()), | 169 util_(delegate_.get(), GetSupportedInputMethods()), |
| 118 component_extension_ime_manager_(new ComponentExtensionIMEManager()), | 170 component_extension_ime_manager_(new ComponentExtensionIMEManager()), |
| 119 weak_ptr_factory_(this) { | 171 weak_ptr_factory_(this) { |
| 120 IBusDaemonController::GetInstance()->AddObserver(this); | 172 IBusDaemonController::GetInstance()->AddObserver(this); |
| 173 | |
| 174 full_latin_keyboard_languages_.reserve( | |
| 175 arraysize(kFullLatinKeyboardLanguageList)); | |
| 176 | |
| 177 for (size_t i = 0; i < arraysize(kFullLatinKeyboardLanguageList); ++i) { | |
| 178 full_latin_keyboard_languages_.push_back( | |
| 179 TwoLetterLanguageCode(kFullLatinKeyboardLanguageList[i])); | |
| 180 } | |
| 181 std::sort(full_latin_keyboard_languages_.begin(), | |
| 182 full_latin_keyboard_languages_.end()); | |
| 121 } | 183 } |
| 122 | 184 |
| 123 InputMethodManagerImpl::~InputMethodManagerImpl() { | 185 InputMethodManagerImpl::~InputMethodManagerImpl() { |
| 124 if (ibus_controller_.get()) | 186 if (ibus_controller_.get()) |
| 125 ibus_controller_->RemoveObserver(this); | 187 ibus_controller_->RemoveObserver(this); |
| 126 IBusDaemonController::GetInstance()->RemoveObserver(this); | 188 IBusDaemonController::GetInstance()->RemoveObserver(this); |
| 127 if (candidate_window_controller_.get()) { | 189 if (candidate_window_controller_.get()) { |
| 128 candidate_window_controller_->RemoveObserver(this); | 190 candidate_window_controller_->RemoveObserver(this); |
| 129 candidate_window_controller_->Shutdown(); | 191 candidate_window_controller_->Shutdown(); |
| 130 } | 192 } |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 200 } | 262 } |
| 201 if (result->empty()) { | 263 if (result->empty()) { |
| 202 // Initially |active_input_method_ids_| is empty. browser_tests might take | 264 // Initially |active_input_method_ids_| is empty. browser_tests might take |
| 203 // this path. | 265 // this path. |
| 204 result->push_back( | 266 result->push_back( |
| 205 InputMethodUtil::GetFallbackInputMethodDescriptor()); | 267 InputMethodUtil::GetFallbackInputMethodDescriptor()); |
| 206 } | 268 } |
| 207 return result.Pass(); | 269 return result.Pass(); |
| 208 } | 270 } |
| 209 | 271 |
| 272 const std::vector<std::string>& | |
| 273 InputMethodManagerImpl::GetActiveInputMethodIds() const { | |
| 274 return active_input_method_ids_; | |
| 275 } | |
| 276 | |
| 210 size_t InputMethodManagerImpl::GetNumActiveInputMethods() const { | 277 size_t InputMethodManagerImpl::GetNumActiveInputMethods() const { |
| 211 return active_input_method_ids_.size(); | 278 return active_input_method_ids_.size(); |
| 212 } | 279 } |
| 213 | 280 |
| 214 void InputMethodManagerImpl::EnableLayouts(const std::string& language_code, | 281 void InputMethodManagerImpl::EnableLayouts(const std::string& language_code, |
| 215 const std::string& initial_layout) { | 282 const std::string& initial_layout) { |
| 216 if (state_ == STATE_TERMINATING) | 283 if (state_ == STATE_TERMINATING) |
| 217 return; | 284 return; |
| 218 | 285 |
| 219 std::vector<std::string> candidates; | 286 std::vector<std::string> candidates; |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 243 // Not efficient, but should be fine, as the two vectors are very | 310 // Not efficient, but should be fine, as the two vectors are very |
| 244 // short (2-5 items). | 311 // short (2-5 items). |
| 245 if (!Contains(layouts, candidate)) | 312 if (!Contains(layouts, candidate)) |
| 246 layouts.push_back(candidate); | 313 layouts.push_back(candidate); |
| 247 } | 314 } |
| 248 | 315 |
| 249 active_input_method_ids_.swap(layouts); | 316 active_input_method_ids_.swap(layouts); |
| 250 ChangeInputMethod(initial_layout); // you can pass empty |initial_layout|. | 317 ChangeInputMethod(initial_layout); // you can pass empty |initial_layout|. |
| 251 } | 318 } |
| 252 | 319 |
| 320 // Adds new input method to given list. | |
| 321 bool InputMethodManagerImpl::EnableInputMethodImpl( | |
| 322 const std::string& input_method_id, | |
| 323 std::vector<std::string>& new_active_input_method_ids) const { | |
| 324 if (!util_.IsValidInputMethodId(input_method_id)) { | |
| 325 DVLOG(1) << "EnableInputMethod: Invalid ID: " << input_method_id; | |
| 326 return false; | |
| 327 } | |
| 328 | |
| 329 if (!Contains(new_active_input_method_ids, input_method_id)) | |
| 330 new_active_input_method_ids.push_back(input_method_id); | |
| 331 | |
| 332 return true; | |
| 333 } | |
| 334 | |
| 335 // starts or stops the system input method framework as needed. | |
|
Mattias Nissler (ping if slow)
2013/07/11 10:05:49
nit: Starts
Alexander Alekseev
2013/07/12 20:10:49
Done.
| |
| 336 void InputMethodManagerImpl::ReconfigureIMFramework() { | |
| 337 if (component_extension_ime_manager_->IsInitialized()) | |
| 338 LoadNecessaryComponentExtensions(); | |
| 339 | |
| 340 if (ContainOnlyKeyboardLayout(active_input_method_ids_)) { | |
|
Mattias Nissler (ping if slow)
2013/07/11 10:05:49
nit: ContainOnlyKeyboardLayout should be ContainsO
Alexander Alekseev
2013/07/12 20:10:49
Done.
| |
| 341 // Do NOT call ibus_controller_->Stop(); here to work around a crash issue | |
| 342 // at crosbug.com/27051. | |
|
Mattias Nissler (ping if slow)
2013/07/11 10:05:49
nit: new code should refer to crbug.com IMHO
Alexander Alekseev
2013/07/12 20:10:49
Done.
| |
| 343 // TODO(yusukes): We can safely call Stop(); here once crosbug.com/26443 | |
| 344 // is implemented. | |
| 345 } else { | |
| 346 MaybeInitializeCandidateWindowController(); | |
| 347 IBusDaemonController::GetInstance()->Start(); | |
| 348 } | |
| 349 } | |
| 350 | |
| 351 bool InputMethodManagerImpl::EnableInputMethod( | |
| 352 const std::string& input_method_id) { | |
| 353 if (!EnableInputMethodImpl(input_method_id, active_input_method_ids_)) | |
| 354 return false; | |
| 355 | |
| 356 ReconfigureIMFramework(); | |
| 357 return true; | |
| 358 } | |
| 359 | |
| 253 bool InputMethodManagerImpl::EnableInputMethods( | 360 bool InputMethodManagerImpl::EnableInputMethods( |
| 254 const std::vector<std::string>& new_active_input_method_ids) { | 361 const std::vector<std::string>& new_active_input_method_ids) { |
| 255 if (state_ == STATE_TERMINATING) | 362 if (state_ == STATE_TERMINATING) |
| 256 return false; | 363 return false; |
| 257 | 364 |
| 258 // Filter unknown or obsolete IDs. | 365 // Filter unknown or obsolete IDs. |
| 259 std::vector<std::string> new_active_input_method_ids_filtered; | 366 std::vector<std::string> new_active_input_method_ids_filtered; |
| 260 | 367 |
| 261 for (size_t i = 0; i < new_active_input_method_ids.size(); ++i) { | 368 for (size_t i = 0; i < new_active_input_method_ids.size(); ++i) |
| 262 const std::string& input_method_id = new_active_input_method_ids[i]; | 369 EnableInputMethodImpl(new_active_input_method_ids[i], |
| 263 if (util_.IsValidInputMethodId(input_method_id)) | 370 new_active_input_method_ids_filtered); |
| 264 new_active_input_method_ids_filtered.push_back(input_method_id); | |
| 265 else | |
| 266 DVLOG(1) << "EnableInputMethods: Invalid ID: " << input_method_id; | |
| 267 } | |
| 268 | 371 |
| 269 if (new_active_input_method_ids_filtered.empty()) { | 372 if (new_active_input_method_ids_filtered.empty()) { |
| 270 DVLOG(1) << "EnableInputMethods: No valid input method ID"; | 373 DVLOG(1) << "EnableInputMethods: No valid input method ID"; |
| 271 return false; | 374 return false; |
| 272 } | 375 } |
| 273 | 376 |
| 274 // Copy extension IDs to |new_active_input_method_ids_filtered|. We have to | 377 // Copy extension IDs to |new_active_input_method_ids_filtered|. We have to |
| 275 // keep relative order of the extension input method IDs. | 378 // keep relative order of the extension input method IDs. |
| 276 for (size_t i = 0; i < active_input_method_ids_.size(); ++i) { | 379 for (size_t i = 0; i < active_input_method_ids_.size(); ++i) { |
| 277 const std::string& input_method_id = active_input_method_ids_[i]; | 380 const std::string& input_method_id = active_input_method_ids_[i]; |
| 278 if (extension_ime_util::IsExtensionIME(input_method_id)) | 381 if (extension_ime_util::IsExtensionIME(input_method_id)) |
| 279 new_active_input_method_ids_filtered.push_back(input_method_id); | 382 new_active_input_method_ids_filtered.push_back(input_method_id); |
| 280 } | 383 } |
| 281 active_input_method_ids_.swap(new_active_input_method_ids_filtered); | 384 active_input_method_ids_.swap(new_active_input_method_ids_filtered); |
| 282 | 385 |
| 283 if (component_extension_ime_manager_->IsInitialized()) | 386 ReconfigureIMFramework(); |
| 284 LoadNecessaryComponentExtensions(); | |
| 285 | |
| 286 if (ContainOnlyKeyboardLayout(active_input_method_ids_)) { | |
| 287 // Do NOT call ibus_controller_->Stop(); here to work around a crash issue | |
| 288 // at crosbug.com/27051. | |
| 289 // TODO(yusukes): We can safely call Stop(); here once crosbug.com/26443 | |
| 290 // is implemented. | |
| 291 } else { | |
| 292 MaybeInitializeCandidateWindowController(); | |
| 293 IBusDaemonController::GetInstance()->Start(); | |
| 294 } | |
| 295 | 387 |
| 296 // If |current_input_method| is no longer in |active_input_method_ids_|, | 388 // If |current_input_method| is no longer in |active_input_method_ids_|, |
| 297 // ChangeInputMethod() picks the first one in |active_input_method_ids_|. | 389 // ChangeInputMethod() picks the first one in |active_input_method_ids_|. |
| 298 ChangeInputMethod(current_input_method_.id()); | 390 ChangeInputMethod(current_input_method_.id()); |
| 299 return true; | 391 return true; |
| 300 } | 392 } |
| 301 | 393 |
| 302 bool InputMethodManagerImpl::MigrateOldInputMethods( | 394 bool InputMethodManagerImpl::MigrateOldInputMethods( |
| 303 std::vector<std::string>* input_method_ids) { | 395 std::vector<std::string>* input_method_ids) { |
| 304 bool rewritten = false; | 396 bool rewritten = false; |
| (...skipping 633 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 938 else | 1030 else |
| 939 DVLOG(1) << "Failed to initialize the candidate window controller"; | 1031 DVLOG(1) << "Failed to initialize the candidate window controller"; |
| 940 } | 1032 } |
| 941 | 1033 |
| 942 bool InputMethodManagerImpl::IsIBusConnectionAlive() { | 1034 bool InputMethodManagerImpl::IsIBusConnectionAlive() { |
| 943 return DBusThreadManager::Get() && DBusThreadManager::Get()->GetIBusClient(); | 1035 return DBusThreadManager::Get() && DBusThreadManager::Get()->GetIBusClient(); |
| 944 } | 1036 } |
| 945 | 1037 |
| 946 } // namespace input_method | 1038 } // namespace input_method |
| 947 } // namespace chromeos | 1039 } // namespace chromeos |
| OLD | NEW |