OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2011 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 "chrome/browser/extensions/extension_ime_ui_api.h" | |
6 | |
7 #include <string> | |
8 | |
9 #include "base/json/json_writer.h" | |
10 #include "base/logging.h" | |
11 #include "base/string_util.h" | |
12 #include "base/values.h" | |
13 #include "chrome/browser/extensions/extension_event_router.h" | |
14 #include "chrome/browser/profiles/profile.h" | |
15 #include "third_party/cros/chromeos_cros_api.h" | |
16 #include "third_party/cros/chromeos_input_method_ui.h" | |
17 | |
18 namespace events { | |
19 | |
20 const char kOnUpdateAuxiliaryText[] = | |
21 "experimental.ime.ui.onUpdateAuxiliaryText"; | |
22 const char kOnUpdateLookupTable[] = "experimental.ime.ui.onUpdateLookupTable"; | |
23 const char kOnSetCursorLocation[] = "experimental.ime.ui.onSetCursorLocation"; | |
24 | |
25 } // namespace events | |
26 | |
27 class ImeUiController { | |
28 public: | |
29 explicit ImeUiController(ExtensionImeUiEventRouter* router); | |
30 ~ImeUiController(); | |
31 | |
32 void CandidateClicked(int index, int button, int flags); | |
33 void CursorUp(); | |
34 void CursorDown(); | |
35 void PageUp(); | |
36 void PageDown(); | |
37 private: | |
38 // The function is called when |HideAuxiliaryText| signal is received in | |
39 // libcros. |input_method_library| is a void pointer to this object. | |
Yusuke Sato
2011/04/18 08:21:29
It might be better to rename input_method_library
Peng
2011/04/18 14:35:38
Done.
| |
40 static void OnHideAuxiliaryText(void* input_method_library); | |
41 | |
42 // The function is called when |HideLookupTable| signal is received in | |
43 // libcros. |input_method_library| is a void pointer to this object. | |
44 static void OnHideLookupTable(void* input_method_library); | |
45 | |
46 // The function is called when |SetCursorLocation| signal is received | |
47 // in libcros. |input_method_library| is a void pointer to this object. | |
48 static void OnSetCursorLocation(void* input_method_library, | |
49 int x, | |
50 int y, | |
51 int width, | |
52 int height); | |
53 | |
54 // The function is called when |UpdateAuxiliaryText| signal is received | |
55 // in libcros. |input_method_library| is a void pointer to this object. | |
56 static void OnUpdateAuxiliaryText(void* input_method_library, | |
57 const std::string& utf8_text, | |
58 bool visible); | |
59 | |
60 // The function is called when |UpdateLookupTable| signal is received | |
61 // in libcros. |input_method_library| is a void pointer to this object. | |
62 static void OnUpdateLookupTable(void* input_method_library, | |
63 const chromeos::InputMethodLookupTable& lookup_table); | |
64 | |
65 // This function is called by libcros when ibus connects or disconnects. | |
66 // |input_method_library| is a void pointer to this object. | |
67 static void OnConnectionChange(void* input_method_library, bool connected); | |
68 | |
69 ExtensionImeUiEventRouter* router_; | |
70 chromeos::InputMethodUiStatusConnection* ui_status_connection_; | |
71 | |
72 DISALLOW_COPY_AND_ASSIGN(ImeUiController); | |
73 }; | |
74 | |
75 ImeUiController::ImeUiController( | |
76 ExtensionImeUiEventRouter* router) : | |
77 router_(router), | |
78 ui_status_connection_(NULL) { | |
79 std::string error; | |
80 chromeos::LoadLibcros(NULL, error); | |
81 | |
82 chromeos::InputMethodUiStatusMonitorFunctions functions; | |
83 functions.hide_auxiliary_text = | |
84 &ImeUiController::OnHideAuxiliaryText; | |
85 functions.hide_lookup_table = | |
86 &ImeUiController::OnHideLookupTable; | |
87 functions.set_cursor_location = | |
88 &ImeUiController::OnSetCursorLocation; | |
89 functions.update_auxiliary_text = | |
90 &ImeUiController::OnUpdateAuxiliaryText; | |
91 functions.update_lookup_table = | |
92 &ImeUiController::OnUpdateLookupTable; | |
93 ui_status_connection_ = chromeos::MonitorInputMethodUiStatus(functions, this); | |
94 | |
95 if (!ui_status_connection_) | |
96 LOG(ERROR) << "chromeos::MonitorInputMethodUiStatus() failed!"; | |
97 } | |
98 | |
99 ImeUiController::~ImeUiController() { | |
100 chromeos::DisconnectInputMethodUiStatus(ui_status_connection_); | |
101 } | |
102 | |
103 void ImeUiController::CandidateClicked( | |
104 int index, int button, int flags) { | |
105 chromeos::NotifyCandidateClicked(ui_status_connection_, index, button, flags); | |
106 } | |
107 | |
108 void ImeUiController::CursorUp() { | |
109 chromeos::NotifyCursorUp(ui_status_connection_); | |
110 } | |
111 | |
112 void ImeUiController::CursorDown() { | |
113 chromeos::NotifyCursorDown(ui_status_connection_); | |
114 } | |
115 | |
116 void ImeUiController::PageUp() { | |
117 chromeos::NotifyPageUp(ui_status_connection_); | |
Zachary Kuznia
2011/04/18 03:52:29
CursorUp, CursorDown, PageUp and PageDown are not
Peng
2011/04/18 14:35:38
I think it is necessary for touch devices. Because
| |
118 } | |
119 | |
120 void ImeUiController::PageDown() { | |
121 chromeos::NotifyPageDown(ui_status_connection_); | |
122 } | |
123 | |
124 void ImeUiController::OnHideAuxiliaryText( | |
125 void* input_method_library) { | |
126 ImeUiController *self = static_cast<ImeUiController*>(input_method_library); | |
127 self->router_->OnHideAuxiliaryText(); | |
128 } | |
129 | |
130 void ImeUiController::OnHideLookupTable( | |
131 void* input_method_library) { | |
132 ImeUiController *self = static_cast<ImeUiController*>(input_method_library); | |
133 self->router_->OnHideLookupTable(); | |
134 } | |
135 | |
136 void ImeUiController::OnSetCursorLocation( | |
137 void* input_method_library, | |
138 int x, int y, int width, int height) { | |
139 ImeUiController *self = static_cast<ImeUiController*>(input_method_library); | |
140 self->router_->OnSetCursorLocation(x, y, width, height); | |
141 } | |
142 | |
143 void ImeUiController::OnUpdateAuxiliaryText( | |
144 void* input_method_library, | |
145 const std::string& utf8_text, | |
146 bool visible) { | |
147 ImeUiController *self = static_cast<ImeUiController*>(input_method_library); | |
148 if (!visible) { | |
149 self->router_->OnHideAuxiliaryText(); | |
150 } else { | |
151 self->router_->OnUpdateAuxiliaryText(utf8_text); | |
152 } | |
153 } | |
154 | |
155 void ImeUiController::OnUpdateLookupTable( | |
156 void* input_method_library, | |
157 const chromeos::InputMethodLookupTable& lookup_table) { | |
158 ImeUiController *self = static_cast<ImeUiController*>(input_method_library); | |
159 self->router_->OnUpdateLookupTable(lookup_table); | |
160 } | |
161 | |
162 ExtensionImeUiEventRouter* | |
163 ExtensionImeUiEventRouter::GetInstance() { | |
164 return Singleton<ExtensionImeUiEventRouter>::get(); | |
165 } | |
166 | |
167 ExtensionImeUiEventRouter::ExtensionImeUiEventRouter() | |
168 : profile_(NULL), | |
169 ime_ui_controller_(NULL) { | |
170 } | |
171 | |
172 ExtensionImeUiEventRouter::~ExtensionImeUiEventRouter() { | |
173 delete ime_ui_controller_; | |
174 } | |
175 | |
176 void ExtensionImeUiEventRouter::Init() { | |
177 if (ime_ui_controller_ == NULL) { | |
178 ime_ui_controller_ = new ImeUiController(this); | |
179 } | |
180 } | |
181 | |
182 void ExtensionImeUiEventRouter::Register( | |
183 Profile* profile, const std::string& extension_id) { | |
184 profile_ = profile; | |
185 extension_id_ = extension_id; | |
186 } | |
187 | |
188 void ExtensionImeUiEventRouter::CandidateClicked(Profile* profile, | |
189 const std::string& extension_id, int index, int button) { | |
190 if (profile_ != profile || extension_id_ != extension_id) { | |
191 DLOG(WARNING) << "called from unregistered extension"; | |
192 } | |
193 ime_ui_controller_->CandidateClicked(index, button, 0); | |
194 } | |
195 | |
196 void ExtensionImeUiEventRouter::CursorUp(Profile* profile, | |
197 const std::string& extension_id) { | |
198 if (profile_ != profile || extension_id_ != extension_id) { | |
199 DLOG(WARNING) << "called from unregistered extension"; | |
200 } | |
201 ime_ui_controller_->CursorUp(); | |
202 } | |
203 | |
204 void ExtensionImeUiEventRouter::CursorDown(Profile* profile, | |
205 const std::string& extension_id) { | |
206 if (profile_ != profile || extension_id_ != extension_id) { | |
207 DLOG(WARNING) << "called from unregistered extension"; | |
208 } | |
209 ime_ui_controller_->CursorDown(); | |
210 } | |
211 | |
212 void ExtensionImeUiEventRouter::PageUp(Profile* profile, | |
213 const std::string& extension_id) { | |
214 if (profile_ != profile || extension_id_ != extension_id) { | |
215 DLOG(WARNING) << "called from unregistered extension"; | |
216 } | |
217 ime_ui_controller_->PageUp(); | |
218 } | |
219 | |
220 void ExtensionImeUiEventRouter::PageDown(Profile* profile, | |
221 const std::string& extension_id) { | |
222 if (profile_ != profile || extension_id_ != extension_id) { | |
223 DLOG(WARNING) << "called from unregistered extension"; | |
224 } | |
225 ime_ui_controller_->PageDown(); | |
226 } | |
227 | |
228 void ExtensionImeUiEventRouter::OnHideAuxiliaryText() { | |
229 OnUpdateAuxiliaryText(""); | |
230 } | |
231 | |
232 void ExtensionImeUiEventRouter::OnHideLookupTable() { | |
233 if (profile_ == NULL || extension_id_.empty()) | |
234 return; | |
235 | |
236 DictionaryValue* dict = new DictionaryValue(); | |
237 dict->SetBoolean("visible", false); | |
238 | |
239 ListValue *candidates = new ListValue(); | |
240 dict->Set("candidates", candidates); | |
241 | |
242 ListValue args; | |
243 args.Append(dict); | |
244 | |
245 std::string json_args; | |
246 base::JSONWriter::Write(&args, false, &json_args); | |
247 profile_->GetExtensionEventRouter()->DispatchEventToExtension( | |
248 extension_id_, events::kOnUpdateLookupTable, json_args, profile_, GURL()); | |
249 } | |
250 | |
251 void ExtensionImeUiEventRouter::OnSetCursorLocation( | |
252 int x, int y, int width, int height) { | |
253 | |
254 if (profile_ == NULL || extension_id_.empty()) | |
255 return; | |
256 | |
257 ListValue args; | |
258 args.Append(Value::CreateIntegerValue(x)); | |
259 args.Append(Value::CreateIntegerValue(y)); | |
260 args.Append(Value::CreateIntegerValue(width)); | |
261 args.Append(Value::CreateIntegerValue(height)); | |
262 | |
263 std::string json_args; | |
264 base::JSONWriter::Write(&args, false, &json_args); | |
265 profile_->GetExtensionEventRouter()->DispatchEventToExtension( | |
266 extension_id_, events::kOnSetCursorLocation, json_args, profile_, GURL()); | |
267 } | |
268 | |
269 void ExtensionImeUiEventRouter::OnUpdateAuxiliaryText( | |
270 const std::string& utf8_text) { | |
271 if (profile_ == NULL || extension_id_.empty()) | |
272 return; | |
273 | |
274 ListValue args; | |
275 args.Append(Value::CreateStringValue(utf8_text)); | |
276 | |
277 std::string json_args; | |
278 base::JSONWriter::Write(&args, false, &json_args); | |
279 profile_->GetExtensionEventRouter()->DispatchEventToExtension( | |
280 extension_id_, events::kOnUpdateAuxiliaryText, json_args, profile_, GURL()); | |
281 } | |
282 | |
283 void ExtensionImeUiEventRouter::OnUpdateLookupTable( | |
284 const chromeos::InputMethodLookupTable& lookup_table) { | |
285 if (profile_ == NULL || extension_id_.empty()) | |
286 return; | |
287 | |
288 DictionaryValue* dict = new DictionaryValue(); | |
289 dict->SetBoolean("visible", lookup_table.visible); | |
290 | |
291 if (lookup_table.visible) { | |
292 } | |
293 | |
294 ListValue *candidates = new ListValue(); | |
295 for (size_t i = 0; i < lookup_table.candidates.size(); i++) { | |
296 candidates->Append(Value::CreateStringValue(lookup_table.candidates[i])); | |
297 } | |
298 | |
299 dict->Set("candidates", candidates); | |
300 | |
301 ListValue args; | |
302 args.Append(dict); | |
303 | |
304 std::string json_args; | |
305 base::JSONWriter::Write(&args, false, &json_args); | |
306 profile_->GetExtensionEventRouter()->DispatchEventToExtension( | |
307 extension_id_, events::kOnUpdateLookupTable, json_args, profile_, GURL()); | |
308 } | |
309 | |
310 void ImeUiFunction::Run() { | |
311 SendResponse(RunImpl()); | |
312 } | |
313 | |
314 bool RegisterImeUiFunction::RunImpl() { | |
315 ExtensionImeUiEventRouter::GetInstance()->Register( | |
316 profile(), extension_id()); | |
317 return true; | |
318 } | |
319 | |
320 bool CandidateClickedImeUiFunction::RunImpl() { | |
321 int index = 0; | |
322 int button = 0; | |
323 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &index)); | |
324 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(1, &button)); | |
325 | |
326 ExtensionImeUiEventRouter::GetInstance()->CandidateClicked( | |
327 profile(), extension_id(), index, button); | |
328 | |
329 return true; | |
330 } | |
331 | |
332 bool CursorUpImeUiFunction::RunImpl() { | |
333 ExtensionImeUiEventRouter::GetInstance()->CursorUp( | |
334 profile(), extension_id()); | |
335 return true; | |
336 } | |
337 | |
338 bool CursorDownImeUiFunction::RunImpl() { | |
339 ExtensionImeUiEventRouter::GetInstance()->CursorDown( | |
340 profile(), extension_id()); | |
341 return true; | |
342 } | |
343 | |
344 bool PageUpImeUiFunction::RunImpl() { | |
345 ExtensionImeUiEventRouter::GetInstance()->PageUp( | |
346 profile(), extension_id()); | |
347 return true; | |
348 } | |
349 | |
350 bool PageDownImeUiFunction::RunImpl() { | |
351 ExtensionImeUiEventRouter::GetInstance()->PageDown( | |
352 profile(), extension_id()); | |
353 return true; | |
354 } | |
355 | |
OLD | NEW |