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