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