Add ICU message format support
[chromium-blink-merge.git] / ui / base / ime / chromeos / component_extension_ime_manager.cc
blob69f1d88ef74e8e65d90b22b965375ac68809c761
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
3 // found in the LICENSE file.
5 #include "ui/base/ime/chromeos/component_extension_ime_manager.h"
7 #include "base/command_line.h"
8 #include "base/logging.h"
9 #include "base/strings/string_util.h"
10 #include "chromeos/chromeos_switches.h"
11 #include "ui/base/ime/chromeos/extension_ime_util.h"
13 namespace chromeos {
15 namespace {
17 // The whitelist for enabling extension based xkb keyboards at login session.
18 const char* kLoginLayoutWhitelist[] = {
19 "be",
20 "br",
21 "ca",
22 "ca(eng)",
23 "ca(multix)",
24 "ch",
25 "ch(fr)",
26 "cz",
27 "cz(qwerty)",
28 "de",
29 "de(neo)",
30 "dk",
31 "ee",
32 "es",
33 "es(cat)",
34 "fi",
35 "fr",
36 "gb(dvorak)",
37 "gb(extd)",
38 "hr",
39 "hu",
40 "ie",
41 "is",
42 "it",
43 "jp",
44 "latam",
45 "lt",
46 "lv(apostrophe)",
47 "mt",
48 "no",
49 "pl",
50 "pt",
51 "ro",
52 "se",
53 "si",
54 "tr",
55 "us",
56 "us(altgr-intl)",
57 "us(colemak)",
58 "us(dvorak)",
59 "us(dvp)",
60 "us(intl)"
63 // Gets the input method category according to the given input method id.
64 // This is used for sorting a list of input methods.
65 int GetInputMethodCategory(const std::string& id) {
66 const std::string engine_id =
67 chromeos::extension_ime_util::GetComponentIDByInputMethodID(id);
68 if (base::StartsWith(engine_id, "xkb:", base::CompareCase::SENSITIVE))
69 return 0;
70 if (base::StartsWith(engine_id, "vkd_", base::CompareCase::SENSITIVE))
71 return 1;
72 if (engine_id.find("-t-i0-") != std::string::npos &&
73 !base::StartsWith(engine_id, "zh-", base::CompareCase::SENSITIVE)) {
74 return 2;
76 return 3;
79 bool InputMethodCompare(const input_method::InputMethodDescriptor& im1,
80 const input_method::InputMethodDescriptor& im2) {
81 return GetInputMethodCategory(im1.id()) < GetInputMethodCategory(im2.id());
84 } // namespace
86 ComponentExtensionEngine::ComponentExtensionEngine() {
89 ComponentExtensionEngine::~ComponentExtensionEngine() {
92 ComponentExtensionIME::ComponentExtensionIME() {
95 ComponentExtensionIME::~ComponentExtensionIME() {
98 ComponentExtensionIMEManagerDelegate::ComponentExtensionIMEManagerDelegate() {
101 ComponentExtensionIMEManagerDelegate::~ComponentExtensionIMEManagerDelegate() {
104 ComponentExtensionIMEManager::ComponentExtensionIMEManager() {
105 for (size_t i = 0; i < arraysize(kLoginLayoutWhitelist); ++i) {
106 login_layout_set_.insert(kLoginLayoutWhitelist[i]);
110 ComponentExtensionIMEManager::~ComponentExtensionIMEManager() {
113 void ComponentExtensionIMEManager::Initialize(
114 scoped_ptr<ComponentExtensionIMEManagerDelegate> delegate) {
115 delegate_ = delegate.Pass();
116 std::vector<ComponentExtensionIME> ext_list = delegate_->ListIME();
117 for (size_t i = 0; i < ext_list.size(); ++i) {
118 ComponentExtensionIME& ext = ext_list[i];
119 bool extension_exists = IsWhitelistedExtension(ext.id);
120 if (!extension_exists)
121 component_extension_imes_[ext.id] = ext;
122 for (size_t j = 0; j < ext.engines.size(); ++j) {
123 ComponentExtensionEngine& ime = ext.engines[j];
124 const std::string input_method_id =
125 extension_ime_util::GetComponentInputMethodID(ext.id, ime.engine_id);
126 if (extension_exists && !IsWhitelisted(input_method_id))
127 component_extension_imes_[ext.id].engines.push_back(ime);
128 input_method_id_set_.insert(input_method_id);
133 bool ComponentExtensionIMEManager::LoadComponentExtensionIME(
134 Profile* profile,
135 const std::string& input_method_id) {
136 ComponentExtensionIME ime;
137 if (FindEngineEntry(input_method_id, &ime)) {
138 delegate_->Load(profile, ime.id, ime.manifest, ime.path);
139 return true;
141 return false;
144 bool ComponentExtensionIMEManager::UnloadComponentExtensionIME(
145 Profile* profile,
146 const std::string& input_method_id) {
147 ComponentExtensionIME ime;
148 if (!FindEngineEntry(input_method_id, &ime))
149 return false;
150 delegate_->Unload(profile, ime.id, ime.path);
151 return true;
154 bool ComponentExtensionIMEManager::IsWhitelisted(
155 const std::string& input_method_id) {
156 return input_method_id_set_.find(input_method_id) !=
157 input_method_id_set_.end();
160 bool ComponentExtensionIMEManager::IsWhitelistedExtension(
161 const std::string& extension_id) {
162 return component_extension_imes_.find(extension_id) !=
163 component_extension_imes_.end();
166 input_method::InputMethodDescriptors
167 ComponentExtensionIMEManager::GetAllIMEAsInputMethodDescriptor() {
168 bool enable_new_korean_ime =
169 !base::CommandLine::ForCurrentProcess()->HasSwitch(
170 switches::kDisableNewKoreanIme);
171 input_method::InputMethodDescriptors result;
172 for (std::map<std::string, ComponentExtensionIME>::const_iterator it =
173 component_extension_imes_.begin();
174 it != component_extension_imes_.end(); ++it) {
175 const ComponentExtensionIME& ext = it->second;
176 for (size_t j = 0; j < ext.engines.size(); ++j) {
177 const ComponentExtensionEngine& ime = ext.engines[j];
178 // Filter out new Korean IME if the experimental flag is OFF.
179 if (!enable_new_korean_ime && ime.engine_id == "ko-t-i0-und")
180 continue;
181 const std::string input_method_id =
182 extension_ime_util::GetComponentInputMethodID(
183 ext.id, ime.engine_id);
184 const std::vector<std::string>& layouts = ime.layouts;
185 result.push_back(
186 input_method::InputMethodDescriptor(
187 input_method_id,
188 ime.display_name,
189 ime.indicator,
190 layouts,
191 ime.language_codes,
192 // Enables extension based xkb keyboards on login screen.
193 extension_ime_util::IsKeyboardLayoutExtension(
194 input_method_id) && IsInLoginLayoutWhitelist(layouts),
195 ime.options_page_url,
196 ime.input_view_url));
199 std::stable_sort(result.begin(), result.end(), InputMethodCompare);
200 return result;
203 input_method::InputMethodDescriptors
204 ComponentExtensionIMEManager::GetXkbIMEAsInputMethodDescriptor() {
205 input_method::InputMethodDescriptors result;
206 const input_method::InputMethodDescriptors& descriptors =
207 GetAllIMEAsInputMethodDescriptor();
208 for (size_t i = 0; i < descriptors.size(); ++i) {
209 if (extension_ime_util::IsKeyboardLayoutExtension(descriptors[i].id()))
210 result.push_back(descriptors[i]);
212 return result;
215 bool ComponentExtensionIMEManager::FindEngineEntry(
216 const std::string& input_method_id,
217 ComponentExtensionIME* out_extension) {
218 if (!IsWhitelisted(input_method_id))
219 return false;
221 std::string extension_id =
222 extension_ime_util::GetExtensionIDFromInputMethodID(input_method_id);
223 std::map<std::string, ComponentExtensionIME>::iterator it =
224 component_extension_imes_.find(extension_id);
225 if (it == component_extension_imes_.end())
226 return false;
228 if (out_extension)
229 *out_extension = it->second;
230 return true;
233 bool ComponentExtensionIMEManager::IsInLoginLayoutWhitelist(
234 const std::vector<std::string>& layouts) {
235 for (size_t i = 0; i < layouts.size(); ++i) {
236 if (login_layout_set_.find(layouts[i]) != login_layout_set_.end())
237 return true;
239 return false;
242 } // namespace chromeos