d34ef1904e56ed37010ce221ca72de2925dfcf72
[platform/framework/web/crosswalk.git] / src / chromeos / ime / component_extension_ime_manager.cc
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.
4
5 #include "chromeos/ime/component_extension_ime_manager.h"
6
7 #include "base/logging.h"
8 #include "base/strings/string_util.h"
9 #include "chromeos/ime/extension_ime_util.h"
10
11 namespace chromeos {
12
13 namespace {
14
15 // The whitelist for enabling extension based xkb keyboards at login session.
16 const char* kLoginLayoutWhitelist[] = {
17   "be",
18   "br",
19   "ca",
20   "ca(eng)",
21   "ca(multix)",
22   "ch",
23   "ch(fr)",
24   "cz",
25   "cz(qwerty)",
26   "de",
27   "de(neo)",
28   "dk",
29   "ee",
30   "es",
31   "es(cat)",
32   "fi",
33   "fr",
34   "gb(dvorak)",
35   "gb(extd)",
36   "hr",
37   "hu",
38   "is",
39   "it",
40   "jp",
41   "latam",
42   "lt",
43   "lv(apostrophe)",
44   "no",
45   "pl",
46   "pt",
47   "ro",
48   "se",
49   "si",
50   "tr",
51   "us",
52   "us(altgr-intl)",
53   "us(colemak)",
54   "us(dvorak)",
55   "us(intl)"
56 };
57
58 } // namespace
59
60 ComponentExtensionEngine::ComponentExtensionEngine() {
61 }
62
63 ComponentExtensionEngine::~ComponentExtensionEngine() {
64 }
65
66 ComponentExtensionIME::ComponentExtensionIME() {
67 }
68
69 ComponentExtensionIME::~ComponentExtensionIME() {
70 }
71
72 ComponentExtensionIMEManagerDelegate::ComponentExtensionIMEManagerDelegate() {
73 }
74
75 ComponentExtensionIMEManagerDelegate::~ComponentExtensionIMEManagerDelegate() {
76 }
77
78 ComponentExtensionIMEManager::ComponentExtensionIMEManager()
79     : is_initialized_(false), was_initialization_notified_(false) {
80   for (size_t i = 0; i < arraysize(kLoginLayoutWhitelist); ++i) {
81     login_layout_set_.insert(kLoginLayoutWhitelist[i]);
82   }
83 }
84
85 ComponentExtensionIMEManager::~ComponentExtensionIMEManager() {
86 }
87
88 void ComponentExtensionIMEManager::Initialize(
89     scoped_ptr<ComponentExtensionIMEManagerDelegate> delegate) {
90   delegate_ = delegate.Pass();
91   component_extension_imes_ = delegate_->ListIME();
92   is_initialized_ = true;
93 }
94
95 void ComponentExtensionIMEManager::NotifyInitialized() {
96   if (is_initialized_ && !was_initialization_notified_) {
97     FOR_EACH_OBSERVER(
98         Observer, observers_, OnImeComponentExtensionInitialized());
99     was_initialization_notified_ = true;
100   }
101 }
102
103 bool ComponentExtensionIMEManager::IsInitialized() {
104   return is_initialized_;
105 }
106
107 bool ComponentExtensionIMEManager::LoadComponentExtensionIME(
108     const std::string& input_method_id) {
109   ComponentExtensionIME ime;
110   if (FindEngineEntry(input_method_id, &ime, NULL))
111     return delegate_->Load(ime.id, ime.manifest, ime.path);
112   else
113     return false;
114 }
115
116 bool ComponentExtensionIMEManager::UnloadComponentExtensionIME(
117     const std::string& input_method_id) {
118   ComponentExtensionIME ime;
119   if (!FindEngineEntry(input_method_id, &ime, NULL))
120     return false;
121   delegate_->Unload(ime.id, ime.path);
122   return true;
123 }
124
125 bool ComponentExtensionIMEManager::IsWhitelisted(
126     const std::string& input_method_id) {
127   return extension_ime_util::IsComponentExtensionIME(input_method_id) &&
128       FindEngineEntry(input_method_id, NULL, NULL);
129 }
130
131 bool ComponentExtensionIMEManager::IsWhitelistedExtension(
132     const std::string& extension_id) {
133   for (size_t i = 0; i < component_extension_imes_.size(); ++i) {
134     if (component_extension_imes_[i].id == extension_id)
135       return true;
136   }
137   return false;
138 }
139
140 std::string ComponentExtensionIMEManager::GetId(
141     const std::string& extension_id,
142     const std::string& engine_id) {
143   ComponentExtensionEngine engine;
144   const std::string& input_method_id =
145       extension_ime_util::GetComponentInputMethodID(extension_id, engine_id);
146   if (!FindEngineEntry(input_method_id, NULL, &engine))
147     return "";
148   return input_method_id;
149 }
150
151 std::string ComponentExtensionIMEManager::GetName(
152     const std::string& input_method_id) {
153   ComponentExtensionEngine engine;
154   if (!FindEngineEntry(input_method_id, NULL, &engine))
155     return "";
156   return engine.display_name;
157 }
158
159 std::string ComponentExtensionIMEManager::GetDescription(
160     const std::string& input_method_id) {
161   ComponentExtensionEngine engine;
162   if (!FindEngineEntry(input_method_id, NULL, &engine))
163     return "";
164   return engine.description;
165 }
166
167 std::vector<std::string> ComponentExtensionIMEManager::ListIMEByLanguage(
168     const std::string& language) {
169   std::vector<std::string> result;
170   for (size_t i = 0; i < component_extension_imes_.size(); ++i) {
171     for (size_t j = 0; j < component_extension_imes_[i].engines.size(); ++j) {
172       const ComponentExtensionIME& ime = component_extension_imes_[i];
173       if (std::find(ime.engines[j].language_codes.begin(),
174                     ime.engines[j].language_codes.end(),
175                     language) != ime.engines[j].language_codes.end()) {
176         result.push_back(extension_ime_util::GetComponentInputMethodID(
177             ime.id,
178             ime.engines[j].engine_id));
179       }
180     }
181   }
182   return result;
183 }
184
185 input_method::InputMethodDescriptors
186     ComponentExtensionIMEManager::GetAllIMEAsInputMethodDescriptor() {
187   input_method::InputMethodDescriptors result;
188   for (size_t i = 0; i < component_extension_imes_.size(); ++i) {
189     for (size_t j = 0; j < component_extension_imes_[i].engines.size(); ++j) {
190       const std::string input_method_id =
191           extension_ime_util::GetComponentInputMethodID(
192               component_extension_imes_[i].id,
193               component_extension_imes_[i].engines[j].engine_id);
194       const std::vector<std::string>& layouts =
195           component_extension_imes_[i].engines[j].layouts;
196       result.push_back(
197           input_method::InputMethodDescriptor(
198               input_method_id,
199               component_extension_imes_[i].engines[j].display_name,
200               std::string(), // TODO(uekawa): Set short name.
201               layouts,
202               component_extension_imes_[i].engines[j].language_codes,
203               // Enables extension based xkb keyboards on login screen.
204               extension_ime_util::IsKeyboardLayoutExtension(
205                   input_method_id) && IsInLoginLayoutWhitelist(layouts),
206               component_extension_imes_[i].engines[j].options_page_url,
207               component_extension_imes_[i].engines[j].input_view_url));
208     }
209   }
210   return result;
211 }
212
213 input_method::InputMethodDescriptors
214 ComponentExtensionIMEManager::GetXkbIMEAsInputMethodDescriptor() {
215   input_method::InputMethodDescriptors result;
216   const input_method::InputMethodDescriptors& descriptors =
217       GetAllIMEAsInputMethodDescriptor();
218   for (size_t i = 0; i < descriptors.size(); ++i) {
219     if (extension_ime_util::IsKeyboardLayoutExtension(descriptors[i].id()))
220       result.push_back(descriptors[i]);
221   }
222   return result;
223 }
224
225 void ComponentExtensionIMEManager::AddObserver(Observer* observer) {
226   observers_.AddObserver(observer);
227 }
228
229 void ComponentExtensionIMEManager::RemoveObserver(Observer* observer) {
230   observers_.RemoveObserver(observer);
231 }
232
233 bool ComponentExtensionIMEManager::FindEngineEntry(
234     const std::string& input_method_id,
235     ComponentExtensionIME* out_extension,
236     ComponentExtensionEngine* out_engine) {
237   if (!extension_ime_util::IsComponentExtensionIME(input_method_id))
238     return false;
239   for (size_t i = 0; i < component_extension_imes_.size(); ++i) {
240     const std::string extension_id = component_extension_imes_[i].id;
241     const std::vector<ComponentExtensionEngine>& engines =
242         component_extension_imes_[i].engines;
243
244     for (size_t j = 0; j < engines.size(); ++j) {
245       const std::string trial_ime_id =
246           extension_ime_util::GetComponentInputMethodID(
247               extension_id, engines[j].engine_id);
248       if (trial_ime_id != input_method_id)
249         continue;
250
251       if (out_extension)
252         *out_extension = component_extension_imes_[i];
253       if (out_engine)
254         *out_engine = component_extension_imes_[i].engines[j];
255       return true;
256     }
257   }
258   return false;
259 }
260
261 bool ComponentExtensionIMEManager::IsInLoginLayoutWhitelist(
262     const std::vector<std::string>& layouts) {
263   for (size_t i = 0; i < layouts.size(); ++i) {
264     if (login_layout_set_.find(layouts[i]) != login_layout_set_.end())
265       return true;
266   }
267   return false;
268 }
269
270 }  // namespace chromeos