| 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_util.h" | 5 #include "chrome/browser/chromeos/input_method/input_method_util.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <functional> | 8 #include <functional> |
| 9 #include <map> | 9 #include <map> |
| 10 #include <utility> | 10 #include <utility> |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 119 { "ja", "us", "_comp_ime_fpfbhcjppmaeaijcidgiibchfbnhbeljnacl_mozc_us" }, | 119 { "ja", "us", "_comp_ime_fpfbhcjppmaeaijcidgiibchfbnhbeljnacl_mozc_us" }, |
| 120 { "ja", "jp", "_comp_ime_fpfbhcjppmaeaijcidgiibchfbnhbeljnacl_mozc_jp" }, | 120 { "ja", "jp", "_comp_ime_fpfbhcjppmaeaijcidgiibchfbnhbeljnacl_mozc_jp" }, |
| 121 { "zh-CN", "us", "_comp_ime_nmblnjkfdkabgdofidlkienfnnbjhnabzh-t-i0-pinyin" }, | 121 { "zh-CN", "us", "_comp_ime_nmblnjkfdkabgdofidlkienfnnbjhnabzh-t-i0-pinyin" }, |
| 122 { "zh-TW", "us", | 122 { "zh-TW", "us", |
| 123 "_comp_ime_goedamlknlnjaengojinmfgpmdjmkooozh-hant-t-i0-und" }, | 123 "_comp_ime_goedamlknlnjaengojinmfgpmdjmkooozh-hant-t-i0-und" }, |
| 124 { "th", "us", "_comp_ime_jhffeifommiaekmbkkjlpmilogcfdohpvkd_th" }, | 124 { "th", "us", "_comp_ime_jhffeifommiaekmbkkjlpmilogcfdohpvkd_th" }, |
| 125 { "vi", "us", "_comp_ime_jhffeifommiaekmbkkjlpmilogcfdohpvkd_vi_tcvn" }, | 125 { "vi", "us", "_comp_ime_jhffeifommiaekmbkkjlpmilogcfdohpvkd_vi_tcvn" }, |
| 126 { "vi", "us", "_comp_ime_jhffeifommiaekmbkkjlpmilogcfdohpvkd_vi_tcvn" }, | 126 { "vi", "us", "_comp_ime_jhffeifommiaekmbkkjlpmilogcfdohpvkd_vi_tcvn" }, |
| 127 }; | 127 }; |
| 128 | 128 |
| 129 struct _XkbConfigItem { |
| 130 std::string layout_name; |
| 131 std::string indicator; |
| 132 bool allow_login; |
| 133 }; |
| 134 |
| 135 // The map from xkb layout to the indicator text. |
| 136 // Refer to crbug.com/349829. |
| 137 const _XkbConfigItem kXkbIndicators[] = { |
| 138 {"am", "AM"}, |
| 139 {"be", "BE"}, |
| 140 {"be", "BE"}, |
| 141 {"be", "BE"}, |
| 142 {"bg", "BG"}, |
| 143 {"bg(phonetic)", "BG"}, |
| 144 {"br", "BR"}, |
| 145 {"by", "BY"}, |
| 146 {"ca", "CA"}, |
| 147 {"ca(eng)", "CA"}, |
| 148 {"ca(multix)", "CA"}, |
| 149 {"ch", "CH"}, |
| 150 {"ch(fr)", "CH"}, |
| 151 {"cz", "CZ"}, |
| 152 {"cz(qwerty)", "CS"}, |
| 153 {"de", "DE"}, |
| 154 {"de(neo)", "NEO"}, |
| 155 {"dk", "DK"}, |
| 156 {"ee", "EE"}, |
| 157 {"es", "ES"}, |
| 158 {"es(cat)", "CAS"}, |
| 159 {"fi", "FI"}, |
| 160 {"fr", "FR"}, |
| 161 {"gb(dvorak)", "DV"}, |
| 162 {"gb(extd)", "GB"}, |
| 163 {"ge", "GE"}, |
| 164 {"gr", "GR"}, |
| 165 {"hr", "HR"}, |
| 166 {"hu", "HU"}, |
| 167 {"il", "IL"}, |
| 168 {"is", "IS"}, |
| 169 {"it", "IT"}, |
| 170 {"jp", "JA"}, |
| 171 {"latam", "LA"}, |
| 172 {"lt", "LT"}, |
| 173 {"lv(apostrophe)", "LV"}, |
| 174 {"mn", "MN"}, |
| 175 {"no", "NO"}, |
| 176 {"pl", "PL"}, |
| 177 {"pt", "PT"}, |
| 178 {"ro", "RO"}, |
| 179 {"rs", "RS"}, |
| 180 {"ru", "RU"}, |
| 181 {"ru(phonetic)", "RU"}, |
| 182 {"se", "SE"}, |
| 183 {"si", "SI"}, |
| 184 {"sk", "SK"}, |
| 185 {"tr", "TR"}, |
| 186 {"ua", "UA"}, |
| 187 {"us", "US"}, |
| 188 {"us(altgr-intl)", "EXTD"}, |
| 189 {"us(colemak)", "CO"}, |
| 190 {"us(dvorak)", "DV"}, |
| 191 {"us(intl)", "INTL"}, |
| 192 }; |
| 193 |
| 129 } // namespace | 194 } // namespace |
| 130 | 195 |
| 131 namespace chromeos { | 196 namespace chromeos { |
| 132 | 197 |
| 133 extern const char* kExtensionImePrefix; | 198 extern const char* kExtensionImePrefix; |
| 134 | 199 |
| 135 namespace input_method { | 200 namespace input_method { |
| 136 | 201 |
| 137 namespace { | 202 namespace { |
| 138 | 203 |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 294 ReloadInternalMaps(); | 359 ReloadInternalMaps(); |
| 295 | 360 |
| 296 // Initialize a map from English string to Chrome string resource ID as well. | 361 // Initialize a map from English string to Chrome string resource ID as well. |
| 297 for (size_t i = 0; i < kEnglishToResourceIdArraySize; ++i) { | 362 for (size_t i = 0; i < kEnglishToResourceIdArraySize; ++i) { |
| 298 const EnglishToResouceId& map_entry = kEnglishToResourceIdArray[i]; | 363 const EnglishToResouceId& map_entry = kEnglishToResourceIdArray[i]; |
| 299 const bool result = english_to_resource_id_.insert(std::make_pair( | 364 const bool result = english_to_resource_id_.insert(std::make_pair( |
| 300 map_entry.english_string_from_ibus, map_entry.resource_id)).second; | 365 map_entry.english_string_from_ibus, map_entry.resource_id)).second; |
| 301 DCHECK(result) << "Duplicated string is found: " | 366 DCHECK(result) << "Duplicated string is found: " |
| 302 << map_entry.english_string_from_ibus; | 367 << map_entry.english_string_from_ibus; |
| 303 } | 368 } |
| 369 |
| 370 // Initialize the map from xkb layout to indicator text. |
| 371 for (size_t i = 0; i < arraysize(kXkbIndicators); ++i) { |
| 372 xkb_layout_to_indicator_[kXkbIndicators[i].layout_name] = |
| 373 kXkbIndicators[i].indicator; |
| 374 } |
| 304 } | 375 } |
| 305 | 376 |
| 306 InputMethodUtil::~InputMethodUtil() { | 377 InputMethodUtil::~InputMethodUtil() { |
| 307 } | 378 } |
| 308 | 379 |
| 309 bool InputMethodUtil::TranslateStringInternal( | 380 bool InputMethodUtil::TranslateStringInternal( |
| 310 const std::string& english_string, base::string16 *out_string) const { | 381 const std::string& english_string, base::string16 *out_string) const { |
| 311 DCHECK(out_string); | 382 DCHECK(out_string); |
| 312 HashType::const_iterator iter = english_to_resource_id_.find(english_string); | 383 HashType::const_iterator iter = english_to_resource_id_.find(english_string); |
| 313 if (iter == english_to_resource_id_.end()) { | 384 if (iter == english_to_resource_id_.end()) { |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 391 // Check special cases first. | 462 // Check special cases first. |
| 392 for (size_t i = 0; i < kMappingFromIdToIndicatorTextLen; ++i) { | 463 for (size_t i = 0; i < kMappingFromIdToIndicatorTextLen; ++i) { |
| 393 if (kMappingFromIdToIndicatorText[i].input_method_id == | 464 if (kMappingFromIdToIndicatorText[i].input_method_id == |
| 394 input_method.id()) { | 465 input_method.id()) { |
| 395 text = base::UTF8ToUTF16(kMappingFromIdToIndicatorText[i].indicator_text); | 466 text = base::UTF8ToUTF16(kMappingFromIdToIndicatorText[i].indicator_text); |
| 396 break; | 467 break; |
| 397 } | 468 } |
| 398 } | 469 } |
| 399 | 470 |
| 400 // Display the keyboard layout name when using a keyboard layout. | 471 // Display the keyboard layout name when using a keyboard layout. |
| 401 if (text.empty() && | 472 if (text.empty() && IsKeyboardLayout(input_method.id())) { |
| 402 IsKeyboardLayout(input_method.id())) { | 473 std::map<std::string, std::string>::const_iterator it = |
| 403 const size_t kMaxKeyboardLayoutNameLen = 2; | 474 xkb_layout_to_indicator_.find(GetKeyboardLayoutName( |
| 404 const base::string16 keyboard_layout = | 475 input_method.id())); |
| 405 base::UTF8ToUTF16(GetKeyboardLayoutName(input_method.id())); | 476 if (it != xkb_layout_to_indicator_.end()) |
| 406 text = StringToUpperASCII(keyboard_layout).substr( | 477 text = base::UTF8ToUTF16(it->second); |
| 407 0, kMaxKeyboardLayoutNameLen); | |
| 408 } | 478 } |
| 409 | 479 |
| 410 // TODO(yusukes): Some languages have two or more input methods. For example, | 480 // TODO(yusukes): Some languages have two or more input methods. For example, |
| 411 // Thai has 3, Vietnamese has 4. If these input methods could be activated at | 481 // Thai has 3, Vietnamese has 4. If these input methods could be activated at |
| 412 // the same time, we should do either of the following: | 482 // the same time, we should do either of the following: |
| 413 // (1) Add mappings to |kMappingFromIdToIndicatorText| | 483 // (1) Add mappings to |kMappingFromIdToIndicatorText| |
| 414 // (2) Add suffix (1, 2, ...) to |text| when ambiguous. | 484 // (2) Add suffix (1, 2, ...) to |text| when ambiguous. |
| 415 | 485 |
| 416 if (text.empty()) { | 486 if (text.empty()) { |
| 417 const size_t kMaxLanguageNameLen = 2; | 487 const size_t kMaxLanguageNameLen = 2; |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 476 } | 546 } |
| 477 | 547 |
| 478 DCHECK(!text.empty()); | 548 DCHECK(!text.empty()); |
| 479 return text; | 549 return text; |
| 480 } | 550 } |
| 481 | 551 |
| 482 const InputMethodDescriptor* InputMethodUtil::GetInputMethodDescriptorFromId( | 552 const InputMethodDescriptor* InputMethodUtil::GetInputMethodDescriptorFromId( |
| 483 const std::string& input_method_id) const { | 553 const std::string& input_method_id) const { |
| 484 InputMethodIdToDescriptorMap::const_iterator iter | 554 InputMethodIdToDescriptorMap::const_iterator iter |
| 485 = id_to_descriptor_.find(input_method_id); | 555 = id_to_descriptor_.find(input_method_id); |
| 486 if (iter == id_to_descriptor_.end()) { | 556 if (iter == id_to_descriptor_.end()) |
| 487 // If failed to find the descriptor for given id, it may because of the id | |
| 488 // is a component extension xkb id (_comp_ime_...xkb:...). | |
| 489 // So try to convert it to legacy xkb id and find again. | |
| 490 // This hack is mainly for OOBE session, which requires a sync call to get | |
| 491 // the input method descriptor for extension xkb id. | |
| 492 // TODO(shuchen): need to support async wait for component extension | |
| 493 // loading in OOBE session. This hack won't be needed when it's been done. | |
| 494 iter = id_to_descriptor_.find( | |
| 495 extension_ime_util::MaybeGetLegacyXkbId(input_method_id)); | |
| 496 if (iter == id_to_descriptor_.end()) | |
| 497 return NULL; | 557 return NULL; |
| 498 } | |
| 499 return &(iter->second); | 558 return &(iter->second); |
| 500 } | 559 } |
| 501 | 560 |
| 502 bool InputMethodUtil::GetInputMethodIdsFromLanguageCode( | 561 bool InputMethodUtil::GetInputMethodIdsFromLanguageCode( |
| 503 const std::string& normalized_language_code, | 562 const std::string& normalized_language_code, |
| 504 InputMethodType type, | 563 InputMethodType type, |
| 505 std::vector<std::string>* out_input_method_ids) const { | 564 std::vector<std::string>* out_input_method_ids) const { |
| 506 return GetInputMethodIdsFromLanguageCodeInternal( | 565 return GetInputMethodIdsFromLanguageCodeInternal( |
| 507 language_code_to_ids_, | 566 language_code_to_ids_, |
| 508 normalized_language_code, type, out_input_method_ids); | 567 normalized_language_code, type, out_input_method_ids); |
| (...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 701 | 760 |
| 702 bool InputMethodUtil::IsLoginKeyboard(const std::string& input_method_id) | 761 bool InputMethodUtil::IsLoginKeyboard(const std::string& input_method_id) |
| 703 const { | 762 const { |
| 704 const InputMethodDescriptor* ime = | 763 const InputMethodDescriptor* ime = |
| 705 GetInputMethodDescriptorFromId(input_method_id); | 764 GetInputMethodDescriptorFromId(input_method_id); |
| 706 return ime ? ime->is_login_keyboard() : false; | 765 return ime ? ime->is_login_keyboard() : false; |
| 707 } | 766 } |
| 708 | 767 |
| 709 void InputMethodUtil::SetComponentExtensions( | 768 void InputMethodUtil::SetComponentExtensions( |
| 710 const InputMethodDescriptors& imes) { | 769 const InputMethodDescriptors& imes) { |
| 711 component_extension_ime_id_to_descriptor_.clear(); | |
| 712 for (size_t i = 0; i < imes.size(); ++i) { | 770 for (size_t i = 0; i < imes.size(); ++i) { |
| 713 const InputMethodDescriptor& input_method = imes.at(i); | 771 const InputMethodDescriptor& input_method = imes[i]; |
| 714 DCHECK(!input_method.language_codes().empty()); | 772 DCHECK(!input_method.language_codes().empty()); |
| 715 const std::string language_code = input_method.language_codes().at(0); | 773 const std::vector<std::string>& language_codes = |
| 716 id_to_language_code_.insert( | 774 input_method.language_codes(); |
| 717 std::make_pair(input_method.id(), language_code)); | 775 id_to_language_code_[input_method.id()] = language_codes[0]; |
| 718 id_to_descriptor_.insert( | 776 id_to_descriptor_[input_method.id()] = input_method; |
| 719 std::make_pair(input_method.id(), input_method)); | 777 for (size_t j = 0; j < language_codes.size(); ++j) { |
| 778 language_code_to_ids_.insert( |
| 779 std::make_pair(language_codes[j], input_method.id())); |
| 780 } |
| 720 } | 781 } |
| 721 } | 782 } |
| 722 | 783 |
| 723 InputMethodDescriptor InputMethodUtil::GetFallbackInputMethodDescriptor() { | 784 InputMethodDescriptor InputMethodUtil::GetFallbackInputMethodDescriptor() { |
| 724 std::vector<std::string> layouts; | 785 std::vector<std::string> layouts; |
| 725 layouts.push_back("us"); | 786 layouts.push_back("us"); |
| 726 std::vector<std::string> languages; | 787 std::vector<std::string> languages; |
| 727 languages.push_back("en-US"); | 788 languages.push_back("en-US"); |
| 728 return InputMethodDescriptor( | 789 return InputMethodDescriptor( |
| 729 extension_ime_util::GetInputMethodIDByKeyboardLayout("xkb:us::eng"), | 790 extension_ime_util::GetInputMethodIDByKeyboardLayout("xkb:us::eng"), |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 765 if (IsKeyboardLayout(input_method.id())) { | 826 if (IsKeyboardLayout(input_method.id())) { |
| 766 xkb_id_to_descriptor_.insert( | 827 xkb_id_to_descriptor_.insert( |
| 767 std::make_pair(input_method.GetPreferredKeyboardLayout(), | 828 std::make_pair(input_method.GetPreferredKeyboardLayout(), |
| 768 input_method)); | 829 input_method)); |
| 769 } | 830 } |
| 770 } | 831 } |
| 771 } | 832 } |
| 772 | 833 |
| 773 } // namespace input_method | 834 } // namespace input_method |
| 774 } // namespace chromeos | 835 } // namespace chromeos |
| OLD | NEW |