network_state_handler.cc revision f8ee788a64d60abd8f2d742a5fdedde054ecd910
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/guid.h" 10#include "base/location.h" 11#include "base/logging.h" 12#include "base/metrics/histogram.h" 13#include "base/stl_util.h" 14#include "base/strings/string_util.h" 15#include "base/strings/stringprintf.h" 16#include "base/values.h" 17#include "chromeos/network/device_state.h" 18#include "chromeos/network/managed_state.h" 19#include "chromeos/network/network_event_log.h" 20#include "chromeos/network/network_state.h" 21#include "chromeos/network/network_state_handler_observer.h" 22#include "chromeos/network/shill_property_handler.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_DEVICE: 41 return "Device"; 42 } 43 NOTREACHED(); 44 return ""; 45} 46 47std::string GetLogName(const ManagedState* state) { 48 if (!state) 49 return "None"; 50 return base::StringPrintf("%s (%s)", state->name().c_str(), 51 state->path().c_str()); 52} 53 54} // namespace 55 56const char NetworkStateHandler::kDefaultCheckPortalList[] = 57 "ethernet,wifi,cellular"; 58 59NetworkStateHandler::NetworkStateHandler() { 60} 61 62NetworkStateHandler::~NetworkStateHandler() { 63 FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_, IsShuttingDown()); 64 STLDeleteContainerPointers(network_list_.begin(), network_list_.end()); 65 STLDeleteContainerPointers(device_list_.begin(), device_list_.end()); 66} 67 68void NetworkStateHandler::InitShillPropertyHandler() { 69 shill_property_handler_.reset(new internal::ShillPropertyHandler(this)); 70 shill_property_handler_->Init(); 71} 72 73// static 74NetworkStateHandler* NetworkStateHandler::InitializeForTest() { 75 NetworkStateHandler* handler = new NetworkStateHandler(); 76 handler->InitShillPropertyHandler(); 77 return handler; 78} 79 80void NetworkStateHandler::AddObserver( 81 NetworkStateHandlerObserver* observer, 82 const tracked_objects::Location& from_here) { 83 observers_.AddObserver(observer); 84 network_event_log::internal::AddEntry( 85 from_here.file_name(), from_here.line_number(), 86 network_event_log::LOG_LEVEL_DEBUG, 87 "NetworkStateHandler::AddObserver", ""); 88} 89 90void NetworkStateHandler::RemoveObserver( 91 NetworkStateHandlerObserver* observer, 92 const tracked_objects::Location& from_here) { 93 observers_.RemoveObserver(observer); 94 network_event_log::internal::AddEntry( 95 from_here.file_name(), from_here.line_number(), 96 network_event_log::LOG_LEVEL_DEBUG, 97 "NetworkStateHandler::RemoveObserver", ""); 98} 99 100NetworkStateHandler::TechnologyState NetworkStateHandler::GetTechnologyState( 101 const NetworkTypePattern& type) const { 102 std::string technology = GetTechnologyForType(type); 103 TechnologyState state; 104 if (shill_property_handler_->IsTechnologyEnabled(technology)) 105 state = TECHNOLOGY_ENABLED; 106 else if (shill_property_handler_->IsTechnologyEnabling(technology)) 107 state = TECHNOLOGY_ENABLING; 108 else if (shill_property_handler_->IsTechnologyUninitialized(technology)) 109 state = TECHNOLOGY_UNINITIALIZED; 110 else if (shill_property_handler_->IsTechnologyAvailable(technology)) 111 state = TECHNOLOGY_AVAILABLE; 112 else 113 state = TECHNOLOGY_UNAVAILABLE; 114 VLOG(2) << "GetTechnologyState: " << type.ToDebugString() << " = " << state; 115 return state; 116} 117 118void NetworkStateHandler::SetTechnologyEnabled( 119 const NetworkTypePattern& type, 120 bool enabled, 121 const network_handler::ErrorCallback& error_callback) { 122 ScopedVector<std::string> technologies = GetTechnologiesForType(type); 123 for (ScopedVector<std::string>::iterator it = technologies.begin(); 124 it != technologies.end(); ++it) { 125 std::string* technology = *it; 126 DCHECK(technology); 127 if (!shill_property_handler_->IsTechnologyAvailable(*technology)) 128 continue; 129 NET_LOG_USER("SetTechnologyEnabled", 130 base::StringPrintf("%s:%d", technology->c_str(), enabled)); 131 shill_property_handler_->SetTechnologyEnabled( 132 *technology, enabled, error_callback); 133 } 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 (default_network_path_.empty()) 183 return NULL; 184 return GetNetworkState(default_network_path_); 185} 186 187const NetworkState* NetworkStateHandler::ConnectedNetworkByType( 188 const NetworkTypePattern& type) const { 189 for (ManagedStateList::const_iterator iter = network_list_.begin(); 190 iter != network_list_.end(); ++iter) { 191 const NetworkState* network = (*iter)->AsNetworkState(); 192 DCHECK(network); 193 if (!network->update_received()) 194 continue; 195 if (!network->IsConnectedState()) 196 break; // Connected networks are listed first. 197 if (network->Matches(type)) 198 return network; 199 } 200 return NULL; 201} 202 203const NetworkState* NetworkStateHandler::ConnectingNetworkByType( 204 const NetworkTypePattern& type) const { 205 for (ManagedStateList::const_iterator iter = network_list_.begin(); 206 iter != network_list_.end(); ++iter) { 207 const NetworkState* network = (*iter)->AsNetworkState(); 208 DCHECK(network); 209 if (!network->update_received() || network->IsConnectedState()) 210 continue; 211 if (!network->IsConnectingState()) 212 break; // Connected and connecting networks are listed first. 213 if (network->Matches(type)) 214 return network; 215 } 216 return NULL; 217} 218 219const NetworkState* NetworkStateHandler::FirstNetworkByType( 220 const NetworkTypePattern& type) const { 221 for (ManagedStateList::const_iterator iter = network_list_.begin(); 222 iter != network_list_.end(); ++iter) { 223 const NetworkState* network = (*iter)->AsNetworkState(); 224 DCHECK(network); 225 if (!network->update_received()) 226 continue; 227 if (!network->visible()) 228 continue; 229 if (network->Matches(type)) 230 return network; 231 } 232 return NULL; 233} 234 235std::string NetworkStateHandler::FormattedHardwareAddressForType( 236 const NetworkTypePattern& type) const { 237 const DeviceState* device = NULL; 238 const NetworkState* network = ConnectedNetworkByType(type); 239 if (network) 240 device = GetDeviceState(network->device_path()); 241 else 242 device = GetDeviceStateByType(type); 243 if (!device) 244 return std::string(); 245 return network_util::FormattedMacAddress(device->mac_address()); 246} 247 248void NetworkStateHandler::GetVisibleNetworkListByType( 249 const NetworkTypePattern& type, 250 NetworkStateList* list) const { 251 GetNetworkListByType(type, 252 false /* configured_only */, 253 true /* visible_only */, 254 0 /* no limit */, 255 list); 256} 257 258void NetworkStateHandler::GetVisibleNetworkList(NetworkStateList* list) const { 259 GetVisibleNetworkListByType(NetworkTypePattern::Default(), list); 260} 261 262void NetworkStateHandler::GetNetworkListByType(const NetworkTypePattern& type, 263 bool configured_only, 264 bool visible_only, 265 int limit, 266 NetworkStateList* list) const { 267 DCHECK(list); 268 list->clear(); 269 int count = 0; 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() || !network->Matches(type)) 275 continue; 276 if (configured_only && !network->IsInProfile()) 277 continue; 278 if (visible_only && !network->visible()) 279 continue; 280 list->push_back(network); 281 if (limit > 0 && ++count >= limit) 282 break; 283 } 284} 285 286const NetworkState* NetworkStateHandler::GetNetworkStateFromServicePath( 287 const std::string& service_path, 288 bool configured_only) const { 289 ManagedState* managed = 290 GetModifiableManagedState(&network_list_, service_path); 291 if (!managed) 292 return NULL; 293 const NetworkState* network = managed->AsNetworkState(); 294 DCHECK(network); 295 if (!network->update_received() || 296 (configured_only && !network->IsInProfile())) { 297 return NULL; 298 } 299 return network; 300} 301 302const NetworkState* NetworkStateHandler::GetNetworkStateFromGuid( 303 const std::string& guid) const { 304 DCHECK(!guid.empty()); 305 for (ManagedStateList::const_iterator iter = network_list_.begin(); 306 iter != network_list_.end(); ++iter) { 307 const NetworkState* network = (*iter)->AsNetworkState(); 308 if (network->guid() == guid) 309 return network; 310 } 311 return NULL; 312} 313 314void NetworkStateHandler::GetDeviceList(DeviceStateList* list) const { 315 GetDeviceListByType(NetworkTypePattern::Default(), list); 316} 317 318void NetworkStateHandler::GetDeviceListByType(const NetworkTypePattern& type, 319 DeviceStateList* list) const { 320 DCHECK(list); 321 list->clear(); 322 for (ManagedStateList::const_iterator iter = device_list_.begin(); 323 iter != device_list_.end(); ++iter) { 324 const DeviceState* device = (*iter)->AsDeviceState(); 325 DCHECK(device); 326 if (device->update_received() && device->Matches(type)) 327 list->push_back(device); 328 } 329} 330 331void NetworkStateHandler::RequestScan() const { 332 NET_LOG_USER("RequestScan", ""); 333 shill_property_handler_->RequestScan(); 334} 335 336void NetworkStateHandler::WaitForScan(const std::string& type, 337 const base::Closure& callback) { 338 scan_complete_callbacks_[type].push_back(callback); 339 if (!GetScanningByType(NetworkTypePattern::Primitive(type))) 340 RequestScan(); 341} 342 343void NetworkStateHandler::ConnectToBestWifiNetwork() { 344 NET_LOG_USER("ConnectToBestWifiNetwork", ""); 345 WaitForScan(shill::kTypeWifi, 346 base::Bind(&internal::ShillPropertyHandler::ConnectToBestServices, 347 shill_property_handler_->AsWeakPtr())); 348} 349 350void NetworkStateHandler::RequestUpdateForNetwork( 351 const std::string& service_path) { 352 NetworkState* network = GetModifiableNetworkState(service_path); 353 if (network) 354 network->set_update_requested(true); 355 NET_LOG_EVENT("RequestUpdate", service_path); 356 shill_property_handler_->RequestProperties( 357 ManagedState::MANAGED_TYPE_NETWORK, service_path); 358} 359 360void NetworkStateHandler::ClearLastErrorForNetwork( 361 const std::string& service_path) { 362 NetworkState* network = GetModifiableNetworkState(service_path); 363 if (network) 364 network->clear_last_error(); 365} 366 367void NetworkStateHandler::SetCheckPortalList( 368 const std::string& check_portal_list) { 369 NET_LOG_EVENT("SetCheckPortalList", check_portal_list); 370 shill_property_handler_->SetCheckPortalList(check_portal_list); 371} 372 373const NetworkState* NetworkStateHandler::GetEAPForEthernet( 374 const std::string& service_path) const { 375 const NetworkState* network = GetNetworkState(service_path); 376 if (!network) { 377 NET_LOG_ERROR("GetEAPForEthernet", "Unknown service path " + service_path); 378 return NULL; 379 } 380 if (network->type() != shill::kTypeEthernet) { 381 NET_LOG_ERROR("GetEAPForEthernet", "Not of type Ethernet: " + service_path); 382 return NULL; 383 } 384 if (!network->IsConnectedState()) 385 return NULL; 386 387 // The same EAP service is shared for all ethernet services/devices. 388 // However EAP is used/enabled per device and only if the connection was 389 // successfully established. 390 const DeviceState* device = GetDeviceState(network->device_path()); 391 if (!device) { 392 NET_LOG_ERROR( 393 "GetEAPForEthernet", 394 base::StringPrintf("Unknown device %s of connected ethernet service %s", 395 network->device_path().c_str(), 396 service_path.c_str())); 397 return NULL; 398 } 399 if (!device->eap_authentication_completed()) 400 return NULL; 401 402 NetworkStateList list; 403 GetNetworkListByType(NetworkTypePattern::Primitive(shill::kTypeEthernetEap), 404 true /* configured_only */, 405 false /* visible_only */, 406 1 /* limit */, 407 &list); 408 if (list.empty()) { 409 NET_LOG_ERROR("GetEAPForEthernet", 410 base::StringPrintf( 411 "Ethernet service %s connected using EAP, but no " 412 "EAP service found.", 413 service_path.c_str())); 414 return NULL; 415 } 416 return list.front(); 417} 418 419//------------------------------------------------------------------------------ 420// ShillPropertyHandler::Delegate overrides 421 422void NetworkStateHandler::UpdateManagedList(ManagedState::ManagedType type, 423 const base::ListValue& entries) { 424 ManagedStateList* managed_list = GetManagedList(type); 425 NET_LOG_DEBUG("UpdateManagedList: " + ManagedState::TypeToString(type), 426 base::StringPrintf("%" PRIuS, entries.GetSize())); 427 // Create a map of existing entries. Assumes all entries in |managed_list| 428 // are unique. 429 typedef std::map<std::string, ManagedState*> ManagedMap; 430 ManagedMap managed_map; 431 for (ManagedStateList::iterator iter = managed_list->begin(); 432 iter != managed_list->end(); ++iter) { 433 ManagedState* managed = *iter; 434 DCHECK(!ContainsKey(managed_map, managed->path())); 435 managed_map[managed->path()] = managed; 436 } 437 // Clear the list (pointers are temporarily owned by managed_map). 438 managed_list->clear(); 439 // Updates managed_list and request updates for new entries. 440 std::set<std::string> list_entries; 441 for (base::ListValue::const_iterator iter = entries.begin(); 442 iter != entries.end(); ++iter) { 443 std::string path; 444 (*iter)->GetAsString(&path); 445 if (path.empty() || path == shill::kFlimflamServicePath) { 446 NET_LOG_ERROR(base::StringPrintf("Bad path in list:%d", type), path); 447 continue; 448 } 449 ManagedMap::iterator found = managed_map.find(path); 450 if (found == managed_map.end()) { 451 if (list_entries.count(path) != 0) { 452 NET_LOG_ERROR("Duplicate entry in list", path); 453 continue; 454 } 455 ManagedState* managed = ManagedState::Create(type, path); 456 managed_list->push_back(managed); 457 } else { 458 managed_list->push_back(found->second); 459 managed_map.erase(found); 460 } 461 list_entries.insert(path); 462 } 463 // Delete any remaining entries in managed_map. 464 STLDeleteContainerPairSecondPointers(managed_map.begin(), managed_map.end()); 465} 466 467void NetworkStateHandler::UpdateVisibleNetworks( 468 const base::ListValue& entries) { 469 NET_LOG_DEBUG(base::StringPrintf("UpdateVisibleNetworks"), 470 base::StringPrintf("%" PRIuS, entries.GetSize())); 471 // Create a map of all networks and clear the visible state. 472 ManagedStateList* network_list = 473 GetManagedList(ManagedState::MANAGED_TYPE_NETWORK); 474 typedef std::map<std::string, NetworkState*> NetworkMap; 475 NetworkMap network_map; 476 for (ManagedStateList::iterator iter = network_list->begin(); 477 iter != network_list->end(); ++iter) { 478 NetworkState* network = (*iter)->AsNetworkState(); 479 network_map[network->path()] = network; 480 network->set_visible(false); 481 } 482 // Look up each entry and set the associated network to visible. 483 for (base::ListValue::const_iterator iter = entries.begin(); 484 iter != entries.end(); ++iter) { 485 std::string path; 486 (*iter)->GetAsString(&path); 487 NetworkMap::iterator found = network_map.find(path); 488 if (found != network_map.end()) 489 found->second->set_visible(true); 490 else 491 NET_LOG_DEBUG("Visible network not in list", path); 492 } 493} 494 495void NetworkStateHandler::ProfileListChanged() { 496 NET_LOG_EVENT("ProfileListChanged", "Re-Requesting Network Properties"); 497 for (ManagedStateList::iterator iter = network_list_.begin(); 498 iter != network_list_.end(); ++iter) { 499 NetworkState* network = (*iter)->AsNetworkState(); 500 DCHECK(network); 501 shill_property_handler_->RequestProperties( 502 ManagedState::MANAGED_TYPE_NETWORK, network->path()); 503 } 504} 505 506void NetworkStateHandler::UpdateManagedStateProperties( 507 ManagedState::ManagedType type, 508 const std::string& path, 509 const base::DictionaryValue& properties) { 510 ManagedStateList* managed_list = GetManagedList(type); 511 ManagedState* managed = GetModifiableManagedState(managed_list, path); 512 if (!managed) { 513 // The network has been removed from the list of networks. 514 NET_LOG_DEBUG("UpdateManagedStateProperties: Not found", path); 515 return; 516 } 517 managed->set_update_received(); 518 519 std::string desc = GetManagedStateLogType(managed) + " Properties Received"; 520 NET_LOG_DEBUG(desc, GetLogName(managed)); 521 522 if (type == ManagedState::MANAGED_TYPE_NETWORK) { 523 UpdateNetworkStateProperties(managed->AsNetworkState(), properties); 524 } else { 525 // Device 526 for (base::DictionaryValue::Iterator iter(properties); 527 !iter.IsAtEnd(); iter.Advance()) { 528 managed->PropertyChanged(iter.key(), iter.value()); 529 } 530 managed->InitialPropertiesReceived(properties); 531 } 532 managed->set_update_requested(false); 533} 534 535void NetworkStateHandler::UpdateNetworkStateProperties( 536 NetworkState* network, 537 const base::DictionaryValue& properties) { 538 DCHECK(network); 539 bool network_property_updated = false; 540 std::string prev_connection_state = network->connection_state(); 541 for (base::DictionaryValue::Iterator iter(properties); 542 !iter.IsAtEnd(); iter.Advance()) { 543 if (network->PropertyChanged(iter.key(), iter.value())) 544 network_property_updated = true; 545 } 546 network_property_updated |= network->InitialPropertiesReceived(properties); 547 // Notify observers of NetworkState changes. 548 if (network_property_updated || network->update_requested()) { 549 // Signal connection state changed after all properties have been updated. 550 if (ConnectionStateChanged(network, prev_connection_state)) 551 OnNetworkConnectionStateChanged(network); 552 NET_LOG_EVENT("NetworkPropertiesUpdated", GetLogName(network)); 553 NotifyNetworkPropertiesUpdated(network); 554 } 555 UpdateGuid(network); 556} 557 558void NetworkStateHandler::UpdateNetworkServiceProperty( 559 const std::string& service_path, 560 const std::string& key, 561 const base::Value& value) { 562 bool changed = false; 563 NetworkState* network = GetModifiableNetworkState(service_path); 564 if (!network) 565 return; 566 std::string prev_connection_state = network->connection_state(); 567 std::string prev_profile_path = network->profile_path(); 568 changed |= network->PropertyChanged(key, value); 569 if (!changed) 570 return; 571 572 if (key == shill::kStateProperty) { 573 if (ConnectionStateChanged(network, prev_connection_state)) { 574 OnNetworkConnectionStateChanged(network); 575 // If the connection state changes, other properties such as IPConfig 576 // may have changed, so request a full update. 577 RequestUpdateForNetwork(service_path); 578 } 579 } else { 580 std::string value_str; 581 value.GetAsString(&value_str); 582 // Some property changes are noisy and not interesting: 583 // * Wifi SignalStrength 584 // * WifiFrequencyList updates 585 // * Device property changes to "/" (occurs before a service is removed) 586 if (key != shill::kSignalStrengthProperty && 587 key != shill::kWifiFrequencyListProperty && 588 (key != shill::kDeviceProperty || value_str != "/")) { 589 std::string log_event = "NetworkPropertyUpdated"; 590 // Trigger a default network update for interesting changes only. 591 if (network->path() == default_network_path_) { 592 NotifyDefaultNetworkChanged(network); 593 log_event = "Default" + log_event; 594 } 595 // Log event. 596 std::string detail = network->name() + "." + key; 597 detail += " = " + network_event_log::ValueAsString(value); 598 network_event_log::LogLevel log_level; 599 if (key == shill::kErrorProperty || key == shill::kErrorDetailsProperty) { 600 log_level = network_event_log::LOG_LEVEL_ERROR; 601 } else { 602 log_level = network_event_log::LOG_LEVEL_EVENT; 603 } 604 NET_LOG_LEVEL(log_level, log_event, detail); 605 } 606 } 607 608 // All property updates signal 'NetworkPropertiesUpdated'. 609 NotifyNetworkPropertiesUpdated(network); 610 611 // If added to a Profile, request a full update so that a NetworkState 612 // gets created. 613 if (prev_profile_path.empty() && !network->profile_path().empty()) 614 RequestUpdateForNetwork(service_path); 615} 616 617void NetworkStateHandler::UpdateDeviceProperty(const std::string& device_path, 618 const std::string& key, 619 const base::Value& value) { 620 DeviceState* device = GetModifiableDeviceState(device_path); 621 if (!device) 622 return; 623 if (!device->PropertyChanged(key, value)) 624 return; 625 626 std::string detail = device->name() + "." + key; 627 detail += " = " + network_event_log::ValueAsString(value); 628 NET_LOG_EVENT("DevicePropertyUpdated", detail); 629 630 NotifyDeviceListChanged(); 631 632 if (key == shill::kScanningProperty && device->scanning() == false) 633 ScanCompleted(device->type()); 634 if (key == shill::kEapAuthenticationCompletedProperty) { 635 // Notify a change for each Ethernet service using this device. 636 NetworkStateList ethernet_services; 637 GetNetworkListByType(NetworkTypePattern::Ethernet(), 638 false /* configured_only */, 639 false /* visible_only */, 640 0 /* no limit */, 641 ðernet_services); 642 for (NetworkStateList::const_iterator it = ethernet_services.begin(); 643 it != ethernet_services.end(); ++it) { 644 const NetworkState* ethernet_service = *it; 645 if (ethernet_service->update_received() || 646 ethernet_service->device_path() != device->path()) { 647 continue; 648 } 649 RequestUpdateForNetwork(ethernet_service->path()); 650 } 651 } 652} 653 654void NetworkStateHandler::UpdateIPConfigProperties( 655 ManagedState::ManagedType type, 656 const std::string& path, 657 const std::string& ip_config_path, 658 const base::DictionaryValue& properties) { 659 if (type == ManagedState::MANAGED_TYPE_NETWORK) { 660 NetworkState* network = GetModifiableNetworkState(path); 661 if (!network) 662 return; 663 network->IPConfigPropertiesChanged(properties); 664 if (network->path() == default_network_path_) 665 NotifyDefaultNetworkChanged(network); 666 } else if (type == ManagedState::MANAGED_TYPE_DEVICE) { 667 DeviceState* device = GetModifiableDeviceState(path); 668 if (!device) 669 return; 670 device->IPConfigPropertiesChanged(ip_config_path, properties); 671 if (!default_network_path_.empty()) { 672 const NetworkState* default_network = 673 GetNetworkState(default_network_path_); 674 if (default_network && default_network->device_path() == path) 675 NotifyDefaultNetworkChanged(default_network); 676 } 677 } 678} 679 680void NetworkStateHandler::CheckPortalListChanged( 681 const std::string& check_portal_list) { 682 check_portal_list_ = check_portal_list; 683} 684 685void NetworkStateHandler::TechnologyListChanged() { 686 // Eventually we would like to replace Technology state with Device state. 687 // For now, treat technology state changes as device list changes. 688 NotifyDeviceListChanged(); 689} 690 691void NetworkStateHandler::ManagedStateListChanged( 692 ManagedState::ManagedType type) { 693 if (type == ManagedState::MANAGED_TYPE_NETWORK) { 694 // Notify observers that the list of networks has changed. 695 NET_LOG_EVENT("NOTIFY:NetworkListChanged", 696 base::StringPrintf("Size:%" PRIuS, network_list_.size())); 697 FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_, 698 NetworkListChanged()); 699 // Update UMA stats. 700 size_t shared = 0, unshared = 0, visible = 0; 701 for (ManagedStateList::iterator iter = network_list_.begin(); 702 iter != network_list_.end(); ++iter) { 703 NetworkState* network = (*iter)->AsNetworkState(); 704 if (network->visible()) 705 ++visible; 706 if (network->IsInProfile()) { 707 if (network->IsPrivate()) 708 ++unshared; 709 else 710 ++shared; 711 } 712 } 713 UMA_HISTOGRAM_COUNTS_100("Networks.Visible", visible); 714 UMA_HISTOGRAM_COUNTS_100("Networks.RememberedShared", shared); 715 UMA_HISTOGRAM_COUNTS_100("Networks.RememberedUnshared", unshared); 716 } else if (type == ManagedState::MANAGED_TYPE_DEVICE) { 717 std::string devices; 718 for (ManagedStateList::const_iterator iter = device_list_.begin(); 719 iter != device_list_.end(); ++iter) { 720 if (iter != device_list_.begin()) 721 devices += ", "; 722 devices += (*iter)->name(); 723 } 724 NET_LOG_EVENT("DeviceList", devices); 725 NotifyDeviceListChanged(); 726 } else { 727 NOTREACHED(); 728 } 729} 730 731void NetworkStateHandler::DefaultNetworkServiceChanged( 732 const std::string& service_path) { 733 // Shill uses '/' for empty service path values; check explicitly for that. 734 const char* kEmptyServicePath = "/"; 735 std::string new_service_path = 736 (service_path != kEmptyServicePath) ? service_path : ""; 737 if (new_service_path == default_network_path_) 738 return; 739 740 default_network_path_ = service_path; 741 NET_LOG_EVENT("DefaultNetworkServiceChanged:", default_network_path_); 742 const NetworkState* network = NULL; 743 if (!default_network_path_.empty()) { 744 network = GetNetworkState(default_network_path_); 745 if (!network) { 746 // If NetworkState is not available yet, do not notify observers here, 747 // they will be notified when the state is received. 748 NET_LOG_DEBUG("Default NetworkState not available", 749 default_network_path_); 750 return; 751 } 752 } 753 if (network && !network->IsConnectedState()) { 754 NET_LOG_ERROR( 755 "DefaultNetwork is not connected: " + network->connection_state(), 756 network->path()); 757 } 758 NotifyDefaultNetworkChanged(network); 759} 760 761//------------------------------------------------------------------------------ 762// Private methods 763 764void NetworkStateHandler::UpdateGuid(NetworkState* network) { 765 std::string specifier = network->GetSpecifier(); 766 DCHECK(!specifier.empty()); 767 if (!network->guid().empty()) { 768 // If the network is saved in a profile, remove the entry from the map. 769 // Otherwise ensure that the entry matches the specified GUID. (e.g. in 770 // case a visible network with a specified guid gets configured with a 771 // new guid). 772 if (network->IsInProfile()) 773 specifier_guid_map_.erase(specifier); 774 else 775 specifier_guid_map_[specifier] = network->guid(); 776 return; 777 } 778 // Ensure that the NetworkState has a valid GUID. 779 std::string guid; 780 SpecifierGuidMap::iterator iter = specifier_guid_map_.find(specifier); 781 if (iter != specifier_guid_map_.end()) { 782 guid = iter->second; 783 } else { 784 guid = base::GenerateGUID(); 785 specifier_guid_map_[specifier] = guid; 786 } 787 network->SetGuid(guid); 788} 789 790void NetworkStateHandler::NotifyDeviceListChanged() { 791 NET_LOG_DEBUG("NOTIFY:DeviceListChanged", 792 base::StringPrintf("Size:%" PRIuS, device_list_.size())); 793 FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_, 794 DeviceListChanged()); 795} 796 797DeviceState* NetworkStateHandler::GetModifiableDeviceState( 798 const std::string& device_path) const { 799 ManagedState* managed = GetModifiableManagedState(&device_list_, device_path); 800 if (!managed) 801 return NULL; 802 return managed->AsDeviceState(); 803} 804 805NetworkState* NetworkStateHandler::GetModifiableNetworkState( 806 const std::string& service_path) const { 807 ManagedState* managed = 808 GetModifiableManagedState(&network_list_, service_path); 809 if (!managed) 810 return NULL; 811 return managed->AsNetworkState(); 812} 813 814ManagedState* NetworkStateHandler::GetModifiableManagedState( 815 const ManagedStateList* managed_list, 816 const std::string& path) const { 817 for (ManagedStateList::const_iterator iter = managed_list->begin(); 818 iter != managed_list->end(); ++iter) { 819 ManagedState* managed = *iter; 820 if (managed->path() == path) 821 return managed; 822 } 823 return NULL; 824} 825 826NetworkStateHandler::ManagedStateList* NetworkStateHandler::GetManagedList( 827 ManagedState::ManagedType type) { 828 switch (type) { 829 case ManagedState::MANAGED_TYPE_NETWORK: 830 return &network_list_; 831 case ManagedState::MANAGED_TYPE_DEVICE: 832 return &device_list_; 833 } 834 NOTREACHED(); 835 return NULL; 836} 837 838void NetworkStateHandler::OnNetworkConnectionStateChanged( 839 NetworkState* network) { 840 DCHECK(network); 841 std::string event = "NetworkConnectionStateChanged"; 842 if (network->path() == default_network_path_) { 843 event = "Default" + event; 844 if (!network->IsConnectedState()) { 845 NET_LOG_ERROR( 846 "DefaultNetwork is not connected: " + network->connection_state(), 847 network->path()); 848 } 849 } 850 NET_LOG_EVENT("NOTIFY:" + event + ": " + network->connection_state(), 851 GetLogName(network)); 852 FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_, 853 NetworkConnectionStateChanged(network)); 854 if (network->path() == default_network_path_) 855 NotifyDefaultNetworkChanged(network); 856} 857 858void NetworkStateHandler::NotifyDefaultNetworkChanged( 859 const NetworkState* default_network) { 860 NET_LOG_EVENT("NOTIFY:DefaultNetworkChanged", GetLogName(default_network)); 861 FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_, 862 DefaultNetworkChanged(default_network)); 863} 864 865void NetworkStateHandler::NotifyNetworkPropertiesUpdated( 866 const NetworkState* network) { 867 NET_LOG_DEBUG("NOTIFY:NetworkPropertiesUpdated", GetLogName(network)); 868 FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_, 869 NetworkPropertiesUpdated(network)); 870} 871 872void NetworkStateHandler::ScanCompleted(const std::string& type) { 873 size_t num_callbacks = scan_complete_callbacks_.count(type); 874 NET_LOG_EVENT("ScanCompleted", 875 base::StringPrintf("%s:%" PRIuS, type.c_str(), num_callbacks)); 876 if (num_callbacks == 0) 877 return; 878 ScanCallbackList& callback_list = scan_complete_callbacks_[type]; 879 for (ScanCallbackList::iterator iter = callback_list.begin(); 880 iter != callback_list.end(); ++iter) { 881 (*iter).Run(); 882 } 883 scan_complete_callbacks_.erase(type); 884} 885 886std::string NetworkStateHandler::GetTechnologyForType( 887 const NetworkTypePattern& type) const { 888 if (type.MatchesType(shill::kTypeEthernet)) 889 return shill::kTypeEthernet; 890 891 if (type.MatchesType(shill::kTypeWifi)) 892 return shill::kTypeWifi; 893 894 if (type.Equals(NetworkTypePattern::Wimax())) 895 return shill::kTypeWimax; 896 897 // Prefer Wimax over Cellular only if it's available. 898 if (type.MatchesType(shill::kTypeWimax) && 899 shill_property_handler_->IsTechnologyAvailable(shill::kTypeWimax)) { 900 return shill::kTypeWimax; 901 } 902 903 if (type.MatchesType(shill::kTypeCellular)) 904 return shill::kTypeCellular; 905 906 NOTREACHED(); 907 return std::string(); 908} 909 910ScopedVector<std::string> NetworkStateHandler::GetTechnologiesForType( 911 const NetworkTypePattern& type) const { 912 ScopedVector<std::string> technologies; 913 if (type.MatchesType(shill::kTypeEthernet)) 914 technologies.push_back(new std::string(shill::kTypeEthernet)); 915 if (type.MatchesType(shill::kTypeWifi)) 916 technologies.push_back(new std::string(shill::kTypeWifi)); 917 if (type.MatchesType(shill::kTypeWimax)) 918 technologies.push_back(new std::string(shill::kTypeWimax)); 919 if (type.MatchesType(shill::kTypeCellular)) 920 technologies.push_back(new std::string(shill::kTypeCellular)); 921 if (type.MatchesType(shill::kTypeBluetooth)) 922 technologies.push_back(new std::string(shill::kTypeBluetooth)); 923 if (type.MatchesType(shill::kTypeVPN)) 924 technologies.push_back(new std::string(shill::kTypeVPN)); 925 926 CHECK_GT(technologies.size(), 0ul); 927 return technologies.Pass(); 928} 929 930} // namespace chromeos 931