OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chromeos/dbus/ibus/ibus_config_client.h" | 5 #include "chromeos/dbus/ibus/ibus_config_client.h" |
6 | 6 |
| 7 #include <vector> |
| 8 |
7 #include "base/bind.h" | 9 #include "base/bind.h" |
8 #include "base/callback.h" | 10 #include "base/callback.h" |
9 #include "chromeos/dbus/ibus/ibus_constants.h" | 11 #include "chromeos/dbus/ibus/ibus_constants.h" |
10 #include "chromeos/dbus/ibus/ibus_component.h" | 12 #include "chromeos/dbus/ibus/ibus_component.h" |
11 #include "dbus/bus.h" | 13 #include "dbus/bus.h" |
12 #include "dbus/message.h" | 14 #include "dbus/message.h" |
13 #include "dbus/object_path.h" | 15 #include "dbus/object_path.h" |
14 #include "dbus/object_proxy.h" | 16 #include "dbus/object_proxy.h" |
15 | 17 |
16 namespace chromeos { | 18 namespace chromeos { |
17 | 19 |
18 namespace { | 20 namespace { |
19 | 21 |
| 22 // Called when the |signal| is connected. |
| 23 void OnSignalConnected(const std::string& interface, |
| 24 const std::string& signal, |
| 25 bool succeeded) { |
| 26 LOG_IF(ERROR, !succeeded) << "Connect to " << interface << " " |
| 27 << signal << " failed."; |
| 28 } |
| 29 |
| 30 // Called when the GetNameOwner method call is failed. |
| 31 void OnGetNameOwnerFail(dbus::ErrorResponse* response) { |
| 32 // Do nothing, because method call sometimes fails due to bootstrap timing of |
| 33 // ibus-memconf. |
| 34 } |
| 35 |
20 // The IBusConfigClient implementation. | 36 // The IBusConfigClient implementation. |
21 class IBusConfigClientImpl : public IBusConfigClient { | 37 class IBusConfigClientImpl : public IBusConfigClient { |
22 public: | 38 public: |
23 explicit IBusConfigClientImpl(dbus::Bus* bus) | 39 explicit IBusConfigClientImpl(dbus::Bus* bus) |
24 : proxy_(bus->GetObjectProxy(ibus::kServiceName, | 40 : proxy_(NULL), |
25 dbus::ObjectPath( | 41 bus_(bus), |
26 ibus::config::kServicePath))), | |
27 weak_ptr_factory_(this) { | 42 weak_ptr_factory_(this) { |
28 } | 43 } |
29 | 44 |
30 virtual ~IBusConfigClientImpl() {} | 45 virtual ~IBusConfigClientImpl() {} |
31 | 46 |
32 // IBusConfigClient override. | 47 // IBusConfigClient override. |
| 48 virtual void InitializeAsync(const OnIBusConfigReady& on_ready) OVERRIDE { |
| 49 // We should check that the ibus-config daemon actually works first, so we |
| 50 // can't initialize synchronously. |
| 51 dbus::ObjectProxy* dbus_proxy = bus_->GetObjectProxy( |
| 52 ibus::kServiceName, |
| 53 dbus::ObjectPath(ibus::kDBusObjectPath)); |
| 54 |
| 55 // Watch NameOwnerChanged signal which is fired when the ibus-config daemon |
| 56 // request its name ownership. |
| 57 dbus_proxy->ConnectToSignal( |
| 58 ibus::kDBusInterface, |
| 59 ibus::kNameOwnerChangedSignal, |
| 60 base::Bind(&IBusConfigClientImpl::OnNameOwnerChanged, |
| 61 weak_ptr_factory_.GetWeakPtr(), |
| 62 on_ready), |
| 63 base::Bind(&OnSignalConnected)); |
| 64 |
| 65 dbus::MethodCall method_call(ibus::kDBusInterface, |
| 66 ibus::kGetNameOwnerMethod); |
| 67 dbus::MessageWriter writer(&method_call); |
| 68 writer.AppendString(ibus::config::kServiceName); |
| 69 dbus_proxy->CallMethodWithErrorCallback( |
| 70 &method_call, |
| 71 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, |
| 72 base::Bind(&IBusConfigClientImpl::OnGetNameOwner, |
| 73 weak_ptr_factory_.GetWeakPtr(), |
| 74 on_ready), |
| 75 base::Bind(&OnGetNameOwnerFail)); |
| 76 } |
| 77 |
| 78 // IBusConfigClient override. |
33 virtual void SetStringValue(const std::string& section, | 79 virtual void SetStringValue(const std::string& section, |
34 const std::string& key, | 80 const std::string& key, |
35 const std::string& value, | 81 const std::string& value, |
36 const ErrorCallback& error_callback) OVERRIDE { | 82 const ErrorCallback& error_callback) OVERRIDE { |
| 83 if (!proxy_) |
| 84 return; |
37 DCHECK(!error_callback.is_null()); | 85 DCHECK(!error_callback.is_null()); |
38 dbus::MethodCall method_call(ibus::config::kServiceInterface, | 86 dbus::MethodCall method_call(ibus::config::kServiceInterface, |
39 ibus::config::kSetValueMethod); | 87 ibus::config::kSetValueMethod); |
40 dbus::MessageWriter writer(&method_call); | 88 dbus::MessageWriter writer(&method_call); |
41 writer.AppendString(section); | 89 writer.AppendString(section); |
42 writer.AppendString(key); | 90 writer.AppendString(key); |
43 dbus::MessageWriter variant_writer(NULL); | 91 dbus::MessageWriter variant_writer(NULL); |
44 writer.OpenVariant("s", &variant_writer); | 92 writer.OpenVariant("s", &variant_writer); |
45 variant_writer.AppendString(value); | 93 variant_writer.AppendString(value); |
46 writer.CloseContainer(&variant_writer); | 94 writer.CloseContainer(&variant_writer); |
47 CallWithDefaultCallback(&method_call, error_callback); | 95 CallWithDefaultCallback(&method_call, error_callback); |
48 } | 96 } |
49 | 97 |
50 // IBusConfigClient override. | 98 // IBusConfigClient override. |
51 virtual void SetIntValue(const std::string& section, | 99 virtual void SetIntValue(const std::string& section, |
52 const std::string& key, | 100 const std::string& key, |
53 int value, | 101 int value, |
54 const ErrorCallback& error_callback) OVERRIDE { | 102 const ErrorCallback& error_callback) OVERRIDE { |
| 103 if (!proxy_) |
| 104 return; |
55 DCHECK(!error_callback.is_null()); | 105 DCHECK(!error_callback.is_null()); |
56 dbus::MethodCall method_call(ibus::config::kServiceInterface, | 106 dbus::MethodCall method_call(ibus::config::kServiceInterface, |
57 ibus::config::kSetValueMethod); | 107 ibus::config::kSetValueMethod); |
58 dbus::MessageWriter writer(&method_call); | 108 dbus::MessageWriter writer(&method_call); |
59 writer.AppendString(section); | 109 writer.AppendString(section); |
60 writer.AppendString(key); | 110 writer.AppendString(key); |
61 dbus::MessageWriter variant_writer(NULL); | 111 dbus::MessageWriter variant_writer(NULL); |
62 writer.OpenVariant("i", &variant_writer); | 112 writer.OpenVariant("i", &variant_writer); |
63 variant_writer.AppendInt32(value); | 113 variant_writer.AppendInt32(value); |
64 writer.CloseContainer(&variant_writer); | 114 writer.CloseContainer(&variant_writer); |
65 CallWithDefaultCallback(&method_call, error_callback); | 115 CallWithDefaultCallback(&method_call, error_callback); |
66 } | 116 } |
67 | 117 |
68 // IBusConfigClient override. | 118 // IBusConfigClient override. |
69 virtual void SetBoolValue(const std::string& section, | 119 virtual void SetBoolValue(const std::string& section, |
70 const std::string& key, | 120 const std::string& key, |
71 bool value, | 121 bool value, |
72 const ErrorCallback& error_callback) OVERRIDE { | 122 const ErrorCallback& error_callback) OVERRIDE { |
| 123 if (!proxy_) |
| 124 return; |
73 DCHECK(!error_callback.is_null()); | 125 DCHECK(!error_callback.is_null()); |
74 dbus::MethodCall method_call(ibus::config::kServiceInterface, | 126 dbus::MethodCall method_call(ibus::config::kServiceInterface, |
75 ibus::config::kSetValueMethod); | 127 ibus::config::kSetValueMethod); |
76 dbus::MessageWriter writer(&method_call); | 128 dbus::MessageWriter writer(&method_call); |
77 writer.AppendString(section); | 129 writer.AppendString(section); |
78 writer.AppendString(key); | 130 writer.AppendString(key); |
79 dbus::MessageWriter variant_writer(NULL); | 131 dbus::MessageWriter variant_writer(NULL); |
80 writer.OpenVariant("b", &variant_writer); | 132 writer.OpenVariant("b", &variant_writer); |
81 variant_writer.AppendBool(value); | 133 variant_writer.AppendBool(value); |
82 writer.CloseContainer(&variant_writer); | 134 writer.CloseContainer(&variant_writer); |
83 CallWithDefaultCallback(&method_call, error_callback); | 135 CallWithDefaultCallback(&method_call, error_callback); |
84 } | 136 } |
85 | 137 |
86 // IBusConfigClient override. | 138 // IBusConfigClient override. |
87 virtual void SetStringListValue( | 139 virtual void SetStringListValue( |
88 const std::string& section, | 140 const std::string& section, |
89 const std::string& key, | 141 const std::string& key, |
90 const std::vector<std::string>& value, | 142 const std::vector<std::string>& value, |
91 const ErrorCallback& error_callback) OVERRIDE { | 143 const ErrorCallback& error_callback) OVERRIDE { |
| 144 if (!proxy_) |
| 145 return; |
92 DCHECK(!error_callback.is_null()); | 146 DCHECK(!error_callback.is_null()); |
93 dbus::MethodCall method_call(ibus::config::kServiceInterface, | 147 dbus::MethodCall method_call(ibus::config::kServiceInterface, |
94 ibus::config::kSetValueMethod); | 148 ibus::config::kSetValueMethod); |
95 dbus::MessageWriter writer(&method_call); | 149 dbus::MessageWriter writer(&method_call); |
96 writer.AppendString(section); | 150 writer.AppendString(section); |
97 writer.AppendString(key); | 151 writer.AppendString(key); |
98 dbus::MessageWriter variant_writer(NULL); | 152 dbus::MessageWriter variant_writer(NULL); |
99 dbus::MessageWriter array_writer(NULL); | 153 dbus::MessageWriter array_writer(NULL); |
100 | 154 |
101 writer.OpenVariant("as", &variant_writer); | 155 writer.OpenVariant("as", &variant_writer); |
102 variant_writer.OpenArray("s", &array_writer); | 156 variant_writer.OpenArray("s", &array_writer); |
103 for (size_t i = 0; i < value.size(); ++i) { | 157 for (size_t i = 0; i < value.size(); ++i) { |
104 array_writer.AppendString(value[i]); | 158 array_writer.AppendString(value[i]); |
105 } | 159 } |
106 variant_writer.CloseContainer(&array_writer); | 160 variant_writer.CloseContainer(&array_writer); |
107 writer.CloseContainer(&variant_writer); | 161 writer.CloseContainer(&variant_writer); |
108 CallWithDefaultCallback(&method_call, error_callback); | 162 CallWithDefaultCallback(&method_call, error_callback); |
109 } | 163 } |
110 | 164 |
111 private: | 165 private: |
112 void CallWithDefaultCallback(dbus::MethodCall* method_call, | 166 void CallWithDefaultCallback(dbus::MethodCall* method_call, |
113 const ErrorCallback& error_callback) { | 167 const ErrorCallback& error_callback) { |
| 168 if (!proxy_) |
| 169 return; |
114 proxy_->CallMethodWithErrorCallback( | 170 proxy_->CallMethodWithErrorCallback( |
115 method_call, | 171 method_call, |
116 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, | 172 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, |
117 base::Bind(&IBusConfigClientImpl::OnSetValue, | 173 base::Bind(&IBusConfigClientImpl::OnSetValue, |
118 weak_ptr_factory_.GetWeakPtr(), | 174 weak_ptr_factory_.GetWeakPtr(), |
119 error_callback), | 175 error_callback), |
120 base::Bind(&IBusConfigClientImpl::OnSetValueFail, | 176 base::Bind(&IBusConfigClientImpl::OnSetValueFail, |
121 weak_ptr_factory_.GetWeakPtr(), | 177 weak_ptr_factory_.GetWeakPtr(), |
122 error_callback)); | 178 error_callback)); |
123 } | 179 } |
124 | 180 |
125 void OnSetValue(const ErrorCallback& error_callback, | 181 void OnSetValue(const ErrorCallback& error_callback, |
126 dbus::Response* response) { | 182 dbus::Response* response) { |
127 if (!response) { | 183 if (!response) { |
128 LOG(ERROR) << "Response is NULL."; | 184 LOG(ERROR) << "Response is NULL."; |
129 error_callback.Run(); | 185 error_callback.Run(); |
130 return; | 186 return; |
131 } | 187 } |
132 } | 188 } |
133 | 189 |
134 void OnSetValueFail(const ErrorCallback& error_callback, | 190 void OnSetValueFail(const ErrorCallback& error_callback, |
135 dbus::ErrorResponse* response) { | 191 dbus::ErrorResponse* response) { |
136 error_callback.Run(); | 192 error_callback.Run(); |
137 } | 193 } |
138 | 194 |
| 195 void OnNameOwnerChanged(const OnIBusConfigReady& on_ready, |
| 196 dbus::Signal* signal) { |
| 197 DCHECK(signal); |
| 198 std::string name; |
| 199 std::string old_owner; |
| 200 std::string new_owner; |
| 201 |
| 202 dbus::MessageReader reader(signal); |
| 203 if (!reader.PopString(&name) || |
| 204 !reader.PopString(&old_owner) || |
| 205 !reader.PopString(&new_owner)) { |
| 206 DLOG(ERROR) << "Invalid response of NameOwnerChanged." |
| 207 << signal->ToString(); |
| 208 return; |
| 209 } |
| 210 |
| 211 if (name != ibus::config::kServiceName) |
| 212 return; // Not a signal for ibus-config. |
| 213 |
| 214 if (!old_owner.empty() || new_owner.empty()) { |
| 215 DVLOG(1) << "Unexpected name owner change: name=" << name |
| 216 << ", old_owner=" << old_owner << ", new_owner=" << new_owner; |
| 217 proxy_ = NULL; |
| 218 return; |
| 219 } |
| 220 |
| 221 if (proxy_) |
| 222 return; // Already initialized. |
| 223 |
| 224 proxy_ = bus_->GetObjectProxy(ibus::config::kServiceName, |
| 225 dbus::ObjectPath( |
| 226 ibus::config::kServicePath)); |
| 227 if (!on_ready.is_null()) |
| 228 on_ready.Run(); |
| 229 } |
| 230 |
| 231 // Handles response of GetNameOwner. |
| 232 void OnGetNameOwner(const OnIBusConfigReady& on_ready, |
| 233 dbus::Response* response) { |
| 234 if (!response) { |
| 235 LOG(ERROR) << "Response is NULL."; |
| 236 return; |
| 237 } |
| 238 std::string owner; |
| 239 dbus::MessageReader reader(response); |
| 240 |
| 241 if (!reader.PopString(&owner)) { |
| 242 LOG(ERROR) << "Invalid response of GetNameOwner." |
| 243 << response->ToString(); |
| 244 return; |
| 245 } |
| 246 |
| 247 // If the owner is empty, ibus-config daemon is not ready. So will |
| 248 // initialize object proxy on NameOwnerChanged signal. |
| 249 if (owner.empty()) |
| 250 return; |
| 251 |
| 252 proxy_ = bus_->GetObjectProxy(ibus::config::kServiceName, |
| 253 dbus::ObjectPath( |
| 254 ibus::config::kServicePath)); |
| 255 if (!on_ready.is_null()) |
| 256 on_ready.Run(); |
| 257 } |
| 258 |
139 dbus::ObjectProxy* proxy_; | 259 dbus::ObjectProxy* proxy_; |
| 260 dbus::Bus* bus_; |
140 base::WeakPtrFactory<IBusConfigClientImpl> weak_ptr_factory_; | 261 base::WeakPtrFactory<IBusConfigClientImpl> weak_ptr_factory_; |
141 | 262 |
142 DISALLOW_COPY_AND_ASSIGN(IBusConfigClientImpl); | 263 DISALLOW_COPY_AND_ASSIGN(IBusConfigClientImpl); |
143 }; | 264 }; |
144 | 265 |
145 // A stub implementation of IBusConfigClient. | 266 // A stub implementation of IBusConfigClient. |
146 class IBusConfigClientStubImpl : public IBusConfigClient { | 267 class IBusConfigClientStubImpl : public IBusConfigClient { |
147 public: | 268 public: |
148 IBusConfigClientStubImpl() {} | 269 IBusConfigClientStubImpl() {} |
149 virtual ~IBusConfigClientStubImpl() {} | 270 virtual ~IBusConfigClientStubImpl() {} |
| 271 virtual void InitializeAsync(const OnIBusConfigReady& on_ready) OVERRIDE {} |
150 virtual void SetStringValue(const std::string& section, | 272 virtual void SetStringValue(const std::string& section, |
151 const std::string& key, | 273 const std::string& key, |
152 const std::string& value, | 274 const std::string& value, |
153 const ErrorCallback& error_callback) OVERRIDE {} | 275 const ErrorCallback& error_callback) OVERRIDE {} |
154 virtual void SetIntValue(const std::string& section, | 276 virtual void SetIntValue(const std::string& section, |
155 const std::string& key, | 277 const std::string& key, |
156 int value, | 278 int value, |
157 const ErrorCallback& error_callback) OVERRIDE {} | 279 const ErrorCallback& error_callback) OVERRIDE {} |
158 virtual void SetBoolValue(const std::string& section, | 280 virtual void SetBoolValue(const std::string& section, |
159 const std::string& key, | 281 const std::string& key, |
(...skipping 22 matching lines...) Expand all Loading... |
182 IBusConfigClient* IBusConfigClient::Create(DBusClientImplementationType type, | 304 IBusConfigClient* IBusConfigClient::Create(DBusClientImplementationType type, |
183 dbus::Bus* bus) { | 305 dbus::Bus* bus) { |
184 if (type == REAL_DBUS_CLIENT_IMPLEMENTATION) { | 306 if (type == REAL_DBUS_CLIENT_IMPLEMENTATION) { |
185 return new IBusConfigClientImpl(bus); | 307 return new IBusConfigClientImpl(bus); |
186 } | 308 } |
187 DCHECK_EQ(STUB_DBUS_CLIENT_IMPLEMENTATION, type); | 309 DCHECK_EQ(STUB_DBUS_CLIENT_IMPLEMENTATION, type); |
188 return new IBusConfigClientStubImpl(); | 310 return new IBusConfigClientStubImpl(); |
189 } | 311 } |
190 | 312 |
191 } // namespace chromeos | 313 } // namespace chromeos |
OLD | NEW |