Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chromeos/network/network_state_handler.h" | 5 #include "chromeos/network/network_state_handler.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/format_macros.h" | 8 #include "base/format_macros.h" |
| 9 #include "base/guid.h" | 9 #include "base/guid.h" |
| 10 #include "base/location.h" | 10 #include "base/location.h" |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 215 | 215 |
| 216 const NetworkState* NetworkStateHandler::FirstNetworkByType( | 216 const NetworkState* NetworkStateHandler::FirstNetworkByType( |
| 217 const NetworkTypePattern& type) const { | 217 const NetworkTypePattern& type) const { |
| 218 for (ManagedStateList::const_iterator iter = network_list_.begin(); | 218 for (ManagedStateList::const_iterator iter = network_list_.begin(); |
| 219 iter != network_list_.end(); ++iter) { | 219 iter != network_list_.end(); ++iter) { |
| 220 const NetworkState* network = (*iter)->AsNetworkState(); | 220 const NetworkState* network = (*iter)->AsNetworkState(); |
| 221 DCHECK(network); | 221 DCHECK(network); |
| 222 if (!network->update_received()) | 222 if (!network->update_received()) |
| 223 continue; | 223 continue; |
| 224 if (!network->visible()) | 224 if (!network->visible()) |
| 225 continue; | 225 break; |
| 226 if (network->Matches(type)) | 226 if (network->Matches(type)) |
| 227 return network; | 227 return network; |
| 228 } | 228 } |
| 229 return NULL; | 229 return NULL; |
| 230 } | 230 } |
| 231 | 231 |
| 232 std::string NetworkStateHandler::FormattedHardwareAddressForType( | 232 std::string NetworkStateHandler::FormattedHardwareAddressForType( |
| 233 const NetworkTypePattern& type) const { | 233 const NetworkTypePattern& type) const { |
| 234 const DeviceState* device = NULL; | 234 const DeviceState* device = NULL; |
| 235 const NetworkState* network = ConnectedNetworkByType(type); | 235 const NetworkState* network = ConnectedNetworkByType(type); |
| (...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 454 } else { | 454 } else { |
| 455 managed_list->push_back(found->second); | 455 managed_list->push_back(found->second); |
| 456 managed_map.erase(found); | 456 managed_map.erase(found); |
| 457 } | 457 } |
| 458 list_entries.insert(path); | 458 list_entries.insert(path); |
| 459 } | 459 } |
| 460 // Delete any remaining entries in managed_map. | 460 // Delete any remaining entries in managed_map. |
| 461 STLDeleteContainerPairSecondPointers(managed_map.begin(), managed_map.end()); | 461 STLDeleteContainerPairSecondPointers(managed_map.begin(), managed_map.end()); |
| 462 } | 462 } |
| 463 | 463 |
| 464 void NetworkStateHandler::UpdateVisibleNetworks( | |
| 465 const base::ListValue& entries) { | |
| 466 NET_LOG_DEBUG(base::StringPrintf("UpdateVisibleNetworks"), | |
| 467 base::StringPrintf("%" PRIuS, entries.GetSize())); | |
| 468 // Create a map of all networks and clear the visible state. | |
| 469 ManagedStateList* network_list = | |
| 470 GetManagedList(ManagedState::MANAGED_TYPE_NETWORK); | |
| 471 typedef std::map<std::string, NetworkState*> NetworkMap; | |
| 472 NetworkMap network_map; | |
| 473 for (ManagedStateList::iterator iter = network_list->begin(); | |
| 474 iter != network_list->end(); ++iter) { | |
| 475 NetworkState* network = (*iter)->AsNetworkState(); | |
| 476 network_map[network->path()] = network; | |
| 477 network->set_visible(false); | |
| 478 } | |
| 479 // Look up each entry and set the associated network to visible. | |
| 480 for (base::ListValue::const_iterator iter = entries.begin(); | |
| 481 iter != entries.end(); ++iter) { | |
| 482 std::string path; | |
| 483 (*iter)->GetAsString(&path); | |
| 484 NetworkMap::iterator found = network_map.find(path); | |
| 485 if (found != network_map.end()) | |
| 486 found->second->set_visible(true); | |
| 487 else | |
| 488 NET_LOG_DEBUG("Visible network not in list", path); | |
| 489 } | |
| 490 } | |
| 491 | |
| 492 void NetworkStateHandler::ProfileListChanged() { | 464 void NetworkStateHandler::ProfileListChanged() { |
| 493 NET_LOG_EVENT("ProfileListChanged", "Re-Requesting Network Properties"); | 465 NET_LOG_EVENT("ProfileListChanged", "Re-Requesting Network Properties"); |
| 494 for (ManagedStateList::iterator iter = network_list_.begin(); | 466 for (ManagedStateList::iterator iter = network_list_.begin(); |
| 495 iter != network_list_.end(); ++iter) { | 467 iter != network_list_.end(); ++iter) { |
| 496 NetworkState* network = (*iter)->AsNetworkState(); | 468 NetworkState* network = (*iter)->AsNetworkState(); |
| 497 DCHECK(network); | 469 DCHECK(network); |
| 498 shill_property_handler_->RequestProperties( | 470 shill_property_handler_->RequestProperties( |
| 499 ManagedState::MANAGED_TYPE_NETWORK, network->path()); | 471 ManagedState::MANAGED_TYPE_NETWORK, network->path()); |
| 500 } | 472 } |
| 501 } | 473 } |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 534 const base::DictionaryValue& properties) { | 506 const base::DictionaryValue& properties) { |
| 535 DCHECK(network); | 507 DCHECK(network); |
| 536 bool network_property_updated = false; | 508 bool network_property_updated = false; |
| 537 std::string prev_connection_state = network->connection_state(); | 509 std::string prev_connection_state = network->connection_state(); |
| 538 for (base::DictionaryValue::Iterator iter(properties); | 510 for (base::DictionaryValue::Iterator iter(properties); |
| 539 !iter.IsAtEnd(); iter.Advance()) { | 511 !iter.IsAtEnd(); iter.Advance()) { |
| 540 if (network->PropertyChanged(iter.key(), iter.value())) | 512 if (network->PropertyChanged(iter.key(), iter.value())) |
| 541 network_property_updated = true; | 513 network_property_updated = true; |
| 542 } | 514 } |
| 543 network_property_updated |= network->InitialPropertiesReceived(properties); | 515 network_property_updated |= network->InitialPropertiesReceived(properties); |
| 516 UpdateGuid(network); | |
| 517 | |
| 518 // Ensure that sorting is correct. Observers will be notified that the list | |
| 519 // changed one time only when ManagedStateListChanged() is called (after | |
| 520 // all requested updates have been received). | |
| 521 SortNetworkList(); | |
|
pneubeck (no reviews)
2014/06/17 15:30:33
Couldn't this lead to a to huge performance impact
stevenjb
2014/06/17 17:14:08
Yeah, you're right, technically after a scan this
| |
| 522 | |
| 544 // Notify observers of NetworkState changes. | 523 // Notify observers of NetworkState changes. |
| 545 if (network_property_updated || network->update_requested()) { | 524 if (network_property_updated || network->update_requested()) { |
| 546 // Signal connection state changed after all properties have been updated. | 525 // Signal connection state changed after all properties have been updated. |
| 547 if (ConnectionStateChanged(network, prev_connection_state)) | 526 if (ConnectionStateChanged(network, prev_connection_state)) |
| 548 OnNetworkConnectionStateChanged(network); | 527 OnNetworkConnectionStateChanged(network); |
| 549 NET_LOG_EVENT("NetworkPropertiesUpdated", GetLogName(network)); | 528 NET_LOG_EVENT("NetworkPropertiesUpdated", GetLogName(network)); |
| 550 NotifyNetworkPropertiesUpdated(network); | 529 NotifyNetworkPropertiesUpdated(network); |
| 551 } | 530 } |
| 552 UpdateGuid(network); | |
| 553 } | 531 } |
| 554 | 532 |
| 555 void NetworkStateHandler::UpdateNetworkServiceProperty( | 533 void NetworkStateHandler::UpdateNetworkServiceProperty( |
| 556 const std::string& service_path, | 534 const std::string& service_path, |
| 557 const std::string& key, | 535 const std::string& key, |
| 558 const base::Value& value) { | 536 const base::Value& value) { |
| 559 bool changed = false; | 537 bool changed = false; |
| 560 NetworkState* network = GetModifiableNetworkState(service_path); | 538 NetworkState* network = GetModifiableNetworkState(service_path); |
| 561 if (!network) | 539 if (!network) |
| 562 return; | 540 return; |
| 563 std::string prev_connection_state = network->connection_state(); | 541 std::string prev_connection_state = network->connection_state(); |
| 564 std::string prev_profile_path = network->profile_path(); | 542 std::string prev_profile_path = network->profile_path(); |
| 565 changed |= network->PropertyChanged(key, value); | 543 changed |= network->PropertyChanged(key, value); |
| 566 if (!changed) | 544 if (!changed) |
| 567 return; | 545 return; |
| 568 | 546 |
| 569 if (key == shill::kStateProperty) { | 547 if (key == shill::kStateProperty || key == shill::kVisibleProperty) { |
| 570 if (ConnectionStateChanged(network, prev_connection_state)) { | 548 if (ConnectionStateChanged(network, prev_connection_state)) { |
| 571 OnNetworkConnectionStateChanged(network); | 549 OnNetworkConnectionStateChanged(network); |
| 572 // If the connection state changes, other properties such as IPConfig | 550 // If the connection state changes, other properties such as IPConfig |
| 573 // may have changed, so request a full update. | 551 // may have changed, so request a full update. |
| 574 RequestUpdateForNetwork(service_path); | 552 RequestUpdateForNetwork(service_path); |
| 575 } | 553 } |
| 576 } else { | 554 } else { |
| 577 std::string value_str; | 555 std::string value_str; |
| 578 value.GetAsString(&value_str); | 556 value.GetAsString(&value_str); |
| 579 // Some property changes are noisy and not interesting: | 557 // Some property changes are noisy and not interesting: |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 673 | 651 |
| 674 void NetworkStateHandler::TechnologyListChanged() { | 652 void NetworkStateHandler::TechnologyListChanged() { |
| 675 // Eventually we would like to replace Technology state with Device state. | 653 // Eventually we would like to replace Technology state with Device state. |
| 676 // For now, treat technology state changes as device list changes. | 654 // For now, treat technology state changes as device list changes. |
| 677 NotifyDeviceListChanged(); | 655 NotifyDeviceListChanged(); |
| 678 } | 656 } |
| 679 | 657 |
| 680 void NetworkStateHandler::ManagedStateListChanged( | 658 void NetworkStateHandler::ManagedStateListChanged( |
| 681 ManagedState::ManagedType type) { | 659 ManagedState::ManagedType type) { |
| 682 if (type == ManagedState::MANAGED_TYPE_NETWORK) { | 660 if (type == ManagedState::MANAGED_TYPE_NETWORK) { |
| 661 SortNetworkList(); | |
| 662 UpdateNetworkStats(); | |
| 683 // Notify observers that the list of networks has changed. | 663 // Notify observers that the list of networks has changed. |
| 684 NET_LOG_EVENT("NOTIFY:NetworkListChanged", | 664 NET_LOG_EVENT("NOTIFY:NetworkListChanged", |
| 685 base::StringPrintf("Size:%" PRIuS, network_list_.size())); | 665 base::StringPrintf("Size:%" PRIuS, network_list_.size())); |
| 686 FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_, | 666 FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_, |
| 687 NetworkListChanged()); | 667 NetworkListChanged()); |
| 688 // Update UMA stats. | |
| 689 size_t shared = 0, unshared = 0, visible = 0; | |
| 690 for (ManagedStateList::iterator iter = network_list_.begin(); | |
| 691 iter != network_list_.end(); ++iter) { | |
| 692 NetworkState* network = (*iter)->AsNetworkState(); | |
| 693 if (network->visible()) | |
| 694 ++visible; | |
| 695 if (network->IsInProfile()) { | |
| 696 if (network->IsPrivate()) | |
| 697 ++unshared; | |
| 698 else | |
| 699 ++shared; | |
| 700 } | |
| 701 } | |
| 702 UMA_HISTOGRAM_COUNTS_100("Networks.Visible", visible); | |
| 703 UMA_HISTOGRAM_COUNTS_100("Networks.RememberedShared", shared); | |
| 704 UMA_HISTOGRAM_COUNTS_100("Networks.RememberedUnshared", unshared); | |
| 705 } else if (type == ManagedState::MANAGED_TYPE_DEVICE) { | 668 } else if (type == ManagedState::MANAGED_TYPE_DEVICE) { |
| 706 std::string devices; | 669 std::string devices; |
| 707 for (ManagedStateList::const_iterator iter = device_list_.begin(); | 670 for (ManagedStateList::const_iterator iter = device_list_.begin(); |
| 708 iter != device_list_.end(); ++iter) { | 671 iter != device_list_.end(); ++iter) { |
| 709 if (iter != device_list_.begin()) | 672 if (iter != device_list_.begin()) |
| 710 devices += ", "; | 673 devices += ", "; |
| 711 devices += (*iter)->name(); | 674 devices += (*iter)->name(); |
| 712 } | 675 } |
| 713 NET_LOG_EVENT("DeviceList", devices); | 676 NET_LOG_EVENT("DeviceList", devices); |
| 714 NotifyDeviceListChanged(); | 677 NotifyDeviceListChanged(); |
| 715 } else { | 678 } else { |
| 716 NOTREACHED(); | 679 NOTREACHED(); |
| 717 } | 680 } |
| 718 } | 681 } |
| 719 | 682 |
| 683 void NetworkStateHandler::SortNetworkList() { | |
| 684 // Sort networks as follows, maintaining the existing relative ordering: | |
| 685 // * Connected or connecting networks (should be listed first by Shill) | |
| 686 // * Visible non-wifi networks | |
| 687 // * Visible wifi networks | |
| 688 // * Hidden (wifi) networks | |
| 689 // Also update UMA stats. | |
| 690 bool listing_active_networks = true; | |
| 691 ManagedStateList active, non_wifi_visible, wifi_visible, hidden; | |
| 692 for (ManagedStateList::iterator iter = network_list_.begin(); | |
| 693 iter != network_list_.end(); ++iter) { | |
| 694 NetworkState* network = (*iter)->AsNetworkState(); | |
| 695 if (network->IsConnectedState() || network->IsConnectingState()) { | |
| 696 active.push_back(network); | |
| 697 if (!listing_active_networks) { | |
| 698 NET_LOG_ERROR("Active network follows inactive network", | |
| 699 GetLogName(network)); | |
| 700 } | |
| 701 } else { | |
| 702 listing_active_networks = false; | |
| 703 if (network->visible()) { | |
| 704 if (NetworkTypePattern::WiFi().MatchesType(network->type())) | |
| 705 wifi_visible.push_back(network); | |
| 706 else | |
| 707 non_wifi_visible.push_back(network); | |
| 708 } else { | |
| 709 hidden.push_back(network); | |
| 710 } | |
| 711 } | |
| 712 } | |
| 713 // Update |network_list_|. | |
| 714 network_list_.clear(); | |
| 715 network_list_.insert(network_list_.end(), active.begin(), active.end()); | |
| 716 network_list_.insert( | |
| 717 network_list_.end(), non_wifi_visible.begin(), non_wifi_visible.end()); | |
| 718 network_list_.insert( | |
| 719 network_list_.end(), wifi_visible.begin(), wifi_visible.end()); | |
| 720 network_list_.insert(network_list_.end(), hidden.begin(), hidden.end()); | |
| 721 } | |
| 722 | |
| 723 void NetworkStateHandler::UpdateNetworkStats() { | |
| 724 size_t shared = 0, unshared = 0, visible = 0; | |
| 725 for (ManagedStateList::iterator iter = network_list_.begin(); | |
| 726 iter != network_list_.end(); ++iter) { | |
| 727 NetworkState* network = (*iter)->AsNetworkState(); | |
| 728 if (network->visible()) | |
| 729 ++visible; | |
| 730 if (network->IsInProfile()) { | |
| 731 if (network->IsPrivate()) | |
| 732 ++unshared; | |
| 733 else | |
| 734 ++shared; | |
| 735 } | |
| 736 } | |
| 737 UMA_HISTOGRAM_COUNTS_100("Networks.Visible", visible); | |
| 738 UMA_HISTOGRAM_COUNTS_100("Networks.RememberedShared", shared); | |
| 739 UMA_HISTOGRAM_COUNTS_100("Networks.RememberedUnshared", unshared); | |
| 740 } | |
| 741 | |
| 720 void NetworkStateHandler::DefaultNetworkServiceChanged( | 742 void NetworkStateHandler::DefaultNetworkServiceChanged( |
| 721 const std::string& service_path) { | 743 const std::string& service_path) { |
| 722 // Shill uses '/' for empty service path values; check explicitly for that. | 744 // Shill uses '/' for empty service path values; check explicitly for that. |
| 723 const char* kEmptyServicePath = "/"; | 745 const char* kEmptyServicePath = "/"; |
| 724 std::string new_service_path = | 746 std::string new_service_path = |
| 725 (service_path != kEmptyServicePath) ? service_path : ""; | 747 (service_path != kEmptyServicePath) ? service_path : ""; |
| 726 if (new_service_path == default_network_path_) | 748 if (new_service_path == default_network_path_) |
| 727 return; | 749 return; |
| 728 | 750 |
| 729 default_network_path_ = service_path; | 751 default_network_path_ = service_path; |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 910 if (type.MatchesType(shill::kTypeBluetooth)) | 932 if (type.MatchesType(shill::kTypeBluetooth)) |
| 911 technologies.push_back(new std::string(shill::kTypeBluetooth)); | 933 technologies.push_back(new std::string(shill::kTypeBluetooth)); |
| 912 if (type.MatchesType(shill::kTypeVPN)) | 934 if (type.MatchesType(shill::kTypeVPN)) |
| 913 technologies.push_back(new std::string(shill::kTypeVPN)); | 935 technologies.push_back(new std::string(shill::kTypeVPN)); |
| 914 | 936 |
| 915 CHECK_GT(technologies.size(), 0ul); | 937 CHECK_GT(technologies.size(), 0ul); |
| 916 return technologies.Pass(); | 938 return technologies.Pass(); |
| 917 } | 939 } |
| 918 | 940 |
| 919 } // namespace chromeos | 941 } // namespace chromeos |
| OLD | NEW |