network_state_handler.cc revision 2385ea399aae016c0806a4f9ef3c9cfe3d2a39df
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 23namespace chromeos { 24 25namespace { 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 33bool 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 55bool 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 62std::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 75std::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 84const char NetworkStateHandler::kMatchTypeDefault[] = "default"; 85const char NetworkStateHandler::kMatchTypeWireless[] = "wireless"; 86const char NetworkStateHandler::kMatchTypeMobile[] = "mobile"; 87const char NetworkStateHandler::kMatchTypeNonVirtual[] = "non-virtual"; 88const char NetworkStateHandler::kDefaultCheckPortalList[] = 89 "ethernet,wifi,cellular"; 90 91NetworkStateHandler::NetworkStateHandler() { 92} 93 94NetworkStateHandler::~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 100void NetworkStateHandler::InitShillPropertyHandler() { 101 shill_property_handler_.reset(new internal::ShillPropertyHandler(this)); 102 shill_property_handler_->Init(); 103} 104 105// static 106NetworkStateHandler* NetworkStateHandler::InitializeForTest() { 107 NetworkStateHandler* handler = new NetworkStateHandler(); 108 handler->InitShillPropertyHandler(); 109 return handler; 110} 111 112void 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 122void 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 132void NetworkStateHandler::UpdateManagerProperties() { 133 NET_LOG_USER("UpdateManagerProperties", ""); 134 shill_property_handler_->UpdateManagerProperties(); 135} 136 137NetworkStateHandler::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 155void 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 168const DeviceState* NetworkStateHandler::GetDeviceState( 169 const std::string& device_path) const { 170 return GetModifiableDeviceState(device_path); 171} 172 173const 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 184bool 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 195const NetworkState* NetworkStateHandler::GetNetworkState( 196 const std::string& service_path) const { 197 return GetModifiableNetworkState(service_path); 198} 199 200const 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 210const 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 224const 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 240const 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 252std::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 265std::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 279void 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 292void 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 305void 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 320const 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 329void NetworkStateHandler::RequestScan() const { 330 NET_LOG_USER("RequestScan", ""); 331 shill_property_handler_->RequestScan(); 332} 333 334void 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 341void NetworkStateHandler::ConnectToBestWifiNetwork() { 342 NET_LOG_USER("ConnectToBestWifiNetwork", ""); 343 WaitForScan(flimflam::kTypeWifi, 344 base::Bind(&internal::ShillPropertyHandler::ConnectToBestServices, 345 shill_property_handler_->AsWeakPtr())); 346} 347 348bool 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 360void 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 371void NetworkStateHandler::SetConnectingNetwork( 372 const std::string& service_path) { 373 connecting_network_ = service_path; 374 const NetworkState* network = GetNetworkState(service_path); 375 if (network) 376 NET_LOG_EVENT("SetConnectingNetwork", GetManagedStateLogName(network)); 377 else 378 NET_LOG_ERROR("SetConnectingNetwork to unknown network", service_path); 379} 380 381void NetworkStateHandler::SetCheckPortalList( 382 const std::string& check_portal_list) { 383 NET_LOG_EVENT("SetCheckPortalList", check_portal_list); 384 shill_property_handler_->SetCheckPortalList(check_portal_list); 385} 386 387void NetworkStateHandler::GetNetworkStatePropertiesForTest( 388 base::DictionaryValue* dictionary) const { 389 for (ManagedStateList::const_iterator iter = network_list_.begin(); 390 iter != network_list_.end(); ++iter) { 391 base::DictionaryValue* network_dict = new base::DictionaryValue; 392 (*iter)->AsNetworkState()->GetProperties(network_dict); 393 dictionary->SetWithoutPathExpansion((*iter)->path(), network_dict); 394 } 395} 396 397//------------------------------------------------------------------------------ 398// ShillPropertyHandler::Delegate overrides 399 400void NetworkStateHandler::UpdateManagedList(ManagedState::ManagedType type, 401 const base::ListValue& entries) { 402 ManagedStateList* managed_list = GetManagedList(type); 403 NET_LOG_DEBUG(base::StringPrintf("UpdateManagedList:%d", type), 404 base::StringPrintf("%" PRIuS, entries.GetSize())); 405 // Create a map of existing entries. Assumes all entries in |managed_list| 406 // are unique. 407 std::map<std::string, ManagedState*> managed_map; 408 for (ManagedStateList::iterator iter = managed_list->begin(); 409 iter != managed_list->end(); ++iter) { 410 ManagedState* managed = *iter; 411 DCHECK(!ContainsKey(managed_map, managed->path())); 412 managed_map[managed->path()] = managed; 413 } 414 // Clear the list (pointers are temporarily owned by managed_map). 415 managed_list->clear(); 416 // Updates managed_list and request updates for new entries. 417 std::set<std::string> list_entries; 418 for (base::ListValue::const_iterator iter = entries.begin(); 419 iter != entries.end(); ++iter) { 420 std::string path; 421 (*iter)->GetAsString(&path); 422 if (path.empty()) { 423 LOG(ERROR) << "Empty path in list"; 424 continue; 425 } 426 std::map<std::string, ManagedState*>::iterator found = 427 managed_map.find(path); 428 ManagedState* managed; 429 if (found == managed_map.end()) { 430 if (list_entries.count(path) != 0) { 431 LOG(ERROR) << "Duplicate entry in list: " << path; 432 continue; 433 } 434 managed = ManagedState::Create(type, path); 435 managed_list->push_back(managed); 436 } else { 437 managed = found->second; 438 managed_list->push_back(managed); 439 managed_map.erase(found); 440 } 441 list_entries.insert(path); 442 } 443 // Delete any remaning entries in managed_map. 444 STLDeleteContainerPairSecondPointers(managed_map.begin(), managed_map.end()); 445} 446 447void NetworkStateHandler::ProfileListChanged() { 448 NET_LOG_EVENT("ProfileListChanged", "Re-Requesting Network Properties"); 449 for (ManagedStateList::iterator iter = network_list_.begin(); 450 iter != network_list_.end(); ++iter) { 451 shill_property_handler_->RequestProperties( 452 ManagedState::MANAGED_TYPE_NETWORK, (*iter)->path()); 453 } 454} 455 456void NetworkStateHandler::UpdateManagedStateProperties( 457 ManagedState::ManagedType type, 458 const std::string& path, 459 const base::DictionaryValue& properties) { 460 ManagedStateList* managed_list = GetManagedList(type); 461 ManagedState* managed = GetModifiableManagedState(managed_list, path); 462 if (!managed) { 463 if (type != ManagedState::MANAGED_TYPE_FAVORITE) { 464 LOG(ERROR) << "GetPropertiesCallback: " << path << " Not found!"; 465 return; 466 } 467 // A Favorite may not have been created yet if it was added later (e.g. 468 // through ConfigureService) since ServiceCompleteList updates are not 469 // emitted. Add and update the state here. 470 managed = new FavoriteState(path); 471 managed_list->push_back(managed); 472 } 473 managed->set_update_received(); 474 475 std::string desc = GetManagedStateLogType(managed) + " PropertiesReceived"; 476 NET_LOG_DEBUG(desc, GetManagedStateLogName(managed)); 477 478 if (type == ManagedState::MANAGED_TYPE_NETWORK) { 479 UpdateNetworkStateProperties(managed->AsNetworkState(), properties); 480 } else { 481 // Device, Favorite 482 for (base::DictionaryValue::Iterator iter(properties); 483 !iter.IsAtEnd(); iter.Advance()) { 484 managed->PropertyChanged(iter.key(), iter.value()); 485 } 486 managed->InitialPropertiesReceived(properties); 487 } 488 managed->set_update_requested(false); 489} 490 491void NetworkStateHandler::UpdateNetworkStateProperties( 492 NetworkState* network, 493 const base::DictionaryValue& properties) { 494 DCHECK(network); 495 bool network_property_updated = false; 496 std::string prev_connection_state = network->connection_state(); 497 for (base::DictionaryValue::Iterator iter(properties); 498 !iter.IsAtEnd(); iter.Advance()) { 499 if (network->PropertyChanged(iter.key(), iter.value())) 500 network_property_updated = true; 501 } 502 network_property_updated |= network->InitialPropertiesReceived(properties); 503 // Notify observers of NetworkState changes. 504 if (network_property_updated || network->update_requested()) { 505 // Signal connection state changed after all properties have been updated. 506 if (ConnectionStateChanged(network, prev_connection_state)) 507 OnNetworkConnectionStateChanged(network); 508 NetworkPropertiesUpdated(network); 509 } 510} 511 512void NetworkStateHandler::UpdateNetworkServiceProperty( 513 const std::string& service_path, 514 const std::string& key, 515 const base::Value& value) { 516 // Update any associated FavoriteState. 517 ManagedState* favorite = 518 GetModifiableManagedState(&favorite_list_, service_path); 519 if (favorite) 520 favorite->PropertyChanged(key, value); 521 522 // Update the NetworkState. 523 NetworkState* network = GetModifiableNetworkState(service_path); 524 if (!network) 525 return; 526 std::string prev_connection_state = network->connection_state(); 527 if (!network->PropertyChanged(key, value)) 528 return; 529 530 if (key == flimflam::kStateProperty) { 531 if (ConnectionStateChanged(network, prev_connection_state)) 532 OnNetworkConnectionStateChanged(network); 533 } else { 534 if (network->path() == default_network_path_ && 535 key != flimflam::kSignalStrengthProperty && 536 key != shill::kWifiFrequencyListProperty) { 537 // WiFi SignalStrength and WifiFrequencyList updates are too noisy, so 538 // don't trigger default network updates for those changes. 539 OnDefaultNetworkChanged(); 540 } 541 std::string detail = network->name() + "." + key; 542 detail += " = " + network_event_log::ValueAsString(value); 543 network_event_log::LogLevel log_level = network_event_log::LOG_LEVEL_EVENT; 544 if (key == flimflam::kErrorProperty || key == shill::kErrorDetailsProperty) 545 log_level = network_event_log::LOG_LEVEL_ERROR; 546 else if (key == flimflam::kSignalStrengthProperty || 547 key == shill::kWifiFrequencyListProperty) 548 log_level = network_event_log::LOG_LEVEL_DEBUG; 549 NET_LOG_LEVEL(log_level, "NetworkPropertyUpdated", detail); 550 } 551 NetworkPropertiesUpdated(network); 552} 553 554void NetworkStateHandler::UpdateDeviceProperty(const std::string& device_path, 555 const std::string& key, 556 const base::Value& value) { 557 DeviceState* device = GetModifiableDeviceState(device_path); 558 if (!device) 559 return; 560 if (!device->PropertyChanged(key, value)) 561 return; 562 563 std::string detail = device->name() + "." + key; 564 detail += " = " + network_event_log::ValueAsString(value); 565 NET_LOG_EVENT("DevicePropertyUpdated", detail); 566 567 FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_, 568 DeviceListChanged()); 569 570 if (key == flimflam::kScanningProperty && device->scanning() == false) 571 ScanCompleted(device->type()); 572} 573 574void NetworkStateHandler::CheckPortalListChanged( 575 const std::string& check_portal_list) { 576 check_portal_list_ = check_portal_list; 577} 578 579void NetworkStateHandler::NotifyManagerPropertyChanged() { 580 NET_LOG_DEBUG("NotifyManagerPropertyChanged", ""); 581 FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_, 582 NetworkManagerChanged()); 583} 584 585void NetworkStateHandler::ManagedStateListChanged( 586 ManagedState::ManagedType type) { 587 if (type == ManagedState::MANAGED_TYPE_NETWORK) { 588 // Notify observers that the list of networks has changed. 589 NET_LOG_EVENT("NetworkListChanged", 590 base::StringPrintf("Size:%" PRIuS, network_list_.size())); 591 FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_, 592 NetworkListChanged()); 593 // The list order may have changed, so check if the default network changed. 594 if (CheckDefaultNetworkChanged()) 595 OnDefaultNetworkChanged(); 596 } else if (type == ManagedState::MANAGED_TYPE_FAVORITE) { 597 NET_LOG_DEBUG("FavoriteListChanged", 598 base::StringPrintf("Size:%" PRIuS, favorite_list_.size())); 599 FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_, 600 NetworkListChanged()); 601 } else if (type == ManagedState::MANAGED_TYPE_DEVICE) { 602 NET_LOG_DEBUG("DeviceListChanged", 603 base::StringPrintf("Size:%" PRIuS, device_list_.size())); 604 FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_, 605 DeviceListChanged()); 606 } else { 607 NOTREACHED(); 608 } 609} 610 611//------------------------------------------------------------------------------ 612// Private methods 613 614DeviceState* NetworkStateHandler::GetModifiableDeviceState( 615 const std::string& device_path) const { 616 ManagedState* managed = GetModifiableManagedState(&device_list_, device_path); 617 if (!managed) 618 return NULL; 619 return managed->AsDeviceState(); 620} 621 622NetworkState* NetworkStateHandler::GetModifiableNetworkState( 623 const std::string& service_path) const { 624 ManagedState* managed = 625 GetModifiableManagedState(&network_list_, service_path); 626 if (!managed) 627 return NULL; 628 return managed->AsNetworkState(); 629} 630 631ManagedState* NetworkStateHandler::GetModifiableManagedState( 632 const ManagedStateList* managed_list, 633 const std::string& path) const { 634 for (ManagedStateList::const_iterator iter = managed_list->begin(); 635 iter != managed_list->end(); ++iter) { 636 ManagedState* managed = *iter; 637 if (managed->path() == path) 638 return managed; 639 } 640 return NULL; 641} 642 643NetworkStateHandler::ManagedStateList* NetworkStateHandler::GetManagedList( 644 ManagedState::ManagedType type) { 645 switch (type) { 646 case ManagedState::MANAGED_TYPE_NETWORK: 647 return &network_list_; 648 case ManagedState::MANAGED_TYPE_FAVORITE: 649 return &favorite_list_; 650 case ManagedState::MANAGED_TYPE_DEVICE: 651 return &device_list_; 652 } 653 NOTREACHED(); 654 return NULL; 655} 656 657void NetworkStateHandler::OnNetworkConnectionStateChanged( 658 NetworkState* network) { 659 DCHECK(network); 660 NET_LOG_EVENT("NetworkConnectionStateChanged", base::StringPrintf( 661 "%s:%s", GetManagedStateLogName(network).c_str(), 662 network->connection_state().c_str())); 663 FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_, 664 NetworkConnectionStateChanged(network)); 665 if (CheckDefaultNetworkChanged() || network->path() == default_network_path_) 666 OnDefaultNetworkChanged(); 667} 668 669bool NetworkStateHandler::CheckDefaultNetworkChanged() { 670 std::string new_default_network_path; 671 const NetworkState* new_default_network = DefaultNetwork(); 672 if (new_default_network) 673 new_default_network_path = new_default_network->path(); 674 if (new_default_network_path == default_network_path_) 675 return false; 676 default_network_path_ = new_default_network_path; 677 return true; 678} 679 680void NetworkStateHandler::OnDefaultNetworkChanged() { 681 const NetworkState* default_network = DefaultNetwork(); 682 NET_LOG_EVENT("DefaultNetworkChanged", 683 GetManagedStateLogName(default_network)); 684 FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_, 685 DefaultNetworkChanged(default_network)); 686} 687 688void NetworkStateHandler::NetworkPropertiesUpdated( 689 const NetworkState* network) { 690 FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_, 691 NetworkPropertiesUpdated(network)); 692 // If |connecting_network_| transitions to a non-idle, non-connecting state, 693 // clear it *after* signalling observers. 694 if (network->path() == connecting_network_ && 695 !network->IsConnectingState() && 696 network->connection_state() != flimflam::kStateIdle) { 697 connecting_network_.clear(); 698 NET_LOG_EVENT("ClearConnectingNetwork", base::StringPrintf( 699 "%s:%s", GetManagedStateLogName(network).c_str(), 700 network->connection_state().c_str())); 701 } 702} 703 704void NetworkStateHandler::ScanCompleted(const std::string& type) { 705 size_t num_callbacks = scan_complete_callbacks_.count(type); 706 NET_LOG_EVENT("ScanCompleted", 707 base::StringPrintf("%s:%" PRIuS, type.c_str(), num_callbacks)); 708 if (num_callbacks == 0) 709 return; 710 ScanCallbackList& callback_list = scan_complete_callbacks_[type]; 711 for (ScanCallbackList::iterator iter = callback_list.begin(); 712 iter != callback_list.end(); ++iter) { 713 (*iter).Run(); 714 } 715 scan_complete_callbacks_.erase(type); 716} 717 718std::string NetworkStateHandler::GetTechnologyForType( 719 const std::string& type) const { 720 if (type == kMatchTypeMobile) { 721 if (shill_property_handler_->IsTechnologyAvailable(flimflam::kTypeWimax)) 722 return flimflam::kTypeWimax; 723 else 724 return flimflam::kTypeCellular; 725 } 726 if (type == kMatchTypeDefault || type == kMatchTypeNonVirtual || 727 type == kMatchTypeWireless) { 728 NOTREACHED(); 729 return flimflam::kTypeWifi; 730 } 731 return type; 732} 733 734} // namespace chromeos 735