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/memory/weak_ptr.h" |
8 #include "base/message_loop/message_loop.h" | 9 #include "base/message_loop/message_loop.h" |
9 #include "base/stl_util.h" | 10 #include "base/stl_util.h" |
10 #include "base/values.h" | 11 #include "base/values.h" |
11 #include "chromeos/dbus/shill_property_changed_observer.h" | 12 #include "chromeos/dbus/shill_property_changed_observer.h" |
12 #include "chromeos/dbus/shill_service_client_stub.h" | 13 #include "chromeos/dbus/shill_service_client_stub.h" |
| 14 #include "chromeos/network/network_event_log.h" |
13 #include "dbus/bus.h" | 15 #include "dbus/bus.h" |
14 #include "dbus/message.h" | 16 #include "dbus/message.h" |
15 #include "dbus/object_proxy.h" | 17 #include "dbus/object_proxy.h" |
16 #include "third_party/cros_system_api/dbus/service_constants.h" | 18 #include "third_party/cros_system_api/dbus/service_constants.h" |
17 | 19 |
18 namespace chromeos { | 20 namespace chromeos { |
19 | 21 |
20 namespace { | 22 namespace { |
21 | 23 |
22 #ifndef DBUS_ERROR_UNKNOWN_OBJECT | 24 #ifndef DBUS_ERROR_UNKNOWN_OBJECT |
(...skipping 24 matching lines...) Expand all Loading... |
47 | 49 |
48 base::DictionaryValue empty_dictionary; | 50 base::DictionaryValue empty_dictionary; |
49 callback.Run(DBUS_METHOD_CALL_FAILURE, empty_dictionary); | 51 callback.Run(DBUS_METHOD_CALL_FAILURE, empty_dictionary); |
50 } | 52 } |
51 | 53 |
52 // The ShillServiceClient implementation. | 54 // The ShillServiceClient implementation. |
53 class ShillServiceClientImpl : public ShillServiceClient { | 55 class ShillServiceClientImpl : public ShillServiceClient { |
54 public: | 56 public: |
55 explicit ShillServiceClientImpl() | 57 explicit ShillServiceClientImpl() |
56 : bus_(NULL), | 58 : bus_(NULL), |
57 helpers_deleter_(&helpers_) { | 59 weak_ptr_factory_(this) { |
| 60 } |
| 61 |
| 62 virtual ~ShillServiceClientImpl() { |
| 63 for (HelperMap::iterator iter = helpers_.begin(); |
| 64 iter != helpers_.end(); ++iter) { |
| 65 ShillClientHelper* helper = iter->second; |
| 66 bus_->RemoveObjectProxy(shill::kFlimflamServiceName, |
| 67 helper->object_proxy()->object_path(), |
| 68 base::Bind(&base::DoNothing)); |
| 69 delete helper; |
| 70 } |
58 } | 71 } |
59 | 72 |
60 virtual void AddPropertyChangedObserver( | 73 virtual void AddPropertyChangedObserver( |
61 const dbus::ObjectPath& service_path, | 74 const dbus::ObjectPath& service_path, |
62 ShillPropertyChangedObserver* observer) OVERRIDE { | 75 ShillPropertyChangedObserver* observer) OVERRIDE { |
63 GetHelper(service_path)->AddPropertyChangedObserver(observer); | 76 GetHelper(service_path)->AddPropertyChangedObserver(observer); |
64 } | 77 } |
65 | 78 |
66 virtual void RemovePropertyChangedObserver( | 79 virtual void RemovePropertyChangedObserver( |
67 const dbus::ObjectPath& service_path, | 80 const dbus::ObjectPath& service_path, |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
215 private: | 228 private: |
216 typedef std::map<std::string, ShillClientHelper*> HelperMap; | 229 typedef std::map<std::string, ShillClientHelper*> HelperMap; |
217 | 230 |
218 // Returns the corresponding ShillClientHelper for the profile. | 231 // Returns the corresponding ShillClientHelper for the profile. |
219 ShillClientHelper* GetHelper(const dbus::ObjectPath& service_path) { | 232 ShillClientHelper* GetHelper(const dbus::ObjectPath& service_path) { |
220 HelperMap::iterator it = helpers_.find(service_path.value()); | 233 HelperMap::iterator it = helpers_.find(service_path.value()); |
221 if (it != helpers_.end()) | 234 if (it != helpers_.end()) |
222 return it->second; | 235 return it->second; |
223 | 236 |
224 // There is no helper for the profile, create it. | 237 // There is no helper for the profile, create it. |
| 238 NET_LOG_DEBUG("AddShillClientHelper", service_path.value()); |
225 dbus::ObjectProxy* object_proxy = | 239 dbus::ObjectProxy* object_proxy = |
226 bus_->GetObjectProxy(shill::kFlimflamServiceName, service_path); | 240 bus_->GetObjectProxy(shill::kFlimflamServiceName, service_path); |
227 ShillClientHelper* helper = new ShillClientHelper(bus_, object_proxy); | 241 ShillClientHelper* helper = new ShillClientHelper(object_proxy); |
| 242 helper->SetReleasedCallback( |
| 243 base::Bind(&ShillServiceClientImpl::NotifyReleased, |
| 244 weak_ptr_factory_.GetWeakPtr())); |
228 helper->MonitorPropertyChanged(shill::kFlimflamServiceInterface); | 245 helper->MonitorPropertyChanged(shill::kFlimflamServiceInterface); |
229 helpers_.insert(HelperMap::value_type(service_path.value(), helper)); | 246 helpers_.insert(HelperMap::value_type(service_path.value(), helper)); |
230 return helper; | 247 return helper; |
231 } | 248 } |
232 | 249 |
| 250 void NotifyReleased(ShillClientHelper* helper) { |
| 251 // New Shill Service DBus objects are created relatively frequently, so |
| 252 // remove them when they become inactive (no observers and no active method |
| 253 // calls). |
| 254 dbus::ObjectPath object_path = helper->object_proxy()->object_path(); |
| 255 NET_LOG_DEBUG("RemoveShillClientHelper", object_path.value()); |
| 256 bus_->RemoveObjectProxy(shill::kFlimflamServiceName, |
| 257 object_path, base::Bind(&base::DoNothing)); |
| 258 helpers_.erase(object_path.value()); |
| 259 delete helper; |
| 260 } |
| 261 |
233 dbus::Bus* bus_; | 262 dbus::Bus* bus_; |
234 HelperMap helpers_; | 263 HelperMap helpers_; |
235 STLValueDeleter<HelperMap> helpers_deleter_; | 264 base::WeakPtrFactory<ShillServiceClientImpl> weak_ptr_factory_; |
236 | 265 |
237 DISALLOW_COPY_AND_ASSIGN(ShillServiceClientImpl); | 266 DISALLOW_COPY_AND_ASSIGN(ShillServiceClientImpl); |
238 }; | 267 }; |
239 | 268 |
240 } // namespace | 269 } // namespace |
241 | 270 |
242 ShillServiceClient::ShillServiceClient() {} | 271 ShillServiceClient::ShillServiceClient() {} |
243 | 272 |
244 ShillServiceClient::~ShillServiceClient() {} | 273 ShillServiceClient::~ShillServiceClient() {} |
245 | 274 |
246 // static | 275 // static |
247 ShillServiceClient* ShillServiceClient::Create( | 276 ShillServiceClient* ShillServiceClient::Create( |
248 DBusClientImplementationType type) { | 277 DBusClientImplementationType type) { |
249 if (type == REAL_DBUS_CLIENT_IMPLEMENTATION) | 278 if (type == REAL_DBUS_CLIENT_IMPLEMENTATION) |
250 return new ShillServiceClientImpl(); | 279 return new ShillServiceClientImpl(); |
251 DCHECK_EQ(STUB_DBUS_CLIENT_IMPLEMENTATION, type); | 280 DCHECK_EQ(STUB_DBUS_CLIENT_IMPLEMENTATION, type); |
252 return new ShillServiceClientStub(); | 281 return new ShillServiceClientStub(); |
253 } | 282 } |
254 | 283 |
255 } // namespace chromeos | 284 } // namespace chromeos |
OLD | NEW |