OLD | NEW |
---|---|
(Empty) | |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 #include "chromeos/network/network_state_handler_impl.h" | |
6 | |
7 #include "base/bind.h" | |
8 #include "base/stl_util.h" | |
9 #include "base/string_util.h" | |
10 #include "base/values.h" | |
11 #include "chromeos/dbus/dbus_thread_manager.h" | |
12 #include "chromeos/dbus/shill_device_client.h" | |
13 #include "chromeos/dbus/shill_ipconfig_client.h" | |
14 #include "chromeos/dbus/shill_manager_client.h" | |
15 #include "chromeos/dbus/shill_service_client.h" | |
16 #include "chromeos/network/network_state_handler.h" | |
17 #include "chromeos/network/shill_service_observer.h" | |
18 #include "dbus/object_path.h" | |
19 #include "third_party/cros_system_api/dbus/service_constants.h" | |
20 | |
21 namespace { | |
22 | |
23 void ErrorCallbackFunction(const std::string& error_name, | |
24 const std::string& error_message) { | |
25 // TODO(stevenjb): Add error logging. | |
26 LOG(ERROR) << "Shill Error: " << error_name << " : " << error_message; | |
27 } | |
28 | |
29 const base::ListValue* GetListValue(const std::string& key, | |
30 const base::Value& value) { | |
31 const base::ListValue* vlist = NULL; | |
32 if (!value.GetAsList(&vlist)) { | |
33 LOG(ERROR) << "Error parsing key as list: " << key; | |
34 return NULL; | |
35 } | |
36 return vlist; | |
37 } | |
38 | |
39 } // namespace | |
40 | |
41 namespace chromeos { | |
42 namespace internal { | |
43 | |
44 NetworkStateHandlerImpl::NetworkStateHandlerImpl(NetworkStateHandler* base) | |
45 : base_(base), | |
46 shill_manager_(DBusThreadManager::Get()->GetShillManagerClient()), | |
47 weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { | |
48 } | |
49 | |
50 NetworkStateHandlerImpl::~NetworkStateHandlerImpl() { | |
51 // Delete network service observers. | |
52 STLDeleteContainerPairSecondPointers( | |
53 observed_networks_.begin(), observed_networks_.end()); | |
54 CHECK(shill_manager_ == DBusThreadManager::Get()->GetShillManagerClient()); | |
55 shill_manager_->RemovePropertyChangedObserver(this); | |
56 } | |
57 | |
58 void NetworkStateHandlerImpl::Init() { | |
59 shill_manager_->GetProperties( | |
60 base::Bind(&NetworkStateHandlerImpl::ManagerPropertiesCallback, | |
61 weak_ptr_factory_.GetWeakPtr())); | |
62 shill_manager_->AddPropertyChangedObserver(this); | |
63 } | |
64 | |
65 void NetworkStateHandlerImpl::SetTechnologyEnabled( | |
66 const std::string& technology, | |
67 bool enabled) { | |
68 if (enabled) { | |
69 shill_manager_->EnableTechnology(technology, | |
70 base::Bind(&base::DoNothing), | |
71 base::Bind(&ErrorCallbackFunction)); | |
72 } else { | |
73 shill_manager_->DisableTechnology(technology, | |
74 base::Bind(&base::DoNothing), | |
75 base::Bind(&ErrorCallbackFunction)); | |
76 } | |
77 } | |
78 | |
79 void NetworkStateHandlerImpl::RequestScan() const { | |
80 shill_manager_->RequestScan("", | |
81 base::Bind(&base::DoNothing), | |
82 base::Bind(&ErrorCallbackFunction)); | |
83 } | |
84 | |
85 void NetworkStateHandlerImpl::RequestProperties(ManagedState::ManagedType type, | |
86 const std::string& path) { | |
87 ++pending_updates_[type]; | |
pneubeck (no reviews)
2012/10/29 20:27:49
Shill/DBus guarantees x answers to x requests for
stevenjb
2012/10/30 00:40:25
Yes. Even if there is a timeout or an error the ca
| |
88 if (type == ManagedState::MANAGED_TYPE_NETWORK) { | |
89 DBusThreadManager::Get()->GetShillServiceClient()->GetProperties( | |
90 dbus::ObjectPath(path), | |
91 base::Bind(&NetworkStateHandlerImpl::GetPropertiesCallback, | |
92 weak_ptr_factory_.GetWeakPtr(), type, path)); | |
93 } else if (type == ManagedState::MANAGED_TYPE_DEVICE) { | |
94 DBusThreadManager::Get()->GetShillDeviceClient()->GetProperties( | |
95 dbus::ObjectPath(path), | |
96 base::Bind(&NetworkStateHandlerImpl::GetPropertiesCallback, | |
97 weak_ptr_factory_.GetWeakPtr(), type, path)); | |
98 } else { | |
99 NOTREACHED(); | |
100 } | |
101 } | |
102 | |
103 void NetworkStateHandlerImpl::RequestIPConfig( | |
104 const std::string& service_path, | |
105 const std::string& ip_config_path) { | |
106 DBusThreadManager::Get()->GetShillIPConfigClient()->GetProperties( | |
107 dbus::ObjectPath(ip_config_path), | |
108 base::Bind(&NetworkStateHandlerImpl::GetIPConfigCallback, | |
109 weak_ptr_factory_.GetWeakPtr(), | |
110 service_path)); | |
111 } | |
112 | |
113 | |
114 void NetworkStateHandlerImpl::OnPropertyChanged(const std::string& key, | |
115 const base::Value& value) { | |
116 if (ManagerPropertyChanged(key, value)) | |
117 base_->NotifyManagerChanged(); | |
118 } | |
119 | |
120 //------------------------------------------------------------------------------ | |
121 // Private methods | |
122 | |
123 void NetworkStateHandlerImpl::ManagerPropertiesCallback( | |
124 DBusMethodCallStatus call_status, | |
125 const base::DictionaryValue& properties) { | |
126 if (call_status != DBUS_METHOD_CALL_SUCCESS) { | |
127 LOG(ERROR) << "Failed to get Manager properties:" << call_status; | |
128 return; | |
129 } | |
130 bool notify = false; | |
131 for (base::DictionaryValue::Iterator iter(properties); | |
132 iter.HasNext(); iter.Advance()) { | |
133 notify |= ManagerPropertyChanged(iter.key(), iter.value()); | |
134 } | |
135 if (notify) | |
136 base_->NotifyManagerChanged(); | |
137 } | |
138 | |
139 bool NetworkStateHandlerImpl::ManagerPropertyChanged(const std::string& key, | |
140 const base::Value& value) { | |
141 bool notify_manager_changed = false; | |
142 if (key == flimflam::kServicesProperty) { | |
143 const base::ListValue* vlist = GetListValue(key, value); | |
144 if (vlist) { | |
145 base_->UpdateManagedList(ManagedState::MANAGED_TYPE_NETWORK, *vlist); | |
146 // Do not send an UpdateManagerChanged notification to observers. | |
147 // An UpdateNetworkList notification will be sent when the service list | |
148 // updates have completed. | |
149 } | |
150 } else if (key == flimflam::kServiceWatchListProperty) { | |
151 const base::ListValue* vlist = GetListValue(key, value); | |
152 if (vlist) { | |
153 UpdateObservedNetworkServices(*vlist); | |
154 // No notification. | |
155 } | |
156 } else if (key == flimflam::kDevicesProperty) { | |
157 const ListValue* vlist = GetListValue(key, value); | |
158 if (vlist) { | |
159 base_->UpdateManagedList(ManagedState::MANAGED_TYPE_DEVICE, *vlist); | |
160 notify_manager_changed = true; | |
161 } | |
162 } else if (key == flimflam::kAvailableTechnologiesProperty) { | |
163 const base::ListValue* vlist = GetListValue(key, value); | |
164 if (vlist ) { | |
165 base_->SetAvailableTechnologies(*vlist); | |
166 notify_manager_changed = true; | |
167 } | |
168 } else if (key == flimflam::kEnabledTechnologiesProperty) { | |
169 const base::ListValue* vlist = GetListValue(key, value); | |
170 if (vlist) { | |
171 base_->SetEnabledTechnologies(*vlist); | |
172 notify_manager_changed = true; | |
173 } | |
174 } | |
175 return notify_manager_changed; | |
176 } | |
177 | |
178 void NetworkStateHandlerImpl::UpdateObservedNetworkServices( | |
179 const base::ListValue& entries) { | |
180 // Watch all networks in the watch list. | |
181 ShillServiceObserverMap new_observed; | |
182 for (base::ListValue::const_iterator iter = entries.begin(); | |
183 iter != entries.end(); ++iter) { | |
184 std::string path; | |
185 (*iter)->GetAsString(&path); | |
186 if (path.empty()) | |
187 continue; | |
188 ShillServiceObserverMap::iterator iter = observed_networks_.find(path); | |
189 if (iter != observed_networks_.end()) { | |
190 new_observed[path] = observed_networks_[path]; | |
191 } else { | |
192 new_observed[path] = new ShillServiceObserver( | |
193 path, base::Bind( | |
194 &NetworkStateHandlerImpl::NetworkServicePropertyChangedCallback, | |
195 weak_ptr_factory_.GetWeakPtr())); | |
196 // Request an update for newly watched services. | |
197 RequestProperties(ManagedState::MANAGED_TYPE_NETWORK, path); | |
198 } | |
199 observed_networks_.erase(path); | |
200 } | |
201 VLOG(2) << "UpdateObservedNetworkServices, new observed: " | |
202 << new_observed.size(); | |
203 // Delete network service observers still in observed_networks_. | |
204 STLDeleteContainerPairSecondPointers( | |
205 observed_networks_.begin(), observed_networks_.end()); | |
206 observed_networks_.swap(new_observed); | |
207 } | |
208 | |
209 void NetworkStateHandlerImpl::GetPropertiesCallback( | |
210 ManagedState::ManagedType type, | |
211 const std::string& path, | |
212 DBusMethodCallStatus call_status, | |
213 const base::DictionaryValue& properties) { | |
214 VLOG(2) << "GetPropertiesCallback: " << type << " : " << path; | |
215 --pending_updates_[type]; | |
216 if (call_status != DBUS_METHOD_CALL_SUCCESS) { | |
217 LOG(ERROR) << "Failed to get properties for: " << path | |
218 << ": " << call_status; | |
219 return; | |
220 } | |
221 base_->ParseProperties(type, path, properties); | |
pneubeck (no reviews)
2012/10/29 20:27:49
"Parse" is not informative. Perhaps rename it to S
stevenjb
2012/10/30 00:40:25
Well, it is parsing the dictionary, not blindly se
| |
222 // Notify observers only when all updates for that type have completed. | |
223 if (type == ManagedState::MANAGED_TYPE_NETWORK && | |
224 pending_updates_[type] == 0) { | |
pneubeck (no reviews)
2012/10/29 20:27:49
Maybe, moving pending_updates_ back to NetworkStat
stevenjb
2012/10/30 00:40:25
See previous comment. Renamed the function and cha
| |
225 base_->NotifyNetworkServiceObservers(); | |
226 } | |
227 } | |
228 | |
229 void NetworkStateHandlerImpl::NetworkServicePropertyChangedCallback( | |
230 const std::string& path, | |
231 const std::string& key, | |
232 const base::Value& value) { | |
233 base_->NetworkServicePropertyChanged(path, key, value); | |
234 } | |
235 | |
236 void NetworkStateHandlerImpl::GetIPConfigCallback( | |
237 const std::string& service_path, | |
238 DBusMethodCallStatus call_status, | |
239 const base::DictionaryValue& properties) { | |
240 if (call_status != DBUS_METHOD_CALL_SUCCESS) { | |
241 LOG(ERROR) << "Failed to get IP properties for: " << service_path; | |
242 return; | |
243 } | |
244 std::string ip_address; | |
245 if (!properties.GetStringWithoutPathExpansion(flimflam::kAddressProperty, | |
246 &ip_address)) { | |
247 LOG(ERROR) << "Failed to get IP Address property for: " << service_path; | |
248 return; | |
249 } | |
250 base_->SetServiceIPAddress(service_path, ip_address); | |
251 } | |
252 | |
253 } // namespace internal | |
254 } // namespace chromeos | |
OLD | NEW |