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