Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/component_extension_ime_manager_i mpl.h" | 5 #include "chrome/browser/chromeos/input_method/component_extension_ime_manager_i mpl.h" |
| 6 | 6 |
| 7 #include <algorithm> | |
| 8 | |
| 7 #include "base/file_util.h" | 9 #include "base/file_util.h" |
| 10 #include "base/json/json_string_value_serializer.h" | |
| 8 #include "base/logging.h" | 11 #include "base/logging.h" |
| 9 #include "base/path_service.h" | 12 #include "base/path_service.h" |
| 10 #include "chrome/browser/extensions/component_loader.h" | 13 #include "chrome/browser/extensions/component_loader.h" |
| 11 #include "chrome/browser/extensions/extension_service.h" | 14 #include "chrome/browser/extensions/extension_service.h" |
| 12 #include "chrome/browser/profiles/profile.h" | 15 #include "chrome/browser/profiles/profile.h" |
| 13 #include "chrome/browser/profiles/profile_manager.h" | 16 #include "chrome/browser/profiles/profile_manager.h" |
| 14 #include "chrome/common/chrome_paths.h" | 17 #include "chrome/common/chrome_paths.h" |
| 15 #include "chrome/common/extensions/extension_constants.h" | 18 #include "chrome/common/extensions/extension_constants.h" |
| 16 #include "chrome/common/extensions/extension_file_util.h" | 19 #include "chrome/common/extensions/extension_file_util.h" |
| 17 #include "chromeos/ime/extension_ime_util.h" | 20 #include "chromeos/ime/extension_ime_util.h" |
| 18 #include "content/public/browser/browser_thread.h" | |
| 19 #include "extensions/browser/extension_system.h" | 21 #include "extensions/browser/extension_system.h" |
| 20 #include "extensions/common/extension.h" | 22 #include "extensions/common/extension.h" |
| 21 #include "extensions/common/extension_l10n_util.h" | 23 #include "extensions/common/extension_l10n_util.h" |
| 22 #include "extensions/common/file_util.h" | |
| 23 #include "extensions/common/manifest_constants.h" | 24 #include "extensions/common/manifest_constants.h" |
| 25 #include "grit/browser_resources.h" | |
| 26 #include "grit/generated_resources.h" | |
| 24 #include "ui/base/l10n/l10n_util.h" | 27 #include "ui/base/l10n/l10n_util.h" |
| 28 #include "ui/base/resource/resource_bundle.h" | |
| 25 | 29 |
| 26 namespace chromeos { | 30 namespace chromeos { |
| 27 | 31 |
| 28 namespace { | 32 namespace { |
| 29 | 33 |
| 30 struct WhitelistedComponentExtensionIME { | 34 struct WhitelistedComponentExtensionIME { |
| 31 const char* id; | 35 const char* id; |
| 32 const char* path; | 36 int manifest_resource_id; |
| 33 } whitelisted_component_extension[] = { | 37 } whitelisted_component_extension[] = { |
| 34 { | 38 {// ChromeOS Hangul Input. |
| 35 // ChromeOS Hangul Input. | 39 extension_ime_util::kHangulExtensionId, IDR_HANGUL_MANIFEST, |
| 36 extension_ime_util::kHangulExtensionId, | 40 }, |
| 37 "/usr/share/chromeos-assets/input_methods/hangul", | 41 {// Official Google XKB Input. |
| 38 }, | 42 extension_ime_util::kXkbExtensionId, IDR_GOOGLE_XKB_MANIFEST, |
| 39 #if defined(OFFICIAL_BUILD) | 43 }, |
| 40 { | 44 {// Google input tools. |
| 41 // Official Google XKB Input. | 45 extension_ime_util::kT13nExtensionId, IDR_GOOGLE_INPUT_TOOLS_MANIFEST, |
| 42 extension_ime_util::kXkbExtensionId, | 46 }, |
| 43 "/usr/share/chromeos-assets/input_methods/google_xkb", | 47 {// Open-sourced ChromeOS xkb extension. |
| 44 }, | 48 extension_ime_util::kXkbExtensionId, IDR_XKB_MANIFEST, |
| 45 { | 49 }, |
| 46 // Google input tools. | 50 {// Open-sourced ChromeOS Keyboards extension. |
| 47 extension_ime_util::kT13nExtensionId, | 51 extension_ime_util::kM17nExtensionId, IDR_M17N_MANIFEST, |
| 48 "/usr/share/chromeos-assets/input_methods/input_tools", | 52 }, |
| 49 }, | 53 {// Open-sourced Pinyin Chinese Input Method. |
| 50 #else | 54 extension_ime_util::kChinesePinyinExtensionId, IDR_PINYIN_MANIFEST, |
| 51 { | 55 }, |
| 52 // Open-sourced ChromeOS xkb extension. | 56 {// Open-sourced Zhuyin Chinese Input Method. |
| 53 extension_ime_util::kXkbExtensionId, | 57 extension_ime_util::kChineseZhuyinExtensionId, IDR_ZHUYIN_MANIFEST, |
| 54 "/usr/share/chromeos-assets/input_methods/xkb", | 58 }, |
| 55 }, | 59 {// Open-sourced Cangjie Chinese Input Method. |
| 56 { | 60 extension_ime_util::kChineseCangjieExtensionId, IDR_CANGJIE_MANIFEST, |
| 57 // Open-sourced ChromeOS Keyboards extension. | 61 }, |
| 58 extension_ime_util::kM17nExtensionId, | 62 {// Japanese Mozc Input. |
| 59 "/usr/share/chromeos-assets/input_methods/keyboard_layouts", | 63 extension_ime_util::kMozcExtensionId, IDR_MOZC_MANIFEST, |
| 60 }, | 64 }, |
| 61 { | 65 {// Braille hardware keyboard IME that works together with ChromeVox. |
| 62 // Open-sourced Pinyin Chinese Input Method. | 66 extension_misc::kBrailleImeExtensionId, IDR_BRAILLE_MANIFEST, |
| 63 extension_ime_util::kChinesePinyinExtensionId, | 67 }, |
| 64 "/usr/share/chromeos-assets/input_methods/pinyin", | |
| 65 }, | |
| 66 { | |
| 67 // Open-sourced Zhuyin Chinese Input Method. | |
| 68 extension_ime_util::kChineseZhuyinExtensionId, | |
| 69 "/usr/share/chromeos-assets/input_methods/zhuyin", | |
| 70 }, | |
| 71 { | |
| 72 // Open-sourced Cangjie Chinese Input Method. | |
| 73 extension_ime_util::kChineseCangjieExtensionId, | |
| 74 "/usr/share/chromeos-assets/input_methods/cangjie", | |
| 75 }, | |
| 76 { | |
| 77 // Japanese Mozc Input. | |
| 78 extension_ime_util::kMozcExtensionId, | |
| 79 "/usr/share/chromeos-assets/input_methods/nacl_mozc", | |
| 80 }, | |
| 81 #endif | |
| 82 { | |
| 83 // Braille hardware keyboard IME that works together with ChromeVox. | |
| 84 extension_misc::kBrailleImeExtensionId, | |
| 85 extension_misc::kBrailleImeExtensionPath, | |
| 86 }, | |
| 87 }; | 68 }; |
| 88 | 69 |
| 70 const struct InputMethodNameMap { | |
| 71 const char* message_name; | |
| 72 int resource_id; | |
| 73 bool operator()(const InputMethodNameMap& m1, | |
| 74 const InputMethodNameMap& m2) const { | |
|
Nico
2014/07/22 17:05:08
Is this for lower bound? Shouldn't this be operato
Shu Chen
2014/07/23 00:56:45
Done.
| |
| 75 return strcmp(m1.message_name, m2.message_name) < 0; | |
| 76 } | |
| 77 } kInputMethodNameMap[] = { | |
| 78 {"__MSG_INPUTMETHOD_ARRAY__", IDS_IME_NAME_INPUTMETHOD_ARRAY}, | |
| 79 {"__MSG_INPUTMETHOD_CANGJIE__", IDS_IME_NAME_INPUTMETHOD_CANGJIE}, | |
| 80 {"__MSG_INPUTMETHOD_DAYI__", IDS_IME_NAME_INPUTMETHOD_DAYI}, | |
| 81 {"__MSG_INPUTMETHOD_HANGUL_2_SET__", | |
| 82 IDS_IME_NAME_INPUTMETHOD_HANGUL_2_SET}, | |
| 83 {"__MSG_INPUTMETHOD_HANGUL_3_SET_390__", | |
| 84 IDS_IME_NAME_INPUTMETHOD_HANGUL_3_SET_390}, | |
| 85 {"__MSG_INPUTMETHOD_HANGUL_3_SET_FINAL__", | |
| 86 IDS_IME_NAME_INPUTMETHOD_HANGUL_3_SET_FINAL}, | |
| 87 {"__MSG_INPUTMETHOD_HANGUL_3_SET_NO_SHIFT__", | |
| 88 IDS_IME_NAME_INPUTMETHOD_HANGUL_3_SET_NO_SHIFT}, | |
| 89 {"__MSG_INPUTMETHOD_HANGUL_AHNMATAE__", | |
| 90 IDS_IME_NAME_INPUTMETHOD_HANGUL_AHNMATAE}, | |
| 91 {"__MSG_INPUTMETHOD_HANGUL_ROMAJA__", | |
| 92 IDS_IME_NAME_INPUTMETHOD_HANGUL_ROMAJA}, | |
| 93 {"__MSG_INPUTMETHOD_MOZC_JP__", IDS_IME_NAME_INPUTMETHOD_MOZC_JP}, | |
| 94 {"__MSG_INPUTMETHOD_MOZC_US__", IDS_IME_NAME_INPUTMETHOD_MOZC_US}, | |
| 95 {"__MSG_INPUTMETHOD_PINYIN__", IDS_IME_NAME_INPUTMETHOD_PINYIN}, | |
| 96 {"__MSG_INPUTMETHOD_QUICK__", IDS_IME_NAME_INPUTMETHOD_QUICK}, | |
| 97 {"__MSG_INPUTMETHOD_TRADITIONAL_PINYIN__", | |
| 98 IDS_IME_NAME_INPUTMETHOD_TRADITIONAL_PINYIN}, | |
| 99 {"__MSG_INPUTMETHOD_WUBI__", IDS_IME_NAME_INPUTMETHOD_WUBI}, | |
| 100 {"__MSG_INPUTMETHOD_ZHUYIN__", IDS_IME_NAME_INPUTMETHOD_ZHUYIN}, | |
| 101 {"__MSG_KEYBOARD_ARABIC__", IDS_IME_NAME_KEYBOARD_ARABIC}, | |
| 102 {"__MSG_KEYBOARD_ARMENIAN_PHONETIC__", | |
| 103 IDS_IME_NAME_KEYBOARD_ARMENIAN_PHONETIC}, | |
| 104 {"__MSG_KEYBOARD_BELARUSIAN__", IDS_IME_NAME_KEYBOARD_BELARUSIAN}, | |
| 105 {"__MSG_KEYBOARD_BELGIAN__", IDS_IME_NAME_KEYBOARD_BELGIAN}, | |
| 106 {"__MSG_KEYBOARD_BENGALI_PHONETIC__", | |
| 107 IDS_IME_NAME_KEYBOARD_BENGALI_PHONETIC}, | |
| 108 {"__MSG_KEYBOARD_BRAZILIAN__", IDS_IME_NAME_KEYBOARD_BRAZILIAN}, | |
| 109 {"__MSG_KEYBOARD_BULGARIAN_PHONETIC__", | |
| 110 IDS_IME_NAME_KEYBOARD_BULGARIAN_PHONETIC}, | |
| 111 {"__MSG_KEYBOARD_BULGARIAN__", IDS_IME_NAME_KEYBOARD_BULGARIAN}, | |
| 112 {"__MSG_KEYBOARD_CANADIAN_ENGLISH__", | |
| 113 IDS_IME_NAME_KEYBOARD_CANADIAN_ENGLISH}, | |
| 114 {"__MSG_KEYBOARD_CANADIAN_FRENCH__", | |
| 115 IDS_IME_NAME_KEYBOARD_CANADIAN_FRENCH}, | |
| 116 {"__MSG_KEYBOARD_CANADIAN_MULTILINGUAL__", | |
| 117 IDS_IME_NAME_KEYBOARD_CANADIAN_MULTILINGUAL}, | |
| 118 {"__MSG_KEYBOARD_CATALAN__", IDS_IME_NAME_KEYBOARD_CATALAN}, | |
| 119 {"__MSG_KEYBOARD_CROATIAN__", IDS_IME_NAME_KEYBOARD_CROATIAN}, | |
| 120 {"__MSG_KEYBOARD_CZECH_QWERTY__", IDS_IME_NAME_KEYBOARD_CZECH_QWERTY}, | |
| 121 {"__MSG_KEYBOARD_CZECH__", IDS_IME_NAME_KEYBOARD_CZECH}, | |
| 122 {"__MSG_KEYBOARD_DANISH__", IDS_IME_NAME_KEYBOARD_DANISH}, | |
| 123 {"__MSG_KEYBOARD_DEVANAGARI_PHONETIC__", | |
| 124 IDS_IME_NAME_KEYBOARD_DEVANAGARI_PHONETIC}, | |
| 125 {"__MSG_KEYBOARD_ESTONIAN__", IDS_IME_NAME_KEYBOARD_ESTONIAN}, | |
| 126 {"__MSG_KEYBOARD_ETHIOPIC__", IDS_IME_NAME_KEYBOARD_ETHIOPIC}, | |
| 127 {"__MSG_KEYBOARD_FINNISH__", IDS_IME_NAME_KEYBOARD_FINNISH}, | |
| 128 {"__MSG_KEYBOARD_FRENCH__", IDS_IME_NAME_KEYBOARD_FRENCH}, | |
| 129 {"__MSG_KEYBOARD_GEORGIAN__", IDS_IME_NAME_KEYBOARD_GEORGIAN}, | |
| 130 {"__MSG_KEYBOARD_GERMAN_NEO_2__", IDS_IME_NAME_KEYBOARD_GERMAN_NEO_2}, | |
| 131 {"__MSG_KEYBOARD_GERMAN__", IDS_IME_NAME_KEYBOARD_GERMAN}, | |
| 132 {"__MSG_KEYBOARD_GREEK__", IDS_IME_NAME_KEYBOARD_GREEK}, | |
| 133 {"__MSG_KEYBOARD_GUJARATI_PHONETIC__", | |
| 134 IDS_IME_NAME_KEYBOARD_GUJARATI_PHONETIC}, | |
| 135 {"__MSG_KEYBOARD_HEBREW__", IDS_IME_NAME_KEYBOARD_HEBREW}, | |
| 136 {"__MSG_KEYBOARD_HUNGARIAN__", IDS_IME_NAME_KEYBOARD_HUNGARIAN}, | |
| 137 {"__MSG_KEYBOARD_ICELANDIC__", IDS_IME_NAME_KEYBOARD_ICELANDIC}, | |
| 138 {"__MSG_KEYBOARD_IRISH__", IDS_IME_NAME_KEYBOARD_IRISH}, | |
| 139 {"__MSG_KEYBOARD_ITALIAN__", IDS_IME_NAME_KEYBOARD_ITALIAN}, | |
| 140 {"__MSG_KEYBOARD_JAPANESE__", IDS_IME_NAME_KEYBOARD_JAPANESE}, | |
| 141 {"__MSG_KEYBOARD_KANNADA_PHONETIC__", | |
| 142 IDS_IME_NAME_KEYBOARD_KANNADA_PHONETIC}, | |
| 143 {"__MSG_KEYBOARD_KHMER__", IDS_IME_NAME_KEYBOARD_KHMER}, | |
| 144 {"__MSG_KEYBOARD_LAO__", IDS_IME_NAME_KEYBOARD_LAO}, | |
| 145 {"__MSG_KEYBOARD_LATIN_AMERICAN__", IDS_IME_NAME_KEYBOARD_LATIN_AMERICAN}, | |
| 146 {"__MSG_KEYBOARD_LATVIAN__", IDS_IME_NAME_KEYBOARD_LATVIAN}, | |
| 147 {"__MSG_KEYBOARD_LITHUANIAN__", IDS_IME_NAME_KEYBOARD_LITHUANIAN}, | |
| 148 {"__MSG_KEYBOARD_MALAYALAM_PHONETIC__", | |
| 149 IDS_IME_NAME_KEYBOARD_MALAYALAM_PHONETIC}, | |
| 150 {"__MSG_KEYBOARD_MONGOLIAN__", IDS_IME_NAME_KEYBOARD_MONGOLIAN}, | |
| 151 {"__MSG_KEYBOARD_MYANMAR_MYANSAN__", | |
| 152 IDS_IME_NAME_KEYBOARD_MYANMAR_MYANSAN}, | |
| 153 {"__MSG_KEYBOARD_MYANMAR__", IDS_IME_NAME_KEYBOARD_MYANMAR}, | |
| 154 {"__MSG_KEYBOARD_NEPALI_INSCRIPT__", | |
| 155 IDS_IME_NAME_KEYBOARD_NEPALI_INSCRIPT}, | |
| 156 {"__MSG_KEYBOARD_NEPALI_PHONETIC__", | |
| 157 IDS_IME_NAME_KEYBOARD_NEPALI_PHONETIC}, | |
| 158 {"__MSG_KEYBOARD_NORWEGIAN__", IDS_IME_NAME_KEYBOARD_NORWEGIAN}, | |
| 159 {"__MSG_KEYBOARD_PERSIAN__", IDS_IME_NAME_KEYBOARD_PERSIAN}, | |
| 160 {"__MSG_KEYBOARD_POLISH__", IDS_IME_NAME_KEYBOARD_POLISH}, | |
| 161 {"__MSG_KEYBOARD_PORTUGUESE__", IDS_IME_NAME_KEYBOARD_PORTUGUESE}, | |
| 162 {"__MSG_KEYBOARD_ROMANIAN__", IDS_IME_NAME_KEYBOARD_ROMANIAN}, | |
| 163 {"__MSG_KEYBOARD_RUSSIAN_PHONETIC__", | |
| 164 IDS_IME_NAME_KEYBOARD_RUSSIAN_PHONETIC}, | |
| 165 {"__MSG_KEYBOARD_RUSSIAN__", IDS_IME_NAME_KEYBOARD_RUSSIAN}, | |
| 166 {"__MSG_KEYBOARD_SERBIAN__", IDS_IME_NAME_KEYBOARD_SERBIAN}, | |
| 167 {"__MSG_KEYBOARD_SINHALA__", IDS_IME_NAME_KEYBOARD_SINHALA}, | |
| 168 {"__MSG_KEYBOARD_SLOVAKIAN__", IDS_IME_NAME_KEYBOARD_SLOVAKIAN}, | |
| 169 {"__MSG_KEYBOARD_SLOVENIAN__", IDS_IME_NAME_KEYBOARD_SLOVENIAN}, | |
| 170 {"__MSG_KEYBOARD_SORANIKURDISH_AR__", | |
| 171 IDS_IME_NAME_KEYBOARD_SORANIKURDISH_AR}, | |
| 172 {"__MSG_KEYBOARD_SORANIKURDISH_EN__", | |
| 173 IDS_IME_NAME_KEYBOARD_SORANIKURDISH_EN}, | |
| 174 {"__MSG_KEYBOARD_SPANISH__", IDS_IME_NAME_KEYBOARD_SPANISH}, | |
| 175 {"__MSG_KEYBOARD_SWEDISH__", IDS_IME_NAME_KEYBOARD_SWEDISH}, | |
| 176 {"__MSG_KEYBOARD_SWISS_FRENCH__", IDS_IME_NAME_KEYBOARD_SWISS_FRENCH}, | |
| 177 {"__MSG_KEYBOARD_SWISS__", IDS_IME_NAME_KEYBOARD_SWISS}, | |
| 178 {"__MSG_KEYBOARD_TAMIL_INSCRIPT__", IDS_IME_NAME_KEYBOARD_TAMIL_INSCRIPT}, | |
| 179 {"__MSG_KEYBOARD_TAMIL_ITRANS__", IDS_IME_NAME_KEYBOARD_TAMIL_ITRANS}, | |
| 180 {"__MSG_KEYBOARD_TAMIL_PHONETIC__", IDS_IME_NAME_KEYBOARD_TAMIL_PHONETIC}, | |
| 181 {"__MSG_KEYBOARD_TAMIL_TAMIL99__", IDS_IME_NAME_KEYBOARD_TAMIL_TAMIL99}, | |
| 182 {"__MSG_KEYBOARD_TAMIL_TYPEWRITER__", | |
| 183 IDS_IME_NAME_KEYBOARD_TAMIL_TYPEWRITER}, | |
| 184 {"__MSG_KEYBOARD_TELUGU_PHONETIC__", | |
| 185 IDS_IME_NAME_KEYBOARD_TELUGU_PHONETIC}, | |
| 186 {"__MSG_KEYBOARD_THAI_KEDMANEE__", IDS_IME_NAME_KEYBOARD_THAI_KEDMANEE}, | |
| 187 {"__MSG_KEYBOARD_THAI_PATTACHOTE__", | |
| 188 IDS_IME_NAME_KEYBOARD_THAI_PATTACHOTE}, | |
| 189 {"__MSG_KEYBOARD_THAI_TIS__", IDS_IME_NAME_KEYBOARD_THAI_TIS}, | |
| 190 {"__MSG_KEYBOARD_TURKISH__", IDS_IME_NAME_KEYBOARD_TURKISH}, | |
| 191 {"__MSG_KEYBOARD_UKRAINIAN__", IDS_IME_NAME_KEYBOARD_UKRAINIAN}, | |
| 192 {"__MSG_KEYBOARD_UK_DVORAK__", IDS_IME_NAME_KEYBOARD_UK_DVORAK}, | |
| 193 {"__MSG_KEYBOARD_UK__", IDS_IME_NAME_KEYBOARD_UK}, | |
| 194 {"__MSG_KEYBOARD_US_COLEMAK__", IDS_IME_NAME_KEYBOARD_US_COLEMAK}, | |
| 195 {"__MSG_KEYBOARD_US_DVORAK__", IDS_IME_NAME_KEYBOARD_US_DVORAK}, | |
| 196 {"__MSG_KEYBOARD_US_EXTENDED__", IDS_IME_NAME_KEYBOARD_US_EXTENDED}, | |
| 197 {"__MSG_KEYBOARD_US_INTERNATIONAL__", | |
| 198 IDS_IME_NAME_KEYBOARD_US_INTERNATIONAL}, | |
| 199 {"__MSG_KEYBOARD_US__", IDS_IME_NAME_KEYBOARD_US}, | |
| 200 {"__MSG_KEYBOARD_VIETNAMESE_TCVN__", | |
| 201 IDS_IME_NAME_KEYBOARD_VIETNAMESE_TCVN}, | |
| 202 {"__MSG_KEYBOARD_VIETNAMESE_TELEX__", | |
| 203 IDS_IME_NAME_KEYBOARD_VIETNAMESE_TELEX}, | |
| 204 {"__MSG_KEYBOARD_VIETNAMESE_VIQR__", | |
| 205 IDS_IME_NAME_KEYBOARD_VIETNAMESE_VIQR}, | |
| 206 {"__MSG_KEYBOARD_VIETNAMESE_VNI__", IDS_IME_NAME_KEYBOARD_VIETNAMESE_VNI}, | |
| 207 {"__MSG_TRANSLITERATION_AM__", IDS_IME_NAME_TRANSLITERATION_AM}, | |
| 208 {"__MSG_TRANSLITERATION_AR__", IDS_IME_NAME_TRANSLITERATION_AR}, | |
| 209 {"__MSG_TRANSLITERATION_BN__", IDS_IME_NAME_TRANSLITERATION_BN}, | |
| 210 {"__MSG_TRANSLITERATION_EL__", IDS_IME_NAME_TRANSLITERATION_EL}, | |
| 211 {"__MSG_TRANSLITERATION_FA__", IDS_IME_NAME_TRANSLITERATION_FA}, | |
| 212 {"__MSG_TRANSLITERATION_GU__", IDS_IME_NAME_TRANSLITERATION_GU}, | |
| 213 {"__MSG_TRANSLITERATION_HE__", IDS_IME_NAME_TRANSLITERATION_HE}, | |
| 214 {"__MSG_TRANSLITERATION_HI__", IDS_IME_NAME_TRANSLITERATION_HI}, | |
| 215 {"__MSG_TRANSLITERATION_KN__", IDS_IME_NAME_TRANSLITERATION_KN}, | |
| 216 {"__MSG_TRANSLITERATION_ML__", IDS_IME_NAME_TRANSLITERATION_ML}, | |
| 217 {"__MSG_TRANSLITERATION_MR__", IDS_IME_NAME_TRANSLITERATION_MR}, | |
| 218 {"__MSG_TRANSLITERATION_NE__", IDS_IME_NAME_TRANSLITERATION_NE}, | |
| 219 {"__MSG_TRANSLITERATION_OR__", IDS_IME_NAME_TRANSLITERATION_OR}, | |
| 220 {"__MSG_TRANSLITERATION_PA__", IDS_IME_NAME_TRANSLITERATION_PA}, | |
| 221 {"__MSG_TRANSLITERATION_SA__", IDS_IME_NAME_TRANSLITERATION_SA}, | |
| 222 {"__MSG_TRANSLITERATION_SR__", IDS_IME_NAME_TRANSLITERATION_SR}, | |
| 223 {"__MSG_TRANSLITERATION_TA__", IDS_IME_NAME_TRANSLITERATION_TA}, | |
| 224 {"__MSG_TRANSLITERATION_TE__", IDS_IME_NAME_TRANSLITERATION_TE}, | |
| 225 {"__MSG_TRANSLITERATION_TI__", IDS_IME_NAME_TRANSLITERATION_TI}, | |
| 226 {"__MSG_TRANSLITERATION_UR__", IDS_IME_NAME_TRANSLITERATION_UR}, | |
| 227 }; | |
| 228 | |
| 229 const char* kImePathKeyName = "ime_path"; | |
|
Nico
2014/07/22 17:05:08
Make this `const char kImePathKeyName[]`, else the
Shu Chen
2014/07/23 00:56:45
Done.
| |
| 230 | |
| 89 extensions::ComponentLoader* GetComponentLoader() { | 231 extensions::ComponentLoader* GetComponentLoader() { |
| 90 // TODO(skuhne, nkostylev): At this time the only thing which makes sense here | 232 // TODO(skuhne, nkostylev): At this time the only thing which makes sense here |
| 91 // is to use the active profile. Nkostylev is working on getting IME settings | 233 // is to use the active profile. Nkostylev is working on getting IME settings |
| 92 // to work for multi user by collecting all settings from all users. Once that | 234 // to work for multi user by collecting all settings from all users. Once that |
| 93 // is done we might have to re-visit this decision. | 235 // is done we might have to re-visit this decision. |
| 94 Profile* profile = ProfileManager::GetActiveUserProfile(); | 236 Profile* profile = ProfileManager::GetActiveUserProfile(); |
| 95 extensions::ExtensionSystem* extension_system = | 237 extensions::ExtensionSystem* extension_system = |
| 96 extensions::ExtensionSystem::Get(profile); | 238 extensions::ExtensionSystem::Get(profile); |
| 97 ExtensionService* extension_service = extension_system->extension_service(); | 239 ExtensionService* extension_service = extension_system->extension_service(); |
| 98 return extension_service->component_loader(); | 240 return extension_service->component_loader(); |
| 99 } | 241 } |
| 100 } // namespace | 242 } // namespace |
| 101 | 243 |
| 102 ComponentExtensionIMEManagerImpl::ComponentExtensionIMEManagerImpl() | 244 ComponentExtensionIMEManagerImpl::ComponentExtensionIMEManagerImpl() |
| 103 : is_initialized_(false), | 245 : weak_ptr_factory_(this) { |
| 104 weak_ptr_factory_(this) { | 246 ReadComponentExtensionsInfo(&component_extension_list_); |
| 105 } | 247 } |
| 106 | 248 |
| 107 ComponentExtensionIMEManagerImpl::~ComponentExtensionIMEManagerImpl() { | 249 ComponentExtensionIMEManagerImpl::~ComponentExtensionIMEManagerImpl() { |
| 108 } | 250 } |
| 109 | 251 |
| 110 std::vector<ComponentExtensionIME> ComponentExtensionIMEManagerImpl::ListIME() { | 252 std::vector<ComponentExtensionIME> ComponentExtensionIMEManagerImpl::ListIME() { |
| 111 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 112 return component_extension_list_; | 253 return component_extension_list_; |
| 113 } | 254 } |
| 114 | 255 |
| 115 bool ComponentExtensionIMEManagerImpl::Load(const std::string& extension_id, | 256 bool ComponentExtensionIMEManagerImpl::Load(const std::string& extension_id, |
| 116 const std::string& manifest, | 257 const std::string& manifest, |
| 117 const base::FilePath& file_path) { | 258 const base::FilePath& file_path) { |
| 118 DCHECK(thread_checker_.CalledOnValidThread()); | 259 if (!base::PathExists(file_path)) |
| 260 return false; | |
| 261 | |
| 119 Profile* profile = ProfileManager::GetActiveUserProfile(); | 262 Profile* profile = ProfileManager::GetActiveUserProfile(); |
| 120 extensions::ExtensionSystem* extension_system = | 263 extensions::ExtensionSystem* extension_system = |
| 121 extensions::ExtensionSystem::Get(profile); | 264 extensions::ExtensionSystem::Get(profile); |
| 122 ExtensionService* extension_service = extension_system->extension_service(); | 265 ExtensionService* extension_service = extension_system->extension_service(); |
| 123 if (extension_service->GetExtensionById(extension_id, false)) | 266 if (extension_service->GetExtensionById(extension_id, false)) |
| 124 return false; | 267 return false; |
| 125 const std::string loaded_extension_id = | 268 const std::string loaded_extension_id = |
| 126 GetComponentLoader()->Add(manifest, file_path); | 269 GetComponentLoader()->Add(manifest, file_path); |
| 127 DCHECK_EQ(loaded_extension_id, extension_id); | 270 DCHECK_EQ(loaded_extension_id, extension_id); |
| 128 return true; | 271 return true; |
| 129 } | 272 } |
| 130 | 273 |
| 131 void ComponentExtensionIMEManagerImpl::Unload(const std::string& extension_id, | 274 void ComponentExtensionIMEManagerImpl::Unload(const std::string& extension_id, |
| 132 const base::FilePath& file_path) { | 275 const base::FilePath& file_path) { |
| 133 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 134 // Remove(extension_id) does nothing when the extension has already been | 276 // Remove(extension_id) does nothing when the extension has already been |
| 135 // removed or not been registered. | 277 // removed or not been registered. |
| 136 GetComponentLoader()->Remove(extension_id); | 278 GetComponentLoader()->Remove(extension_id); |
| 137 } | 279 } |
| 138 | 280 |
| 139 scoped_ptr<base::DictionaryValue> ComponentExtensionIMEManagerImpl::GetManifest( | 281 scoped_ptr<base::DictionaryValue> ComponentExtensionIMEManagerImpl::GetManifest( |
| 140 const base::FilePath& file_path) { | 282 const std::string& manifest_string) { |
| 141 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)); | |
| 142 std::string error; | 283 std::string error; |
| 143 scoped_ptr<base::DictionaryValue> manifest( | 284 JSONStringValueSerializer serializer(manifest_string); |
| 144 extensions::file_util::LoadManifest(file_path, &error)); | 285 scoped_ptr<base::Value> manifest(serializer.Deserialize(NULL, &error)); |
| 145 if (!manifest.get()) | 286 if (!manifest.get()) |
| 146 LOG(ERROR) << "Failed at getting manifest"; | 287 LOG(ERROR) << "Failed at getting manifest"; |
| 147 if (!extension_l10n_util::LocalizeExtension(file_path, | |
| 148 manifest.get(), | |
| 149 &error)) { | |
| 150 LOG(ERROR) << "Localization failed for: " << file_path.value() | |
| 151 << " Error: " << error; | |
| 152 } | |
| 153 return manifest.Pass(); | |
| 154 } | |
| 155 | 288 |
| 156 void ComponentExtensionIMEManagerImpl::InitializeAsync( | 289 return scoped_ptr<base::DictionaryValue>( |
| 157 const base::Closure& callback) { | 290 static_cast<base::DictionaryValue*>(manifest.release())).Pass(); |
| 158 DCHECK(!is_initialized_); | |
| 159 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 160 | |
| 161 std::vector<ComponentExtensionIME>* component_extension_ime_list | |
| 162 = new std::vector<ComponentExtensionIME>; | |
| 163 content::BrowserThread::PostTaskAndReply( | |
| 164 content::BrowserThread::FILE, | |
| 165 FROM_HERE, | |
| 166 base::Bind(&ComponentExtensionIMEManagerImpl::ReadComponentExtensionsInfo, | |
| 167 base::Unretained(component_extension_ime_list)), | |
| 168 base::Bind( | |
| 169 &ComponentExtensionIMEManagerImpl::OnReadComponentExtensionsInfo, | |
| 170 weak_ptr_factory_.GetWeakPtr(), | |
| 171 base::Owned(component_extension_ime_list), | |
| 172 callback)); | |
| 173 } | |
| 174 | |
| 175 bool ComponentExtensionIMEManagerImpl::IsInitialized() { | |
| 176 return is_initialized_; | |
| 177 } | 291 } |
| 178 | 292 |
| 179 // static | 293 // static |
| 180 bool ComponentExtensionIMEManagerImpl::ReadEngineComponent( | 294 bool ComponentExtensionIMEManagerImpl::ReadEngineComponent( |
| 181 const ComponentExtensionIME& component_extension, | 295 const ComponentExtensionIME& component_extension, |
| 182 const base::DictionaryValue& dict, | 296 const base::DictionaryValue& dict, |
| 183 ComponentExtensionEngine* out) { | 297 ComponentExtensionEngine* out) { |
| 184 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)); | |
| 185 DCHECK(out); | 298 DCHECK(out); |
| 186 std::string type; | 299 std::string type; |
| 187 if (!dict.GetString(extensions::manifest_keys::kType, &type)) | 300 if (!dict.GetString(extensions::manifest_keys::kType, &type)) |
| 188 return false; | 301 return false; |
| 189 if (type != "ime") | 302 if (type != "ime") |
| 190 return false; | 303 return false; |
| 191 if (!dict.GetString(extensions::manifest_keys::kId, &out->engine_id)) | 304 if (!dict.GetString(extensions::manifest_keys::kId, &out->engine_id)) |
| 192 return false; | 305 return false; |
| 193 if (!dict.GetString(extensions::manifest_keys::kName, &out->display_name)) | 306 if (!dict.GetString(extensions::manifest_keys::kName, &out->display_name)) |
| 194 return false; | 307 return false; |
| 195 | 308 |
| 309 // Localizes the input method name. | |
| 310 if (out->display_name.find("__MSG_") == 0) { | |
| 311 const InputMethodNameMap* map = kInputMethodNameMap; | |
| 312 size_t map_size = arraysize(kInputMethodNameMap); | |
| 313 std::string name = StringToUpperASCII(out->display_name); | |
| 314 const InputMethodNameMap map_key = {name.c_str(), 0}; | |
| 315 const InputMethodNameMap* p = | |
| 316 std::lower_bound(map, map + map_size, map_key, map_key); | |
| 317 if (p != map + map_size && !map_key(*p, map_key) && !map_key(map_key, *p)) | |
| 318 out->display_name = l10n_util::GetStringUTF8(p->resource_id); | |
| 319 } | |
| 320 DCHECK(out->display_name.find("__MSG_") == std::string::npos); | |
| 321 | |
| 196 std::set<std::string> languages; | 322 std::set<std::string> languages; |
| 197 const base::Value* language_value = NULL; | 323 const base::Value* language_value = NULL; |
| 198 if (dict.Get(extensions::manifest_keys::kLanguage, &language_value)) { | 324 if (dict.Get(extensions::manifest_keys::kLanguage, &language_value)) { |
| 199 if (language_value->GetType() == base::Value::TYPE_STRING) { | 325 if (language_value->GetType() == base::Value::TYPE_STRING) { |
| 200 std::string language_str; | 326 std::string language_str; |
| 201 language_value->GetAsString(&language_str); | 327 language_value->GetAsString(&language_str); |
| 202 languages.insert(language_str); | 328 languages.insert(language_str); |
| 203 } else if (language_value->GetType() == base::Value::TYPE_LIST) { | 329 } else if (language_value->GetType() == base::Value::TYPE_LIST) { |
| 204 const base::ListValue* language_list = NULL; | 330 const base::ListValue* language_list = NULL; |
| 205 language_value->GetAsList(&language_list); | 331 language_value->GetAsList(&language_list); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 250 } | 376 } |
| 251 | 377 |
| 252 return true; | 378 return true; |
| 253 } | 379 } |
| 254 | 380 |
| 255 // static | 381 // static |
| 256 bool ComponentExtensionIMEManagerImpl::ReadExtensionInfo( | 382 bool ComponentExtensionIMEManagerImpl::ReadExtensionInfo( |
| 257 const base::DictionaryValue& manifest, | 383 const base::DictionaryValue& manifest, |
| 258 const std::string& extension_id, | 384 const std::string& extension_id, |
| 259 ComponentExtensionIME* out) { | 385 ComponentExtensionIME* out) { |
| 260 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)); | |
| 261 if (!manifest.GetString(extensions::manifest_keys::kDescription, | 386 if (!manifest.GetString(extensions::manifest_keys::kDescription, |
| 262 &out->description)) | 387 &out->description)) |
| 263 return false; | 388 return false; |
| 389 std::string path; | |
| 390 if (manifest.GetString(kImePathKeyName, &path)) | |
| 391 out->path = base::FilePath(path); | |
| 264 std::string url_string; | 392 std::string url_string; |
| 265 if (manifest.GetString(extensions::manifest_keys::kOptionsPage, | 393 if (manifest.GetString(extensions::manifest_keys::kOptionsPage, |
| 266 &url_string)) { | 394 &url_string)) { |
| 267 GURL url = extensions::Extension::GetResourceURL( | 395 GURL url = extensions::Extension::GetResourceURL( |
| 268 extensions::Extension::GetBaseURLFromExtensionId(extension_id), | 396 extensions::Extension::GetBaseURLFromExtensionId(extension_id), |
| 269 url_string); | 397 url_string); |
| 270 if (!url.is_valid()) | 398 if (!url.is_valid()) |
| 271 return false; | 399 return false; |
| 272 out->options_page_url = url; | 400 out->options_page_url = url; |
| 273 } | 401 } |
| 274 // It's okay to return true on no option page and/or input view page case. | 402 // It's okay to return true on no option page and/or input view page case. |
| 275 return true; | 403 return true; |
| 276 } | 404 } |
| 277 | 405 |
| 278 // static | 406 // static |
| 279 void ComponentExtensionIMEManagerImpl::ReadComponentExtensionsInfo( | 407 void ComponentExtensionIMEManagerImpl::ReadComponentExtensionsInfo( |
| 280 std::vector<ComponentExtensionIME>* out_imes) { | 408 std::vector<ComponentExtensionIME>* out_imes) { |
| 281 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)); | |
| 282 DCHECK(out_imes); | 409 DCHECK(out_imes); |
| 283 for (size_t i = 0; i < arraysize(whitelisted_component_extension); ++i) { | 410 for (size_t i = 0; i < arraysize(whitelisted_component_extension); ++i) { |
| 284 ComponentExtensionIME component_ime; | 411 ComponentExtensionIME component_ime; |
| 285 component_ime.path = base::FilePath( | 412 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); |
| 286 whitelisted_component_extension[i].path); | 413 component_ime.manifest = |
| 287 | 414 rb.GetRawDataResource( |
| 288 if (!component_ime.path.IsAbsolute()) { | 415 whitelisted_component_extension[i].manifest_resource_id) |
| 289 base::FilePath resources_path; | 416 .as_string(); |
| 290 if (!PathService::Get(chrome::DIR_RESOURCES, &resources_path)) | 417 if (component_ime.manifest.empty()) |
| 291 NOTREACHED(); | |
| 292 component_ime.path = resources_path.Append(component_ime.path); | |
| 293 } | |
| 294 const base::FilePath manifest_path = | |
| 295 component_ime.path.Append("manifest.json"); | |
| 296 | |
| 297 if (!base::PathExists(component_ime.path) || | |
| 298 !base::PathExists(manifest_path)) | |
| 299 continue; | |
| 300 | |
| 301 if (!base::ReadFileToString(manifest_path, &component_ime.manifest)) | |
| 302 continue; | 418 continue; |
| 303 | 419 |
| 304 scoped_ptr<base::DictionaryValue> manifest = | 420 scoped_ptr<base::DictionaryValue> manifest = |
| 305 GetManifest(component_ime.path); | 421 GetManifest(component_ime.manifest); |
| 306 if (!manifest.get()) | 422 if (!manifest.get()) |
| 307 continue; | 423 continue; |
| 308 | 424 |
| 309 if (!ReadExtensionInfo(*manifest.get(), | 425 if (!ReadExtensionInfo(*manifest.get(), |
| 310 whitelisted_component_extension[i].id, | 426 whitelisted_component_extension[i].id, |
| 311 &component_ime)) | 427 &component_ime)) |
| 312 continue; | 428 continue; |
| 313 component_ime.id = whitelisted_component_extension[i].id; | 429 component_ime.id = whitelisted_component_extension[i].id; |
| 314 | 430 |
| 431 if (!component_ime.path.IsAbsolute()) { | |
| 432 base::FilePath resources_path; | |
| 433 if (!PathService::Get(chrome::DIR_RESOURCES, &resources_path)) | |
| 434 NOTREACHED(); | |
| 435 component_ime.path = resources_path.Append(component_ime.path); | |
| 436 } | |
| 437 | |
| 315 const base::ListValue* component_list; | 438 const base::ListValue* component_list; |
| 316 if (!manifest->GetList(extensions::manifest_keys::kInputComponents, | 439 if (!manifest->GetList(extensions::manifest_keys::kInputComponents, |
| 317 &component_list)) | 440 &component_list)) |
| 318 continue; | 441 continue; |
| 319 | 442 |
| 320 for (size_t i = 0; i < component_list->GetSize(); ++i) { | 443 for (size_t i = 0; i < component_list->GetSize(); ++i) { |
| 321 const base::DictionaryValue* dictionary; | 444 const base::DictionaryValue* dictionary; |
| 322 if (!component_list->GetDictionary(i, &dictionary)) | 445 if (!component_list->GetDictionary(i, &dictionary)) |
| 323 continue; | 446 continue; |
| 324 | 447 |
| 325 ComponentExtensionEngine engine; | 448 ComponentExtensionEngine engine; |
| 326 ReadEngineComponent(component_ime, *dictionary, &engine); | 449 ReadEngineComponent(component_ime, *dictionary, &engine); |
| 327 component_ime.engines.push_back(engine); | 450 component_ime.engines.push_back(engine); |
| 328 } | 451 } |
| 329 out_imes->push_back(component_ime); | 452 out_imes->push_back(component_ime); |
| 330 } | 453 } |
| 331 } | 454 } |
| 332 | 455 |
| 333 void ComponentExtensionIMEManagerImpl::OnReadComponentExtensionsInfo( | |
| 334 std::vector<ComponentExtensionIME>* result, | |
| 335 const base::Closure& callback) { | |
| 336 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 337 DCHECK(result); | |
| 338 component_extension_list_ = *result; | |
| 339 is_initialized_ = true; | |
| 340 callback.Run(); | |
| 341 } | |
| 342 | |
| 343 } // namespace chromeos | 456 } // namespace chromeos |
| OLD | NEW |