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 { |
| 75 return strcmp(m1.message_name, m2.message_name) < 0; |
| 76 } |
| 77 } kInputMethodNameMap[] = { |
| 78 {"__MSG_ARMENIAN_PHONETIC_KEYBOARD__", |
| 79 IDS_IME_NAME_ARMENIAN_PHONETIC_KEYBOARD}, |
| 80 {"__MSG_ARRAY_INPUTMETHOD__", IDS_IME_NAME_ARRAY_INPUTMETHOD}, |
| 81 {"__MSG_BELARUSIAN_KEYBOARD__", IDS_IME_NAME_BELARUSIAN_KEYBOARD}, |
| 82 {"__MSG_BELGIAN_KEYBOARD__", IDS_IME_NAME_BELGIAN_KEYBOARD}, |
| 83 {"__MSG_BRAZILIAN_KEYBOARD__", IDS_IME_NAME_BRAZILIAN_KEYBOARD}, |
| 84 {"__MSG_BULGARIAN_KEYBOARD__", IDS_IME_NAME_BULGARIAN_KEYBOARD}, |
| 85 {"__MSG_BULGARIAN_PHONETIC_KEYBOARD__", |
| 86 IDS_IME_NAME_BULGARIAN_PHONETIC_KEYBOARD}, |
| 87 {"__MSG_CANADIAN_ENGLISH_KEYBOARD__", |
| 88 IDS_IME_NAME_CANADIAN_ENGLISH_KEYBOARD}, |
| 89 {"__MSG_CANADIAN_FRENCH_KEYBOARD__", |
| 90 IDS_IME_NAME_CANADIAN_FRENCH_KEYBOARD}, |
| 91 {"__MSG_CANADIAN_MULTILINGUAL_KEYBOARD__", |
| 92 IDS_IME_NAME_CANADIAN_MULTILINGUAL_KEYBOARD}, |
| 93 {"__MSG_CANGJIE_INPUTMETHOD__", IDS_IME_NAME_CANGJIE_INPUTMETHOD}, |
| 94 {"__MSG_CATALAN_KEYBOARD__", IDS_IME_NAME_CATALAN_KEYBOARD}, |
| 95 {"__MSG_CROATIAN_KEYBOARD__", IDS_IME_NAME_CROATIAN_KEYBOARD}, |
| 96 {"__MSG_CZECH_KEYBOARD__", IDS_IME_NAME_CZECH_KEYBOARD}, |
| 97 {"__MSG_CZECH_QWERTY_KEYBOARD__", IDS_IME_NAME_CZECH_QWERTY_KEYBOARD}, |
| 98 {"__MSG_DANISH_KEYBOARD__", IDS_IME_NAME_DANISH_KEYBOARD}, |
| 99 {"__MSG_DAYI_INPUTMETHOD__", IDS_IME_NAME_DAYI_INPUTMETHOD}, |
| 100 {"__MSG_ESTONIAN_KEYBOARD__", IDS_IME_NAME_ESTONIAN_KEYBOARD}, |
| 101 {"__MSG_FINNISH_KEYBOARD__", IDS_IME_NAME_FINNISH_KEYBOARD}, |
| 102 {"__MSG_FRENCH_KEYBOARD__", IDS_IME_NAME_FRENCH_KEYBOARD}, |
| 103 {"__MSG_GEORGIAN_KEYBOARD__", IDS_IME_NAME_GEORGIAN_KEYBOARD}, |
| 104 {"__MSG_GERMAN_KEYBOARD__", IDS_IME_NAME_GERMAN_KEYBOARD}, |
| 105 {"__MSG_GERMAN_NEO_2_KEYBOARD__", IDS_IME_NAME_GERMAN_NEO_2_KEYBOARD}, |
| 106 {"__MSG_GREEK_KEYBOARD__", IDS_IME_NAME_GREEK_KEYBOARD}, |
| 107 {"__MSG_HANGUL_2_SET__", IDS_IME_NAME_HANGUL_2_SET}, |
| 108 {"__MSG_HANGUL_3_SET_390__", IDS_IME_NAME_HANGUL_3_SET_390}, |
| 109 {"__MSG_HANGUL_3_SET_FINAL__", IDS_IME_NAME_HANGUL_3_SET_FINAL}, |
| 110 {"__MSG_HANGUL_3_SET_NO_SHIFT__", IDS_IME_NAME_HANGUL_3_SET_NO_SHIFT}, |
| 111 {"__MSG_HANGUL_AHNMATAE__", IDS_IME_NAME_HANGUL_AHNMATAE}, |
| 112 {"__MSG_HANGUL_ROMAJA__", IDS_IME_NAME_HANGUL_ROMAJA}, |
| 113 {"__MSG_HEBREW_KEYBOARD__", IDS_IME_NAME_HEBREW_KEYBOARD}, |
| 114 {"__MSG_HUNGARIAN_KEYBOARD__", IDS_IME_NAME_HUNGARIAN_KEYBOARD}, |
| 115 {"__MSG_ICELANDIC_KEYBOARD__", IDS_IME_NAME_ICELANDIC_KEYBOARD}, |
| 116 {"__MSG_IRISH_KEYBOARD__", IDS_IME_NAME_IRISH_KEYBOARD}, |
| 117 {"__MSG_ITALIAN_KEYBOARD__", IDS_IME_NAME_ITALIAN_KEYBOARD}, |
| 118 {"__MSG_JAPANESE_KEYBOARD__", IDS_IME_NAME_JAPANESE_KEYBOARD}, |
| 119 {"__MSG_KEYBOARD_ARABIC__", IDS_IME_NAME_KEYBOARD_ARABIC}, |
| 120 {"__MSG_KEYBOARD_BENGALI_PHONETIC__", |
| 121 IDS_IME_NAME_KEYBOARD_BENGALI_PHONETIC}, |
| 122 {"__MSG_KEYBOARD_DEVANAGARI_PHONETIC__", |
| 123 IDS_IME_NAME_KEYBOARD_DEVANAGARI_PHONETIC}, |
| 124 {"__MSG_KEYBOARD_ETHIOPIC__", IDS_IME_NAME_KEYBOARD_ETHIOPIC}, |
| 125 {"__MSG_KEYBOARD_GUJARATI_PHONETIC__", |
| 126 IDS_IME_NAME_KEYBOARD_GUJARATI_PHONETIC}, |
| 127 {"__MSG_KEYBOARD_KANNADA_PHONETIC__", |
| 128 IDS_IME_NAME_KEYBOARD_KANNADA_PHONETIC}, |
| 129 {"__MSG_KEYBOARD_KHMER__", IDS_IME_NAME_KEYBOARD_KHMER}, |
| 130 {"__MSG_KEYBOARD_LAO__", IDS_IME_NAME_KEYBOARD_LAO}, |
| 131 {"__MSG_KEYBOARD_MALAYALAM_PHONETIC__", |
| 132 IDS_IME_NAME_KEYBOARD_MALAYALAM_PHONETIC}, |
| 133 {"__MSG_KEYBOARD_MYANMAR_MYANSAN__", |
| 134 IDS_IME_NAME_KEYBOARD_MYANMAR_MYANSAN}, |
| 135 {"__MSG_KEYBOARD_MYANMAR__", IDS_IME_NAME_KEYBOARD_MYANMAR}, |
| 136 {"__MSG_KEYBOARD_NEPALI_INSCRIPT__", |
| 137 IDS_IME_NAME_KEYBOARD_NEPALI_INSCRIPT}, |
| 138 {"__MSG_KEYBOARD_NEPALI_PHONETIC__", |
| 139 IDS_IME_NAME_KEYBOARD_NEPALI_PHONETIC}, |
| 140 {"__MSG_KEYBOARD_PERSIAN__", IDS_IME_NAME_KEYBOARD_PERSIAN}, |
| 141 {"__MSG_KEYBOARD_SINHALA__", IDS_IME_NAME_KEYBOARD_SINHALA}, |
| 142 {"__MSG_KEYBOARD_SORANIKURDISH_AR__", |
| 143 IDS_IME_NAME_KEYBOARD_SORANIKURDISH_AR}, |
| 144 {"__MSG_KEYBOARD_SORANIKURDISH_EN__", |
| 145 IDS_IME_NAME_KEYBOARD_SORANIKURDISH_EN}, |
| 146 {"__MSG_KEYBOARD_TAMIL_INSCRIPT__", IDS_IME_NAME_KEYBOARD_TAMIL_INSCRIPT}, |
| 147 {"__MSG_KEYBOARD_TAMIL_ITRANS__", IDS_IME_NAME_KEYBOARD_TAMIL_ITRANS}, |
| 148 {"__MSG_KEYBOARD_TAMIL_PHONETIC__", IDS_IME_NAME_KEYBOARD_TAMIL_PHONETIC}, |
| 149 {"__MSG_KEYBOARD_TAMIL_TAMIL99__", IDS_IME_NAME_KEYBOARD_TAMIL_TAMIL99}, |
| 150 {"__MSG_KEYBOARD_TAMIL_TYPEWRITER__", |
| 151 IDS_IME_NAME_KEYBOARD_TAMIL_TYPEWRITER}, |
| 152 {"__MSG_KEYBOARD_TELUGU_PHONETIC__", |
| 153 IDS_IME_NAME_KEYBOARD_TELUGU_PHONETIC}, |
| 154 {"__MSG_KEYBOARD_THAI_KEDMANEE__", IDS_IME_NAME_KEYBOARD_THAI_KEDMANEE}, |
| 155 {"__MSG_KEYBOARD_THAI_PATTACHOTE__", |
| 156 IDS_IME_NAME_KEYBOARD_THAI_PATTACHOTE}, |
| 157 {"__MSG_KEYBOARD_THAI_TIS__", IDS_IME_NAME_KEYBOARD_THAI_TIS}, |
| 158 {"__MSG_KEYBOARD_VIETNAMESE_TCVN__", |
| 159 IDS_IME_NAME_KEYBOARD_VIETNAMESE_TCVN}, |
| 160 {"__MSG_KEYBOARD_VIETNAMESE_TELEX__", |
| 161 IDS_IME_NAME_KEYBOARD_VIETNAMESE_TELEX}, |
| 162 {"__MSG_KEYBOARD_VIETNAMESE_VIQR__", |
| 163 IDS_IME_NAME_KEYBOARD_VIETNAMESE_VIQR}, |
| 164 {"__MSG_KEYBOARD_VIETNAMESE_VNI__", IDS_IME_NAME_KEYBOARD_VIETNAMESE_VNI}, |
| 165 {"__MSG_LATIN_AMERICAN_KEYBOARD__", IDS_IME_NAME_LATIN_AMERICAN_KEYBOARD}, |
| 166 {"__MSG_LATVIAN_KEYBOARD__", IDS_IME_NAME_LATVIAN_KEYBOARD}, |
| 167 {"__MSG_LITHUANIAN_KEYBOARD__", IDS_IME_NAME_LITHUANIAN_KEYBOARD}, |
| 168 {"__MSG_MONGOLIAN_KEYBOARD__", IDS_IME_NAME_MONGOLIAN_KEYBOARD}, |
| 169 {"__MSG_MOZC_JP_INPUTMETHOD__", IDS_IME_NAME_MOZC_JP_INPUTMETHOD}, |
| 170 {"__MSG_MOZC_US_INPUTMETHOD__", IDS_IME_NAME_MOZC_US_INPUTMETHOD}, |
| 171 {"__MSG_NORWEGIAN_KEYBOARD__", IDS_IME_NAME_NORWEGIAN_KEYBOARD}, |
| 172 {"__MSG_PINYIN_INPUTMETHOD__", IDS_IME_NAME_PINYIN_INPUTMETHOD}, |
| 173 {"__MSG_POLISH_KEYBOARD__", IDS_IME_NAME_POLISH_KEYBOARD}, |
| 174 {"__MSG_PORTUGUESE_KEYBOARD__", IDS_IME_NAME_PORTUGUESE_KEYBOARD}, |
| 175 {"__MSG_QUICK_INPUTMETHOD__", IDS_IME_NAME_QUICK_INPUTMETHOD}, |
| 176 {"__MSG_ROMANIAN_KEYBOARD__", IDS_IME_NAME_ROMANIAN_KEYBOARD}, |
| 177 {"__MSG_RUSSIAN_KEYBOARD__", IDS_IME_NAME_RUSSIAN_KEYBOARD}, |
| 178 {"__MSG_RUSSIAN_PHONETIC_KEYBOARD__", |
| 179 IDS_IME_NAME_RUSSIAN_PHONETIC_KEYBOARD}, |
| 180 {"__MSG_SERBIAN_KEYBOARD__", IDS_IME_NAME_SERBIAN_KEYBOARD}, |
| 181 {"__MSG_SLOVAKIAN_KEYBOARD__", IDS_IME_NAME_SLOVAKIAN_KEYBOARD}, |
| 182 {"__MSG_SLOVENIAN_KEYBOARD__", IDS_IME_NAME_SLOVENIAN_KEYBOARD}, |
| 183 {"__MSG_SPANISH_KEYBOARD__", IDS_IME_NAME_SPANISH_KEYBOARD}, |
| 184 {"__MSG_SWEDISH_KEYBOARD__", IDS_IME_NAME_SWEDISH_KEYBOARD}, |
| 185 {"__MSG_SWISS_FRENCH_KEYBOARD__", IDS_IME_NAME_SWISS_FRENCH_KEYBOARD}, |
| 186 {"__MSG_SWISS_KEYBOARD__", IDS_IME_NAME_SWISS_KEYBOARD}, |
| 187 {"__MSG_TRADITIONAL_PINYIN_INPUTMETHOD__", |
| 188 IDS_IME_NAME_TRADITIONAL_PINYIN_INPUTMETHOD}, |
| 189 {"__MSG_TRANSLITERATION_AM__", IDS_IME_NAME_TRANSLITERATION_AM}, |
| 190 {"__MSG_TRANSLITERATION_AR__", IDS_IME_NAME_TRANSLITERATION_AR}, |
| 191 {"__MSG_TRANSLITERATION_BN__", IDS_IME_NAME_TRANSLITERATION_BN}, |
| 192 {"__MSG_TRANSLITERATION_EL__", IDS_IME_NAME_TRANSLITERATION_EL}, |
| 193 {"__MSG_TRANSLITERATION_FA__", IDS_IME_NAME_TRANSLITERATION_FA}, |
| 194 {"__MSG_TRANSLITERATION_GU__", IDS_IME_NAME_TRANSLITERATION_GU}, |
| 195 {"__MSG_TRANSLITERATION_HE__", IDS_IME_NAME_TRANSLITERATION_HE}, |
| 196 {"__MSG_TRANSLITERATION_HI__", IDS_IME_NAME_TRANSLITERATION_HI}, |
| 197 {"__MSG_TRANSLITERATION_KN__", IDS_IME_NAME_TRANSLITERATION_KN}, |
| 198 {"__MSG_TRANSLITERATION_ML__", IDS_IME_NAME_TRANSLITERATION_ML}, |
| 199 {"__MSG_TRANSLITERATION_MR__", IDS_IME_NAME_TRANSLITERATION_MR}, |
| 200 {"__MSG_TRANSLITERATION_NE__", IDS_IME_NAME_TRANSLITERATION_NE}, |
| 201 {"__MSG_TRANSLITERATION_OR__", IDS_IME_NAME_TRANSLITERATION_OR}, |
| 202 {"__MSG_TRANSLITERATION_PA__", IDS_IME_NAME_TRANSLITERATION_PA}, |
| 203 {"__MSG_TRANSLITERATION_SA__", IDS_IME_NAME_TRANSLITERATION_SA}, |
| 204 {"__MSG_TRANSLITERATION_SR__", IDS_IME_NAME_TRANSLITERATION_SR}, |
| 205 {"__MSG_TRANSLITERATION_TA__", IDS_IME_NAME_TRANSLITERATION_TA}, |
| 206 {"__MSG_TRANSLITERATION_TE__", IDS_IME_NAME_TRANSLITERATION_TE}, |
| 207 {"__MSG_TRANSLITERATION_TI__", IDS_IME_NAME_TRANSLITERATION_TI}, |
| 208 {"__MSG_TRANSLITERATION_UR__", IDS_IME_NAME_TRANSLITERATION_UR}, |
| 209 {"__MSG_TURKISH_KEYBOARD__", IDS_IME_NAME_TURKISH_KEYBOARD}, |
| 210 {"__MSG_UKRAINIAN_KEYBOARD__", IDS_IME_NAME_UKRAINIAN_KEYBOARD}, |
| 211 {"__MSG_UK_DVORAK_KEYBOARD__", IDS_IME_NAME_UK_DVORAK_KEYBOARD}, |
| 212 {"__MSG_UK_KEYBOARD__", IDS_IME_NAME_UK_KEYBOARD}, |
| 213 {"__MSG_US_COLEMAK_KEYBOARD__", IDS_IME_NAME_US_COLEMAK_KEYBOARD}, |
| 214 {"__MSG_US_DVORAK_KEYBOARD__", IDS_IME_NAME_US_DVORAK_KEYBOARD}, |
| 215 {"__MSG_US_EXTENDED_KEYBOARD__", IDS_IME_NAME_US_EXTENDED_KEYBOARD}, |
| 216 {"__MSG_US_INTERNATIONAL_KEYBOARD__", |
| 217 IDS_IME_NAME_US_INTERNATIONAL_KEYBOARD}, |
| 218 {"__MSG_US_KEYBOARD__", IDS_IME_NAME_US_KEYBOARD}, |
| 219 {"__MSG_WUBI_INPUTMETHOD__", IDS_IME_NAME_WUBI_INPUTMETHOD}, |
| 220 {"__MSG_ZHUYIN_INPUTMETHOD__", IDS_IME_NAME_ZHUYIN_INPUTMETHOD}, |
| 221 }; |
| 222 |
| 223 const char* kImePathKeyName = "ime_path"; |
| 224 |
89 extensions::ComponentLoader* GetComponentLoader() { | 225 extensions::ComponentLoader* GetComponentLoader() { |
90 // TODO(skuhne, nkostylev): At this time the only thing which makes sense here | 226 // 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 | 227 // 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 | 228 // 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. | 229 // is done we might have to re-visit this decision. |
94 Profile* profile = ProfileManager::GetActiveUserProfile(); | 230 Profile* profile = ProfileManager::GetActiveUserProfile(); |
95 extensions::ExtensionSystem* extension_system = | 231 extensions::ExtensionSystem* extension_system = |
96 extensions::ExtensionSystem::Get(profile); | 232 extensions::ExtensionSystem::Get(profile); |
97 ExtensionService* extension_service = extension_system->extension_service(); | 233 ExtensionService* extension_service = extension_system->extension_service(); |
98 return extension_service->component_loader(); | 234 return extension_service->component_loader(); |
99 } | 235 } |
100 } // namespace | 236 } // namespace |
101 | 237 |
102 ComponentExtensionIMEManagerImpl::ComponentExtensionIMEManagerImpl() | 238 ComponentExtensionIMEManagerImpl::ComponentExtensionIMEManagerImpl() |
103 : is_initialized_(false), | 239 : weak_ptr_factory_(this) { |
104 weak_ptr_factory_(this) { | 240 ReadComponentExtensionsInfo(&component_extension_list_); |
105 } | 241 } |
106 | 242 |
107 ComponentExtensionIMEManagerImpl::~ComponentExtensionIMEManagerImpl() { | 243 ComponentExtensionIMEManagerImpl::~ComponentExtensionIMEManagerImpl() { |
108 } | 244 } |
109 | 245 |
110 std::vector<ComponentExtensionIME> ComponentExtensionIMEManagerImpl::ListIME() { | 246 std::vector<ComponentExtensionIME> ComponentExtensionIMEManagerImpl::ListIME() { |
111 DCHECK(thread_checker_.CalledOnValidThread()); | |
112 return component_extension_list_; | 247 return component_extension_list_; |
113 } | 248 } |
114 | 249 |
115 bool ComponentExtensionIMEManagerImpl::Load(const std::string& extension_id, | 250 bool ComponentExtensionIMEManagerImpl::Load(const std::string& extension_id, |
116 const std::string& manifest, | 251 const std::string& manifest, |
117 const base::FilePath& file_path) { | 252 const base::FilePath& file_path) { |
118 DCHECK(thread_checker_.CalledOnValidThread()); | 253 if (!base::PathExists(file_path)) |
| 254 return false; |
| 255 |
119 Profile* profile = ProfileManager::GetActiveUserProfile(); | 256 Profile* profile = ProfileManager::GetActiveUserProfile(); |
120 extensions::ExtensionSystem* extension_system = | 257 extensions::ExtensionSystem* extension_system = |
121 extensions::ExtensionSystem::Get(profile); | 258 extensions::ExtensionSystem::Get(profile); |
122 ExtensionService* extension_service = extension_system->extension_service(); | 259 ExtensionService* extension_service = extension_system->extension_service(); |
123 if (extension_service->GetExtensionById(extension_id, false)) | 260 if (extension_service->GetExtensionById(extension_id, false)) |
124 return false; | 261 return false; |
125 const std::string loaded_extension_id = | 262 const std::string loaded_extension_id = |
126 GetComponentLoader()->Add(manifest, file_path); | 263 GetComponentLoader()->Add(manifest, file_path); |
127 DCHECK_EQ(loaded_extension_id, extension_id); | 264 DCHECK_EQ(loaded_extension_id, extension_id); |
128 return true; | 265 return true; |
129 } | 266 } |
130 | 267 |
131 void ComponentExtensionIMEManagerImpl::Unload(const std::string& extension_id, | 268 void ComponentExtensionIMEManagerImpl::Unload(const std::string& extension_id, |
132 const base::FilePath& file_path) { | 269 const base::FilePath& file_path) { |
133 DCHECK(thread_checker_.CalledOnValidThread()); | |
134 // Remove(extension_id) does nothing when the extension has already been | 270 // Remove(extension_id) does nothing when the extension has already been |
135 // removed or not been registered. | 271 // removed or not been registered. |
136 GetComponentLoader()->Remove(extension_id); | 272 GetComponentLoader()->Remove(extension_id); |
137 } | 273 } |
138 | 274 |
139 scoped_ptr<base::DictionaryValue> ComponentExtensionIMEManagerImpl::GetManifest( | 275 scoped_ptr<base::DictionaryValue> ComponentExtensionIMEManagerImpl::GetManifest( |
140 const base::FilePath& file_path) { | 276 const std::string& manifest_string) { |
141 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)); | |
142 std::string error; | 277 std::string error; |
143 scoped_ptr<base::DictionaryValue> manifest( | 278 JSONStringValueSerializer serializer(manifest_string); |
144 extensions::file_util::LoadManifest(file_path, &error)); | 279 scoped_ptr<base::Value> manifest(serializer.Deserialize(NULL, &error)); |
145 if (!manifest.get()) | 280 if (!manifest.get()) |
146 LOG(ERROR) << "Failed at getting manifest"; | 281 LOG(ERROR) << "Failed at getting manifest"; |
147 if (!extension_l10n_util::LocalizeExtension(file_path, | 282 if (!manifest->IsType(base::Value::TYPE_DICTIONARY)) |
148 manifest.get(), | 283 LOG(ERROR) << "Invalid manifest format"; |
149 &error)) | |
150 LOG(ERROR) << "Localization failed"; | |
151 | 284 |
152 return manifest.Pass(); | 285 return scoped_ptr<base::DictionaryValue>( |
153 } | 286 static_cast<base::DictionaryValue*>(manifest.release())).Pass(); |
154 | |
155 void ComponentExtensionIMEManagerImpl::InitializeAsync( | |
156 const base::Closure& callback) { | |
157 DCHECK(!is_initialized_); | |
158 DCHECK(thread_checker_.CalledOnValidThread()); | |
159 | |
160 std::vector<ComponentExtensionIME>* component_extension_ime_list | |
161 = new std::vector<ComponentExtensionIME>; | |
162 content::BrowserThread::PostTaskAndReply( | |
163 content::BrowserThread::FILE, | |
164 FROM_HERE, | |
165 base::Bind(&ComponentExtensionIMEManagerImpl::ReadComponentExtensionsInfo, | |
166 base::Unretained(component_extension_ime_list)), | |
167 base::Bind( | |
168 &ComponentExtensionIMEManagerImpl::OnReadComponentExtensionsInfo, | |
169 weak_ptr_factory_.GetWeakPtr(), | |
170 base::Owned(component_extension_ime_list), | |
171 callback)); | |
172 } | |
173 | |
174 bool ComponentExtensionIMEManagerImpl::IsInitialized() { | |
175 return is_initialized_; | |
176 } | 287 } |
177 | 288 |
178 // static | 289 // static |
179 bool ComponentExtensionIMEManagerImpl::ReadEngineComponent( | 290 bool ComponentExtensionIMEManagerImpl::ReadEngineComponent( |
180 const ComponentExtensionIME& component_extension, | 291 const ComponentExtensionIME& component_extension, |
181 const base::DictionaryValue& dict, | 292 const base::DictionaryValue& dict, |
182 ComponentExtensionEngine* out) { | 293 ComponentExtensionEngine* out) { |
183 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)); | |
184 DCHECK(out); | 294 DCHECK(out); |
185 std::string type; | 295 std::string type; |
186 if (!dict.GetString(extensions::manifest_keys::kType, &type)) | 296 if (!dict.GetString(extensions::manifest_keys::kType, &type)) |
187 return false; | 297 return false; |
188 if (type != "ime") | 298 if (type != "ime") |
189 return false; | 299 return false; |
190 if (!dict.GetString(extensions::manifest_keys::kId, &out->engine_id)) | 300 if (!dict.GetString(extensions::manifest_keys::kId, &out->engine_id)) |
191 return false; | 301 return false; |
192 if (!dict.GetString(extensions::manifest_keys::kName, &out->display_name)) | 302 if (!dict.GetString(extensions::manifest_keys::kName, &out->display_name)) |
193 return false; | 303 return false; |
194 | 304 |
| 305 // Localizes the input method name. |
| 306 if (out->display_name.find("__MSG_") == 0) { |
| 307 const InputMethodNameMap* map = kInputMethodNameMap; |
| 308 size_t map_size = arraysize(kInputMethodNameMap); |
| 309 std::string name = StringToUpperASCII(out->display_name); |
| 310 const InputMethodNameMap map_key = {name.c_str(), 0}; |
| 311 const InputMethodNameMap* p = |
| 312 std::lower_bound(map, map + map_size, map_key, map_key); |
| 313 if (p != map + map_size && !map_key(*p, map_key) && !map_key(map_key, *p)) |
| 314 out->display_name = l10n_util::GetStringUTF8(p->resource_id); |
| 315 } |
| 316 DCHECK(out->display_name.find("__MSG_") == std::string::npos); |
| 317 |
195 std::set<std::string> languages; | 318 std::set<std::string> languages; |
196 const base::Value* language_value = NULL; | 319 const base::Value* language_value = NULL; |
197 if (dict.Get(extensions::manifest_keys::kLanguage, &language_value)) { | 320 if (dict.Get(extensions::manifest_keys::kLanguage, &language_value)) { |
198 if (language_value->GetType() == base::Value::TYPE_STRING) { | 321 if (language_value->GetType() == base::Value::TYPE_STRING) { |
199 std::string language_str; | 322 std::string language_str; |
200 language_value->GetAsString(&language_str); | 323 language_value->GetAsString(&language_str); |
201 languages.insert(language_str); | 324 languages.insert(language_str); |
202 } else if (language_value->GetType() == base::Value::TYPE_LIST) { | 325 } else if (language_value->GetType() == base::Value::TYPE_LIST) { |
203 const base::ListValue* language_list = NULL; | 326 const base::ListValue* language_list = NULL; |
204 language_value->GetAsList(&language_list); | 327 language_value->GetAsList(&language_list); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
249 } | 372 } |
250 | 373 |
251 return true; | 374 return true; |
252 } | 375 } |
253 | 376 |
254 // static | 377 // static |
255 bool ComponentExtensionIMEManagerImpl::ReadExtensionInfo( | 378 bool ComponentExtensionIMEManagerImpl::ReadExtensionInfo( |
256 const base::DictionaryValue& manifest, | 379 const base::DictionaryValue& manifest, |
257 const std::string& extension_id, | 380 const std::string& extension_id, |
258 ComponentExtensionIME* out) { | 381 ComponentExtensionIME* out) { |
259 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)); | |
260 if (!manifest.GetString(extensions::manifest_keys::kDescription, | 382 if (!manifest.GetString(extensions::manifest_keys::kDescription, |
261 &out->description)) | 383 &out->description)) |
262 return false; | 384 return false; |
| 385 std::string path; |
| 386 if (manifest.GetString(kImePathKeyName, &path)) |
| 387 out->path = base::FilePath(path); |
263 std::string url_string; | 388 std::string url_string; |
264 if (manifest.GetString(extensions::manifest_keys::kOptionsPage, | 389 if (manifest.GetString(extensions::manifest_keys::kOptionsPage, |
265 &url_string)) { | 390 &url_string)) { |
266 GURL url = extensions::Extension::GetResourceURL( | 391 GURL url = extensions::Extension::GetResourceURL( |
267 extensions::Extension::GetBaseURLFromExtensionId(extension_id), | 392 extensions::Extension::GetBaseURLFromExtensionId(extension_id), |
268 url_string); | 393 url_string); |
269 if (!url.is_valid()) | 394 if (!url.is_valid()) |
270 return false; | 395 return false; |
271 out->options_page_url = url; | 396 out->options_page_url = url; |
272 } | 397 } |
273 // It's okay to return true on no option page and/or input view page case. | 398 // It's okay to return true on no option page and/or input view page case. |
274 return true; | 399 return true; |
275 } | 400 } |
276 | 401 |
277 // static | 402 // static |
278 void ComponentExtensionIMEManagerImpl::ReadComponentExtensionsInfo( | 403 void ComponentExtensionIMEManagerImpl::ReadComponentExtensionsInfo( |
279 std::vector<ComponentExtensionIME>* out_imes) { | 404 std::vector<ComponentExtensionIME>* out_imes) { |
280 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)); | |
281 DCHECK(out_imes); | 405 DCHECK(out_imes); |
282 for (size_t i = 0; i < arraysize(whitelisted_component_extension); ++i) { | 406 for (size_t i = 0; i < arraysize(whitelisted_component_extension); ++i) { |
283 ComponentExtensionIME component_ime; | 407 ComponentExtensionIME component_ime; |
284 component_ime.path = base::FilePath( | 408 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); |
285 whitelisted_component_extension[i].path); | 409 component_ime.manifest = |
286 | 410 rb.GetRawDataResource( |
287 if (!component_ime.path.IsAbsolute()) { | 411 whitelisted_component_extension[i].manifest_resource_id) |
288 base::FilePath resources_path; | 412 .as_string(); |
289 if (!PathService::Get(chrome::DIR_RESOURCES, &resources_path)) | 413 if (component_ime.manifest.empty()) |
290 NOTREACHED(); | |
291 component_ime.path = resources_path.Append(component_ime.path); | |
292 } | |
293 const base::FilePath manifest_path = | |
294 component_ime.path.Append("manifest.json"); | |
295 | |
296 if (!base::PathExists(component_ime.path) || | |
297 !base::PathExists(manifest_path)) | |
298 continue; | |
299 | |
300 if (!base::ReadFileToString(manifest_path, &component_ime.manifest)) | |
301 continue; | 414 continue; |
302 | 415 |
303 scoped_ptr<base::DictionaryValue> manifest = | 416 scoped_ptr<base::DictionaryValue> manifest = |
304 GetManifest(component_ime.path); | 417 GetManifest(component_ime.manifest); |
305 if (!manifest.get()) | 418 if (!manifest.get()) |
306 continue; | 419 continue; |
307 | 420 |
308 if (!ReadExtensionInfo(*manifest.get(), | 421 if (!ReadExtensionInfo(*manifest.get(), |
309 whitelisted_component_extension[i].id, | 422 whitelisted_component_extension[i].id, |
310 &component_ime)) | 423 &component_ime)) |
311 continue; | 424 continue; |
312 component_ime.id = whitelisted_component_extension[i].id; | 425 component_ime.id = whitelisted_component_extension[i].id; |
313 | 426 |
| 427 if (!component_ime.path.IsAbsolute()) { |
| 428 base::FilePath resources_path; |
| 429 if (!PathService::Get(chrome::DIR_RESOURCES, &resources_path)) |
| 430 NOTREACHED(); |
| 431 component_ime.path = resources_path.Append(component_ime.path); |
| 432 } |
| 433 |
314 const base::ListValue* component_list; | 434 const base::ListValue* component_list; |
315 if (!manifest->GetList(extensions::manifest_keys::kInputComponents, | 435 if (!manifest->GetList(extensions::manifest_keys::kInputComponents, |
316 &component_list)) | 436 &component_list)) |
317 continue; | 437 continue; |
318 | 438 |
319 for (size_t i = 0; i < component_list->GetSize(); ++i) { | 439 for (size_t i = 0; i < component_list->GetSize(); ++i) { |
320 const base::DictionaryValue* dictionary; | 440 const base::DictionaryValue* dictionary; |
321 if (!component_list->GetDictionary(i, &dictionary)) | 441 if (!component_list->GetDictionary(i, &dictionary)) |
322 continue; | 442 continue; |
323 | 443 |
324 ComponentExtensionEngine engine; | 444 ComponentExtensionEngine engine; |
325 ReadEngineComponent(component_ime, *dictionary, &engine); | 445 ReadEngineComponent(component_ime, *dictionary, &engine); |
326 component_ime.engines.push_back(engine); | 446 component_ime.engines.push_back(engine); |
327 } | 447 } |
328 out_imes->push_back(component_ime); | 448 out_imes->push_back(component_ime); |
329 } | 449 } |
330 } | 450 } |
331 | 451 |
332 void ComponentExtensionIMEManagerImpl::OnReadComponentExtensionsInfo( | |
333 std::vector<ComponentExtensionIME>* result, | |
334 const base::Closure& callback) { | |
335 DCHECK(thread_checker_.CalledOnValidThread()); | |
336 DCHECK(result); | |
337 component_extension_list_ = *result; | |
338 is_initialized_ = true; | |
339 callback.Run(); | |
340 } | |
341 | |
342 } // namespace chromeos | 452 } // namespace chromeos |
OLD | NEW |