Separate Simple Backend creation from initialization.
[chromium-blink-merge.git] / chromeos / dbus / ibus / ibus_client.cc
blob010bcd4efc486c78a9b89763c783e69ddd4aa303
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_client.h"
7 #include "base/bind.h"
8 #include "base/callback.h"
9 #include "chromeos/dbus/ibus/ibus_constants.h"
10 #include "chromeos/dbus/ibus/ibus_component.h"
11 #include "chromeos/dbus/ibus/ibus_engine_service.h"
12 #include "chromeos/ime/ibus_bridge.h"
13 #include "dbus/bus.h"
14 #include "dbus/message.h"
15 #include "dbus/object_path.h"
16 #include "dbus/object_proxy.h"
18 namespace chromeos {
20 namespace {
22 // The IBusClient implementation.
23 class IBusClientImpl : public IBusClient {
24 public:
25 explicit IBusClientImpl(dbus::Bus* bus)
26 : proxy_(bus->GetObjectProxy(ibus::kServiceName,
27 dbus::ObjectPath(ibus::bus::kServicePath))),
28 weak_ptr_factory_(this) {
31 virtual ~IBusClientImpl() {}
33 // IBusClient override.
34 virtual void CreateInputContext(
35 const std::string& client_name,
36 const CreateInputContextCallback& callback,
37 const ErrorCallback& error_callback) OVERRIDE {
38 DCHECK(!callback.is_null());
39 DCHECK(!error_callback.is_null());
40 dbus::MethodCall method_call(ibus::bus::kServiceInterface,
41 ibus::bus::kCreateInputContextMethod);
42 dbus::MessageWriter writer(&method_call);
43 writer.AppendString(client_name);
44 proxy_->CallMethodWithErrorCallback(
45 &method_call,
46 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
47 base::Bind(&IBusClientImpl::OnCreateInputContext,
48 weak_ptr_factory_.GetWeakPtr(),
49 callback,
50 error_callback),
51 base::Bind(&IBusClientImpl::OnDBusMethodCallFail,
52 weak_ptr_factory_.GetWeakPtr(),
53 error_callback));
56 // IBusClient override.
57 virtual void RegisterComponent(
58 const IBusComponent& ibus_component,
59 const RegisterComponentCallback& callback,
60 const ErrorCallback& error_callback) OVERRIDE {
61 DCHECK(!callback.is_null());
62 DCHECK(!error_callback.is_null());
63 dbus::MethodCall method_call(ibus::bus::kServiceInterface,
64 ibus::bus::kRegisterComponentMethod);
65 dbus::MessageWriter writer(&method_call);
66 AppendIBusComponent(ibus_component, &writer);
67 proxy_->CallMethodWithErrorCallback(
68 &method_call,
69 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
70 base::Bind(&IBusClientImpl::OnRegisterComponent,
71 weak_ptr_factory_.GetWeakPtr(),
72 callback,
73 error_callback),
74 base::Bind(&IBusClientImpl::OnDBusMethodCallFail,
75 weak_ptr_factory_.GetWeakPtr(),
76 error_callback));
79 // IBusClient override.
80 virtual void SetGlobalEngine(const std::string& engine_name,
81 const ErrorCallback& error_callback) OVERRIDE {
82 DCHECK(!error_callback.is_null());
83 dbus::MethodCall method_call(ibus::bus::kServiceInterface,
84 ibus::bus::kSetGlobalEngineMethod);
85 dbus::MessageWriter writer(&method_call);
86 writer.AppendString(engine_name);
87 proxy_->CallMethodWithErrorCallback(
88 &method_call,
89 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
90 base::Bind(&IBusClientImpl::OnSetGlobalEngine,
91 weak_ptr_factory_.GetWeakPtr(),
92 error_callback),
93 base::Bind(&IBusClientImpl::OnDBusMethodCallFail,
94 weak_ptr_factory_.GetWeakPtr(),
95 error_callback));
98 // IBusClient override.
99 virtual void Exit(ExitOption option,
100 const ErrorCallback& error_callback) OVERRIDE {
101 DCHECK(!error_callback.is_null());
102 dbus::MethodCall method_call(ibus::bus::kServiceInterface,
103 ibus::bus::kExitMethod);
104 dbus::MessageWriter writer(&method_call);
105 writer.AppendBool(option == RESTART_IBUS_DAEMON);
106 proxy_->CallMethodWithErrorCallback(
107 &method_call,
108 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
109 base::Bind(&IBusClientImpl::OnExit,
110 weak_ptr_factory_.GetWeakPtr(),
111 error_callback),
112 base::Bind(&IBusClientImpl::OnDBusMethodCallFail,
113 weak_ptr_factory_.GetWeakPtr(),
114 error_callback));
117 private:
118 // Handles responses of CreateInputContext method calls.
119 void OnCreateInputContext(const CreateInputContextCallback& callback,
120 const ErrorCallback& error_callback,
121 dbus::Response* response) {
122 if (!response) {
123 LOG(ERROR) << "Cannot get input context: response is NULL.";
124 error_callback.Run();
125 return;
127 dbus::MessageReader reader(response);
128 dbus::ObjectPath object_path;
129 if (!reader.PopObjectPath(&object_path)) {
130 // The IBus message structure may be changed.
131 LOG(ERROR) << "Invalid response: " << response->ToString();
132 error_callback.Run();
133 return;
135 callback.Run(object_path);
138 // Handles responses of RegisterComponent method calls.
139 void OnRegisterComponent(const RegisterComponentCallback& callback,
140 const ErrorCallback& error_callback,
141 dbus::Response* response) {
142 if (!response) {
143 LOG(ERROR) << "Response is NULL.";
144 error_callback.Run();
145 return;
147 callback.Run();
150 // Handles responses of RegisterComponent method calls.
151 void OnSetGlobalEngine(const ErrorCallback& error_callback,
152 dbus::Response* response) {
153 if (!response) {
154 LOG(ERROR) << "Response is NULL.";
155 error_callback.Run();
156 return;
160 // Handles responses of RegisterComponent method calls.
161 void OnExit(const ErrorCallback& error_callback,
162 dbus::Response* response) {
163 if (!response) {
164 LOG(ERROR) << "Response is NULL.";
165 error_callback.Run();
166 return;
170 // Handles error response of RegisterComponent method call.
171 void OnDBusMethodCallFail(const ErrorCallback& error_callback,
172 dbus::ErrorResponse* response) {
173 error_callback.Run();
176 dbus::ObjectProxy* proxy_;
177 base::WeakPtrFactory<IBusClientImpl> weak_ptr_factory_;
179 DISALLOW_COPY_AND_ASSIGN(IBusClientImpl);
182 // An implementation of IBusClient without ibus-daemon interaction.
183 // Currently this class is used only on linux desktop.
184 // TODO(nona): Use this on ChromeOS device once crbug.com/171351 is fixed.
185 class IBusClientDaemonlessImpl : public IBusClient {
186 public:
187 IBusClientDaemonlessImpl() {}
188 virtual ~IBusClientDaemonlessImpl() {}
190 virtual void CreateInputContext(
191 const std::string& client_name,
192 const CreateInputContextCallback & callback,
193 const ErrorCallback& error_callback) OVERRIDE {
194 // TODO(nona): Remove this function once ibus-daemon is gone.
195 // We don't have to do anything for this function except for calling
196 // |callback| as the success of this function. The original spec of ibus
197 // supports multiple input contexts, but there is only one input context in
198 // Chrome OS. That is all IME events will be came from same input context
199 // and all engine action shuold be forwarded to same input context.
200 dbus::ObjectPath path("dummpy path");
201 callback.Run(path);
204 virtual void RegisterComponent(
205 const IBusComponent& ibus_component,
206 const RegisterComponentCallback& callback,
207 const ErrorCallback& error_callback) OVERRIDE {
208 // TODO(nona): Remove this function once ibus-daemon is gone.
209 // The information about engine is stored in chromeos::InputMethodManager so
210 // IBusBridge doesn't do anything except for calling |callback| as success
211 // of this function.
212 callback.Run();
215 virtual void SetGlobalEngine(const std::string& engine_name,
216 const ErrorCallback& error_callback) OVERRIDE {
217 IBusEngineHandlerInterface* previous_engine =
218 IBusBridge::Get()->GetEngineHandler();
219 if (previous_engine)
220 previous_engine->Disable();
221 IBusBridge::Get()->CreateEngine(engine_name);
222 IBusEngineHandlerInterface* next_engine =
223 IBusBridge::Get()->GetEngineHandler();
224 if (next_engine)
225 next_engine->Enable();
228 virtual void Exit(ExitOption option,
229 const ErrorCallback& error_callback) OVERRIDE {
230 // Exit is not supported on daemon-less implementation.
233 private:
234 DISALLOW_COPY_AND_ASSIGN(IBusClientDaemonlessImpl);
237 } // namespace
239 ///////////////////////////////////////////////////////////////////////////////
240 // IBusClient
242 IBusClient::IBusClient() {}
244 IBusClient::~IBusClient() {}
246 // static
247 IBusClient* IBusClient::Create(DBusClientImplementationType type,
248 dbus::Bus* bus) {
249 if (type == REAL_DBUS_CLIENT_IMPLEMENTATION) {
250 return new IBusClientImpl(bus);
252 DCHECK_EQ(STUB_DBUS_CLIENT_IMPLEMENTATION, type);
253 return new IBusClientDaemonlessImpl();
256 } // namespace chromeos