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 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 |
| 207 void 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 |
| 219 void 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 |
| 231 void 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 |
| 260 void 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 |
| 273 void 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 |
| 285 void NetworkStateHandler::ManagerPropertyChanged() { |
| 286 FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_, |
| 287 NetworkManagerChanged()); |
| 288 } |
| 289 |
| 290 void 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 |
| 320 DeviceState* 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 |
| 328 NetworkState* 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 |
| 337 ManagedState* 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 |
| 349 NetworkStateHandler::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 |
| 361 bool 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 |
OLD | NEW |