OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 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/dbus/ibus/ibus_panel_service.h" | |
6 | |
7 #include <string> | |
8 #include "base/bind.h" | |
9 #include "base/callback.h" | |
10 #include "chromeos/dbus/ibus/ibus_constants.h" | |
11 #include "chromeos/dbus/ibus/ibus_engine_service.h" | |
12 #include "chromeos/dbus/ibus/ibus_input_context_client.h" | |
13 #include "chromeos/dbus/ibus/ibus_lookup_table.h" | |
14 #include "chromeos/dbus/ibus/ibus_property.h" | |
15 #include "chromeos/dbus/ibus/ibus_text.h" | |
16 #include "chromeos/ime/ibus_bridge.h" | |
17 #include "dbus/bus.h" | |
18 #include "dbus/exported_object.h" | |
19 #include "dbus/message.h" | |
20 #include "dbus/object_path.h" | |
21 #include "dbus/object_proxy.h" | |
22 | |
23 namespace chromeos { | |
24 | |
25 class IBusPanelServiceImpl : public IBusPanelService { | |
26 public: | |
27 explicit IBusPanelServiceImpl(dbus::Bus* bus, | |
28 IBusInputContextClient* input_context) | |
29 : bus_(bus), | |
30 candidate_window_handler_(NULL), | |
31 property_handler_(NULL), | |
32 weak_ptr_factory_(this) { | |
33 exported_object_ = bus->GetExportedObject( | |
34 dbus::ObjectPath(ibus::panel::kServicePath)); | |
35 | |
36 exported_object_->ExportMethod( | |
37 ibus::panel::kServiceInterface, | |
38 ibus::panel::kUpdateLookupTableMethod, | |
39 base::Bind(&IBusPanelServiceImpl::UpdateLookupTable, | |
40 weak_ptr_factory_.GetWeakPtr()), | |
41 base::Bind(&IBusPanelServiceImpl::OnMethodExported, | |
42 weak_ptr_factory_.GetWeakPtr())); | |
43 | |
44 exported_object_->ExportMethod( | |
45 ibus::panel::kServiceInterface, | |
46 ibus::panel::kHideLookupTableMethod, | |
47 base::Bind(&IBusPanelServiceImpl::HideLookupTable, | |
48 weak_ptr_factory_.GetWeakPtr()), | |
49 base::Bind(&IBusPanelServiceImpl::OnMethodExported, | |
50 weak_ptr_factory_.GetWeakPtr())); | |
51 | |
52 exported_object_->ExportMethod( | |
53 ibus::panel::kServiceInterface, | |
54 ibus::panel::kUpdateAuxiliaryTextMethod, | |
55 base::Bind(&IBusPanelServiceImpl::UpdateAuxiliaryText, | |
56 weak_ptr_factory_.GetWeakPtr()), | |
57 base::Bind(&IBusPanelServiceImpl::OnMethodExported, | |
58 weak_ptr_factory_.GetWeakPtr())); | |
59 | |
60 exported_object_->ExportMethod( | |
61 ibus::panel::kServiceInterface, | |
62 ibus::panel::kHideAuxiliaryTextMethod, | |
63 base::Bind(&IBusPanelServiceImpl::HideAuxiliaryText, | |
64 weak_ptr_factory_.GetWeakPtr()), | |
65 base::Bind(&IBusPanelServiceImpl::OnMethodExported, | |
66 weak_ptr_factory_.GetWeakPtr())); | |
67 | |
68 exported_object_->ExportMethod( | |
69 ibus::panel::kServiceInterface, | |
70 ibus::panel::kUpdatePreeditTextMethod, | |
71 base::Bind(&IBusPanelServiceImpl::UpdatePreeditText, | |
72 weak_ptr_factory_.GetWeakPtr()), | |
73 base::Bind(&IBusPanelServiceImpl::OnMethodExported, | |
74 weak_ptr_factory_.GetWeakPtr())); | |
75 | |
76 exported_object_->ExportMethod( | |
77 ibus::panel::kServiceInterface, | |
78 ibus::panel::kHidePreeditTextMethod, | |
79 base::Bind(&IBusPanelServiceImpl::HidePreeditText, | |
80 weak_ptr_factory_.GetWeakPtr()), | |
81 base::Bind(&IBusPanelServiceImpl::OnMethodExported, | |
82 weak_ptr_factory_.GetWeakPtr())); | |
83 | |
84 exported_object_->ExportMethod( | |
85 ibus::panel::kServiceInterface, | |
86 ibus::panel::kRegisterPropertiesMethod, | |
87 base::Bind(&IBusPanelServiceImpl::RegisterProperties, | |
88 weak_ptr_factory_.GetWeakPtr()), | |
89 base::Bind(&IBusPanelServiceImpl::OnMethodExported, | |
90 weak_ptr_factory_.GetWeakPtr())); | |
91 | |
92 exported_object_->ExportMethod( | |
93 ibus::panel::kServiceInterface, | |
94 ibus::panel::kUpdatePropertyMethod, | |
95 base::Bind(&IBusPanelServiceImpl::UpdateProperty, | |
96 weak_ptr_factory_.GetWeakPtr()), | |
97 base::Bind(&IBusPanelServiceImpl::OnMethodExported, | |
98 weak_ptr_factory_.GetWeakPtr())); | |
99 | |
100 exported_object_->ExportMethod( | |
101 ibus::panel::kServiceInterface, | |
102 ibus::panel::kFocusInMethod, | |
103 base::Bind(&IBusPanelServiceImpl::NoOperation, | |
104 weak_ptr_factory_.GetWeakPtr()), | |
105 base::Bind(&IBusPanelServiceImpl::OnMethodExported, | |
106 weak_ptr_factory_.GetWeakPtr())); | |
107 | |
108 exported_object_->ExportMethod( | |
109 ibus::panel::kServiceInterface, | |
110 ibus::panel::kFocusOutMethod, | |
111 base::Bind(&IBusPanelServiceImpl::NoOperation, | |
112 weak_ptr_factory_.GetWeakPtr()), | |
113 base::Bind(&IBusPanelServiceImpl::OnMethodExported, | |
114 weak_ptr_factory_.GetWeakPtr())); | |
115 | |
116 exported_object_->ExportMethod( | |
117 ibus::panel::kServiceInterface, | |
118 ibus::panel::kStateChangedMethod, | |
119 base::Bind(&IBusPanelServiceImpl::NoOperation, | |
120 weak_ptr_factory_.GetWeakPtr()), | |
121 base::Bind(&IBusPanelServiceImpl::OnMethodExported, | |
122 weak_ptr_factory_.GetWeakPtr())); | |
123 | |
124 // Request well known name to ibus-daemon. | |
125 bus->RequestOwnership( | |
126 ibus::panel::kServiceName, | |
127 dbus::Bus::REQUIRE_PRIMARY, | |
128 base::Bind(&IBusPanelServiceImpl::OnRequestOwnership, | |
129 weak_ptr_factory_.GetWeakPtr())); | |
130 | |
131 input_context->SetSetCursorLocationHandler( | |
132 base::Bind(&IBusPanelServiceImpl::SetCursorLocation, | |
133 weak_ptr_factory_.GetWeakPtr())); | |
134 } | |
135 | |
136 virtual ~IBusPanelServiceImpl() { | |
137 bus_->UnregisterExportedObject( | |
138 dbus::ObjectPath(ibus::panel::kServicePath)); | |
139 } | |
140 | |
141 // IBusPanelService override. | |
142 virtual void SetUpCandidateWindowHandler( | |
143 IBusPanelCandidateWindowHandlerInterface* handler) OVERRIDE { | |
144 DCHECK(handler); | |
145 candidate_window_handler_ = handler; | |
146 } | |
147 | |
148 // IBusPanelService override. | |
149 virtual void SetUpPropertyHandler( | |
150 IBusPanelPropertyHandlerInterface* handler) OVERRIDE { | |
151 DCHECK(handler); | |
152 property_handler_ = handler; | |
153 } | |
154 | |
155 // IBusPanelService override. | |
156 virtual void CandidateClicked(uint32 index, | |
157 ibus::IBusMouseButton button, | |
158 uint32 state) OVERRIDE { | |
159 dbus::Signal signal(ibus::panel::kServiceInterface, | |
160 ibus::panel::kCandidateClickedSignal); | |
161 dbus::MessageWriter writer(&signal); | |
162 writer.AppendUint32(index); | |
163 writer.AppendUint32(static_cast<uint32>(button)); | |
164 writer.AppendUint32(state); | |
165 exported_object_->SendSignal(&signal); | |
166 } | |
167 | |
168 // IBusPanelService override. | |
169 virtual void CursorUp() OVERRIDE { | |
170 dbus::Signal signal(ibus::panel::kServiceInterface, | |
171 ibus::panel::kCursorUpSignal); | |
172 exported_object_->SendSignal(&signal); | |
173 } | |
174 | |
175 // IBusPanelService override. | |
176 virtual void CursorDown() OVERRIDE { | |
177 dbus::Signal signal(ibus::panel::kServiceInterface, | |
178 ibus::panel::kCursorDownSignal); | |
179 exported_object_->SendSignal(&signal); | |
180 } | |
181 | |
182 // IBusPanelService override. | |
183 virtual void PageUp() OVERRIDE { | |
184 dbus::Signal signal(ibus::panel::kServiceInterface, | |
185 ibus::panel::kPageUpSignal); | |
186 exported_object_->SendSignal(&signal); | |
187 } | |
188 | |
189 // IBusPanelService override. | |
190 virtual void PageDown() OVERRIDE { | |
191 dbus::Signal signal(ibus::panel::kServiceInterface, | |
192 ibus::panel::kPageDownSignal); | |
193 exported_object_->SendSignal(&signal); | |
194 } | |
195 | |
196 private: | |
197 // Handles UpdateLookupTable method call from ibus-daemon. | |
198 void UpdateLookupTable(dbus::MethodCall* method_call, | |
199 dbus::ExportedObject::ResponseSender response_sender) { | |
200 if (!candidate_window_handler_) | |
201 return; | |
202 | |
203 dbus::MessageReader reader(method_call); | |
204 IBusLookupTable table; | |
205 if (!PopIBusLookupTable(&reader, &table)) { | |
206 LOG(WARNING) << "UpdateLookupTable called with incorrect parameters: " | |
207 << method_call->ToString(); | |
208 return; | |
209 } | |
210 bool visible = false; | |
211 if (!reader.PopBool(&visible)) { | |
212 LOG(WARNING) << "UpdateLookupTable called with incorrect parameters: " | |
213 << method_call->ToString(); | |
214 return; | |
215 } | |
216 candidate_window_handler_->UpdateLookupTable(table, visible); | |
217 response_sender.Run(dbus::Response::FromMethodCall(method_call)); | |
218 } | |
219 | |
220 // Handles HideLookupTable method call from ibus-daemon. | |
221 void HideLookupTable(dbus::MethodCall* method_call, | |
222 dbus::ExportedObject::ResponseSender response_sender) { | |
223 if (!candidate_window_handler_) | |
224 return; | |
225 | |
226 candidate_window_handler_->HideLookupTable(); | |
227 response_sender.Run(dbus::Response::FromMethodCall(method_call)); | |
228 } | |
229 | |
230 // Handles UpdateAuxiliaryText method call from ibus-daemon. | |
231 void UpdateAuxiliaryText( | |
232 dbus::MethodCall* method_call, | |
233 dbus::ExportedObject::ResponseSender response_sender) { | |
234 if (!candidate_window_handler_) | |
235 return; | |
236 | |
237 dbus::MessageReader reader(method_call); | |
238 std::string text; | |
239 if (!PopStringFromIBusText(&reader, &text)) { | |
240 LOG(WARNING) << "UpdateAuxiliaryText called with incorrect parameters: " | |
241 << method_call->ToString(); | |
242 return; | |
243 } | |
244 bool visible = false; | |
245 if (!reader.PopBool(&visible)) { | |
246 LOG(WARNING) << "UpdateAuxiliaryText called with incorrect parameters: " | |
247 << method_call->ToString(); | |
248 return; | |
249 } | |
250 candidate_window_handler_->UpdateAuxiliaryText(text, visible); | |
251 response_sender.Run(dbus::Response::FromMethodCall(method_call)); | |
252 } | |
253 | |
254 // Handles HideAuxiliaryText method call from ibus-daemon. | |
255 void HideAuxiliaryText(dbus::MethodCall* method_call, | |
256 dbus::ExportedObject::ResponseSender response_sender) { | |
257 if (!candidate_window_handler_) | |
258 return; | |
259 | |
260 candidate_window_handler_->HideAuxiliaryText(); | |
261 response_sender.Run(dbus::Response::FromMethodCall(method_call)); | |
262 } | |
263 | |
264 // Handles UpdatePreeditText method call from ibus-daemon. | |
265 void UpdatePreeditText(dbus::MethodCall* method_call, | |
266 dbus::ExportedObject::ResponseSender response_sender) { | |
267 if (!candidate_window_handler_) | |
268 return; | |
269 | |
270 dbus::MessageReader reader(method_call); | |
271 std::string text; | |
272 if (!PopStringFromIBusText(&reader, &text)) { | |
273 LOG(WARNING) << "UpdatePreeditText called with incorrect parameters: " | |
274 << method_call->ToString(); | |
275 return; | |
276 } | |
277 uint32 cursor_pos = 0; | |
278 if (!reader.PopUint32(&cursor_pos)) { | |
279 LOG(WARNING) << "UpdatePreeditText called with incorrect parameters: " | |
280 << method_call->ToString(); | |
281 return; | |
282 } | |
283 bool visible = false; | |
284 if (!reader.PopBool(&visible)) { | |
285 LOG(WARNING) << "UpdatePreeditText called with incorrect parameters: " | |
286 << method_call->ToString(); | |
287 return; | |
288 } | |
289 candidate_window_handler_->UpdatePreeditText(text, cursor_pos, visible); | |
290 response_sender.Run(dbus::Response::FromMethodCall(method_call)); | |
291 } | |
292 | |
293 // Handles HidePreeditText method call from ibus-daemon. | |
294 void HidePreeditText(dbus::MethodCall* method_call, | |
295 dbus::ExportedObject::ResponseSender response_sender) { | |
296 if (!candidate_window_handler_) | |
297 return; | |
298 | |
299 candidate_window_handler_->HidePreeditText(); | |
300 response_sender.Run(dbus::Response::FromMethodCall(method_call)); | |
301 } | |
302 | |
303 // Handles RegisterProperties method call from ibus-daemon. | |
304 void RegisterProperties( | |
305 dbus::MethodCall* method_call, | |
306 dbus::ExportedObject::ResponseSender response_sender) { | |
307 if (!property_handler_) | |
308 return; | |
309 | |
310 dbus::MessageReader reader(method_call); | |
311 IBusPropertyList properties; | |
312 if (!PopIBusPropertyList(&reader, &properties)) { | |
313 DLOG(WARNING) << "RegisterProperties called with incorrect parameters:" | |
314 << method_call->ToString(); | |
315 return; | |
316 } | |
317 property_handler_->RegisterProperties(properties); | |
318 | |
319 response_sender.Run(dbus::Response::FromMethodCall(method_call)); | |
320 } | |
321 | |
322 // Handles UpdateProperty method call from ibus-daemon. | |
323 void UpdateProperty(dbus::MethodCall* method_call, | |
324 dbus::ExportedObject::ResponseSender response_sender) { | |
325 if (!property_handler_) | |
326 return; | |
327 | |
328 dbus::MessageReader reader(method_call); | |
329 IBusProperty property; | |
330 if (!PopIBusProperty(&reader, &property)) { | |
331 DLOG(WARNING) << "RegisterProperties called with incorrect parameters:" | |
332 << method_call->ToString(); | |
333 return; | |
334 } | |
335 property_handler_->UpdateProperty(property); | |
336 | |
337 response_sender.Run(dbus::Response::FromMethodCall(method_call)); | |
338 } | |
339 | |
340 void SetCursorLocation(const ibus::Rect& cursor_location, | |
341 const ibus::Rect& composition_head) { | |
342 if (candidate_window_handler_) | |
343 candidate_window_handler_->SetCursorLocation(cursor_location, | |
344 composition_head); | |
345 } | |
346 | |
347 // Handles FocusIn, FocusOut, StateChanged method calls from IBus, and ignores | |
348 // them. | |
349 void NoOperation(dbus::MethodCall* method_call, | |
350 dbus::ExportedObject::ResponseSender response_sender) { | |
351 if (!property_handler_) | |
352 return; | |
353 | |
354 response_sender.Run(dbus::Response::FromMethodCall(method_call)); | |
355 } | |
356 | |
357 // Called when the method call is exported. | |
358 void OnMethodExported(const std::string& interface_name, | |
359 const std::string& method_name, | |
360 bool success) { | |
361 LOG_IF(WARNING, !success) << "Failed to export " | |
362 << interface_name << "." << method_name; | |
363 } | |
364 | |
365 // Called when the well knwon name is acquired. | |
366 void OnRequestOwnership(const std::string& name, bool obtained) { | |
367 LOG_IF(ERROR, !obtained) << "Failed to acquire well known name:" | |
368 << name; | |
369 } | |
370 | |
371 // D-Bus bus object used for unregistering exported methods in dtor. | |
372 dbus::Bus* bus_; | |
373 | |
374 // All incoming method calls are passed on to the |candidate_window_handler_| | |
375 // or |property_handler|. This class does not take ownership of following | |
376 // handlers. | |
377 IBusPanelCandidateWindowHandlerInterface* candidate_window_handler_; | |
378 IBusPanelPropertyHandlerInterface* property_handler_; | |
379 | |
380 scoped_refptr<dbus::ExportedObject> exported_object_; | |
381 base::WeakPtrFactory<IBusPanelServiceImpl> weak_ptr_factory_; | |
382 | |
383 DISALLOW_COPY_AND_ASSIGN(IBusPanelServiceImpl); | |
384 }; | |
385 | |
386 // An implementation of IBusPanelService without ibus-daemon interaction. | |
387 // Currently this class is used only on linux desktop. | |
388 // TODO(nona): Use this on ChromeOS device once crbug.com/171351 is fixed. | |
389 class IBusPanelServiceDaemonlessImpl : public IBusPanelService { | |
390 public: | |
391 IBusPanelServiceDaemonlessImpl() {} | |
392 virtual ~IBusPanelServiceDaemonlessImpl() {} | |
393 | |
394 // IBusPanelService override. | |
395 virtual void SetUpCandidateWindowHandler( | |
396 IBusPanelCandidateWindowHandlerInterface* handler) OVERRIDE { | |
397 IBusBridge::Get()->SetCandidateWindowHandler(handler); | |
398 } | |
399 | |
400 // IBusPanelService override. | |
401 virtual void SetUpPropertyHandler( | |
402 IBusPanelPropertyHandlerInterface* handler) OVERRIDE { | |
403 IBusBridge::Get()->SetPropertyHandler(handler); | |
404 } | |
405 | |
406 // IBusPanelService override. | |
407 virtual void CandidateClicked(uint32 index, | |
408 ibus::IBusMouseButton button, | |
409 uint32 state) OVERRIDE { | |
410 IBusEngineHandlerInterface* engine = IBusBridge::Get()->GetEngineHandler(); | |
411 if (engine) | |
412 engine->CandidateClicked(index, button, state); | |
413 } | |
414 | |
415 // IBusPanelService override. | |
416 virtual void CursorUp() OVERRIDE { | |
417 // Cursor Up is not supported on Chrome OS. | |
418 } | |
419 | |
420 // IBusPanelService override. | |
421 virtual void CursorDown() OVERRIDE { | |
422 // Cursor Down is not supported on Chrome OS. | |
423 } | |
424 | |
425 // IBusPanelService override. | |
426 virtual void PageUp() OVERRIDE { | |
427 // Page Up is not supported on Chrome OS. | |
428 } | |
429 | |
430 // IBusPanelService override. | |
431 virtual void PageDown() OVERRIDE { | |
432 // Page Down is not supported on Chrome OS. | |
433 } | |
434 | |
435 private: | |
436 DISALLOW_COPY_AND_ASSIGN(IBusPanelServiceDaemonlessImpl); | |
437 }; | |
438 | |
439 IBusPanelService::IBusPanelService() { | |
440 } | |
441 | |
442 IBusPanelService::~IBusPanelService() { | |
443 } | |
444 | |
445 // static | |
446 IBusPanelService* IBusPanelService::Create( | |
447 DBusClientImplementationType type, | |
448 dbus::Bus* bus, | |
449 IBusInputContextClient* input_context) { | |
450 if (type == REAL_DBUS_CLIENT_IMPLEMENTATION) { | |
451 return new IBusPanelServiceImpl(bus, input_context); | |
452 } else { | |
453 return new IBusPanelServiceDaemonlessImpl(); | |
454 } | |
455 } | |
456 | |
457 } // namespace chromeos | |
OLD | NEW |