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/shill_service_client.h" | 5 #include "chromeos/dbus/shill_service_client.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/chromeos/chromeos_version.h" | 8 #include "base/chromeos/chromeos_version.h" |
9 #include "base/message_loop.h" | 9 #include "base/message_loop.h" |
10 #include "base/stl_util.h" | 10 #include "base/stl_util.h" |
(...skipping 22 matching lines...) Expand all Loading... |
33 // "org.freedesktop.DBus.Error.UnknownMethod". crbug.com/130660 | 33 // "org.freedesktop.DBus.Error.UnknownMethod". crbug.com/130660 |
34 if (error_name == DBUS_ERROR_UNKNOWN_METHOD) | 34 if (error_name == DBUS_ERROR_UNKNOWN_METHOD) |
35 VLOG(1) << log_string; | 35 VLOG(1) << log_string; |
36 else | 36 else |
37 LOG(ERROR) << log_string; | 37 LOG(ERROR) << log_string; |
38 | 38 |
39 base::DictionaryValue empty_dictionary; | 39 base::DictionaryValue empty_dictionary; |
40 callback.Run(DBUS_METHOD_CALL_FAILURE, empty_dictionary); | 40 callback.Run(DBUS_METHOD_CALL_FAILURE, empty_dictionary); |
41 } | 41 } |
42 | 42 |
| 43 // ShillClientHelper callback wrappers. |
| 44 // For each one of the different callback types in ShillClientHelper, we define |
| 45 // a wrapper that attachs a clousure to the given callback. This allows it to |
| 46 // call a second callback (the clousure) after the first callback is called. |
| 47 // This is used to get a notification in the ShillServiceClient when a |
| 48 // MethodCall returns. |
| 49 |
| 50 // * Wrapper for DictionaryValueCallback. |
| 51 void RunDictionaryValueCallback( |
| 52 const base::Closure& closure, |
| 53 const ShillClientHelper::DictionaryValueCallback& callback, |
| 54 DBusMethodCallStatus call_status, |
| 55 const DictionaryValue& argument) { |
| 56 callback.Run(call_status, argument); |
| 57 closure.Run(); |
| 58 } |
| 59 |
| 60 ShillClientHelper::DictionaryValueCallback |
| 61 AttachClosureToDictionaryValueCallback( |
| 62 const ShillClientHelper::DictionaryValueCallback& callback, |
| 63 const base::Closure& closure) { |
| 64 return base::Bind(&RunDictionaryValueCallback, closure, callback); |
| 65 } |
| 66 |
| 67 // * Wrapper for ListValueCallback |
| 68 void RunListValueCallback( |
| 69 const base::Closure& closure, |
| 70 const ShillClientHelper::ListValueCallback& callback, |
| 71 const ListValue& argument) { |
| 72 callback.Run(argument); |
| 73 closure.Run(); |
| 74 } |
| 75 |
| 76 ShillClientHelper::ListValueCallback AttachClosureToListValueCallback( |
| 77 const ShillClientHelper::ListValueCallback& callback, |
| 78 const base::Closure& closure) { |
| 79 return base::Bind(&RunListValueCallback, closure, callback); |
| 80 } |
| 81 |
| 82 // * Wrapper for ErrorCallback |
| 83 void RunErrorCallback( |
| 84 const base::Closure& closure, |
| 85 const ShillClientHelper::ErrorCallback& callback, |
| 86 const std::string& error_name, |
| 87 const std::string& error_message) { |
| 88 callback.Run(error_name, error_message); |
| 89 closure.Run(); |
| 90 } |
| 91 |
| 92 ShillClientHelper::ErrorCallback AttachClosureToErrorCallback( |
| 93 const ShillClientHelper::ErrorCallback& callback, |
| 94 const base::Closure& closure) { |
| 95 return base::Bind(&RunErrorCallback, closure, callback); |
| 96 } |
| 97 |
| 98 // * Wrapper for Closure |
| 99 void RunClosure(const base::Closure& closure, |
| 100 const base::Closure& callback) { |
| 101 callback.Run(); |
| 102 closure.Run(); |
| 103 } |
| 104 |
| 105 base::Closure AttachClosureToClosure( |
| 106 const base::Closure& callback, |
| 107 const base::Closure& closure) { |
| 108 return base::Bind(&RunClosure, closure, callback); |
| 109 } |
| 110 |
43 // The ShillServiceClient implementation. | 111 // The ShillServiceClient implementation. |
44 class ShillServiceClientImpl : public ShillServiceClient { | 112 class ShillServiceClientImpl : public ShillServiceClient { |
45 public: | 113 public: |
46 explicit ShillServiceClientImpl(dbus::Bus* bus) | 114 explicit ShillServiceClientImpl(dbus::Bus* bus) |
47 : bus_(bus), | 115 : bus_(bus), |
48 helpers_deleter_(&helpers_) { | 116 helpers_deleter_(&helpers_), |
| 117 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) { |
49 } | 118 } |
50 | 119 |
51 ///////////////////////////////////// | 120 ///////////////////////////////////// |
52 // ShillServiceClient overrides. | 121 // ShillServiceClient overrides. |
53 virtual void AddPropertyChangedObserver( | 122 virtual void AddPropertyChangedObserver( |
54 const dbus::ObjectPath& service_path, | 123 const dbus::ObjectPath& service_path, |
55 ShillPropertyChangedObserver* observer) OVERRIDE { | 124 ShillPropertyChangedObserver* observer) OVERRIDE { |
56 GetHelper(service_path)->AddPropertyChangedObserver(observer); | 125 GetHelper(service_path)->AddPropertyChangedObserver(observer); |
57 } | 126 } |
58 | 127 |
59 virtual void RemovePropertyChangedObserver( | 128 virtual void RemovePropertyChangedObserver( |
60 const dbus::ObjectPath& service_path, | 129 const dbus::ObjectPath& service_path, |
61 ShillPropertyChangedObserver* observer) OVERRIDE { | 130 ShillPropertyChangedObserver* observer) OVERRIDE { |
62 GetHelper(service_path)->RemovePropertyChangedObserver(observer); | 131 GetHelper(service_path)->RemovePropertyChangedObserver(observer); |
| 132 OnHelperStatusUpdate(service_path); |
63 } | 133 } |
64 | 134 |
65 virtual void GetProperties(const dbus::ObjectPath& service_path, | 135 virtual void GetProperties(const dbus::ObjectPath& service_path, |
66 const DictionaryValueCallback& callback) OVERRIDE { | 136 const DictionaryValueCallback& callback) OVERRIDE { |
67 dbus::MethodCall method_call(flimflam::kFlimflamServiceInterface, | 137 dbus::MethodCall method_call(flimflam::kFlimflamServiceInterface, |
68 flimflam::kGetPropertiesFunction); | 138 flimflam::kGetPropertiesFunction); |
69 GetHelper(service_path)->CallDictionaryValueMethodWithErrorCallback( | 139 GetHelper(service_path)->CallDictionaryValueMethodWithErrorCallback( |
70 &method_call, | 140 &method_call, |
71 base::Bind(callback, DBUS_METHOD_CALL_SUCCESS), | 141 base::Bind( |
72 base::Bind(&OnGetPropertiesError, service_path, callback)); | 142 AttachClosureToDictionaryValueCallback(callback, |
| 143 base::Bind(&ShillServiceClientImpl::OnHelperStatusUpdate, |
| 144 weak_ptr_factory_.GetWeakPtr(), service_path)), |
| 145 DBUS_METHOD_CALL_SUCCESS), |
| 146 AttachClosureToErrorCallback( |
| 147 base::Bind(&OnGetPropertiesError, service_path, callback), |
| 148 HelperStatusUpdateCallback(service_path))); |
73 } | 149 } |
74 | 150 |
75 virtual void SetProperty(const dbus::ObjectPath& service_path, | 151 virtual void SetProperty(const dbus::ObjectPath& service_path, |
76 const std::string& name, | 152 const std::string& name, |
77 const base::Value& value, | 153 const base::Value& value, |
78 const base::Closure& callback, | 154 const base::Closure& callback, |
79 const ErrorCallback& error_callback) OVERRIDE { | 155 const ErrorCallback& error_callback) OVERRIDE { |
80 dbus::MethodCall method_call(flimflam::kFlimflamServiceInterface, | 156 dbus::MethodCall method_call(flimflam::kFlimflamServiceInterface, |
81 flimflam::kSetPropertyFunction); | 157 flimflam::kSetPropertyFunction); |
82 dbus::MessageWriter writer(&method_call); | 158 dbus::MessageWriter writer(&method_call); |
83 writer.AppendString(name); | 159 writer.AppendString(name); |
84 ShillClientHelper::AppendValueDataAsVariant(&writer, value); | 160 ShillClientHelper::AppendValueDataAsVariant(&writer, value); |
85 GetHelper(service_path)->CallVoidMethodWithErrorCallback(&method_call, | 161 GetHelper(service_path)->CallVoidMethodWithErrorCallback( |
86 callback, | 162 &method_call, |
87 error_callback); | 163 AttachClosureToClosure(callback, |
| 164 HelperStatusUpdateCallback(service_path)), |
| 165 AttachClosureToErrorCallback(error_callback, |
| 166 HelperStatusUpdateCallback(service_path))); |
88 } | 167 } |
89 | 168 |
90 virtual void ClearProperty(const dbus::ObjectPath& service_path, | 169 virtual void ClearProperty(const dbus::ObjectPath& service_path, |
91 const std::string& name, | 170 const std::string& name, |
92 const base::Closure& callback, | 171 const base::Closure& callback, |
93 const ErrorCallback& error_callback) OVERRIDE { | 172 const ErrorCallback& error_callback) OVERRIDE { |
94 dbus::MethodCall method_call(flimflam::kFlimflamServiceInterface, | 173 dbus::MethodCall method_call(flimflam::kFlimflamServiceInterface, |
95 flimflam::kClearPropertyFunction); | 174 flimflam::kClearPropertyFunction); |
96 dbus::MessageWriter writer(&method_call); | 175 dbus::MessageWriter writer(&method_call); |
97 writer.AppendString(name); | 176 writer.AppendString(name); |
98 GetHelper(service_path)->CallVoidMethodWithErrorCallback(&method_call, | 177 GetHelper(service_path)->CallVoidMethodWithErrorCallback( |
99 callback, | 178 &method_call, |
100 error_callback); | 179 AttachClosureToClosure(callback, |
| 180 HelperStatusUpdateCallback(service_path)), |
| 181 AttachClosureToErrorCallback(error_callback, |
| 182 HelperStatusUpdateCallback(service_path))); |
101 } | 183 } |
102 | 184 |
103 | 185 |
104 virtual void ClearProperties(const dbus::ObjectPath& service_path, | 186 virtual void ClearProperties(const dbus::ObjectPath& service_path, |
105 const std::vector<std::string>& names, | 187 const std::vector<std::string>& names, |
106 const ListValueCallback& callback, | 188 const ListValueCallback& callback, |
107 const ErrorCallback& error_callback) OVERRIDE { | 189 const ErrorCallback& error_callback) OVERRIDE { |
108 dbus::MethodCall method_call(flimflam::kFlimflamServiceInterface, | 190 dbus::MethodCall method_call(flimflam::kFlimflamServiceInterface, |
109 shill::kClearPropertiesFunction); | 191 shill::kClearPropertiesFunction); |
110 dbus::MessageWriter writer(&method_call); | 192 dbus::MessageWriter writer(&method_call); |
111 writer.AppendArrayOfStrings(names); | 193 writer.AppendArrayOfStrings(names); |
112 GetHelper(service_path)->CallListValueMethodWithErrorCallback( | 194 GetHelper(service_path)->CallListValueMethodWithErrorCallback( |
113 &method_call, | 195 &method_call, |
114 callback, | 196 AttachClosureToListValueCallback(callback, |
115 error_callback); | 197 HelperStatusUpdateCallback(service_path)), |
| 198 AttachClosureToErrorCallback(error_callback, |
| 199 HelperStatusUpdateCallback(service_path))); |
116 } | 200 } |
117 | 201 |
118 virtual void Connect(const dbus::ObjectPath& service_path, | 202 virtual void Connect(const dbus::ObjectPath& service_path, |
119 const base::Closure& callback, | 203 const base::Closure& callback, |
120 const ErrorCallback& error_callback) OVERRIDE { | 204 const ErrorCallback& error_callback) OVERRIDE { |
121 dbus::MethodCall method_call(flimflam::kFlimflamServiceInterface, | 205 dbus::MethodCall method_call(flimflam::kFlimflamServiceInterface, |
122 flimflam::kConnectFunction); | 206 flimflam::kConnectFunction); |
123 GetHelper(service_path)->CallVoidMethodWithErrorCallback( | 207 GetHelper(service_path)->CallVoidMethodWithErrorCallback( |
124 &method_call, callback, error_callback); | 208 &method_call, |
| 209 AttachClosureToClosure(callback, |
| 210 HelperStatusUpdateCallback(service_path)), |
| 211 AttachClosureToErrorCallback(error_callback, |
| 212 HelperStatusUpdateCallback(service_path))); |
125 } | 213 } |
126 | 214 |
127 virtual void Disconnect(const dbus::ObjectPath& service_path, | 215 virtual void Disconnect(const dbus::ObjectPath& service_path, |
128 const base::Closure& callback, | 216 const base::Closure& callback, |
129 const ErrorCallback& error_callback) OVERRIDE { | 217 const ErrorCallback& error_callback) OVERRIDE { |
130 dbus::MethodCall method_call(flimflam::kFlimflamServiceInterface, | 218 dbus::MethodCall method_call(flimflam::kFlimflamServiceInterface, |
131 flimflam::kDisconnectFunction); | 219 flimflam::kDisconnectFunction); |
132 GetHelper(service_path)->CallVoidMethodWithErrorCallback(&method_call, | 220 GetHelper(service_path)->CallVoidMethodWithErrorCallback( |
133 callback, | 221 &method_call, |
134 error_callback); | 222 AttachClosureToClosure(callback, |
| 223 HelperStatusUpdateCallback(service_path)), |
| 224 AttachClosureToErrorCallback(error_callback, |
| 225 HelperStatusUpdateCallback(service_path))); |
135 } | 226 } |
136 | 227 |
137 virtual void Remove(const dbus::ObjectPath& service_path, | 228 virtual void Remove(const dbus::ObjectPath& service_path, |
138 const base::Closure& callback, | 229 const base::Closure& callback, |
139 const ErrorCallback& error_callback) OVERRIDE { | 230 const ErrorCallback& error_callback) OVERRIDE { |
140 dbus::MethodCall method_call(flimflam::kFlimflamServiceInterface, | 231 dbus::MethodCall method_call(flimflam::kFlimflamServiceInterface, |
141 flimflam::kRemoveServiceFunction); | 232 flimflam::kRemoveServiceFunction); |
142 GetHelper(service_path)->CallVoidMethodWithErrorCallback(&method_call, | 233 GetHelper(service_path)->CallVoidMethodWithErrorCallback( |
143 callback, | 234 &method_call, |
144 error_callback); | 235 AttachClosureToClosure(callback, |
| 236 HelperStatusUpdateCallback(service_path)), |
| 237 AttachClosureToErrorCallback(error_callback, |
| 238 HelperStatusUpdateCallback(service_path))); |
145 } | 239 } |
146 | 240 |
147 virtual void ActivateCellularModem( | 241 virtual void ActivateCellularModem( |
148 const dbus::ObjectPath& service_path, | 242 const dbus::ObjectPath& service_path, |
149 const std::string& carrier, | 243 const std::string& carrier, |
150 const base::Closure& callback, | 244 const base::Closure& callback, |
151 const ErrorCallback& error_callback) OVERRIDE { | 245 const ErrorCallback& error_callback) OVERRIDE { |
152 dbus::MethodCall method_call(flimflam::kFlimflamServiceInterface, | 246 dbus::MethodCall method_call(flimflam::kFlimflamServiceInterface, |
153 flimflam::kActivateCellularModemFunction); | 247 flimflam::kActivateCellularModemFunction); |
154 dbus::MessageWriter writer(&method_call); | 248 dbus::MessageWriter writer(&method_call); |
155 writer.AppendString(carrier); | 249 writer.AppendString(carrier); |
156 GetHelper(service_path)->CallVoidMethodWithErrorCallback(&method_call, | 250 GetHelper(service_path)->CallVoidMethodWithErrorCallback( |
157 callback, | 251 &method_call, |
158 error_callback); | 252 AttachClosureToClosure(callback, |
| 253 HelperStatusUpdateCallback(service_path)), |
| 254 AttachClosureToErrorCallback(error_callback, |
| 255 HelperStatusUpdateCallback(service_path))); |
159 } | 256 } |
160 | 257 |
161 virtual bool CallActivateCellularModemAndBlock( | 258 virtual bool CallActivateCellularModemAndBlock( |
162 const dbus::ObjectPath& service_path, | 259 const dbus::ObjectPath& service_path, |
163 const std::string& carrier) OVERRIDE { | 260 const std::string& carrier) OVERRIDE { |
164 dbus::MethodCall method_call(flimflam::kFlimflamServiceInterface, | 261 dbus::MethodCall method_call(flimflam::kFlimflamServiceInterface, |
165 flimflam::kActivateCellularModemFunction); | 262 flimflam::kActivateCellularModemFunction); |
166 dbus::MessageWriter writer(&method_call); | 263 dbus::MessageWriter writer(&method_call); |
167 writer.AppendString(carrier); | 264 writer.AppendString(carrier); |
168 return GetHelper(service_path)->CallVoidMethodAndBlock(&method_call); | 265 bool result = GetHelper(service_path)->CallVoidMethodAndBlock(&method_call); |
| 266 OnHelperStatusUpdate(service_path); |
| 267 return result; |
169 } | 268 } |
170 | 269 |
171 virtual ShillServiceClient::TestInterface* GetTestInterface() OVERRIDE { | 270 virtual ShillServiceClient::TestInterface* GetTestInterface() OVERRIDE { |
172 return NULL; | 271 return NULL; |
173 } | 272 } |
174 | 273 |
175 private: | 274 private: |
176 typedef std::map<std::string, ShillClientHelper*> HelperMap; | 275 typedef std::map<std::string, ShillClientHelper*> HelperMap; |
177 | 276 |
178 // Returns the corresponding ShillClientHelper for the profile. | 277 // Returns the corresponding ShillClientHelper for the profile. |
179 ShillClientHelper* GetHelper(const dbus::ObjectPath& service_path) { | 278 ShillClientHelper* GetHelper(const dbus::ObjectPath& service_path) { |
180 HelperMap::iterator it = helpers_.find(service_path.value()); | 279 HelperMap::iterator it = helpers_.find(service_path.value()); |
181 if (it != helpers_.end()) | 280 if (it != helpers_.end()) |
182 return it->second; | 281 return it->second; |
183 | 282 |
184 // There is no helper for the profile, create it. | 283 // There is no helper for the profile, create it. |
185 dbus::ObjectProxy* object_proxy = | 284 dbus::ObjectProxy* object_proxy = |
186 bus_->GetObjectProxy(flimflam::kFlimflamServiceName, service_path); | 285 bus_->GetObjectProxy(flimflam::kFlimflamServiceName, service_path); |
187 ShillClientHelper* helper = new ShillClientHelper(bus_, object_proxy); | 286 ShillClientHelper* helper = new ShillClientHelper(bus_, object_proxy); |
188 helper->MonitorPropertyChanged(flimflam::kFlimflamServiceInterface); | 287 helper->MonitorPropertyChanged(flimflam::kFlimflamServiceInterface); |
189 helpers_.insert(HelperMap::value_type(service_path.value(), helper)); | 288 helpers_.insert(HelperMap::value_type(service_path.value(), helper)); |
190 return helper; | 289 return helper; |
191 } | 290 } |
192 | 291 |
| 292 // Returns a Closure that calls OnHelperStatusUpdate with the given |
| 293 // |service_path| argument. |
| 294 base::Closure HelperStatusUpdateCallback( |
| 295 const dbus::ObjectPath& service_path) { |
| 296 return base::Bind(&ShillServiceClientImpl::OnHelperStatusUpdate, |
| 297 weak_ptr_factory_.GetWeakPtr(), service_path); |
| 298 } |
| 299 |
| 300 // This function is called every time the IsObserved or the IsWaitingResponse |
| 301 // helper's properties may have changed. If both are false, the cached helper |
| 302 // can be safely removed. |
| 303 void OnHelperStatusUpdate(const dbus::ObjectPath& service_path) { |
| 304 HelperMap::iterator it = helpers_.find(service_path.value()); |
| 305 if (it == helpers_.end()) |
| 306 return; |
| 307 |
| 308 ShillClientHelper* const helper = it->second; |
| 309 if (!helper->IsObserved() && !helper->IsWaitingResponse()) { |
| 310 helpers_.erase(it); |
| 311 delete helper; |
| 312 bus_->RemoveObjectProxy(flimflam::kFlimflamServiceName, service_path, |
| 313 base::Bind(&base::DoNothing)); |
| 314 } |
| 315 } |
| 316 |
193 dbus::Bus* bus_; | 317 dbus::Bus* bus_; |
194 HelperMap helpers_; | 318 HelperMap helpers_; |
195 STLValueDeleter<HelperMap> helpers_deleter_; | 319 STLValueDeleter<HelperMap> helpers_deleter_; |
196 | 320 |
| 321 // Note: This should remain the last member so it'll be destroyed and |
| 322 // invalidate its weak pointers before any other members are destroyed. |
| 323 base::WeakPtrFactory<ShillServiceClientImpl> weak_ptr_factory_; |
| 324 |
197 DISALLOW_COPY_AND_ASSIGN(ShillServiceClientImpl); | 325 DISALLOW_COPY_AND_ASSIGN(ShillServiceClientImpl); |
198 }; | 326 }; |
199 | 327 |
200 // A stub implementation of ShillServiceClient. | 328 // A stub implementation of ShillServiceClient. |
201 class ShillServiceClientStubImpl : public ShillServiceClient, | 329 class ShillServiceClientStubImpl : public ShillServiceClient, |
202 public ShillServiceClient::TestInterface { | 330 public ShillServiceClient::TestInterface { |
203 public: | 331 public: |
204 ShillServiceClientStubImpl() : weak_ptr_factory_(this) { | 332 ShillServiceClientStubImpl() : |
| 333 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) { |
205 SetDefaultProperties(); | 334 SetDefaultProperties(); |
206 } | 335 } |
207 | 336 |
208 virtual ~ShillServiceClientStubImpl() { | 337 virtual ~ShillServiceClientStubImpl() { |
209 STLDeleteContainerPairSecondPointers( | 338 STLDeleteContainerPairSecondPointers( |
210 observer_list_.begin(), observer_list_.end()); | 339 observer_list_.begin(), observer_list_.end()); |
211 } | 340 } |
212 | 341 |
213 // ShillServiceClient overrides. | 342 // ShillServiceClient overrides. |
214 | 343 |
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
530 ShillServiceClient* ShillServiceClient::Create( | 659 ShillServiceClient* ShillServiceClient::Create( |
531 DBusClientImplementationType type, | 660 DBusClientImplementationType type, |
532 dbus::Bus* bus) { | 661 dbus::Bus* bus) { |
533 if (type == REAL_DBUS_CLIENT_IMPLEMENTATION) | 662 if (type == REAL_DBUS_CLIENT_IMPLEMENTATION) |
534 return new ShillServiceClientImpl(bus); | 663 return new ShillServiceClientImpl(bus); |
535 DCHECK_EQ(STUB_DBUS_CLIENT_IMPLEMENTATION, type); | 664 DCHECK_EQ(STUB_DBUS_CLIENT_IMPLEMENTATION, type); |
536 return new ShillServiceClientStubImpl(); | 665 return new ShillServiceClientStubImpl(); |
537 } | 666 } |
538 | 667 |
539 } // namespace chromeos | 668 } // namespace chromeos |
OLD | NEW |