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_engine_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_input_context_client.h"
12#include "chromeos/dbus/ibus/ibus_lookup_table.h"
13#include "chromeos/dbus/ibus/ibus_panel_service.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
23namespace chromeos {
24
25class IBusEngineServiceImpl : public IBusEngineService {
26 public:
27  IBusEngineServiceImpl(dbus::Bus* bus,
28                        const dbus::ObjectPath& object_path)
29      : bus_(bus),
30        engine_handler_(NULL),
31        object_path_(object_path),
32        weak_ptr_factory_(this) {
33    exported_object_ = bus->GetExportedObject(object_path_);
34
35    exported_object_->ExportMethod(
36        ibus::engine::kServiceInterface,
37        ibus::engine::kFocusInMethod,
38        base::Bind(&IBusEngineServiceImpl::FocusIn,
39                   weak_ptr_factory_.GetWeakPtr()),
40        base::Bind(&IBusEngineServiceImpl::OnMethodExported,
41                   weak_ptr_factory_.GetWeakPtr()));
42
43    exported_object_->ExportMethod(
44        ibus::engine::kServiceInterface,
45        ibus::engine::kFocusOutMethod,
46        base::Bind(&IBusEngineServiceImpl::FocusOut,
47                   weak_ptr_factory_.GetWeakPtr()),
48        base::Bind(&IBusEngineServiceImpl::OnMethodExported,
49                   weak_ptr_factory_.GetWeakPtr()));
50
51    exported_object_->ExportMethod(
52        ibus::engine::kServiceInterface,
53        ibus::engine::kEnableMethod,
54        base::Bind(&IBusEngineServiceImpl::Enable,
55                   weak_ptr_factory_.GetWeakPtr()),
56        base::Bind(&IBusEngineServiceImpl::OnMethodExported,
57                   weak_ptr_factory_.GetWeakPtr()));
58
59    exported_object_->ExportMethod(
60        ibus::engine::kServiceInterface,
61        ibus::engine::kDisableMethod,
62        base::Bind(&IBusEngineServiceImpl::Disable,
63                   weak_ptr_factory_.GetWeakPtr()),
64        base::Bind(&IBusEngineServiceImpl::OnMethodExported,
65                   weak_ptr_factory_.GetWeakPtr()));
66
67    exported_object_->ExportMethod(
68        ibus::engine::kServiceInterface,
69        ibus::engine::kPropertyActivateMethod,
70        base::Bind(&IBusEngineServiceImpl::PropertyActivate,
71                   weak_ptr_factory_.GetWeakPtr()),
72        base::Bind(&IBusEngineServiceImpl::OnMethodExported,
73                   weak_ptr_factory_.GetWeakPtr()));
74
75    exported_object_->ExportMethod(
76        ibus::engine::kServiceInterface,
77        ibus::engine::kPropertyShowMethod,
78        base::Bind(&IBusEngineServiceImpl::PropertyShow,
79                   weak_ptr_factory_.GetWeakPtr()),
80        base::Bind(&IBusEngineServiceImpl::OnMethodExported,
81                   weak_ptr_factory_.GetWeakPtr()));
82
83    exported_object_->ExportMethod(
84        ibus::engine::kServiceInterface,
85        ibus::engine::kPropertyHideMethod,
86        base::Bind(&IBusEngineServiceImpl::PropertyHide,
87                   weak_ptr_factory_.GetWeakPtr()),
88        base::Bind(&IBusEngineServiceImpl::OnMethodExported,
89                   weak_ptr_factory_.GetWeakPtr()));
90
91    exported_object_->ExportMethod(
92        ibus::engine::kServiceInterface,
93        ibus::engine::kSetCapabilityMethod,
94        base::Bind(&IBusEngineServiceImpl::SetCapability,
95                   weak_ptr_factory_.GetWeakPtr()),
96        base::Bind(&IBusEngineServiceImpl::OnMethodExported,
97                   weak_ptr_factory_.GetWeakPtr()));
98
99    exported_object_->ExportMethod(
100        ibus::engine::kServiceInterface,
101        ibus::engine::kResetMethod,
102        base::Bind(&IBusEngineServiceImpl::Reset,
103                   weak_ptr_factory_.GetWeakPtr()),
104        base::Bind(&IBusEngineServiceImpl::OnMethodExported,
105                   weak_ptr_factory_.GetWeakPtr()));
106
107    exported_object_->ExportMethod(
108        ibus::engine::kServiceInterface,
109        ibus::engine::kProcessKeyEventMethod,
110        base::Bind(&IBusEngineServiceImpl::ProcessKeyEvent,
111                   weak_ptr_factory_.GetWeakPtr()),
112        base::Bind(&IBusEngineServiceImpl::OnMethodExported,
113                   weak_ptr_factory_.GetWeakPtr()));
114
115    exported_object_->ExportMethod(
116        ibus::engine::kServiceInterface,
117        ibus::engine::kCandidateClickedMethod,
118        base::Bind(&IBusEngineServiceImpl::CandidateClicked,
119                   weak_ptr_factory_.GetWeakPtr()),
120        base::Bind(&IBusEngineServiceImpl::OnMethodExported,
121                   weak_ptr_factory_.GetWeakPtr()));
122
123    exported_object_->ExportMethod(
124        ibus::engine::kServiceInterface,
125        ibus::engine::kSetSurroundingTextMethod,
126        base::Bind(&IBusEngineServiceImpl::SetSurroundingText,
127                   weak_ptr_factory_.GetWeakPtr()),
128        base::Bind(&IBusEngineServiceImpl::OnMethodExported,
129                   weak_ptr_factory_.GetWeakPtr()));
130  }
131
132  virtual ~IBusEngineServiceImpl() {
133    bus_->UnregisterExportedObject(object_path_);
134  }
135
136  // IBusEngineService override.
137  virtual void SetEngine(IBusEngineHandlerInterface* handler) OVERRIDE {
138    DVLOG_IF(1, engine_handler_ != NULL) << "Replace engine.";
139    if (engine_handler_)
140      engine_handler_->Disable();
141    engine_handler_ = handler;
142  }
143
144  // IBusEngineService override.
145  virtual void UnsetEngine(IBusEngineHandlerInterface* handler) OVERRIDE {
146    if (engine_handler_ == handler)
147      engine_handler_ = NULL;
148  }
149
150  // IBusEngineService override.
151  virtual void RegisterProperties(
152      const IBusPropertyList& property_list) OVERRIDE {
153    dbus::Signal signal(ibus::engine::kServiceInterface,
154                        ibus::engine::kRegisterPropertiesSignal);
155    dbus::MessageWriter writer(&signal);
156    AppendIBusPropertyList(property_list, &writer);
157    exported_object_->SendSignal(&signal);
158  }
159
160  // IBusEngineService override.
161  virtual void UpdatePreedit(const IBusText& ibus_text,
162                             uint32 cursor_pos,
163                             bool is_visible,
164                             IBusEnginePreeditFocusOutMode mode) OVERRIDE {
165    dbus::Signal signal(ibus::engine::kServiceInterface,
166                        ibus::engine::kUpdatePreeditSignal);
167    dbus::MessageWriter writer(&signal);
168    AppendIBusText(ibus_text, &writer);
169    writer.AppendUint32(cursor_pos);
170    writer.AppendBool(is_visible);
171    writer.AppendUint32(static_cast<uint32>(mode));
172    exported_object_->SendSignal(&signal);
173  }
174
175  // IBusEngineService override.
176  virtual void UpdateAuxiliaryText(const IBusText& ibus_text,
177                                   bool is_visible) OVERRIDE {
178    dbus::Signal signal(ibus::engine::kServiceInterface,
179                        ibus::engine::kUpdateAuxiliaryTextSignal);
180    dbus::MessageWriter writer(&signal);
181    AppendIBusText(ibus_text, &writer);
182    writer.AppendBool(is_visible);
183    exported_object_->SendSignal(&signal);
184  }
185
186  // IBusEngineService override.
187  virtual void UpdateLookupTable(const IBusLookupTable& lookup_table,
188                                 bool is_visible) OVERRIDE {
189    dbus::Signal signal(ibus::engine::kServiceInterface,
190                        ibus::engine::kUpdateLookupTableSignal);
191    dbus::MessageWriter writer(&signal);
192    AppendIBusLookupTable(lookup_table, &writer);
193    writer.AppendBool(is_visible);
194    exported_object_->SendSignal(&signal);
195  }
196
197  // IBusEngineService override.
198  virtual void UpdateProperty(const IBusProperty& property) OVERRIDE {
199    dbus::Signal signal(ibus::engine::kServiceInterface,
200                        ibus::engine::kUpdatePropertySignal);
201    dbus::MessageWriter writer(&signal);
202    AppendIBusProperty(property, &writer);
203    exported_object_->SendSignal(&signal);
204  }
205
206  // IBusEngineService override.
207  virtual void ForwardKeyEvent(uint32 keyval, uint32 keycode,
208                               uint32 state) OVERRIDE {
209    dbus::Signal signal(ibus::engine::kServiceInterface,
210                        ibus::engine::kForwardKeyEventSignal);
211    dbus::MessageWriter writer(&signal);
212    writer.AppendUint32(keyval);
213    writer.AppendUint32(keycode);
214    writer.AppendUint32(state);
215    exported_object_->SendSignal(&signal);
216  }
217
218  // IBusEngineService override.
219  virtual void RequireSurroundingText() OVERRIDE {
220    dbus::Signal signal(ibus::engine::kServiceInterface,
221                        ibus::engine::kRequireSurroundingTextSignal);
222    exported_object_->SendSignal(&signal);
223  }
224
225  // IBusEngineService override.
226  virtual void CommitText(const std::string& text) OVERRIDE {
227    dbus::Signal signal(ibus::engine::kServiceInterface,
228                        ibus::engine::kCommitTextSignal);
229    dbus::MessageWriter writer(&signal);
230    AppendStringAsIBusText(text, &writer);
231    exported_object_->SendSignal(&signal);
232  }
233
234  // IBusEngineService override.
235  virtual void DeleteSurroundingText(int32 offset, uint32 length) OVERRIDE {
236    dbus::Signal signal(ibus::engine::kServiceInterface,
237                        ibus::engine::kDeleteSurroundingTextSignal);
238    dbus::MessageWriter writer(&signal);
239    writer.AppendInt32(offset);
240    writer.AppendUint32(length);
241    exported_object_->SendSignal(&signal);
242  }
243
244 private:
245  // Handles FocusIn method call from ibus-daemon.
246  void FocusIn(dbus::MethodCall* method_call,
247               dbus::ExportedObject::ResponseSender response_sender) {
248    if (engine_handler_ == NULL)
249      return;
250    engine_handler_->FocusIn();
251    response_sender.Run(dbus::Response::FromMethodCall(method_call));
252  }
253
254  // Handles FocusOut method call from ibus-daemon.
255  void FocusOut(dbus::MethodCall* method_call,
256                dbus::ExportedObject::ResponseSender response_sender) {
257    if (engine_handler_ == NULL)
258      return;
259    engine_handler_->FocusOut();
260    response_sender.Run(dbus::Response::FromMethodCall(method_call));
261  }
262
263  // Handles Enable method call from ibus-daemon.
264  void Enable(dbus::MethodCall* method_call,
265              dbus::ExportedObject::ResponseSender response_sender) {
266    if (engine_handler_ == NULL)
267      return;
268    engine_handler_->Enable();
269    response_sender.Run(dbus::Response::FromMethodCall(method_call));
270  }
271
272  // Handles Disable method call from ibus-daemon.
273  void Disable(dbus::MethodCall* method_call,
274               dbus::ExportedObject::ResponseSender response_sender) {
275    if (engine_handler_ == NULL)
276      return;
277    engine_handler_->Disable();
278    response_sender.Run(dbus::Response::FromMethodCall(method_call));
279  }
280
281  // Handles PropertyActivate method call from ibus-daemon.
282  void PropertyActivate(dbus::MethodCall* method_call,
283                        dbus::ExportedObject::ResponseSender response_sender) {
284    if (engine_handler_ == NULL)
285      return;
286    dbus::MessageReader reader(method_call);
287    std::string property_name;
288    if (!reader.PopString(&property_name)) {
289      LOG(WARNING) << "PropertyActivate called with incorrect parameters: "
290                   << method_call->ToString();
291      return;
292    }
293    uint32 property_state = 0;
294    if (!reader.PopUint32(&property_state)) {
295      LOG(WARNING) << "PropertyActivate called with incorrect parameters: "
296                   << method_call->ToString();
297      return;
298    }
299    engine_handler_->PropertyActivate(
300        property_name,
301        static_cast<ibus::IBusPropertyState>(property_state));
302    response_sender.Run(dbus::Response::FromMethodCall(method_call));
303  }
304
305  // Handles PropertyShow method call from ibus-daemon.
306  void PropertyShow(dbus::MethodCall* method_call,
307                    dbus::ExportedObject::ResponseSender response_sender) {
308    if (engine_handler_ == NULL)
309      return;
310    dbus::MessageReader reader(method_call);
311    std::string property_name;
312    if (!reader.PopString(&property_name)) {
313      LOG(WARNING) << "PropertyShow called with incorrect parameters: "
314                   << method_call->ToString();
315      return;
316    }
317    engine_handler_->PropertyShow(property_name);
318    response_sender.Run(dbus::Response::FromMethodCall(method_call));
319  }
320
321  // Handles PropertyHide method call from ibus-daemon.
322  void PropertyHide(dbus::MethodCall* method_call,
323                    dbus::ExportedObject::ResponseSender response_sender) {
324    if (engine_handler_ == NULL)
325      return;
326    dbus::MessageReader reader(method_call);
327    std::string property_name;
328    if (!reader.PopString(&property_name)) {
329      LOG(WARNING) << "PropertyHide called with incorrect parameters: "
330                   << method_call->ToString();
331      return;
332    }
333    engine_handler_->PropertyHide(property_name);
334    response_sender.Run(dbus::Response::FromMethodCall(method_call));
335  }
336
337  // Handles SetCapability method call from ibus-daemon.
338  void SetCapability(dbus::MethodCall* method_call,
339                     dbus::ExportedObject::ResponseSender response_sender) {
340    if (engine_handler_ == NULL)
341      return;
342    dbus::MessageReader reader(method_call);
343    uint32 capability = 0;
344    if (!reader.PopUint32(&capability)) {
345      LOG(WARNING) << "SetCapability called with incorrect parameters: "
346                   << method_call->ToString();
347      return;
348    }
349    engine_handler_->SetCapability(
350        static_cast<IBusEngineHandlerInterface::IBusCapability>(capability));
351    response_sender.Run(dbus::Response::FromMethodCall(method_call));
352  }
353
354  void Reset(dbus::MethodCall* method_call,
355             dbus::ExportedObject::ResponseSender response_sender) {
356    if (engine_handler_ == NULL)
357      return;
358    engine_handler_->Reset();
359    response_sender.Run(dbus::Response::FromMethodCall(method_call));
360  }
361
362  // Handles ProcessKeyEvent method call from ibus-daemon.
363  void ProcessKeyEvent(dbus::MethodCall* method_call,
364                       dbus::ExportedObject::ResponseSender response_sender) {
365    if (engine_handler_ == NULL)
366      return;
367    dbus::MessageReader reader(method_call);
368    uint32 keysym = 0;
369    if (!reader.PopUint32(&keysym)) {
370      LOG(WARNING) << "ProcessKeyEvent called with incorrect parameters: "
371                   << method_call->ToString();
372      return;
373    }
374    uint32 keycode = 0;
375    if (!reader.PopUint32(&keycode)) {
376      LOG(WARNING) << "ProcessKeyEvent called with incorrect parameters: "
377                   << method_call->ToString();
378      return;
379    }
380    uint32 state = 0;
381    if (!reader.PopUint32(&state)) {
382      LOG(WARNING) << "ProcessKeyEvent called with incorrect parameters: "
383                   << method_call->ToString();
384      return;
385    }
386    engine_handler_->ProcessKeyEvent(
387        keysym, keycode, state,
388        base::Bind(&IBusEngineServiceImpl::KeyEventDone,
389                   weak_ptr_factory_.GetWeakPtr(),
390                   base::Passed(dbus::Response::FromMethodCall(method_call)),
391                   response_sender));
392  }
393
394  void KeyEventDone(scoped_ptr<dbus::Response> response,
395                    const dbus::ExportedObject::ResponseSender& response_sender,
396                    bool consume) {
397    if (engine_handler_ == NULL)
398      return;
399    dbus::MessageWriter writer(response.get());
400    writer.AppendBool(consume);
401    response_sender.Run(response.Pass());
402  }
403
404  // Handles CandidateClicked method call from ibus-daemon.
405  void CandidateClicked(dbus::MethodCall* method_call,
406                        dbus::ExportedObject::ResponseSender response_sender) {
407    if (engine_handler_ == NULL)
408      return;
409    dbus::MessageReader reader(method_call);
410    uint32 index = 0;
411    if (!reader.PopUint32(&index)) {
412      LOG(WARNING) << "CandidateClicked called with incorrect parameters: "
413                   << method_call->ToString();
414      return;
415    }
416    uint32 button = 0;
417    if (!reader.PopUint32(&button)) {
418      LOG(WARNING) << "CandidateClicked called with incorrect parameters: "
419                   << method_call->ToString();
420      return;
421    }
422    uint32 state = 0;
423    if (!reader.PopUint32(&state)) {
424      LOG(WARNING) << "CandidateClicked called with incorrect parameters: "
425                   << method_call->ToString();
426      return;
427    }
428    engine_handler_->CandidateClicked(
429        index,
430        static_cast<ibus::IBusMouseButton>(button),
431        state);
432    response_sender.Run(dbus::Response::FromMethodCall(method_call));
433  }
434
435  // Handles SetSurroundingText method call from ibus-daemon.
436  void SetSurroundingText(
437      dbus::MethodCall* method_call,
438      dbus::ExportedObject::ResponseSender response_sender) {
439    if (engine_handler_ == NULL)
440      return;
441    dbus::MessageReader reader(method_call);
442    std::string text;
443    if (!PopStringFromIBusText(&reader, &text)) {
444      LOG(WARNING) << "SetSurroundingText called with incorrect parameters: "
445                   << method_call->ToString();
446      return;
447    }
448    uint32 cursor_pos = 0;
449    if (!reader.PopUint32(&cursor_pos)) {
450      LOG(WARNING) << "CandidateClicked called with incorrect parameters: "
451                   << method_call->ToString();
452      return;
453    }
454    uint32 anchor_pos = 0;
455    if (!reader.PopUint32(&anchor_pos)) {
456      LOG(WARNING) << "CandidateClicked called with incorrect parameters: "
457                   << method_call->ToString();
458      return;
459    }
460
461    engine_handler_->SetSurroundingText(text, cursor_pos, anchor_pos);
462    response_sender.Run(dbus::Response::FromMethodCall(method_call));
463  }
464
465  // Called when the method call is exported.
466  void OnMethodExported(const std::string& interface_name,
467                        const std::string& method_name,
468                        bool success) {
469    LOG_IF(WARNING, !success) << "Failed to export "
470                              << interface_name << "." << method_name;
471  }
472
473  // D-Bus bus object used for unregistering exported methods in dtor.
474  dbus::Bus* bus_;
475
476  // All incoming method calls are passed on to the |engine_handler_|.
477  IBusEngineHandlerInterface* engine_handler_;
478
479  dbus::ObjectPath object_path_;
480  scoped_refptr<dbus::ExportedObject> exported_object_;
481  base::WeakPtrFactory<IBusEngineServiceImpl> weak_ptr_factory_;
482
483  DISALLOW_COPY_AND_ASSIGN(IBusEngineServiceImpl);
484};
485
486// An implementation of IBusEngineService without ibus-daemon interaction.
487// Currently this class is used only on linux desktop.
488// TODO(nona): Use this on ChromeOS device once crbug.com/171351 is fixed.
489class IBusEngineServiceDaemonlessImpl : public IBusEngineService {
490 public:
491  IBusEngineServiceDaemonlessImpl() {}
492  virtual ~IBusEngineServiceDaemonlessImpl() {}
493
494  // IBusEngineService override.
495  virtual void SetEngine(IBusEngineHandlerInterface* handler) OVERRIDE {
496    IBusBridge::Get()->SetEngineHandler(handler);
497  }
498
499  // IBusEngineService override.
500  virtual void UnsetEngine(IBusEngineHandlerInterface* handler) OVERRIDE {
501    if (IBusBridge::Get()->GetEngineHandler() == handler)
502      IBusBridge::Get()->SetEngineHandler(NULL);
503  }
504
505  // IBusEngineService override.
506  virtual void RegisterProperties(
507      const IBusPropertyList& property_list) OVERRIDE {
508    IBusPanelPropertyHandlerInterface* property =
509        IBusBridge::Get()->GetPropertyHandler();
510    if (property)
511      property->RegisterProperties(property_list);
512  }
513
514  // IBusEngineService override.
515  virtual void UpdatePreedit(const IBusText& ibus_text,
516                             uint32 cursor_pos,
517                             bool is_visible,
518                             IBusEnginePreeditFocusOutMode mode) OVERRIDE {
519    IBusInputContextHandlerInterface* input_context =
520        IBusBridge::Get()->GetInputContextHandler();
521    if (input_context)
522      input_context->UpdatePreeditText(ibus_text, cursor_pos, is_visible);
523  }
524
525  // IBusEngineService override.
526  virtual void UpdateAuxiliaryText(const IBusText& ibus_text,
527                                   bool is_visible) OVERRIDE {
528    IBusPanelCandidateWindowHandlerInterface* candidate_window =
529        IBusBridge::Get()->GetCandidateWindowHandler();
530    if (candidate_window)
531      candidate_window->UpdateAuxiliaryText(ibus_text.text(), is_visible);
532  }
533
534  // IBusEngineService override.
535  virtual void UpdateLookupTable(const IBusLookupTable& lookup_table,
536                                 bool is_visible) OVERRIDE {
537    IBusPanelCandidateWindowHandlerInterface* candidate_window =
538        IBusBridge::Get()->GetCandidateWindowHandler();
539    if (candidate_window)
540      candidate_window->UpdateLookupTable(lookup_table, is_visible);
541  }
542
543  // IBusEngineService override.
544  virtual void UpdateProperty(const IBusProperty& property) OVERRIDE {
545    IBusPanelPropertyHandlerInterface* property_handler =
546        IBusBridge::Get()->GetPropertyHandler();
547    if (property_handler)
548      property_handler->UpdateProperty(property);
549  }
550
551  // IBusEngineService override.
552  virtual void ForwardKeyEvent(uint32 keyval, uint32 keycode,
553                               uint32 state) OVERRIDE {
554    IBusInputContextHandlerInterface* input_context =
555        IBusBridge::Get()->GetInputContextHandler();
556    if (input_context)
557      input_context->ForwardKeyEvent(keyval, keycode, state);
558  }
559
560  // IBusEngineService override.
561  virtual void RequireSurroundingText() OVERRIDE {
562    // Do nothing.
563  }
564
565  // IBusEngineService override.
566  virtual void CommitText(const std::string& text) OVERRIDE {
567    IBusInputContextHandlerInterface* input_context =
568        IBusBridge::Get()->GetInputContextHandler();
569    if (input_context) {
570      IBusText ibus_text;
571      ibus_text.set_text(text);
572      input_context->CommitText(ibus_text);
573    }
574  }
575
576  // IBusEngineService override.
577  virtual void DeleteSurroundingText(int32 offset, uint32 length) OVERRIDE {
578    IBusInputContextHandlerInterface* input_context =
579        IBusBridge::Get()->GetInputContextHandler();
580    if (input_context)
581      input_context->DeleteSurroundingText(offset, length);
582  }
583 private:
584  DISALLOW_COPY_AND_ASSIGN(IBusEngineServiceDaemonlessImpl);
585};
586
587IBusEngineService::IBusEngineService() {
588}
589
590IBusEngineService::~IBusEngineService() {
591}
592
593// static
594IBusEngineService* IBusEngineService::Create(
595    DBusClientImplementationType type,
596    dbus::Bus* bus,
597    const dbus::ObjectPath& object_path) {
598  if (type == REAL_DBUS_CLIENT_IMPLEMENTATION)
599    return new IBusEngineServiceImpl(bus, object_path);
600  else
601    return new IBusEngineServiceDaemonlessImpl();
602}
603
604}  // namespace chromeos
605