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/bind.h" 8 #include "base/format_macros.h" 9 #include "base/location.h" 10 #include "base/stl_util.h" 11 #include "base/strings/string_util.h" 12 #include "base/strings/stringprintf.h" 13 #include "base/values.h" 14 #include "chromeos/network/device_state.h" 15 #include "chromeos/network/favorite_state.h" 16 #include "chromeos/network/managed_state.h" 17 #include "chromeos/network/network_event_log.h" 18 #include "chromeos/network/network_state.h" 19 #include "chromeos/network/network_state_handler_observer.h" 20 #include "chromeos/network/shill_property_handler.h" 21 #include "third_party/cros_system_api/dbus/service_constants.h" 22 23 namespace chromeos { 24 25 namespace { 26 27 // Returns true if |network->type()| == |match_type|, or it matches one of the 28 // following special match types: 29 // * kMatchTypeDefault matches any network (i.e. the first instance) 30 // * kMatchTypeNonVirtual matches non virtual networks 31 // * kMatchTypeWireless matches wireless networks 32 // * kMatchTypeMobile matches cellular or wimax networks 33 bool ManagedStateMatchesType(const ManagedState* managed, 34 const std::string& match_type) { 35 const std::string& type = managed->type(); 36 if (match_type == NetworkStateHandler::kMatchTypeDefault) 37 return true; 38 if (match_type == type) 39 return true; 40 if (match_type == NetworkStateHandler::kMatchTypeNonVirtual && 41 type != flimflam::kTypeVPN) { 42 return true; 43 } 44 if (match_type == NetworkStateHandler::kMatchTypeWireless && 45 type != flimflam::kTypeEthernet && type != flimflam::kTypeVPN) { 46 return true; 47 } 48 if (match_type == NetworkStateHandler::kMatchTypeMobile && 49 (type == flimflam::kTypeCellular || type == flimflam::kTypeWimax)) { 50 return true; 51 } 52 return false; 53 } 54 55 bool ConnectionStateChanged(NetworkState* network, 56 const std::string& prev_connection_state) { 57 return (network->connection_state() != prev_connection_state) && 58 (network->connection_state() != flimflam::kStateIdle || 59 !prev_connection_state.empty()); 60 } 61 62 std::string GetManagedStateLogType(const ManagedState* state) { 63 switch (state->managed_type()) { 64 case ManagedState::MANAGED_TYPE_NETWORK: 65 return "Network"; 66 case ManagedState::MANAGED_TYPE_FAVORITE: 67 return "Favorite"; 68 case ManagedState::MANAGED_TYPE_DEVICE: 69 return "Device"; 70 } 71 NOTREACHED(); 72 return ""; 73 } 74 75 std::string GetManagedStateLogName(const ManagedState* state) { 76 if (!state) 77 return "None"; 78 return base::StringPrintf("%s (%s)", state->name().c_str(), 79 state->path().c_str()); 80 } 81 82 } // namespace 83 84 const char NetworkStateHandler::kMatchTypeDefault[] = "default"; 85 const char NetworkStateHandler::kMatchTypeWireless[] = "wireless"; 86 const char NetworkStateHandler::kMatchTypeMobile[] = "mobile"; 87 const char NetworkStateHandler::kMatchTypeNonVirtual[] = "non-virtual"; 88 const char NetworkStateHandler::kDefaultCheckPortalList[] = 89 "ethernet,wifi,cellular"; 90 91 NetworkStateHandler::NetworkStateHandler() { 92 } 93 94 NetworkStateHandler::~NetworkStateHandler() { 95 STLDeleteContainerPointers(network_list_.begin(), network_list_.end()); 96 STLDeleteContainerPointers(favorite_list_.begin(), favorite_list_.end()); 97 STLDeleteContainerPointers(device_list_.begin(), device_list_.end()); 98 } 99 100 void NetworkStateHandler::InitShillPropertyHandler() { 101 shill_property_handler_.reset(new internal::ShillPropertyHandler(this)); 102 shill_property_handler_->Init(); 103 } 104 105 // static 106 NetworkStateHandler* NetworkStateHandler::InitializeForTest() { 107 NetworkStateHandler* handler = new NetworkStateHandler(); 108 handler->InitShillPropertyHandler(); 109 return handler; 110 } 111 112 void NetworkStateHandler::AddObserver( 113 NetworkStateHandlerObserver* observer, 114 const tracked_objects::Location& from_here) { 115 observers_.AddObserver(observer); 116 network_event_log::internal::AddEntry( 117 from_here.file_name(), from_here.line_number(), 118 network_event_log::LOG_LEVEL_DEBUG, 119 "NetworkStateHandler::AddObserver", ""); 120 } 121 122 void NetworkStateHandler::RemoveObserver( 123 NetworkStateHandlerObserver* observer, 124 const tracked_objects::Location& from_here) { 125 observers_.RemoveObserver(observer); 126 network_event_log::internal::AddEntry( 127 from_here.file_name(), from_here.line_number(), 128 network_event_log::LOG_LEVEL_DEBUG, 129 "NetworkStateHandler::RemoveObserver", ""); 130 } 131 132 void NetworkStateHandler::UpdateManagerProperties() { 133 NET_LOG_USER("UpdateManagerProperties", ""); 134 shill_property_handler_->UpdateManagerProperties(); 135 } 136 137 NetworkStateHandler::TechnologyState NetworkStateHandler::GetTechnologyState( 138 const std::string& type) const { 139 std::string technology = GetTechnologyForType(type); 140 TechnologyState state; 141 if (shill_property_handler_->IsTechnologyEnabled(technology)) 142 state = TECHNOLOGY_ENABLED; 143 else if (shill_property_handler_->IsTechnologyEnabling(technology)) 144 state = TECHNOLOGY_ENABLING; 145 else if (shill_property_handler_->IsTechnologyUninitialized(technology)) 146 state = TECHNOLOGY_UNINITIALIZED; 147 else if (shill_property_handler_->IsTechnologyAvailable(technology)) 148 state = TECHNOLOGY_AVAILABLE; 149 else 150 state = TECHNOLOGY_UNAVAILABLE; 151 VLOG(2) << "GetTechnologyState: " << type << " = " << state; 152 return state; 153 } 154 155 void NetworkStateHandler::SetTechnologyEnabled( 156 const std::string& type, 157 bool enabled, 158 const network_handler::ErrorCallback& error_callback) { 159 std::string technology = GetTechnologyForType(type); 160 NET_LOG_USER("SetTechnologyEnabled", 161 base::StringPrintf("%s:%d", technology.c_str(), enabled)); 162 shill_property_handler_->SetTechnologyEnabled( 163 technology, enabled, error_callback); 164 // Signal Technology state changed -> ENABLING 165 NotifyManagerPropertyChanged(); 166 } 167 168 const DeviceState* NetworkStateHandler::GetDeviceState( 169 const std::string& device_path) const { 170 return GetModifiableDeviceState(device_path); 171 } 172 173 const DeviceState* NetworkStateHandler::GetDeviceStateByType( 174 const std::string& type) const { 175 for (ManagedStateList::const_iterator iter = device_list_.begin(); 176 iter != device_list_.end(); ++iter) { 177 ManagedState* device = *iter; 178 if (ManagedStateMatchesType(device, type)) 179 return device->AsDeviceState(); 180 } 181 return NULL; 182 } 183 184 bool NetworkStateHandler::GetScanningByType(const std::string& type) const { 185 for (ManagedStateList::const_iterator iter = device_list_.begin(); 186 iter != device_list_.end(); ++iter) { 187 const DeviceState* device = (*iter)->AsDeviceState(); 188 DCHECK(device); 189 if (ManagedStateMatchesType(device, type) && device->scanning()) 190 return true; 191 } 192 return false; 193 } 194 195 const NetworkState* NetworkStateHandler::GetNetworkState( 196 const std::string& service_path) const { 197 return GetModifiableNetworkState(service_path); 198 } 199 200 const NetworkState* NetworkStateHandler::DefaultNetwork() const { 201 if (network_list_.empty()) 202 return NULL; 203 const NetworkState* network = network_list_.front()->AsNetworkState(); 204 DCHECK(network); 205 if (!network->IsConnectedState()) 206 return NULL; 207 return network; 208 } 209 210 const NetworkState* NetworkStateHandler::ConnectedNetworkByType( 211 const std::string& type) const { 212 for (ManagedStateList::const_iterator iter = network_list_.begin(); 213 iter != network_list_.end(); ++iter) { 214 const NetworkState* network = (*iter)->AsNetworkState(); 215 DCHECK(network); 216 if (!network->IsConnectedState()) 217 break; // Connected networks are listed first. 218 if (ManagedStateMatchesType(network, type)) 219 return network; 220 } 221 return NULL; 222 } 223 224 const NetworkState* NetworkStateHandler::ConnectingNetworkByType( 225 const std::string& type) const { 226 for (ManagedStateList::const_iterator iter = network_list_.begin(); 227 iter != network_list_.end(); ++iter) { 228 const NetworkState* network = (*iter)->AsNetworkState(); 229 DCHECK(network); 230 if (network->IsConnectedState()) 231 continue; 232 if (!network->IsConnectingState()) 233 break; // Connected and connecting networks are listed first. 234 if (ManagedStateMatchesType(network, type)) 235 return network; 236 } 237 return NULL; 238 } 239 240 const NetworkState* NetworkStateHandler::FirstNetworkByType( 241 const std::string& type) const { 242 for (ManagedStateList::const_iterator iter = network_list_.begin(); 243 iter != network_list_.end(); ++iter) { 244 const NetworkState* network = (*iter)->AsNetworkState(); 245 DCHECK(network); 246 if (ManagedStateMatchesType(network, type)) 247 return network; 248 } 249 return NULL; 250 } 251 252 std::string NetworkStateHandler::HardwareAddressForType( 253 const std::string& type) const { 254 std::string result; 255 const NetworkState* network = ConnectedNetworkByType(type); 256 if (network) { 257 const DeviceState* device = GetDeviceState(network->device_path()); 258 if (device) 259 result = device->mac_address(); 260 } 261 StringToUpperASCII(&result); 262 return result; 263 } 264 265 std::string NetworkStateHandler::FormattedHardwareAddressForType( 266 const std::string& type) const { 267 std::string address = HardwareAddressForType(type); 268 if (address.size() % 2 != 0) 269 return address; 270 std::string result; 271 for (size_t i = 0; i < address.size(); ++i) { 272 if ((i != 0) && (i % 2 == 0)) 273 result.push_back(':'); 274 result.push_back(address[i]); 275 } 276 return result; 277 } 278 279 void NetworkStateHandler::GetNetworkList(NetworkStateList* list) const { 280 DCHECK(list); 281 list->clear(); 282 for (ManagedStateList::const_iterator iter = network_list_.begin(); 283 iter != network_list_.end(); ++iter) { 284 if (!(*iter)->update_received()) 285 continue; 286 const NetworkState* network = (*iter)->AsNetworkState(); 287 DCHECK(network); 288 list->push_back(network); 289 } 290 } 291 292 void NetworkStateHandler::GetDeviceList(DeviceStateList* list) const { 293 DCHECK(list); 294 list->clear(); 295 for (ManagedStateList::const_iterator iter = device_list_.begin(); 296 iter != device_list_.end(); ++iter) { 297 if (!(*iter)->update_received()) 298 continue; 299 const DeviceState* device = (*iter)->AsDeviceState(); 300 DCHECK(device); 301 list->push_back(device); 302 } 303 } 304 305 void NetworkStateHandler::GetFavoriteList(FavoriteStateList* list) const { 306 DCHECK(list); 307 FavoriteStateList result; 308 list->clear(); 309 for (ManagedStateList::const_iterator iter = favorite_list_.begin(); 310 iter != favorite_list_.end(); ++iter) { 311 if (!(*iter)->update_received()) 312 continue; 313 const FavoriteState* favorite = (*iter)->AsFavoriteState(); 314 DCHECK(favorite); 315 if (favorite->is_favorite()) 316 list->push_back(favorite); 317 } 318 } 319 320 const FavoriteState* NetworkStateHandler::GetFavoriteState( 321 const std::string& service_path) const { 322 ManagedState* managed = 323 GetModifiableManagedState(&favorite_list_, service_path); 324 if (!managed) 325 return NULL; 326 return managed->AsFavoriteState(); 327 } 328 329 void NetworkStateHandler::RequestScan() const { 330 NET_LOG_USER("RequestScan", ""); 331 shill_property_handler_->RequestScan(); 332 } 333 334 void NetworkStateHandler::WaitForScan(const std::string& type, 335 const base::Closure& callback) { 336 scan_complete_callbacks_[type].push_back(callback); 337 if (!GetScanningByType(type)) 338 RequestScan(); 339 } 340 341 void NetworkStateHandler::ConnectToBestWifiNetwork() { 342 NET_LOG_USER("ConnectToBestWifiNetwork", ""); 343 WaitForScan(flimflam::kTypeWifi, 344 base::Bind(&internal::ShillPropertyHandler::ConnectToBestServices, 345 shill_property_handler_->AsWeakPtr())); 346 } 347 348 bool NetworkStateHandler::RequestUpdateForNetwork( 349 const std::string& service_path) { 350 NetworkState* network = GetModifiableNetworkState(service_path); 351 if (!network) 352 return false; // Only request an update for known networks. 353 network->set_update_requested(true); 354 NET_LOG_EVENT("RequestUpdate", service_path); 355 shill_property_handler_->RequestProperties( 356 ManagedState::MANAGED_TYPE_NETWORK, service_path); 357 return true; 358 } 359 360 void NetworkStateHandler::RequestUpdateForAllNetworks() { 361 NET_LOG_EVENT("RequestUpdateForAllNetworks", ""); 362 for (ManagedStateList::iterator iter = network_list_.begin(); 363 iter != network_list_.end(); ++iter) { 364 ManagedState* network = *iter; 365 network->set_update_requested(true); 366 shill_property_handler_->RequestProperties( 367 ManagedState::MANAGED_TYPE_NETWORK, network->path()); 368 } 369 } 370 371 void NetworkStateHandler::SetCheckPortalList( 372 const std::string& check_portal_list) { 373 NET_LOG_EVENT("SetCheckPortalList", check_portal_list); 374 shill_property_handler_->SetCheckPortalList(check_portal_list); 375 } 376 377 void NetworkStateHandler::GetNetworkStatePropertiesForTest( 378 base::DictionaryValue* dictionary) const { 379 for (ManagedStateList::const_iterator iter = network_list_.begin(); 380 iter != network_list_.end(); ++iter) { 381 base::DictionaryValue* network_dict = new base::DictionaryValue; 382 (*iter)->AsNetworkState()->GetProperties(network_dict); 383 dictionary->SetWithoutPathExpansion((*iter)->path(), network_dict); 384 } 385 } 386 387 //------------------------------------------------------------------------------ 388 // ShillPropertyHandler::Delegate overrides 389 390 void NetworkStateHandler::UpdateManagedList(ManagedState::ManagedType type, 391 const base::ListValue& entries) { 392 ManagedStateList* managed_list = GetManagedList(type); 393 NET_LOG_DEBUG(base::StringPrintf("UpdateManagedList:%d", type), 394 base::StringPrintf("%" PRIuS, entries.GetSize())); 395 // Create a map of existing entries. Assumes all entries in |managed_list| 396 // are unique. 397 std::map<std::string, ManagedState*> managed_map; 398 for (ManagedStateList::iterator iter = managed_list->begin(); 399 iter != managed_list->end(); ++iter) { 400 ManagedState* managed = *iter; 401 DCHECK(!ContainsKey(managed_map, managed->path())); 402 managed_map[managed->path()] = managed; 403 } 404 // Clear the list (pointers are temporarily owned by managed_map). 405 managed_list->clear(); 406 // Updates managed_list and request updates for new entries. 407 std::set<std::string> list_entries; 408 for (base::ListValue::const_iterator iter = entries.begin(); 409 iter != entries.end(); ++iter) { 410 std::string path; 411 (*iter)->GetAsString(&path); 412 if (path.empty()) { 413 LOG(ERROR) << "Empty path in list"; 414 continue; 415 } 416 std::map<std::string, ManagedState*>::iterator found = 417 managed_map.find(path); 418 ManagedState* managed; 419 if (found == managed_map.end()) { 420 if (list_entries.count(path) != 0) { 421 LOG(ERROR) << "Duplicate entry in list: " << path; 422 continue; 423 } 424 managed = ManagedState::Create(type, path); 425 managed_list->push_back(managed); 426 } else { 427 managed = found->second; 428 managed_list->push_back(managed); 429 managed_map.erase(found); 430 } 431 list_entries.insert(path); 432 } 433 // Delete any remaining entries in managed_map. 434 STLDeleteContainerPairSecondPointers(managed_map.begin(), managed_map.end()); 435 } 436 437 void NetworkStateHandler::ProfileListChanged() { 438 NET_LOG_EVENT("ProfileListChanged", "Re-Requesting Network Properties"); 439 for (ManagedStateList::iterator iter = network_list_.begin(); 440 iter != network_list_.end(); ++iter) { 441 shill_property_handler_->RequestProperties( 442 ManagedState::MANAGED_TYPE_NETWORK, (*iter)->path()); 443 } 444 } 445 446 void NetworkStateHandler::UpdateManagedStateProperties( 447 ManagedState::ManagedType type, 448 const std::string& path, 449 const base::DictionaryValue& properties) { 450 ManagedStateList* managed_list = GetManagedList(type); 451 ManagedState* managed = GetModifiableManagedState(managed_list, path); 452 if (!managed) { 453 if (type != ManagedState::MANAGED_TYPE_FAVORITE) { 454 LOG(ERROR) << "GetPropertiesCallback: " << path << " Not found!"; 455 return; 456 } 457 // A Favorite may not have been created yet if it was added later (e.g. 458 // through ConfigureService) since ServiceCompleteList updates are not 459 // emitted. Add and update the state here. 460 managed = new FavoriteState(path); 461 managed_list->push_back(managed); 462 } 463 managed->set_update_received(); 464 465 std::string desc = GetManagedStateLogType(managed) + " PropertiesReceived"; 466 NET_LOG_DEBUG(desc, GetManagedStateLogName(managed)); 467 468 if (type == ManagedState::MANAGED_TYPE_NETWORK) { 469 UpdateNetworkStateProperties(managed->AsNetworkState(), properties); 470 } else { 471 // Device, Favorite 472 for (base::DictionaryValue::Iterator iter(properties); 473 !iter.IsAtEnd(); iter.Advance()) { 474 managed->PropertyChanged(iter.key(), iter.value()); 475 } 476 managed->InitialPropertiesReceived(properties); 477 } 478 managed->set_update_requested(false); 479 } 480 481 void NetworkStateHandler::UpdateNetworkStateProperties( 482 NetworkState* network, 483 const base::DictionaryValue& properties) { 484 DCHECK(network); 485 bool network_property_updated = false; 486 std::string prev_connection_state = network->connection_state(); 487 for (base::DictionaryValue::Iterator iter(properties); 488 !iter.IsAtEnd(); iter.Advance()) { 489 if (network->PropertyChanged(iter.key(), iter.value())) 490 network_property_updated = true; 491 } 492 network_property_updated |= network->InitialPropertiesReceived(properties); 493 // Notify observers of NetworkState changes. 494 if (network_property_updated || network->update_requested()) { 495 // Signal connection state changed after all properties have been updated. 496 if (ConnectionStateChanged(network, prev_connection_state)) 497 OnNetworkConnectionStateChanged(network); 498 NetworkPropertiesUpdated(network); 499 } 500 } 501 502 void NetworkStateHandler::UpdateNetworkServiceProperty( 503 const std::string& service_path, 504 const std::string& key, 505 const base::Value& value) { 506 // Update any associated FavoriteState. 507 ManagedState* favorite = 508 GetModifiableManagedState(&favorite_list_, service_path); 509 if (favorite) 510 favorite->PropertyChanged(key, value); 511 512 // Update the NetworkState. 513 NetworkState* network = GetModifiableNetworkState(service_path); 514 if (!network) 515 return; 516 std::string prev_connection_state = network->connection_state(); 517 std::string prev_profile_path = network->profile_path(); 518 if (!network->PropertyChanged(key, value)) 519 return; 520 521 if (key == flimflam::kStateProperty) { 522 if (ConnectionStateChanged(network, prev_connection_state)) { 523 OnNetworkConnectionStateChanged(network); 524 // If the connection state changes, other properties such as IPConfig 525 // may have changed, so request a full update. 526 RequestUpdateForNetwork(service_path); 527 } 528 } else { 529 bool noisy_property = 530 key == flimflam::kSignalStrengthProperty || 531 key == shill::kWifiFrequencyListProperty; 532 if (network->path() == default_network_path_ && !noisy_property) { 533 // Wifi SignalStrength and WifiFrequencyList updates are too noisy, so 534 // don't trigger default network updates for those changes. 535 OnDefaultNetworkChanged(); 536 } 537 if (prev_profile_path.empty() && !network->profile_path().empty()) { 538 // If added to a Profile, request a full update so that a FavoriteState 539 // gets created. 540 RequestUpdateForNetwork(service_path); 541 } 542 if (!noisy_property) { 543 std::string detail = network->name() + "." + key; 544 detail += " = " + network_event_log::ValueAsString(value); 545 network_event_log::LogLevel log_level; 546 if (key == flimflam::kErrorProperty || 547 key == shill::kErrorDetailsProperty) { 548 log_level = network_event_log::LOG_LEVEL_ERROR; 549 } else { 550 log_level = network_event_log::LOG_LEVEL_EVENT; 551 } 552 NET_LOG_LEVEL(log_level, "NetworkPropertyUpdated", detail); 553 } 554 } 555 NetworkPropertiesUpdated(network); 556 } 557 558 void NetworkStateHandler::UpdateDeviceProperty(const std::string& device_path, 559 const std::string& key, 560 const base::Value& value) { 561 DeviceState* device = GetModifiableDeviceState(device_path); 562 if (!device) 563 return; 564 if (!device->PropertyChanged(key, value)) 565 return; 566 567 std::string detail = device->name() + "." + key; 568 detail += " = " + network_event_log::ValueAsString(value); 569 NET_LOG_EVENT("DevicePropertyUpdated", detail); 570 571 FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_, 572 DeviceListChanged()); 573 574 if (key == flimflam::kScanningProperty && device->scanning() == false) 575 ScanCompleted(device->type()); 576 } 577 578 void NetworkStateHandler::CheckPortalListChanged( 579 const std::string& check_portal_list) { 580 check_portal_list_ = check_portal_list; 581 } 582 583 void NetworkStateHandler::NotifyManagerPropertyChanged() { 584 NET_LOG_DEBUG("NotifyManagerPropertyChanged", ""); 585 FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_, 586 NetworkManagerChanged()); 587 } 588 589 void NetworkStateHandler::ManagedStateListChanged( 590 ManagedState::ManagedType type) { 591 if (type == ManagedState::MANAGED_TYPE_NETWORK) { 592 // Notify observers that the list of networks has changed. 593 NET_LOG_EVENT("NetworkListChanged", 594 base::StringPrintf("Size:%" PRIuS, network_list_.size())); 595 FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_, 596 NetworkListChanged()); 597 // The list order may have changed, so check if the default network changed. 598 if (CheckDefaultNetworkChanged()) 599 OnDefaultNetworkChanged(); 600 } else if (type == ManagedState::MANAGED_TYPE_FAVORITE) { 601 NET_LOG_DEBUG("FavoriteListChanged", 602 base::StringPrintf("Size:%" PRIuS, favorite_list_.size())); 603 // The FavoriteState list only changes when the NetworkState list changes, 604 // so no need to signal observers here again. 605 } else if (type == ManagedState::MANAGED_TYPE_DEVICE) { 606 NET_LOG_DEBUG("DeviceListChanged", 607 base::StringPrintf("Size:%" PRIuS, device_list_.size())); 608 FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_, 609 DeviceListChanged()); 610 } else { 611 NOTREACHED(); 612 } 613 } 614 615 //------------------------------------------------------------------------------ 616 // Private methods 617 618 DeviceState* NetworkStateHandler::GetModifiableDeviceState( 619 const std::string& device_path) const { 620 ManagedState* managed = GetModifiableManagedState(&device_list_, device_path); 621 if (!managed) 622 return NULL; 623 return managed->AsDeviceState(); 624 } 625 626 NetworkState* NetworkStateHandler::GetModifiableNetworkState( 627 const std::string& service_path) const { 628 ManagedState* managed = 629 GetModifiableManagedState(&network_list_, service_path); 630 if (!managed) 631 return NULL; 632 return managed->AsNetworkState(); 633 } 634 635 ManagedState* NetworkStateHandler::GetModifiableManagedState( 636 const ManagedStateList* managed_list, 637 const std::string& path) const { 638 for (ManagedStateList::const_iterator iter = managed_list->begin(); 639 iter != managed_list->end(); ++iter) { 640 ManagedState* managed = *iter; 641 if (managed->path() == path) 642 return managed; 643 } 644 return NULL; 645 } 646 647 NetworkStateHandler::ManagedStateList* NetworkStateHandler::GetManagedList( 648 ManagedState::ManagedType type) { 649 switch (type) { 650 case ManagedState::MANAGED_TYPE_NETWORK: 651 return &network_list_; 652 case ManagedState::MANAGED_TYPE_FAVORITE: 653 return &favorite_list_; 654 case ManagedState::MANAGED_TYPE_DEVICE: 655 return &device_list_; 656 } 657 NOTREACHED(); 658 return NULL; 659 } 660 661 void NetworkStateHandler::OnNetworkConnectionStateChanged( 662 NetworkState* network) { 663 DCHECK(network); 664 NET_LOG_EVENT("NetworkConnectionStateChanged", base::StringPrintf( 665 "%s:%s", GetManagedStateLogName(network).c_str(), 666 network->connection_state().c_str())); 667 FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_, 668 NetworkConnectionStateChanged(network)); 669 if (CheckDefaultNetworkChanged() || network->path() == default_network_path_) 670 OnDefaultNetworkChanged(); 671 } 672 673 bool NetworkStateHandler::CheckDefaultNetworkChanged() { 674 std::string new_default_network_path; 675 const NetworkState* new_default_network = DefaultNetwork(); 676 if (new_default_network) 677 new_default_network_path = new_default_network->path(); 678 if (new_default_network_path == default_network_path_) 679 return false; 680 default_network_path_ = new_default_network_path; 681 return true; 682 } 683 684 void NetworkStateHandler::OnDefaultNetworkChanged() { 685 const NetworkState* default_network = DefaultNetwork(); 686 NET_LOG_EVENT("DefaultNetworkChanged", 687 GetManagedStateLogName(default_network)); 688 FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_, 689 DefaultNetworkChanged(default_network)); 690 } 691 692 void NetworkStateHandler::NetworkPropertiesUpdated( 693 const NetworkState* network) { 694 FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_, 695 NetworkPropertiesUpdated(network)); 696 } 697 698 void NetworkStateHandler::ScanCompleted(const std::string& type) { 699 size_t num_callbacks = scan_complete_callbacks_.count(type); 700 NET_LOG_EVENT("ScanCompleted", 701 base::StringPrintf("%s:%" PRIuS, type.c_str(), num_callbacks)); 702 if (num_callbacks == 0) 703 return; 704 ScanCallbackList& callback_list = scan_complete_callbacks_[type]; 705 for (ScanCallbackList::iterator iter = callback_list.begin(); 706 iter != callback_list.end(); ++iter) { 707 (*iter).Run(); 708 } 709 scan_complete_callbacks_.erase(type); 710 } 711 712 std::string NetworkStateHandler::GetTechnologyForType( 713 const std::string& type) const { 714 if (type == kMatchTypeMobile) { 715 if (shill_property_handler_->IsTechnologyAvailable(flimflam::kTypeWimax)) 716 return flimflam::kTypeWimax; 717 else 718 return flimflam::kTypeCellular; 719 } 720 if (type == kMatchTypeDefault || type == kMatchTypeNonVirtual || 721 type == kMatchTypeWireless) { 722 NOTREACHED(); 723 return flimflam::kTypeWifi; 724 } 725 return type; 726 } 727 728 } // namespace chromeos 729