network_state_handler.cc revision 5821806d5e7f356e8fa4b058a389a808ea183019
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 17namespace chromeos { 18 19NetworkStateHandler::NetworkStateHandler() { 20} 21 22NetworkStateHandler::~NetworkStateHandler() { 23 STLDeleteContainerPointers(network_list_.begin(), network_list_.end()); 24 STLDeleteContainerPointers(device_list_.begin(), device_list_.end()); 25} 26 27void NetworkStateHandler::Init() { 28 shill_property_handler_.reset(new internal::ShillPropertyHandler(this)); 29 shill_property_handler_->Init(); 30} 31 32void NetworkStateHandler::AddObserver(NetworkStateHandlerObserver* observer) { 33 observers_.AddObserver(observer); 34} 35 36void NetworkStateHandler::RemoveObserver( 37 NetworkStateHandlerObserver* observer) { 38 observers_.RemoveObserver(observer); 39} 40 41bool NetworkStateHandler::TechnologyAvailable( 42 const std::string& technology) const { 43 return available_technologies_.find(technology) != 44 available_technologies_.end(); 45} 46 47bool NetworkStateHandler::TechnologyEnabled( 48 const std::string& technology) const { 49 return enabled_technologies_.find(technology) != enabled_technologies_.end(); 50} 51 52void NetworkStateHandler::SetTechnologyEnabled(const std::string& technology, 53 bool enabled) { 54 shill_property_handler_->SetTechnologyEnabled(technology, enabled); 55} 56 57const DeviceState* NetworkStateHandler::GetDeviceState( 58 const std::string& device_path) const { 59 return GetModifiableDeviceState(device_path); 60} 61 62const 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 73const NetworkState* NetworkStateHandler::GetNetworkState( 74 const std::string& service_path) const { 75 return GetModifiableNetworkState(service_path); 76} 77 78const 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 88const 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 102const 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 120std::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 133std::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 147void 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 163void 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 DCHECK(!path.empty()); 182 std::map<std::string, ManagedState*>::iterator found = 183 managed_map.find(path); 184 bool request_properties = false; 185 ManagedState* managed; 186 bool is_observing = shill_property_handler_->IsObservingNetwork(path); 187 if (found == managed_map.end()) { 188 request_properties = true; 189 managed = ManagedState::Create(type, path); 190 managed_list->push_back(managed); 191 } else { 192 managed = found->second; 193 managed_list->push_back(managed); 194 managed_map.erase(found); 195 if (!managed->is_observed() && is_observing) 196 request_properties = true; 197 } 198 if (is_observing) 199 managed->set_is_observed(true); 200 if (request_properties) 201 shill_property_handler_->RequestProperties(type, path); 202 } 203 // Delete any remaning entries in managed_map. 204 STLDeleteContainerPairSecondPointers(managed_map.begin(), managed_map.end()); 205} 206 207void NetworkStateHandler::UpdateAvailableTechnologies( 208 const base::ListValue& technologies) { 209 available_technologies_.clear(); 210 for (base::ListValue::const_iterator iter = technologies.begin(); 211 iter != technologies.end(); ++iter) { 212 std::string technology; 213 (*iter)->GetAsString(&technology); 214 DCHECK(!technology.empty()); 215 available_technologies_.insert(technology); 216 } 217} 218 219void NetworkStateHandler::UpdateEnabledTechnologies( 220 const base::ListValue& technologies) { 221 enabled_technologies_.clear(); 222 for (base::ListValue::const_iterator iter = technologies.begin(); 223 iter != technologies.end(); ++iter) { 224 std::string technology; 225 (*iter)->GetAsString(&technology); 226 DCHECK(!technology.empty()); 227 enabled_technologies_.insert(technology); 228 } 229} 230 231void NetworkStateHandler::UpdateManagedStateProperties( 232 ManagedState::ManagedType type, 233 const std::string& path, 234 const base::DictionaryValue& properties) { 235 ManagedState* managed = GetModifiableManagedState(GetManagedList(type), path); 236 if (!managed) { 237 LOG(ERROR) << "GetPropertiesCallback: " << path << " Not found!"; 238 return; 239 } 240 bool network_property_changed = false; 241 for (base::DictionaryValue::Iterator iter(properties); 242 iter.HasNext(); iter.Advance()) { 243 if (type == ManagedState::MANAGED_TYPE_NETWORK) { 244 if (ParseNetworkServiceProperty(managed->AsNetworkState(), 245 iter.key(), iter.value())) 246 network_property_changed = true; 247 } else { 248 managed->PropertyChanged(iter.key(), iter.value()); 249 } 250 } 251 // Notify observers. 252 if (network_property_changed) { 253 NetworkState* network = managed->AsNetworkState(); 254 DCHECK(network); 255 FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_, 256 NetworkServiceChanged(network)); 257 } 258} 259 260void NetworkStateHandler::UpdateNetworkServiceProperty( 261 const std::string& service_path, 262 const std::string& key, 263 const base::Value& value) { 264 NetworkState* network = GetModifiableNetworkState(service_path); 265 if (!network) 266 return; 267 if (ParseNetworkServiceProperty(network, key, value)) { 268 FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_, 269 NetworkServiceChanged(network)); 270 } 271} 272 273void NetworkStateHandler::UpdateNetworkServiceIPAddress( 274 const std::string& service_path, 275 const std::string& ip_address) { 276 NetworkState* network = GetModifiableNetworkState(service_path); 277 if (!network) 278 return; 279 network->set_ip_address(ip_address); 280 FOR_EACH_OBSERVER( 281 NetworkStateHandlerObserver, observers_, 282 NetworkServiceChanged(network)); 283} 284 285void NetworkStateHandler::ManagerPropertyChanged() { 286 FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_, 287 NetworkManagerChanged()); 288} 289 290void NetworkStateHandler::ManagedStateListChanged( 291 ManagedState::ManagedType type) { 292 if (type == ManagedState::MANAGED_TYPE_NETWORK) { 293 // Notify observers that the list of networks has changed. 294 NetworkStateList network_list; 295 GetNetworkList(&network_list); 296 FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_, 297 NetworkListChanged(network_list)); 298 // Update the active network and notify observers if it has changed. 299 NetworkState* new_active_network = 300 network_list_.empty() ? NULL : network_list_.front()->AsNetworkState(); 301 std::string new_active_network_path; 302 if (new_active_network) 303 new_active_network_path = new_active_network->path(); 304 if (new_active_network_path != active_network_path_) { 305 active_network_path_ = new_active_network_path; 306 FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_, 307 ActiveNetworkChanged(new_active_network)); 308 } 309 } else if (type == ManagedState::MANAGED_TYPE_DEVICE) { 310 FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_, 311 DeviceListChanged()); 312 } else { 313 NOTREACHED(); 314 } 315} 316 317//------------------------------------------------------------------------------ 318// Private methods 319 320DeviceState* NetworkStateHandler::GetModifiableDeviceState( 321 const std::string& device_path) const { 322 ManagedState* managed = GetModifiableManagedState(&device_list_, device_path); 323 if (!managed) 324 return NULL; 325 return managed->AsDeviceState(); 326} 327 328NetworkState* NetworkStateHandler::GetModifiableNetworkState( 329 const std::string& service_path) const { 330 ManagedState* managed = 331 GetModifiableManagedState(&network_list_, service_path); 332 if (!managed) 333 return NULL; 334 return managed->AsNetworkState(); 335} 336 337ManagedState* NetworkStateHandler::GetModifiableManagedState( 338 const ManagedStateList* managed_list, 339 const std::string& path) const { 340 for (ManagedStateList::const_iterator iter = managed_list->begin(); 341 iter != managed_list->end(); ++iter) { 342 ManagedState* managed = *iter; 343 if (managed->path() == path) 344 return managed; 345 } 346 return NULL; 347} 348 349NetworkStateHandler::ManagedStateList* NetworkStateHandler::GetManagedList( 350 ManagedState::ManagedType type) { 351 switch(type) { 352 case ManagedState::MANAGED_TYPE_NETWORK: 353 return &network_list_; 354 case ManagedState::MANAGED_TYPE_DEVICE: 355 return &device_list_; 356 } 357 NOTREACHED(); 358 return NULL; 359} 360 361bool NetworkStateHandler::ParseNetworkServiceProperty( 362 NetworkState* network, 363 const std::string& key, 364 const base::Value& value) { 365 DCHECK(network); 366 bool property_changed = false; 367 if (key == shill::kIPConfigProperty) { 368 // Handle IPConfig here instead of in NetworkState::PropertyChanged since 369 // we need to call into shill_property_handler_ to fetch them. This will 370 // trigger a call to UpdateNetworkServiceIPAddress(), which will notify 371 // any observers. 372 std::string ip_config_path; 373 value.GetAsString(&ip_config_path); 374 DCHECK(!ip_config_path.empty()); 375 shill_property_handler_->RequestIPConfig(network->path(), ip_config_path); 376 } else { 377 if (network->PropertyChanged(key, value)) { 378 property_changed = true; 379 if (network->path() == active_network_path_ && 380 key == flimflam::kStateProperty) { 381 FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_, 382 ActiveNetworkStateChanged(network)); 383 } 384 } 385 } 386 return property_changed; 387} 388 389} // namespace chromeos 390