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.h" | |
6 | |
7 #include "base/stl_util.h" | |
8 #include "base/string_util.h" | |
9 #include "base/values.h" | |
10 #include "chromeos/network/device_state.h" | |
11 #include "chromeos/network/managed_state.h" | |
12 #include "chromeos/network/network_state.h" | |
13 #include "chromeos/network/network_state_handler_observer.h" | |
14 #include "chromeos/network/shill_property_handler.h" | |
15 #include "third_party/cros_system_api/dbus/service_constants.h" | |
16 | |
17 namespace chromeos { | |
18 | |
19 NetworkStateHandler::NetworkStateHandler() { | |
20 } | |
21 | |
22 NetworkStateHandler::~NetworkStateHandler() { | |
23 STLDeleteContainerPointers(network_list_.begin(), network_list_.end()); | |
24 STLDeleteContainerPointers(device_list_.begin(), device_list_.end()); | |
25 } | |
26 | |
27 void NetworkStateHandler::Init() { | |
28 shill_property_handler_.reset(new internal::ShillPropertyHandler(this)); | |
29 shill_property_handler_->Init(); | |
30 } | |
31 | |
32 void NetworkStateHandler::AddObserver(NetworkStateHandlerObserver* observer) { | |
33 observers_.AddObserver(observer); | |
34 } | |
35 | |
36 void NetworkStateHandler::RemoveObserver( | |
37 NetworkStateHandlerObserver* observer) { | |
38 observers_.RemoveObserver(observer); | |
39 } | |
40 | |
41 bool NetworkStateHandler::TechnologyAvailable( | |
42 const std::string& technology) const { | |
43 return available_technologies_.find(technology) != | |
44 available_technologies_.end(); | |
45 } | |
46 | |
47 bool NetworkStateHandler::TechnologyEnabled( | |
48 const std::string& technology) const { | |
49 return enabled_technologies_.find(technology) != enabled_technologies_.end(); | |
50 } | |
51 | |
52 void NetworkStateHandler::SetTechnologyEnabled(const std::string& technology, | |
53 bool enabled) { | |
54 shill_property_handler_->SetTechnologyEnabled(technology, enabled); | |
55 } | |
56 | |
57 const DeviceState* NetworkStateHandler::GetDeviceState( | |
58 const std::string& device_path) const { | |
59 return GetModifiableDeviceState(device_path); | |
60 } | |
61 | |
62 const DeviceState* NetworkStateHandler::GetDeviceStateByType( | |
63 const std::string& type) const { | |
64 for (ManagedStateList::const_iterator iter = device_list_.begin(); | |
65 iter != device_list_.end(); ++iter) { | |
66 ManagedState* device = *iter; | |
67 if (device->type() == type) | |
68 return device->AsDeviceState(); | |
69 } | |
70 return NULL; | |
71 } | |
72 | |
73 const NetworkState* NetworkStateHandler::GetNetworkState( | |
74 const std::string& service_path) const { | |
75 return GetModifiableNetworkState(service_path); | |
76 } | |
77 | |
78 const NetworkState* NetworkStateHandler::ActiveNetwork() const { | |
79 if (network_list_.empty()) | |
80 return NULL; | |
81 const NetworkState* network = network_list_.front()->AsNetworkState(); | |
82 DCHECK(network); | |
83 if (!network->IsConnectedState()) | |
84 return NULL; | |
85 return network; | |
86 } | |
87 | |
88 const NetworkState* NetworkStateHandler::ConnectedNetworkByType( | |
89 const std::string& type) const { | |
90 for (ManagedStateList::const_iterator iter = network_list_.begin(); | |
91 iter != network_list_.end(); ++iter) { | |
92 const NetworkState* network = (*iter)->AsNetworkState(); | |
93 DCHECK(network); | |
94 if (!network->IsConnectedState()) | |
95 break; // Connected networks are listed first. | |
96 if (network->type() == type) | |
97 return network; | |
98 } | |
99 return NULL; | |
100 } | |
101 | |
102 const NetworkState* NetworkStateHandler::ConnectingNetworkByType( | |
103 const std::string& type) const { | |
104 for (ManagedStateList::const_iterator iter = network_list_.begin(); | |
105 iter != network_list_.end(); ++iter) { | |
106 const NetworkState* network = (*iter)->AsNetworkState(); | |
107 DCHECK(network); | |
108 if (network->IsConnectedState()) | |
109 continue; | |
110 if (!network->IsConnectingState()) | |
111 break; // Connected and connecting networks are listed first. | |
112 if (network->type() == type || | |
113 (type.empty() && type != flimflam::kTypeEthernet)) { | |
114 return network; | |
115 } | |
116 } | |
117 return NULL; | |
118 } | |
119 | |
120 std::string NetworkStateHandler::HardwareAddressForType( | |
121 const std::string& type) const { | |
122 std::string result; | |
123 const NetworkState* network = ConnectedNetworkByType(type); | |
124 if (network) { | |
125 const DeviceState* device = GetDeviceState(network->device_path()); | |
126 if (device) | |
127 result = device->mac_address(); | |
128 } | |
129 StringToUpperASCII(&result); | |
130 return result; | |
131 } | |
132 | |
133 std::string NetworkStateHandler::FormattedHardwareAddressForType( | |
134 const std::string& type) const { | |
135 std::string address = HardwareAddressForType(type); | |
136 if (address.size() % 2 != 0) | |
137 return address; | |
138 std::string result; | |
139 for (size_t i = 0; i < address.size(); ++i) { | |
140 if ((i != 0) && (i % 2 == 0)) | |
141 result.push_back(':'); | |
142 result.push_back(address[i]); | |
143 } | |
144 return result; | |
145 } | |
146 | |
147 void NetworkStateHandler::GetNetworkList(NetworkStateList* list) const { | |
148 DCHECK(list); | |
149 shill_property_handler_->RequestScan(); | |
150 NetworkStateList result; | |
151 list->clear(); | |
152 for (ManagedStateList::const_iterator iter = network_list_.begin(); | |
153 iter != network_list_.end(); ++iter) { | |
154 const NetworkState* network = (*iter)->AsNetworkState(); | |
155 DCHECK(network); | |
156 list->push_back(network); | |
157 } | |
158 } | |
159 | |
160 //------------------------------------------------------------------------------ | |
161 // ShillPropertyHandler::Delegate overrides | |
162 | |
163 void NetworkStateHandler::UpdateManagedList(ManagedState::ManagedType type, | |
164 const base::ListValue& entries) { | |
165 ManagedStateList* managed_list = GetManagedList(type); | |
166 VLOG(2) << "UpdateManagedList: " << type; | |
167 // Create a map of existing entries. | |
168 std::map<std::string, ManagedState*> managed_map; | |
169 for (ManagedStateList::iterator iter = managed_list->begin(); | |
170 iter != managed_list->end(); ++iter) { | |
171 ManagedState* managed = *iter; | |
172 managed_map[managed->path()] = managed; | |
173 } | |
174 // Clear the list (pointers are owned by managed_map). | |
175 managed_list->clear(); | |
176 // Updates managed_list and request updates for new entries. | |
177 for (base::ListValue::const_iterator iter = entries.begin(); | |
178 iter != entries.end(); ++iter) { | |
179 std::string path; | |
180 (*iter)->GetAsString(&path); | |
181 if (path.empty()) | |
gauravsh
2012/11/06 01:56:59
This ignores an error in GetAsString() or having a
stevenjb
2012/11/06 03:17:03
Shouldn't happen, changed to DCHECK
pneubeck (no reviews)
2012/11/06 09:18:19
A general question about the usage of DCHECK/NOTRE
| |
182 continue; | |
183 std::map<std::string, ManagedState*>::iterator found = | |
184 managed_map.find(path); | |
185 bool request_properties = false; | |
186 ManagedState* managed; | |
187 bool is_observing = shill_property_handler_->IsObservingNetwork(path); | |
188 if (found == managed_map.end()) { | |
189 request_properties = true; | |
190 managed = ManagedState::Create(type, path); | |
191 managed_list->push_back(managed); | |
192 } else { | |
193 managed = found->second; | |
194 managed_list->push_back(managed); | |
195 managed_map.erase(found); | |
196 if (!managed->is_observed() && is_observing) | |
197 request_properties = true; | |
198 } | |
199 if (is_observing) | |
200 managed->set_is_observed(true); | |
201 if (request_properties) | |
202 shill_property_handler_->RequestProperties(type, path); | |
203 } | |
204 // Delete any remaning entries in managed_map. | |
205 STLDeleteContainerPairSecondPointers(managed_map.begin(), managed_map.end()); | |
206 } | |
207 | |
208 void NetworkStateHandler::UpdateAvailableTechnologies( | |
209 const base::ListValue& technologies) { | |
210 available_technologies_.clear(); | |
211 for (base::ListValue::const_iterator iter = technologies.begin(); | |
212 iter != technologies.end(); ++iter) { | |
213 std::string technology; | |
214 (*iter)->GetAsString(&technology); | |
215 DCHECK(!technology.empty()); | |
216 available_technologies_.insert(technology); | |
217 } | |
218 } | |
219 | |
220 void NetworkStateHandler::UpdateEnabledTechnologies( | |
221 const base::ListValue& technologies) { | |
222 enabled_technologies_.clear(); | |
223 for (base::ListValue::const_iterator iter = technologies.begin(); | |
224 iter != technologies.end(); ++iter) { | |
225 std::string technology; | |
226 (*iter)->GetAsString(&technology); | |
gauravsh
2012/11/06 01:56:59
See my comment in UpdateManagedList. Why is it ok
stevenjb
2012/11/06 03:17:03
Should never happen which is why it's a DCHECK.
| |
227 DCHECK(!technology.empty()); | |
228 enabled_technologies_.insert(technology); | |
229 } | |
230 } | |
231 | |
232 void NetworkStateHandler::UpdateManagedStateProperties( | |
233 ManagedState::ManagedType type, | |
234 const std::string& path, | |
235 const base::DictionaryValue& properties) { | |
236 ManagedState* managed = GetModifiableManagedState(GetManagedList(type), path); | |
237 if (!managed) { | |
238 LOG(ERROR) << "GetPropertiesCallback: " << path << " Not found!"; | |
239 return; | |
240 } | |
241 bool property_changed = false; | |
242 for (base::DictionaryValue::Iterator iter(properties); | |
243 iter.HasNext(); iter.Advance()) { | |
244 if (type == ManagedState::MANAGED_TYPE_NETWORK) { | |
245 if (ParseNetworkServiceProperty(managed->AsNetworkState(), | |
246 iter.key(), iter.value())) | |
247 property_changed = true; | |
248 } else { | |
249 if (managed->PropertyChanged(iter.key(), iter.value())) | |
250 property_changed = true; | |
gauravsh
2012/11/06 01:56:59
Since MANAGED_TYPE_DEVICE type never causes observ
stevenjb
2012/11/06 03:17:03
Renamed
| |
251 } | |
252 } | |
253 // Notify observers. | |
254 if (property_changed && type == ManagedState::MANAGED_TYPE_NETWORK) { | |
255 NetworkState* network = managed->AsNetworkState(); | |
256 DCHECK(network); | |
257 FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_, | |
258 NetworkServiceChanged(network)); | |
259 } | |
260 } | |
261 | |
262 void NetworkStateHandler::UpdateNetworkServiceProperty( | |
263 const std::string& service_path, | |
264 const std::string& key, | |
265 const base::Value& value) { | |
266 NetworkState* network = GetModifiableNetworkState(service_path); | |
267 if (!network) | |
268 return; | |
269 if (ParseNetworkServiceProperty(network, key, value)) { | |
270 FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_, | |
271 NetworkServiceChanged(network)); | |
272 } | |
273 } | |
274 | |
275 void NetworkStateHandler::UpdateNetworkServiceIPAddress( | |
276 const std::string& service_path, | |
277 const std::string& ip_address) { | |
278 NetworkState* network = GetModifiableNetworkState(service_path); | |
279 if (!network) | |
280 return; | |
281 network->set_ip_address(ip_address); | |
282 FOR_EACH_OBSERVER( | |
283 NetworkStateHandlerObserver, observers_, | |
284 NetworkServiceChanged(network)); | |
285 } | |
286 | |
287 void NetworkStateHandler::ManagerPropertyChanged() { | |
288 FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_, | |
289 NetworkManagerChanged()); | |
290 } | |
291 | |
292 void NetworkStateHandler::ManagedStateListChanged( | |
293 ManagedState::ManagedType type) { | |
294 if (type == ManagedState::MANAGED_TYPE_NETWORK) { | |
295 // Notify observers that the list of networks has changed. | |
296 NetworkStateList network_list; | |
297 GetNetworkList(&network_list); | |
298 FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_, | |
299 NetworkListChanged(network_list)); | |
300 // Update the active network and notify observers if it has changed. | |
301 NetworkState* new_active_network = | |
302 network_list_.empty() ? NULL : network_list_.front()->AsNetworkState(); | |
303 std::string new_active_network_path; | |
304 if (new_active_network) | |
305 new_active_network_path = new_active_network->path(); | |
306 if (new_active_network_path != active_network_path_) { | |
307 active_network_path_ = new_active_network_path; | |
308 FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_, | |
309 ActiveNetworkChanged(new_active_network)); | |
310 } | |
311 } else if (type == ManagedState::MANAGED_TYPE_DEVICE) { | |
312 FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_, | |
313 DeviceListChanged()); | |
314 } else { | |
315 NOTREACHED(); | |
316 } | |
317 } | |
318 | |
319 //------------------------------------------------------------------------------ | |
320 // Private methods | |
321 | |
322 DeviceState* NetworkStateHandler::GetModifiableDeviceState( | |
323 const std::string& device_path) const { | |
324 ManagedState* managed = GetModifiableManagedState(&device_list_, device_path); | |
325 if (!managed) | |
326 return NULL; | |
327 return managed->AsDeviceState(); | |
328 } | |
329 | |
330 NetworkState* NetworkStateHandler::GetModifiableNetworkState( | |
331 const std::string& service_path) const { | |
332 ManagedState* managed = | |
333 GetModifiableManagedState(&network_list_, service_path); | |
334 if (!managed) | |
335 return NULL; | |
336 return managed->AsNetworkState(); | |
337 } | |
338 | |
339 ManagedState* NetworkStateHandler::GetModifiableManagedState( | |
340 const ManagedStateList* managed_list, | |
341 const std::string& path) const { | |
342 for (ManagedStateList::const_iterator iter = managed_list->begin(); | |
343 iter != managed_list->end(); ++iter) { | |
344 ManagedState* managed = *iter; | |
345 if (managed->path() == path) | |
346 return managed; | |
347 } | |
348 return NULL; | |
349 } | |
350 | |
351 NetworkStateHandler::ManagedStateList* NetworkStateHandler::GetManagedList( | |
352 ManagedState::ManagedType type) { | |
353 switch(type) { | |
354 case ManagedState::MANAGED_TYPE_NETWORK: | |
355 return &network_list_; | |
356 case ManagedState::MANAGED_TYPE_DEVICE: | |
357 return &device_list_; | |
358 } | |
359 NOTREACHED(); | |
360 return NULL; | |
361 } | |
362 | |
363 bool NetworkStateHandler::ParseNetworkServiceProperty( | |
364 NetworkState* network, | |
365 const std::string& key, | |
366 const base::Value& value) { | |
367 DCHECK(network); | |
368 bool property_changed = false; | |
369 // Handle IPConfig here since it requires additional complexity that is | |
370 // better handled here than in NetworkState::PropertyChanged (e.g. | |
371 // observer notification). | |
372 if (key == shill::kIPConfigProperty) { | |
gauravsh
2012/11/06 01:56:59
Is this something that should be re-factored at so
stevenjb
2012/11/06 03:17:03
Moved the comment inside the if() and clarified it
| |
373 std::string ip_config_path; | |
374 if (value.GetAsString(&ip_config_path)) { | |
375 property_changed = true; | |
376 shill_property_handler_->RequestIPConfig(network->path(), ip_config_path); | |
377 } else { | |
378 NOTREACHED(); | |
379 } | |
380 } else { | |
381 if (network->PropertyChanged(key, value)) { | |
382 property_changed = true; | |
383 if (network->path() == active_network_path_ && | |
384 key == flimflam::kStateProperty) { | |
385 FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_, | |
386 ActiveNetworkStateChanged(network)); | |
387 } | |
388 } | |
389 } | |
390 return property_changed; | |
391 } | |
392 | |
393 } // namespace chromeos | |
OLD | NEW |