network_state_handler.cc revision f2477e01787aa58f445919b809d89e252beef54f
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() != shill::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 Device/Technology state changed. 135 NotifyDeviceListChanged(); 136} 137 138const DeviceState* NetworkStateHandler::GetDeviceState( 139 const std::string& device_path) const { 140 const DeviceState* device = GetModifiableDeviceState(device_path); 141 if (device && !device->update_received()) 142 return NULL; 143 return device; 144} 145 146const DeviceState* NetworkStateHandler::GetDeviceStateByType( 147 const NetworkTypePattern& type) const { 148 for (ManagedStateList::const_iterator iter = device_list_.begin(); 149 iter != device_list_.end(); ++iter) { 150 ManagedState* device = *iter; 151 if (!device->update_received()) 152 continue; 153 if (device->Matches(type)) 154 return device->AsDeviceState(); 155 } 156 return NULL; 157} 158 159bool NetworkStateHandler::GetScanningByType( 160 const NetworkTypePattern& type) const { 161 for (ManagedStateList::const_iterator iter = device_list_.begin(); 162 iter != device_list_.end(); ++iter) { 163 const DeviceState* device = (*iter)->AsDeviceState(); 164 DCHECK(device); 165 if (!device->update_received()) 166 continue; 167 if (device->Matches(type) && device->scanning()) 168 return true; 169 } 170 return false; 171} 172 173const NetworkState* NetworkStateHandler::GetNetworkState( 174 const std::string& service_path) const { 175 const NetworkState* network = GetModifiableNetworkState(service_path); 176 if (network && !network->update_received()) 177 return NULL; 178 return network; 179} 180 181const NetworkState* NetworkStateHandler::DefaultNetwork() const { 182 if (network_list_.empty()) 183 return NULL; 184 const NetworkState* network = network_list_.front()->AsNetworkState(); 185 DCHECK(network); 186 if (!network->update_received() || !network->IsConnectedState()) 187 return NULL; 188 return network; 189} 190 191const FavoriteState* NetworkStateHandler::DefaultFavoriteNetwork() const { 192 const NetworkState* default_network = DefaultNetwork(); 193 if (!default_network) 194 return NULL; 195 const FavoriteState* default_favorite = 196 GetFavoriteState(default_network->path()); 197 DCHECK(default_favorite); 198 DCHECK(default_favorite->update_received()); 199 return default_favorite; 200} 201 202const NetworkState* NetworkStateHandler::ConnectedNetworkByType( 203 const NetworkTypePattern& type) const { 204 for (ManagedStateList::const_iterator iter = network_list_.begin(); 205 iter != network_list_.end(); ++iter) { 206 const NetworkState* network = (*iter)->AsNetworkState(); 207 DCHECK(network); 208 if (!network->update_received()) 209 continue; 210 if (!network->IsConnectedState()) 211 break; // Connected networks are listed first. 212 if (network->Matches(type)) 213 return network; 214 } 215 return NULL; 216} 217 218const NetworkState* NetworkStateHandler::ConnectingNetworkByType( 219 const NetworkTypePattern& type) const { 220 for (ManagedStateList::const_iterator iter = network_list_.begin(); 221 iter != network_list_.end(); ++iter) { 222 const NetworkState* network = (*iter)->AsNetworkState(); 223 DCHECK(network); 224 if (!network->update_received() || network->IsConnectedState()) 225 continue; 226 if (!network->IsConnectingState()) 227 break; // Connected and connecting networks are listed first. 228 if (network->Matches(type)) 229 return network; 230 } 231 return NULL; 232} 233 234const NetworkState* NetworkStateHandler::FirstNetworkByType( 235 const NetworkTypePattern& type) const { 236 for (ManagedStateList::const_iterator iter = network_list_.begin(); 237 iter != network_list_.end(); ++iter) { 238 const NetworkState* network = (*iter)->AsNetworkState(); 239 DCHECK(network); 240 if (!network->update_received()) 241 continue; 242 if (network->Matches(type)) 243 return network; 244 } 245 return NULL; 246} 247 248std::string NetworkStateHandler::HardwareAddressForType( 249 const NetworkTypePattern& type) const { 250 const DeviceState* device = NULL; 251 const NetworkState* network = ConnectedNetworkByType(type); 252 if (network) 253 device = GetDeviceState(network->device_path()); 254 else 255 device = GetDeviceStateByType(type); 256 if (!device) 257 return std::string(); 258 std::string result = device->mac_address(); 259 StringToUpperASCII(&result); 260 return result; 261} 262 263std::string NetworkStateHandler::FormattedHardwareAddressForType( 264 const NetworkTypePattern& type) const { 265 std::string address = HardwareAddressForType(type); 266 if (address.size() % 2 != 0) 267 return address; 268 std::string result; 269 for (size_t i = 0; i < address.size(); ++i) { 270 if ((i != 0) && (i % 2 == 0)) 271 result.push_back(':'); 272 result.push_back(address[i]); 273 } 274 return result; 275} 276 277void NetworkStateHandler::GetNetworkList(NetworkStateList* list) const { 278 GetNetworkListByType(NetworkTypePattern::Default(), list); 279} 280 281void NetworkStateHandler::GetNetworkListByType(const NetworkTypePattern& type, 282 NetworkStateList* list) const { 283 DCHECK(list); 284 list->clear(); 285 for (ManagedStateList::const_iterator iter = network_list_.begin(); 286 iter != network_list_.end(); ++iter) { 287 const NetworkState* network = (*iter)->AsNetworkState(); 288 DCHECK(network); 289 if (network->update_received() && network->Matches(type)) 290 list->push_back(network); 291 } 292} 293 294void NetworkStateHandler::GetDeviceList(DeviceStateList* list) const { 295 DCHECK(list); 296 list->clear(); 297 for (ManagedStateList::const_iterator iter = device_list_.begin(); 298 iter != device_list_.end(); ++iter) { 299 const DeviceState* device = (*iter)->AsDeviceState(); 300 DCHECK(device); 301 if (device->update_received()) 302 list->push_back(device); 303 } 304} 305 306void NetworkStateHandler::GetFavoriteList(FavoriteStateList* list) const { 307 GetFavoriteListByType(NetworkTypePattern::Default(), list); 308} 309 310void NetworkStateHandler::GetFavoriteListByType(const NetworkTypePattern& type, 311 FavoriteStateList* list) const { 312 DCHECK(list); 313 FavoriteStateList result; 314 list->clear(); 315 for (ManagedStateList::const_iterator iter = favorite_list_.begin(); 316 iter != favorite_list_.end(); ++iter) { 317 const FavoriteState* favorite = (*iter)->AsFavoriteState(); 318 DCHECK(favorite); 319 if (favorite->update_received() && favorite->is_favorite() && 320 favorite->Matches(type)) { 321 list->push_back(favorite); 322 } 323 } 324} 325 326const FavoriteState* NetworkStateHandler::GetFavoriteState( 327 const std::string& service_path) const { 328 ManagedState* managed = 329 GetModifiableManagedState(&favorite_list_, service_path); 330 if (!managed) 331 return NULL; 332 if (managed && !managed->update_received()) 333 return NULL; 334 return managed->AsFavoriteState(); 335} 336 337void NetworkStateHandler::RequestScan() const { 338 NET_LOG_USER("RequestScan", ""); 339 shill_property_handler_->RequestScan(); 340} 341 342void NetworkStateHandler::WaitForScan(const std::string& type, 343 const base::Closure& callback) { 344 scan_complete_callbacks_[type].push_back(callback); 345 if (!GetScanningByType(NetworkTypePattern::Primitive(type))) 346 RequestScan(); 347} 348 349void NetworkStateHandler::ConnectToBestWifiNetwork() { 350 NET_LOG_USER("ConnectToBestWifiNetwork", ""); 351 WaitForScan(shill::kTypeWifi, 352 base::Bind(&internal::ShillPropertyHandler::ConnectToBestServices, 353 shill_property_handler_->AsWeakPtr())); 354} 355 356void NetworkStateHandler::RequestUpdateForNetwork( 357 const std::string& service_path) { 358 NetworkState* network = GetModifiableNetworkState(service_path); 359 if (network) 360 network->set_update_requested(true); 361 NET_LOG_EVENT("RequestUpdate", service_path); 362 shill_property_handler_->RequestProperties( 363 ManagedState::MANAGED_TYPE_NETWORK, service_path); 364} 365 366void NetworkStateHandler::RequestUpdateForAllNetworks() { 367 NET_LOG_EVENT("RequestUpdateForAllNetworks", ""); 368 for (ManagedStateList::iterator iter = network_list_.begin(); 369 iter != network_list_.end(); ++iter) { 370 ManagedState* network = *iter; 371 network->set_update_requested(true); 372 shill_property_handler_->RequestProperties( 373 ManagedState::MANAGED_TYPE_NETWORK, network->path()); 374 } 375} 376 377void NetworkStateHandler::SetCheckPortalList( 378 const std::string& check_portal_list) { 379 NET_LOG_EVENT("SetCheckPortalList", check_portal_list); 380 shill_property_handler_->SetCheckPortalList(check_portal_list); 381} 382 383const FavoriteState* NetworkStateHandler::GetEAPForEthernet( 384 const std::string& service_path) const { 385 const NetworkState* network = GetNetworkState(service_path); 386 if (!network) { 387 NET_LOG_ERROR("GetEAPForEthernet", "Unknown service path " + service_path); 388 return NULL; 389 } 390 if (network->type() != shill::kTypeEthernet) { 391 NET_LOG_ERROR("GetEAPForEthernet", "Not of type Ethernet: " + service_path); 392 return NULL; 393 } 394 if (!network->IsConnectedState()) 395 return NULL; 396 397 // The same EAP service is shared for all ethernet services/devices. 398 // However EAP is used/enabled per device and only if the connection was 399 // successfully established. 400 const DeviceState* device = GetDeviceState(network->device_path()); 401 if (!device) { 402 NET_LOG_ERROR( 403 "GetEAPForEthernet", 404 base::StringPrintf("Unknown device %s of connected ethernet service %s", 405 network->device_path().c_str(), 406 service_path.c_str())); 407 return NULL; 408 } 409 if (!device->eap_authentication_completed()) 410 return NULL; 411 412 FavoriteStateList list; 413 GetFavoriteListByType(NetworkTypePattern::Primitive(shill::kTypeEthernetEap), 414 &list); 415 if (list.empty()) { 416 NET_LOG_ERROR("GetEAPForEthernet", 417 base::StringPrintf( 418 "Ethernet service %s connected using EAP, but no " 419 "EAP service found.", 420 service_path.c_str())); 421 return NULL; 422 } 423 DCHECK(list.size() == 1); 424 return list.front(); 425} 426 427void NetworkStateHandler::GetNetworkStatePropertiesForTest( 428 base::DictionaryValue* dictionary) const { 429 for (ManagedStateList::const_iterator iter = network_list_.begin(); 430 iter != network_list_.end(); ++iter) { 431 base::DictionaryValue* network_dict = new base::DictionaryValue; 432 (*iter)->AsNetworkState()->GetProperties(network_dict); 433 dictionary->SetWithoutPathExpansion((*iter)->path(), network_dict); 434 } 435} 436 437//------------------------------------------------------------------------------ 438// ShillPropertyHandler::Delegate overrides 439 440void NetworkStateHandler::UpdateManagedList(ManagedState::ManagedType type, 441 const base::ListValue& entries) { 442 ManagedStateList* managed_list = GetManagedList(type); 443 NET_LOG_DEBUG(base::StringPrintf("UpdateManagedList:%d", type), 444 base::StringPrintf("%" PRIuS, entries.GetSize())); 445 // Create a map of existing entries. Assumes all entries in |managed_list| 446 // are unique. 447 std::map<std::string, ManagedState*> managed_map; 448 for (ManagedStateList::iterator iter = managed_list->begin(); 449 iter != managed_list->end(); ++iter) { 450 ManagedState* managed = *iter; 451 DCHECK(!ContainsKey(managed_map, managed->path())); 452 managed_map[managed->path()] = managed; 453 } 454 // Clear the list (pointers are temporarily owned by managed_map). 455 managed_list->clear(); 456 // Updates managed_list and request updates for new entries. 457 std::set<std::string> list_entries; 458 for (base::ListValue::const_iterator iter = entries.begin(); 459 iter != entries.end(); ++iter) { 460 std::string path; 461 (*iter)->GetAsString(&path); 462 if (path.empty()) { 463 LOG(ERROR) << "Empty path in list"; 464 continue; 465 } 466 std::map<std::string, ManagedState*>::iterator found = 467 managed_map.find(path); 468 ManagedState* managed; 469 if (found == managed_map.end()) { 470 if (list_entries.count(path) != 0) { 471 LOG(ERROR) << "Duplicate entry in list: " << path; 472 continue; 473 } 474 managed = ManagedState::Create(type, path); 475 managed_list->push_back(managed); 476 } else { 477 managed = found->second; 478 managed_list->push_back(managed); 479 managed_map.erase(found); 480 } 481 list_entries.insert(path); 482 } 483 // Delete any remaining entries in managed_map. 484 STLDeleteContainerPairSecondPointers(managed_map.begin(), managed_map.end()); 485} 486 487void NetworkStateHandler::ProfileListChanged() { 488 NET_LOG_EVENT("ProfileListChanged", "Re-Requesting Network Properties"); 489 for (ManagedStateList::iterator iter = network_list_.begin(); 490 iter != network_list_.end(); ++iter) { 491 shill_property_handler_->RequestProperties( 492 ManagedState::MANAGED_TYPE_NETWORK, (*iter)->path()); 493 } 494} 495 496void NetworkStateHandler::UpdateManagedStateProperties( 497 ManagedState::ManagedType type, 498 const std::string& path, 499 const base::DictionaryValue& properties) { 500 ManagedStateList* managed_list = GetManagedList(type); 501 ManagedState* managed = GetModifiableManagedState(managed_list, path); 502 if (!managed) { 503 if (type != ManagedState::MANAGED_TYPE_FAVORITE) { 504 // The network has been removed from the list of visible networks. 505 NET_LOG_DEBUG("UpdateManagedStateProperties: Not found", path); 506 return; 507 } 508 // A Favorite may not have been created yet if it was added later (e.g. 509 // through ConfigureService) since ServiceCompleteList updates are not 510 // emitted. Add and update the state here. 511 managed = new FavoriteState(path); 512 managed_list->push_back(managed); 513 } 514 managed->set_update_received(); 515 516 std::string desc = GetManagedStateLogType(managed) + " PropertiesReceived"; 517 NET_LOG_DEBUG(desc, GetManagedStateLogName(managed)); 518 519 if (type == ManagedState::MANAGED_TYPE_NETWORK) { 520 UpdateNetworkStateProperties(managed->AsNetworkState(), properties); 521 } else { 522 // Device, Favorite 523 for (base::DictionaryValue::Iterator iter(properties); 524 !iter.IsAtEnd(); iter.Advance()) { 525 managed->PropertyChanged(iter.key(), iter.value()); 526 } 527 managed->InitialPropertiesReceived(properties); 528 } 529 managed->set_update_requested(false); 530} 531 532void NetworkStateHandler::UpdateNetworkStateProperties( 533 NetworkState* network, 534 const base::DictionaryValue& properties) { 535 DCHECK(network); 536 bool network_property_updated = false; 537 std::string prev_connection_state = network->connection_state(); 538 for (base::DictionaryValue::Iterator iter(properties); 539 !iter.IsAtEnd(); iter.Advance()) { 540 if (network->PropertyChanged(iter.key(), iter.value())) 541 network_property_updated = true; 542 } 543 network_property_updated |= network->InitialPropertiesReceived(properties); 544 // Notify observers of NetworkState changes. 545 if (network_property_updated || network->update_requested()) { 546 // Signal connection state changed after all properties have been updated. 547 if (ConnectionStateChanged(network, prev_connection_state)) 548 OnNetworkConnectionStateChanged(network); 549 NetworkPropertiesUpdated(network); 550 } 551} 552 553void NetworkStateHandler::UpdateNetworkServiceProperty( 554 const std::string& service_path, 555 const std::string& key, 556 const base::Value& value) { 557 // Update any associated FavoriteState. 558 ManagedState* favorite = 559 GetModifiableManagedState(&favorite_list_, service_path); 560 bool changed = false; 561 if (favorite) 562 changed |= favorite->PropertyChanged(key, value); 563 564 // Update the NetworkState. 565 NetworkState* network = GetModifiableNetworkState(service_path); 566 if (!network) 567 return; 568 std::string prev_connection_state = network->connection_state(); 569 std::string prev_profile_path = network->profile_path(); 570 changed |= network->PropertyChanged(key, value); 571 if (!changed) 572 return; 573 574 if (key == shill::kStateProperty) { 575 if (ConnectionStateChanged(network, prev_connection_state)) { 576 OnNetworkConnectionStateChanged(network); 577 // If the connection state changes, other properties such as IPConfig 578 // may have changed, so request a full update. 579 RequestUpdateForNetwork(service_path); 580 } 581 } else { 582 std::string value_str; 583 value.GetAsString(&value_str); 584 // Some property changes are noisy and not interesting: 585 // * Wifi SignalStrength 586 // * WifiFrequencyList updates 587 // * Device property changes to "/" (occurs before a service is removed) 588 if (key != shill::kSignalStrengthProperty && 589 key != shill::kWifiFrequencyListProperty && 590 (key != shill::kDeviceProperty || value_str != "/")) { 591 // Trigger a default network update for interesting changes only. 592 if (network->path() == default_network_path_) 593 OnDefaultNetworkChanged(); 594 // Log interesting event. 595 std::string detail = network->name() + "." + key; 596 detail += " = " + network_event_log::ValueAsString(value); 597 network_event_log::LogLevel log_level; 598 if (key == shill::kErrorProperty || key == shill::kErrorDetailsProperty) { 599 log_level = network_event_log::LOG_LEVEL_ERROR; 600 } else { 601 log_level = network_event_log::LOG_LEVEL_EVENT; 602 } 603 NET_LOG_LEVEL(log_level, "NetworkPropertyUpdated", detail); 604 } 605 } 606 607 // All property updates signal 'NetworkPropertiesUpdated'. 608 NetworkPropertiesUpdated(network); 609 610 // If added to a Profile, request a full update so that a FavoriteState 611 // gets created. 612 if (prev_profile_path.empty() && !network->profile_path().empty()) 613 RequestUpdateForNetwork(service_path); 614} 615 616void NetworkStateHandler::UpdateDeviceProperty(const std::string& device_path, 617 const std::string& key, 618 const base::Value& value) { 619 DeviceState* device = GetModifiableDeviceState(device_path); 620 if (!device) 621 return; 622 if (!device->PropertyChanged(key, value)) 623 return; 624 625 std::string detail = device->name() + "." + key; 626 detail += " = " + network_event_log::ValueAsString(value); 627 NET_LOG_EVENT("DevicePropertyUpdated", detail); 628 629 NotifyDeviceListChanged(); 630 631 if (key == shill::kScanningProperty && device->scanning() == false) 632 ScanCompleted(device->type()); 633 if (key == shill::kEapAuthenticationCompletedProperty) { 634 // Notify a change for each Ethernet service using this device. 635 NetworkStateList ethernet_services; 636 GetNetworkListByType(NetworkTypePattern::Ethernet(), ðernet_services); 637 for (NetworkStateList::const_iterator it = ethernet_services.begin(); 638 it != ethernet_services.end(); ++it) { 639 const NetworkState* ethernet_service = *it; 640 if (ethernet_service->update_received() || 641 ethernet_service->device_path() != device->path()) { 642 continue; 643 } 644 RequestUpdateForNetwork(ethernet_service->path()); 645 } 646 } 647} 648 649void NetworkStateHandler::CheckPortalListChanged( 650 const std::string& check_portal_list) { 651 check_portal_list_ = check_portal_list; 652} 653 654void NetworkStateHandler::TechnologyListChanged() { 655 // Eventually we would like to replace Technology state with Device state. 656 // For now, treat technology state changes as device list changes. 657 NotifyDeviceListChanged(); 658} 659 660void NetworkStateHandler::ManagedStateListChanged( 661 ManagedState::ManagedType type) { 662 if (type == ManagedState::MANAGED_TYPE_NETWORK) { 663 // Notify observers that the list of networks has changed. 664 NET_LOG_EVENT("NetworkListChanged", 665 base::StringPrintf("Size:%" PRIuS, network_list_.size())); 666 FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_, 667 NetworkListChanged()); 668 // The list order may have changed, so check if the default network changed. 669 if (CheckDefaultNetworkChanged()) 670 OnDefaultNetworkChanged(); 671 // Update UMA stats. 672 UMA_HISTOGRAM_COUNTS_100("Networks.Visible", network_list_.size()); 673 } else if (type == ManagedState::MANAGED_TYPE_FAVORITE) { 674 NET_LOG_DEBUG("FavoriteListChanged", 675 base::StringPrintf("Size:%" PRIuS, favorite_list_.size())); 676 // The FavoriteState list only changes when the NetworkState list changes, 677 // so no need to signal observers here again. 678 679 // Update UMA stats. 680 size_t shared = 0, unshared = 0; 681 for (ManagedStateList::iterator iter = favorite_list_.begin(); 682 iter != favorite_list_.end(); ++iter) { 683 FavoriteState* favorite = (*iter)->AsFavoriteState(); 684 if (!favorite->is_favorite()) 685 continue; 686 if (favorite->IsPrivate()) 687 ++unshared; 688 else 689 ++shared; 690 } 691 UMA_HISTOGRAM_COUNTS_100("Networks.RememberedShared", shared); 692 UMA_HISTOGRAM_COUNTS_100("Networks.RememberedUnshared", unshared); 693 } else if (type == ManagedState::MANAGED_TYPE_DEVICE) { 694 NotifyDeviceListChanged(); 695 } else { 696 NOTREACHED(); 697 } 698} 699 700//------------------------------------------------------------------------------ 701// Private methods 702 703void NetworkStateHandler::NotifyDeviceListChanged() { 704 NET_LOG_DEBUG("NotifyDeviceListChanged", 705 base::StringPrintf("Size:%" PRIuS, device_list_.size())); 706 FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_, 707 DeviceListChanged()); 708} 709 710DeviceState* NetworkStateHandler::GetModifiableDeviceState( 711 const std::string& device_path) const { 712 ManagedState* managed = GetModifiableManagedState(&device_list_, device_path); 713 if (!managed) 714 return NULL; 715 return managed->AsDeviceState(); 716} 717 718NetworkState* NetworkStateHandler::GetModifiableNetworkState( 719 const std::string& service_path) const { 720 ManagedState* managed = 721 GetModifiableManagedState(&network_list_, service_path); 722 if (!managed) 723 return NULL; 724 return managed->AsNetworkState(); 725} 726 727ManagedState* NetworkStateHandler::GetModifiableManagedState( 728 const ManagedStateList* managed_list, 729 const std::string& path) const { 730 for (ManagedStateList::const_iterator iter = managed_list->begin(); 731 iter != managed_list->end(); ++iter) { 732 ManagedState* managed = *iter; 733 if (managed->path() == path) 734 return managed; 735 } 736 return NULL; 737} 738 739NetworkStateHandler::ManagedStateList* NetworkStateHandler::GetManagedList( 740 ManagedState::ManagedType type) { 741 switch (type) { 742 case ManagedState::MANAGED_TYPE_NETWORK: 743 return &network_list_; 744 case ManagedState::MANAGED_TYPE_FAVORITE: 745 return &favorite_list_; 746 case ManagedState::MANAGED_TYPE_DEVICE: 747 return &device_list_; 748 } 749 NOTREACHED(); 750 return NULL; 751} 752 753void NetworkStateHandler::OnNetworkConnectionStateChanged( 754 NetworkState* network) { 755 DCHECK(network); 756 NET_LOG_EVENT("NetworkConnectionStateChanged", base::StringPrintf( 757 "%s:%s", GetManagedStateLogName(network).c_str(), 758 network->connection_state().c_str())); 759 FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_, 760 NetworkConnectionStateChanged(network)); 761 if (CheckDefaultNetworkChanged() || network->path() == default_network_path_) 762 OnDefaultNetworkChanged(); 763} 764 765bool NetworkStateHandler::CheckDefaultNetworkChanged() { 766 std::string new_default_network_path; 767 const NetworkState* new_default_network = DefaultNetwork(); 768 if (new_default_network) 769 new_default_network_path = new_default_network->path(); 770 if (new_default_network_path == default_network_path_) 771 return false; 772 default_network_path_ = new_default_network_path; 773 return true; 774} 775 776void NetworkStateHandler::OnDefaultNetworkChanged() { 777 const NetworkState* default_network = DefaultNetwork(); 778 NET_LOG_EVENT("DefaultNetworkChanged", 779 GetManagedStateLogName(default_network)); 780 FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_, 781 DefaultNetworkChanged(default_network)); 782} 783 784void NetworkStateHandler::NetworkPropertiesUpdated( 785 const NetworkState* network) { 786 FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_, 787 NetworkPropertiesUpdated(network)); 788} 789 790void NetworkStateHandler::ScanCompleted(const std::string& type) { 791 size_t num_callbacks = scan_complete_callbacks_.count(type); 792 NET_LOG_EVENT("ScanCompleted", 793 base::StringPrintf("%s:%" PRIuS, type.c_str(), num_callbacks)); 794 if (num_callbacks == 0) 795 return; 796 ScanCallbackList& callback_list = scan_complete_callbacks_[type]; 797 for (ScanCallbackList::iterator iter = callback_list.begin(); 798 iter != callback_list.end(); ++iter) { 799 (*iter).Run(); 800 } 801 scan_complete_callbacks_.erase(type); 802} 803 804std::string NetworkStateHandler::GetTechnologyForType( 805 const NetworkTypePattern& type) const { 806 if (type.MatchesType(shill::kTypeEthernet)) 807 return shill::kTypeEthernet; 808 809 if (type.MatchesType(shill::kTypeWifi)) 810 return shill::kTypeWifi; 811 812 if (type.Equals(NetworkTypePattern::Wimax())) 813 return shill::kTypeWimax; 814 815 // Prefer Wimax over Cellular only if it's available. 816 if (type.MatchesType(shill::kTypeWimax) && 817 shill_property_handler_->IsTechnologyAvailable(shill::kTypeWimax)) { 818 return shill::kTypeWimax; 819 } 820 821 if (type.MatchesType(shill::kTypeCellular)) 822 return shill::kTypeCellular; 823 824 NOTREACHED(); 825 return std::string(); 826} 827 828} // namespace chromeos 829