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