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.
5 #include "chromeos/dbus/ibus/ibus_panel_service.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"
18 #include "dbus/exported_object.h"
19 #include "dbus/message.h"
20 #include "dbus/object_path.h"
21 #include "dbus/object_proxy.h"
25 class IBusPanelServiceImpl
: public IBusPanelService
{
27 explicit IBusPanelServiceImpl(dbus::Bus
* bus
,
28 IBusInputContextClient
* input_context
)
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
));
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()));
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()));
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()));
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()));
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()));
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()));
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()));
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()));
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()));
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()));
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()));
124 // Request well known name to ibus-daemon.
125 bus
->RequestOwnership(
126 ibus::panel::kServiceName
,
127 base::Bind(&IBusPanelServiceImpl::OnRequestOwnership
,
128 weak_ptr_factory_
.GetWeakPtr()));
130 input_context
->SetSetCursorLocationHandler(
131 base::Bind(&IBusPanelServiceImpl::SetCursorLocation
,
132 weak_ptr_factory_
.GetWeakPtr()));
135 virtual ~IBusPanelServiceImpl() {
136 bus_
->UnregisterExportedObject(
137 dbus::ObjectPath(ibus::panel::kServicePath
));
140 // IBusPanelService override.
141 virtual void SetUpCandidateWindowHandler(
142 IBusPanelCandidateWindowHandlerInterface
* handler
) OVERRIDE
{
144 candidate_window_handler_
= handler
;
147 // IBusPanelService override.
148 virtual void SetUpPropertyHandler(
149 IBusPanelPropertyHandlerInterface
* handler
) OVERRIDE
{
151 property_handler_
= handler
;
154 // IBusPanelService override.
155 virtual void CandidateClicked(uint32 index
,
156 ibus::IBusMouseButton button
,
157 uint32 state
) OVERRIDE
{
158 dbus::Signal
signal(ibus::panel::kServiceInterface
,
159 ibus::panel::kCandidateClickedSignal
);
160 dbus::MessageWriter
writer(&signal
);
161 writer
.AppendUint32(index
);
162 writer
.AppendUint32(static_cast<uint32
>(button
));
163 writer
.AppendUint32(state
);
164 exported_object_
->SendSignal(&signal
);
167 // IBusPanelService override.
168 virtual void CursorUp() OVERRIDE
{
169 dbus::Signal
signal(ibus::panel::kServiceInterface
,
170 ibus::panel::kCursorUpSignal
);
171 exported_object_
->SendSignal(&signal
);
174 // IBusPanelService override.
175 virtual void CursorDown() OVERRIDE
{
176 dbus::Signal
signal(ibus::panel::kServiceInterface
,
177 ibus::panel::kCursorDownSignal
);
178 exported_object_
->SendSignal(&signal
);
181 // IBusPanelService override.
182 virtual void PageUp() OVERRIDE
{
183 dbus::Signal
signal(ibus::panel::kServiceInterface
,
184 ibus::panel::kPageUpSignal
);
185 exported_object_
->SendSignal(&signal
);
188 // IBusPanelService override.
189 virtual void PageDown() OVERRIDE
{
190 dbus::Signal
signal(ibus::panel::kServiceInterface
,
191 ibus::panel::kPageDownSignal
);
192 exported_object_
->SendSignal(&signal
);
196 // Handles UpdateLookupTable method call from ibus-daemon.
197 void UpdateLookupTable(dbus::MethodCall
* method_call
,
198 dbus::ExportedObject::ResponseSender response_sender
) {
199 if (!candidate_window_handler_
)
202 dbus::MessageReader
reader(method_call
);
203 IBusLookupTable table
;
204 if (!PopIBusLookupTable(&reader
, &table
)) {
205 LOG(WARNING
) << "UpdateLookupTable called with incorrect parameters: "
206 << method_call
->ToString();
209 bool visible
= false;
210 if (!reader
.PopBool(&visible
)) {
211 LOG(WARNING
) << "UpdateLookupTable called with incorrect parameters: "
212 << method_call
->ToString();
215 candidate_window_handler_
->UpdateLookupTable(table
, visible
);
216 response_sender
.Run(dbus::Response::FromMethodCall(method_call
));
219 // Handles HideLookupTable method call from ibus-daemon.
220 void HideLookupTable(dbus::MethodCall
* method_call
,
221 dbus::ExportedObject::ResponseSender response_sender
) {
222 if (!candidate_window_handler_
)
225 candidate_window_handler_
->HideLookupTable();
226 response_sender
.Run(dbus::Response::FromMethodCall(method_call
));
229 // Handles UpdateAuxiliaryText method call from ibus-daemon.
230 void UpdateAuxiliaryText(
231 dbus::MethodCall
* method_call
,
232 dbus::ExportedObject::ResponseSender response_sender
) {
233 if (!candidate_window_handler_
)
236 dbus::MessageReader
reader(method_call
);
238 if (!PopStringFromIBusText(&reader
, &text
)) {
239 LOG(WARNING
) << "UpdateAuxiliaryText called with incorrect parameters: "
240 << method_call
->ToString();
243 bool visible
= false;
244 if (!reader
.PopBool(&visible
)) {
245 LOG(WARNING
) << "UpdateAuxiliaryText called with incorrect parameters: "
246 << method_call
->ToString();
249 candidate_window_handler_
->UpdateAuxiliaryText(text
, visible
);
250 response_sender
.Run(dbus::Response::FromMethodCall(method_call
));
253 // Handles HideAuxiliaryText method call from ibus-daemon.
254 void HideAuxiliaryText(dbus::MethodCall
* method_call
,
255 dbus::ExportedObject::ResponseSender response_sender
) {
256 if (!candidate_window_handler_
)
259 candidate_window_handler_
->HideAuxiliaryText();
260 response_sender
.Run(dbus::Response::FromMethodCall(method_call
));
263 // Handles UpdatePreeditText method call from ibus-daemon.
264 void UpdatePreeditText(dbus::MethodCall
* method_call
,
265 dbus::ExportedObject::ResponseSender response_sender
) {
266 if (!candidate_window_handler_
)
269 dbus::MessageReader
reader(method_call
);
271 if (!PopStringFromIBusText(&reader
, &text
)) {
272 LOG(WARNING
) << "UpdatePreeditText called with incorrect parameters: "
273 << method_call
->ToString();
276 uint32 cursor_pos
= 0;
277 if (!reader
.PopUint32(&cursor_pos
)) {
278 LOG(WARNING
) << "UpdatePreeditText called with incorrect parameters: "
279 << method_call
->ToString();
282 bool visible
= false;
283 if (!reader
.PopBool(&visible
)) {
284 LOG(WARNING
) << "UpdatePreeditText called with incorrect parameters: "
285 << method_call
->ToString();
288 candidate_window_handler_
->UpdatePreeditText(text
, cursor_pos
, visible
);
289 response_sender
.Run(dbus::Response::FromMethodCall(method_call
));
292 // Handles HidePreeditText method call from ibus-daemon.
293 void HidePreeditText(dbus::MethodCall
* method_call
,
294 dbus::ExportedObject::ResponseSender response_sender
) {
295 if (!candidate_window_handler_
)
298 candidate_window_handler_
->HidePreeditText();
299 response_sender
.Run(dbus::Response::FromMethodCall(method_call
));
302 // Handles RegisterProperties method call from ibus-daemon.
303 void RegisterProperties(
304 dbus::MethodCall
* method_call
,
305 dbus::ExportedObject::ResponseSender response_sender
) {
306 if (!property_handler_
)
309 dbus::MessageReader
reader(method_call
);
310 IBusPropertyList properties
;
311 if (!PopIBusPropertyList(&reader
, &properties
)) {
312 DLOG(WARNING
) << "RegisterProperties called with incorrect parameters:"
313 << method_call
->ToString();
316 property_handler_
->RegisterProperties(properties
);
318 response_sender
.Run(dbus::Response::FromMethodCall(method_call
));
321 // Handles UpdateProperty method call from ibus-daemon.
322 void UpdateProperty(dbus::MethodCall
* method_call
,
323 dbus::ExportedObject::ResponseSender response_sender
) {
324 if (!property_handler_
)
327 dbus::MessageReader
reader(method_call
);
328 IBusProperty property
;
329 if (!PopIBusProperty(&reader
, &property
)) {
330 DLOG(WARNING
) << "RegisterProperties called with incorrect parameters:"
331 << method_call
->ToString();
334 property_handler_
->UpdateProperty(property
);
336 response_sender
.Run(dbus::Response::FromMethodCall(method_call
));
339 void SetCursorLocation(const ibus::Rect
& cursor_location
,
340 const ibus::Rect
& composition_head
) {
341 if (candidate_window_handler_
)
342 candidate_window_handler_
->SetCursorLocation(cursor_location
,
346 // Handles FocusIn, FocusOut, StateChanged method calls from IBus, and ignores
348 void NoOperation(dbus::MethodCall
* method_call
,
349 dbus::ExportedObject::ResponseSender response_sender
) {
350 if (!property_handler_
)
353 response_sender
.Run(dbus::Response::FromMethodCall(method_call
));
356 // Called when the method call is exported.
357 void OnMethodExported(const std::string
& interface_name
,
358 const std::string
& method_name
,
360 LOG_IF(WARNING
, !success
) << "Failed to export "
361 << interface_name
<< "." << method_name
;
364 // Called when the well knwon name is acquired.
365 void OnRequestOwnership(const std::string
& name
, bool obtained
) {
366 LOG_IF(ERROR
, !obtained
) << "Failed to acquire well known name:"
370 // D-Bus bus object used for unregistering exported methods in dtor.
373 // All incoming method calls are passed on to the |candidate_window_handler_|
374 // or |property_handler|. This class does not take ownership of following
376 IBusPanelCandidateWindowHandlerInterface
* candidate_window_handler_
;
377 IBusPanelPropertyHandlerInterface
* property_handler_
;
379 scoped_refptr
<dbus::ExportedObject
> exported_object_
;
380 base::WeakPtrFactory
<IBusPanelServiceImpl
> weak_ptr_factory_
;
382 DISALLOW_COPY_AND_ASSIGN(IBusPanelServiceImpl
);
385 // An implementation of IBusPanelService without ibus-daemon interaction.
386 // Currently this class is used only on linux desktop.
387 // TODO(nona): Use this on ChromeOS device once crbug.com/171351 is fixed.
388 class IBusPanelServiceDaemonlessImpl
: public IBusPanelService
{
390 IBusPanelServiceDaemonlessImpl() {}
391 virtual ~IBusPanelServiceDaemonlessImpl() {}
393 // IBusPanelService override.
394 virtual void SetUpCandidateWindowHandler(
395 IBusPanelCandidateWindowHandlerInterface
* handler
) OVERRIDE
{
396 IBusBridge::Get()->SetCandidateWindowHandler(handler
);
399 // IBusPanelService override.
400 virtual void SetUpPropertyHandler(
401 IBusPanelPropertyHandlerInterface
* handler
) OVERRIDE
{
402 IBusBridge::Get()->SetPropertyHandler(handler
);
405 // IBusPanelService override.
406 virtual void CandidateClicked(uint32 index
,
407 ibus::IBusMouseButton button
,
408 uint32 state
) OVERRIDE
{
409 IBusEngineHandlerInterface
* engine
= IBusBridge::Get()->GetEngineHandler();
411 engine
->CandidateClicked(index
, button
, state
);
414 // IBusPanelService override.
415 virtual void CursorUp() OVERRIDE
{
416 // Cursor Up is not supported on Chrome OS.
419 // IBusPanelService override.
420 virtual void CursorDown() OVERRIDE
{
421 // Cursor Down is not supported on Chrome OS.
424 // IBusPanelService override.
425 virtual void PageUp() OVERRIDE
{
426 // Page Up is not supported on Chrome OS.
429 // IBusPanelService override.
430 virtual void PageDown() OVERRIDE
{
431 // Page Down is not supported on Chrome OS.
435 DISALLOW_COPY_AND_ASSIGN(IBusPanelServiceDaemonlessImpl
);
438 IBusPanelService::IBusPanelService() {
441 IBusPanelService::~IBusPanelService() {
445 IBusPanelService
* IBusPanelService::Create(
446 DBusClientImplementationType type
,
448 IBusInputContextClient
* input_context
) {
449 if (type
== REAL_DBUS_CLIENT_IMPLEMENTATION
) {
450 return new IBusPanelServiceImpl(bus
, input_context
);
452 return new IBusPanelServiceDaemonlessImpl();
456 } // namespace chromeos