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 | |
stevenjb
2013/02/07 01:12:30
So, I apologize for continuing to iterate on this,
hashimoto
2013/02/07 05:20:31
Wasn't the bug marked as P1/ReleaseBlocker?
I thin
| |
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); |
287 // TODO(deymo): Delay the MonitorPropertyChanged call until an observer is | |
288 // added to the helper. If no observer is add and every call finishes we | |
289 // delete the helper making this AddMatch and RemoveMatch blocking cycle is | |
290 // useless. | |
stevenjb
2013/02/07 01:12:30
This doesn't seem too difficult, I think it's wort
| |
188 helper->MonitorPropertyChanged(flimflam::kFlimflamServiceInterface); | 291 helper->MonitorPropertyChanged(flimflam::kFlimflamServiceInterface); |
189 helpers_.insert(HelperMap::value_type(service_path.value(), helper)); | 292 helpers_.insert(HelperMap::value_type(service_path.value(), helper)); |
190 return helper; | 293 return helper; |
191 } | 294 } |
192 | 295 |
296 // Returns a Closure that calls OnHelperStatusUpdate with the given | |
297 // |service_path| argument. | |
298 base::Closure HelperStatusUpdateCallback( | |
299 const dbus::ObjectPath& service_path) { | |
300 return base::Bind(&ShillServiceClientImpl::OnHelperStatusUpdate, | |
301 weak_ptr_factory_.GetWeakPtr(), service_path); | |
302 } | |
303 | |
304 // This function is called every time the IsObserved or the IsWaitingResponse | |
305 // helper's properties may have changed. If both are false, the cached helper | |
306 // can be safely removed. | |
307 void OnHelperStatusUpdate(const dbus::ObjectPath& service_path) { | |
308 HelperMap::iterator it = helpers_.find(service_path.value()); | |
309 if (it == helpers_.end()) | |
310 return; | |
311 | |
312 ShillClientHelper* const helper = it->second; | |
313 if (!helper->IsObserved() && !helper->IsWaitingResponse()) { | |
314 helpers_.erase(it); | |
315 delete helper; | |
316 bus_->RemoveObjectProxy(flimflam::kFlimflamServiceName, service_path, | |
317 base::Bind(&base::DoNothing)); | |
318 } | |
319 } | |
320 | |
193 dbus::Bus* bus_; | 321 dbus::Bus* bus_; |
194 HelperMap helpers_; | 322 HelperMap helpers_; |
195 STLValueDeleter<HelperMap> helpers_deleter_; | 323 STLValueDeleter<HelperMap> helpers_deleter_; |
196 | 324 |
325 // Note: This should remain the last member so it'll be destroyed and | |
326 // invalidate its weak pointers before any other members are destroyed. | |
327 base::WeakPtrFactory<ShillServiceClientImpl> weak_ptr_factory_; | |
328 | |
197 DISALLOW_COPY_AND_ASSIGN(ShillServiceClientImpl); | 329 DISALLOW_COPY_AND_ASSIGN(ShillServiceClientImpl); |
198 }; | 330 }; |
199 | 331 |
200 // A stub implementation of ShillServiceClient. | 332 // A stub implementation of ShillServiceClient. |
201 class ShillServiceClientStubImpl : public ShillServiceClient, | 333 class ShillServiceClientStubImpl : public ShillServiceClient, |
202 public ShillServiceClient::TestInterface { | 334 public ShillServiceClient::TestInterface { |
203 public: | 335 public: |
204 ShillServiceClientStubImpl() : weak_ptr_factory_(this) { | 336 ShillServiceClientStubImpl() : |
337 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) { | |
205 SetDefaultProperties(); | 338 SetDefaultProperties(); |
206 } | 339 } |
207 | 340 |
208 virtual ~ShillServiceClientStubImpl() { | 341 virtual ~ShillServiceClientStubImpl() { |
209 STLDeleteContainerPairSecondPointers( | 342 STLDeleteContainerPairSecondPointers( |
210 observer_list_.begin(), observer_list_.end()); | 343 observer_list_.begin(), observer_list_.end()); |
211 } | 344 } |
212 | 345 |
213 // ShillServiceClient overrides. | 346 // ShillServiceClient overrides. |
214 | 347 |
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
530 ShillServiceClient* ShillServiceClient::Create( | 663 ShillServiceClient* ShillServiceClient::Create( |
531 DBusClientImplementationType type, | 664 DBusClientImplementationType type, |
532 dbus::Bus* bus) { | 665 dbus::Bus* bus) { |
533 if (type == REAL_DBUS_CLIENT_IMPLEMENTATION) | 666 if (type == REAL_DBUS_CLIENT_IMPLEMENTATION) |
534 return new ShillServiceClientImpl(bus); | 667 return new ShillServiceClientImpl(bus); |
535 DCHECK_EQ(STUB_DBUS_CLIENT_IMPLEMENTATION, type); | 668 DCHECK_EQ(STUB_DBUS_CLIENT_IMPLEMENTATION, type); |
536 return new ShillServiceClientStubImpl(); | 669 return new ShillServiceClientStubImpl(); |
537 } | 670 } |
538 | 671 |
539 } // namespace chromeos | 672 } // namespace chromeos |
OLD | NEW |