Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(370)

Side by Side Diff: chromeos/dbus/shill_service_client.cc

Issue 12220025: Shill: ShillServiceClient destroys ShillClientHelpers when they are not need. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Testing add for add/remove observer. Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « chromeos/dbus/shill_client_helper.cc ('k') | chromeos/dbus/shill_service_client_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
OLDNEW
« no previous file with comments | « chromeos/dbus/shill_client_helper.cc ('k') | chromeos/dbus/shill_service_client_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698