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.
5 #include "chromeos/network/network_state_handler.h"
8 #include "base/format_macros.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"
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());
36 std::string GetManagedStateLogType(const ManagedState* state) {
37 switch (state->managed_type()) {
38 case ManagedState::MANAGED_TYPE_NETWORK:
40 case ManagedState::MANAGED_TYPE_DEVICE:
47 std::string GetLogName(const ManagedState* state) {
50 return base::StringPrintf("%s (%s)", state->name().c_str(),
51 state->path().c_str());
56 const char NetworkStateHandler::kDefaultCheckPortalList[] =
57 "ethernet,wifi,cellular";
59 NetworkStateHandler::NetworkStateHandler()
60 : network_list_sorted_(false) {
63 NetworkStateHandler::~NetworkStateHandler() {
64 FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_, IsShuttingDown());
65 STLDeleteContainerPointers(network_list_.begin(), network_list_.end());
66 STLDeleteContainerPointers(device_list_.begin(), device_list_.end());
69 void NetworkStateHandler::InitShillPropertyHandler() {
70 shill_property_handler_.reset(new internal::ShillPropertyHandler(this));
71 shill_property_handler_->Init();
75 NetworkStateHandler* NetworkStateHandler::InitializeForTest() {
76 NetworkStateHandler* handler = new NetworkStateHandler();
77 handler->InitShillPropertyHandler();
81 void NetworkStateHandler::AddObserver(
82 NetworkStateHandlerObserver* observer,
83 const tracked_objects::Location& from_here) {
84 observers_.AddObserver(observer);
85 network_event_log::internal::AddEntry(
86 from_here.file_name(), from_here.line_number(),
87 network_event_log::LOG_LEVEL_DEBUG,
88 "NetworkStateHandler::AddObserver", "");
91 void NetworkStateHandler::RemoveObserver(
92 NetworkStateHandlerObserver* observer,
93 const tracked_objects::Location& from_here) {
94 observers_.RemoveObserver(observer);
95 network_event_log::internal::AddEntry(
96 from_here.file_name(), from_here.line_number(),
97 network_event_log::LOG_LEVEL_DEBUG,
98 "NetworkStateHandler::RemoveObserver", "");
101 NetworkStateHandler::TechnologyState NetworkStateHandler::GetTechnologyState(
102 const NetworkTypePattern& type) const {
103 std::string technology = GetTechnologyForType(type);
104 TechnologyState state;
105 if (shill_property_handler_->IsTechnologyEnabled(technology))
106 state = TECHNOLOGY_ENABLED;
107 else if (shill_property_handler_->IsTechnologyEnabling(technology))
108 state = TECHNOLOGY_ENABLING;
109 else if (shill_property_handler_->IsTechnologyUninitialized(technology))
110 state = TECHNOLOGY_UNINITIALIZED;
111 else if (shill_property_handler_->IsTechnologyAvailable(technology))
112 state = TECHNOLOGY_AVAILABLE;
114 state = TECHNOLOGY_UNAVAILABLE;
115 VLOG(2) << "GetTechnologyState: " << type.ToDebugString() << " = " << state;
119 void NetworkStateHandler::SetTechnologyEnabled(
120 const NetworkTypePattern& type,
122 const network_handler::ErrorCallback& error_callback) {
123 ScopedVector<std::string> technologies = GetTechnologiesForType(type);
124 for (ScopedVector<std::string>::iterator it = technologies.begin();
125 it != technologies.end(); ++it) {
126 std::string* technology = *it;
128 if (!shill_property_handler_->IsTechnologyAvailable(*technology))
130 NET_LOG_USER("SetTechnologyEnabled",
131 base::StringPrintf("%s:%d", technology->c_str(), enabled));
132 shill_property_handler_->SetTechnologyEnabled(
133 *technology, enabled, error_callback);
135 // Signal Device/Technology state changed.
136 NotifyDeviceListChanged();
139 const DeviceState* NetworkStateHandler::GetDeviceState(
140 const std::string& device_path) const {
141 const DeviceState* device = GetModifiableDeviceState(device_path);
142 if (device && !device->update_received())
147 const DeviceState* NetworkStateHandler::GetDeviceStateByType(
148 const NetworkTypePattern& type) const {
149 for (ManagedStateList::const_iterator iter = device_list_.begin();
150 iter != device_list_.end(); ++iter) {
151 ManagedState* device = *iter;
152 if (!device->update_received())
154 if (device->Matches(type))
155 return device->AsDeviceState();
160 bool NetworkStateHandler::GetScanningByType(
161 const NetworkTypePattern& type) const {
162 for (ManagedStateList::const_iterator iter = device_list_.begin();
163 iter != device_list_.end(); ++iter) {
164 const DeviceState* device = (*iter)->AsDeviceState();
166 if (!device->update_received())
168 if (device->Matches(type) && device->scanning())
174 const NetworkState* NetworkStateHandler::GetNetworkState(
175 const std::string& service_path) const {
176 const NetworkState* network = GetModifiableNetworkState(service_path);
177 if (network && !network->update_received())
182 const NetworkState* NetworkStateHandler::DefaultNetwork() const {
183 if (default_network_path_.empty())
185 return GetNetworkState(default_network_path_);
188 const NetworkState* NetworkStateHandler::ConnectedNetworkByType(
189 const NetworkTypePattern& type) const {
190 // Active networks are always listed first by Shill so no need to sort.
191 for (ManagedStateList::const_iterator iter = network_list_.begin();
192 iter != network_list_.end(); ++iter) {
193 const NetworkState* network = (*iter)->AsNetworkState();
195 if (!network->update_received())
197 if (!network->IsConnectedState())
198 break; // Connected networks are listed first.
199 if (network->Matches(type))
205 const NetworkState* NetworkStateHandler::ConnectingNetworkByType(
206 const NetworkTypePattern& type) const {
207 // Active networks are always listed first by Shill so no need to sort.
208 for (ManagedStateList::const_iterator iter = network_list_.begin();
209 iter != network_list_.end(); ++iter) {
210 const NetworkState* network = (*iter)->AsNetworkState();
212 if (!network->update_received() || network->IsConnectedState())
214 if (!network->IsConnectingState())
215 break; // Connected and connecting networks are listed first.
216 if (network->Matches(type))
222 const NetworkState* NetworkStateHandler::FirstNetworkByType(
223 const NetworkTypePattern& type) {
224 if (!network_list_sorted_)
225 SortNetworkList(); // Sort to ensure visible networks are listed first.
226 for (ManagedStateList::const_iterator iter = network_list_.begin();
227 iter != network_list_.end(); ++iter) {
228 const NetworkState* network = (*iter)->AsNetworkState();
230 if (!network->update_received())
232 if (!network->visible())
234 if (network->Matches(type))
240 std::string NetworkStateHandler::FormattedHardwareAddressForType(
241 const NetworkTypePattern& type) const {
242 const DeviceState* device = NULL;
243 const NetworkState* network = ConnectedNetworkByType(type);
245 device = GetDeviceState(network->device_path());
247 device = GetDeviceStateByType(type);
249 return std::string();
250 return network_util::FormattedMacAddress(device->mac_address());
253 void NetworkStateHandler::GetVisibleNetworkListByType(
254 const NetworkTypePattern& type,
255 NetworkStateList* list) {
256 GetNetworkListByType(type,
257 false /* configured_only */,
258 true /* visible_only */,
263 void NetworkStateHandler::GetVisibleNetworkList(NetworkStateList* list) {
264 GetVisibleNetworkListByType(NetworkTypePattern::Default(), list);
267 void NetworkStateHandler::GetNetworkListByType(const NetworkTypePattern& type,
268 bool configured_only,
271 NetworkStateList* list) {
275 // Sort the network list if necessary.
276 if (!network_list_sorted_)
278 for (ManagedStateList::const_iterator iter = network_list_.begin();
279 iter != network_list_.end(); ++iter) {
280 const NetworkState* network = (*iter)->AsNetworkState();
282 if (!network->update_received() || !network->Matches(type))
284 if (configured_only && !network->IsInProfile())
286 if (visible_only && !network->visible())
288 list->push_back(network);
289 if (limit > 0 && ++count >= limit)
294 const NetworkState* NetworkStateHandler::GetNetworkStateFromServicePath(
295 const std::string& service_path,
296 bool configured_only) const {
297 ManagedState* managed =
298 GetModifiableManagedState(&network_list_, service_path);
301 const NetworkState* network = managed->AsNetworkState();
303 if (!network->update_received() ||
304 (configured_only && !network->IsInProfile())) {
310 const NetworkState* NetworkStateHandler::GetNetworkStateFromGuid(
311 const std::string& guid) const {
312 DCHECK(!guid.empty());
313 for (ManagedStateList::const_iterator iter = network_list_.begin();
314 iter != network_list_.end(); ++iter) {
315 const NetworkState* network = (*iter)->AsNetworkState();
316 if (network->guid() == guid)
322 void NetworkStateHandler::GetDeviceList(DeviceStateList* list) const {
323 GetDeviceListByType(NetworkTypePattern::Default(), list);
326 void NetworkStateHandler::GetDeviceListByType(const NetworkTypePattern& type,
327 DeviceStateList* list) const {
330 for (ManagedStateList::const_iterator iter = device_list_.begin();
331 iter != device_list_.end(); ++iter) {
332 const DeviceState* device = (*iter)->AsDeviceState();
334 if (device->update_received() && device->Matches(type))
335 list->push_back(device);
339 void NetworkStateHandler::RequestScan() const {
340 NET_LOG_USER("RequestScan", "");
341 shill_property_handler_->RequestScan();
344 void NetworkStateHandler::WaitForScan(const std::string& type,
345 const base::Closure& callback) {
346 scan_complete_callbacks_[type].push_back(callback);
347 if (!GetScanningByType(NetworkTypePattern::Primitive(type)))
351 void NetworkStateHandler::ConnectToBestWifiNetwork() {
352 NET_LOG_USER("ConnectToBestWifiNetwork", "");
353 WaitForScan(shill::kTypeWifi,
354 base::Bind(&internal::ShillPropertyHandler::ConnectToBestServices,
355 shill_property_handler_->AsWeakPtr()));
358 void NetworkStateHandler::RequestUpdateForNetwork(
359 const std::string& service_path) {
360 NetworkState* network = GetModifiableNetworkState(service_path);
362 network->set_update_requested(true);
363 NET_LOG_EVENT("RequestUpdate", service_path);
364 shill_property_handler_->RequestProperties(
365 ManagedState::MANAGED_TYPE_NETWORK, service_path);
368 void NetworkStateHandler::ClearLastErrorForNetwork(
369 const std::string& service_path) {
370 NetworkState* network = GetModifiableNetworkState(service_path);
372 network->clear_last_error();
375 void NetworkStateHandler::SetCheckPortalList(
376 const std::string& check_portal_list) {
377 NET_LOG_EVENT("SetCheckPortalList", check_portal_list);
378 shill_property_handler_->SetCheckPortalList(check_portal_list);
381 void NetworkStateHandler::SetWakeOnLanEnabled(bool enabled) {
382 NET_LOG_EVENT("SetWakeOnLanEnabled",
383 base::StringPrintf("%s", enabled ? "true" : "false"));
384 shill_property_handler_->SetWakeOnLanEnabled(enabled);
387 const NetworkState* NetworkStateHandler::GetEAPForEthernet(
388 const std::string& service_path) {
389 const NetworkState* network = GetNetworkState(service_path);
391 NET_LOG_ERROR("GetEAPForEthernet", "Unknown service path " + service_path);
394 if (network->type() != shill::kTypeEthernet) {
395 NET_LOG_ERROR("GetEAPForEthernet", "Not of type Ethernet: " + service_path);
398 if (!network->IsConnectedState())
401 // The same EAP service is shared for all ethernet services/devices.
402 // However EAP is used/enabled per device and only if the connection was
403 // successfully established.
404 const DeviceState* device = GetDeviceState(network->device_path());
408 base::StringPrintf("Unknown device %s of connected ethernet service %s",
409 network->device_path().c_str(),
410 service_path.c_str()));
413 if (!device->eap_authentication_completed())
416 NetworkStateList list;
417 GetNetworkListByType(NetworkTypePattern::Primitive(shill::kTypeEthernetEap),
418 true /* configured_only */,
419 false /* visible_only */,
423 NET_LOG_ERROR("GetEAPForEthernet",
425 "Ethernet service %s connected using EAP, but no "
426 "EAP service found.",
427 service_path.c_str()));
433 //------------------------------------------------------------------------------
434 // ShillPropertyHandler::Delegate overrides
436 void NetworkStateHandler::UpdateManagedList(ManagedState::ManagedType type,
437 const base::ListValue& entries) {
438 ManagedStateList* managed_list = GetManagedList(type);
439 NET_LOG_DEBUG("UpdateManagedList: " + ManagedState::TypeToString(type),
440 base::StringPrintf("%" PRIuS, entries.GetSize()));
441 // Create a map of existing entries. Assumes all entries in |managed_list|
443 typedef std::map<std::string, ManagedState*> ManagedMap;
444 ManagedMap managed_map;
445 for (ManagedStateList::iterator iter = managed_list->begin();
446 iter != managed_list->end(); ++iter) {
447 ManagedState* managed = *iter;
448 DCHECK(!ContainsKey(managed_map, managed->path()));
449 managed_map[managed->path()] = managed;
451 // Clear the list (pointers are temporarily owned by managed_map).
452 managed_list->clear();
453 // Updates managed_list and request updates for new entries.
454 std::set<std::string> list_entries;
455 for (base::ListValue::const_iterator iter = entries.begin();
456 iter != entries.end(); ++iter) {
458 (*iter)->GetAsString(&path);
459 if (path.empty() || path == shill::kFlimflamServicePath) {
460 NET_LOG_ERROR(base::StringPrintf("Bad path in list:%d", type), path);
463 ManagedMap::iterator found = managed_map.find(path);
464 if (found == managed_map.end()) {
465 if (list_entries.count(path) != 0) {
466 NET_LOG_ERROR("Duplicate entry in list", path);
469 ManagedState* managed = ManagedState::Create(type, path);
470 managed_list->push_back(managed);
472 managed_list->push_back(found->second);
473 managed_map.erase(found);
475 list_entries.insert(path);
477 // Delete any remaining entries in managed_map.
478 STLDeleteContainerPairSecondPointers(managed_map.begin(), managed_map.end());
481 void NetworkStateHandler::ProfileListChanged() {
482 NET_LOG_EVENT("ProfileListChanged", "Re-Requesting Network Properties");
483 for (ManagedStateList::iterator iter = network_list_.begin();
484 iter != network_list_.end(); ++iter) {
485 NetworkState* network = (*iter)->AsNetworkState();
487 shill_property_handler_->RequestProperties(
488 ManagedState::MANAGED_TYPE_NETWORK, network->path());
492 void NetworkStateHandler::UpdateManagedStateProperties(
493 ManagedState::ManagedType type,
494 const std::string& path,
495 const base::DictionaryValue& properties) {
496 ManagedStateList* managed_list = GetManagedList(type);
497 ManagedState* managed = GetModifiableManagedState(managed_list, path);
499 // The network has been removed from the list of networks.
500 NET_LOG_DEBUG("UpdateManagedStateProperties: Not found", path);
503 managed->set_update_received();
505 std::string desc = GetManagedStateLogType(managed) + " Properties Received";
506 NET_LOG_DEBUG(desc, GetLogName(managed));
508 if (type == ManagedState::MANAGED_TYPE_NETWORK) {
509 UpdateNetworkStateProperties(managed->AsNetworkState(), properties);
512 for (base::DictionaryValue::Iterator iter(properties);
513 !iter.IsAtEnd(); iter.Advance()) {
514 managed->PropertyChanged(iter.key(), iter.value());
516 managed->InitialPropertiesReceived(properties);
518 managed->set_update_requested(false);
521 void NetworkStateHandler::UpdateNetworkStateProperties(
522 NetworkState* network,
523 const base::DictionaryValue& properties) {
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;
532 network_property_updated |= network->InitialPropertiesReceived(properties);
534 network_list_sorted_ = false;
536 // Notify observers of NetworkState changes.
537 if (network_property_updated || network->update_requested()) {
538 // Signal connection state changed after all properties have been updated.
539 if (ConnectionStateChanged(network, prev_connection_state))
540 OnNetworkConnectionStateChanged(network);
541 NET_LOG_EVENT("NetworkPropertiesUpdated", GetLogName(network));
542 NotifyNetworkPropertiesUpdated(network);
546 void NetworkStateHandler::UpdateNetworkServiceProperty(
547 const std::string& service_path,
548 const std::string& key,
549 const base::Value& value) {
550 bool changed = false;
551 NetworkState* network = GetModifiableNetworkState(service_path);
554 std::string prev_connection_state = network->connection_state();
555 std::string prev_profile_path = network->profile_path();
556 changed |= network->PropertyChanged(key, value);
560 if (key == shill::kStateProperty || key == shill::kVisibleProperty) {
561 network_list_sorted_ = false;
562 if (ConnectionStateChanged(network, prev_connection_state)) {
563 OnNetworkConnectionStateChanged(network);
564 // If the connection state changes, other properties such as IPConfig
565 // may have changed, so request a full update.
566 RequestUpdateForNetwork(service_path);
569 std::string value_str;
570 value.GetAsString(&value_str);
571 // Some property changes are noisy and not interesting:
572 // * Wifi SignalStrength
573 // * WifiFrequencyList updates
574 // * Device property changes to "/" (occurs before a service is removed)
575 if (key != shill::kSignalStrengthProperty &&
576 key != shill::kWifiFrequencyListProperty &&
577 (key != shill::kDeviceProperty || value_str != "/")) {
578 std::string log_event = "NetworkPropertyUpdated";
579 // Trigger a default network update for interesting changes only.
580 if (network->path() == default_network_path_) {
581 NotifyDefaultNetworkChanged(network);
582 log_event = "Default" + log_event;
585 std::string detail = network->name() + "." + key;
586 detail += " = " + network_event_log::ValueAsString(value);
587 network_event_log::LogLevel log_level;
588 if (key == shill::kErrorProperty || key == shill::kErrorDetailsProperty) {
589 log_level = network_event_log::LOG_LEVEL_ERROR;
591 log_level = network_event_log::LOG_LEVEL_EVENT;
593 NET_LOG_LEVEL(log_level, log_event, detail);
597 // All property updates signal 'NetworkPropertiesUpdated'.
598 NotifyNetworkPropertiesUpdated(network);
600 // If added to a Profile, request a full update so that a NetworkState
602 if (prev_profile_path.empty() && !network->profile_path().empty())
603 RequestUpdateForNetwork(service_path);
606 void NetworkStateHandler::UpdateDeviceProperty(const std::string& device_path,
607 const std::string& key,
608 const base::Value& value) {
609 DeviceState* device = GetModifiableDeviceState(device_path);
612 if (!device->PropertyChanged(key, value))
615 std::string detail = device->name() + "." + key;
616 detail += " = " + network_event_log::ValueAsString(value);
617 NET_LOG_EVENT("DevicePropertyUpdated", detail);
619 NotifyDeviceListChanged();
620 NotifyDevicePropertiesUpdated(device);
622 if (key == shill::kScanningProperty && device->scanning() == false)
623 ScanCompleted(device->type());
624 if (key == shill::kEapAuthenticationCompletedProperty) {
625 // Notify a change for each Ethernet service using this device.
626 NetworkStateList ethernet_services;
627 GetNetworkListByType(NetworkTypePattern::Ethernet(),
628 false /* configured_only */,
629 false /* visible_only */,
632 for (NetworkStateList::const_iterator it = ethernet_services.begin();
633 it != ethernet_services.end(); ++it) {
634 const NetworkState* ethernet_service = *it;
635 if (ethernet_service->update_received() ||
636 ethernet_service->device_path() != device->path()) {
639 RequestUpdateForNetwork(ethernet_service->path());
644 void NetworkStateHandler::UpdateIPConfigProperties(
645 ManagedState::ManagedType type,
646 const std::string& path,
647 const std::string& ip_config_path,
648 const base::DictionaryValue& properties) {
649 if (type == ManagedState::MANAGED_TYPE_NETWORK) {
650 NetworkState* network = GetModifiableNetworkState(path);
653 network->IPConfigPropertiesChanged(properties);
654 NotifyNetworkPropertiesUpdated(network);
655 if (network->path() == default_network_path_)
656 NotifyDefaultNetworkChanged(network);
657 } else if (type == ManagedState::MANAGED_TYPE_DEVICE) {
658 DeviceState* device = GetModifiableDeviceState(path);
661 device->IPConfigPropertiesChanged(ip_config_path, properties);
662 NotifyDevicePropertiesUpdated(device);
663 if (!default_network_path_.empty()) {
664 const NetworkState* default_network =
665 GetNetworkState(default_network_path_);
666 if (default_network && default_network->device_path() == path)
667 NotifyDefaultNetworkChanged(default_network);
672 void NetworkStateHandler::CheckPortalListChanged(
673 const std::string& check_portal_list) {
674 check_portal_list_ = check_portal_list;
677 void NetworkStateHandler::TechnologyListChanged() {
678 // Eventually we would like to replace Technology state with Device state.
679 // For now, treat technology state changes as device list changes.
680 NotifyDeviceListChanged();
683 void NetworkStateHandler::ManagedStateListChanged(
684 ManagedState::ManagedType type) {
685 if (type == ManagedState::MANAGED_TYPE_NETWORK) {
687 UpdateNetworkStats();
688 // Notify observers that the list of networks has changed.
689 NET_LOG_EVENT("NOTIFY:NetworkListChanged",
690 base::StringPrintf("Size:%" PRIuS, network_list_.size()));
691 FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_,
692 NetworkListChanged());
693 } else if (type == ManagedState::MANAGED_TYPE_DEVICE) {
695 for (ManagedStateList::const_iterator iter = device_list_.begin();
696 iter != device_list_.end(); ++iter) {
697 if (iter != device_list_.begin())
699 devices += (*iter)->name();
701 NET_LOG_EVENT("DeviceList", devices);
702 NotifyDeviceListChanged();
708 void NetworkStateHandler::SortNetworkList() {
709 // Note: usually active networks will precede inactive networks, however
710 // this may briefly be untrue during state transitions (e.g. a network may
711 // transition to idle before the list is updated).
712 ManagedStateList active, non_wifi_visible, wifi_visible, hidden, new_networks;
713 for (ManagedStateList::iterator iter = network_list_.begin();
714 iter != network_list_.end(); ++iter) {
715 NetworkState* network = (*iter)->AsNetworkState();
716 if (!network->update_received()) {
717 new_networks.push_back(network);
720 if (network->IsConnectedState() || network->IsConnectingState()) {
721 active.push_back(network);
724 if (network->visible()) {
725 if (NetworkTypePattern::WiFi().MatchesType(network->type()))
726 wifi_visible.push_back(network);
728 non_wifi_visible.push_back(network);
730 hidden.push_back(network);
733 network_list_.clear();
734 network_list_.insert(network_list_.end(), active.begin(), active.end());
735 network_list_.insert(
736 network_list_.end(), non_wifi_visible.begin(), non_wifi_visible.end());
737 network_list_.insert(
738 network_list_.end(), wifi_visible.begin(), wifi_visible.end());
739 network_list_.insert(network_list_.end(), hidden.begin(), hidden.end());
740 network_list_.insert(
741 network_list_.end(), new_networks.begin(), new_networks.end());
742 network_list_sorted_ = true;
745 void NetworkStateHandler::UpdateNetworkStats() {
746 size_t shared = 0, unshared = 0, visible = 0;
747 for (ManagedStateList::iterator iter = network_list_.begin();
748 iter != network_list_.end(); ++iter) {
749 NetworkState* network = (*iter)->AsNetworkState();
750 if (network->visible())
752 if (network->IsInProfile()) {
753 if (network->IsPrivate())
759 UMA_HISTOGRAM_COUNTS_100("Networks.Visible", visible);
760 UMA_HISTOGRAM_COUNTS_100("Networks.RememberedShared", shared);
761 UMA_HISTOGRAM_COUNTS_100("Networks.RememberedUnshared", unshared);
764 void NetworkStateHandler::DefaultNetworkServiceChanged(
765 const std::string& service_path) {
766 // Shill uses '/' for empty service path values; check explicitly for that.
767 const char* kEmptyServicePath = "/";
768 std::string new_service_path =
769 (service_path != kEmptyServicePath) ? service_path : "";
770 if (new_service_path == default_network_path_)
773 default_network_path_ = service_path;
774 NET_LOG_EVENT("DefaultNetworkServiceChanged:", default_network_path_);
775 const NetworkState* network = NULL;
776 if (!default_network_path_.empty()) {
777 network = GetNetworkState(default_network_path_);
779 // If NetworkState is not available yet, do not notify observers here,
780 // they will be notified when the state is received.
781 NET_LOG_DEBUG("Default NetworkState not available",
782 default_network_path_);
786 if (network && !network->IsConnectedState()) {
788 "DefaultNetwork is not connected: " + network->connection_state(),
791 NotifyDefaultNetworkChanged(network);
794 //------------------------------------------------------------------------------
797 void NetworkStateHandler::UpdateGuid(NetworkState* network) {
798 std::string specifier = network->GetSpecifier();
799 DCHECK(!specifier.empty());
800 if (!network->guid().empty()) {
801 // If the network is saved in a profile, remove the entry from the map.
802 // Otherwise ensure that the entry matches the specified GUID. (e.g. in
803 // case a visible network with a specified guid gets configured with a
805 if (network->IsInProfile())
806 specifier_guid_map_.erase(specifier);
808 specifier_guid_map_[specifier] = network->guid();
811 // Ensure that the NetworkState has a valid GUID.
813 SpecifierGuidMap::iterator iter = specifier_guid_map_.find(specifier);
814 if (iter != specifier_guid_map_.end()) {
817 guid = base::GenerateGUID();
818 specifier_guid_map_[specifier] = guid;
820 network->SetGuid(guid);
823 void NetworkStateHandler::NotifyDeviceListChanged() {
824 NET_LOG_DEBUG("NOTIFY:DeviceListChanged",
825 base::StringPrintf("Size:%" PRIuS, device_list_.size()));
826 FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_,
827 DeviceListChanged());
830 DeviceState* NetworkStateHandler::GetModifiableDeviceState(
831 const std::string& device_path) const {
832 ManagedState* managed = GetModifiableManagedState(&device_list_, device_path);
835 return managed->AsDeviceState();
838 NetworkState* NetworkStateHandler::GetModifiableNetworkState(
839 const std::string& service_path) const {
840 ManagedState* managed =
841 GetModifiableManagedState(&network_list_, service_path);
844 return managed->AsNetworkState();
847 ManagedState* NetworkStateHandler::GetModifiableManagedState(
848 const ManagedStateList* managed_list,
849 const std::string& path) const {
850 for (ManagedStateList::const_iterator iter = managed_list->begin();
851 iter != managed_list->end(); ++iter) {
852 ManagedState* managed = *iter;
853 if (managed->path() == path)
859 NetworkStateHandler::ManagedStateList* NetworkStateHandler::GetManagedList(
860 ManagedState::ManagedType type) {
862 case ManagedState::MANAGED_TYPE_NETWORK:
863 return &network_list_;
864 case ManagedState::MANAGED_TYPE_DEVICE:
865 return &device_list_;
871 void NetworkStateHandler::OnNetworkConnectionStateChanged(
872 NetworkState* network) {
874 std::string event = "NetworkConnectionStateChanged";
875 if (network->path() == default_network_path_) {
876 event = "Default" + event;
877 if (!network->IsConnectedState()) {
879 "DefaultNetwork is not connected: " + network->connection_state(),
881 default_network_path_.clear();
883 NotifyDefaultNetworkChanged(NULL);
886 NET_LOG_EVENT("NOTIFY:" + event + ": " + network->connection_state(),
887 GetLogName(network));
888 FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_,
889 NetworkConnectionStateChanged(network));
890 if (network->path() == default_network_path_)
891 NotifyDefaultNetworkChanged(network);
894 void NetworkStateHandler::NotifyDefaultNetworkChanged(
895 const NetworkState* default_network) {
896 NET_LOG_EVENT("NOTIFY:DefaultNetworkChanged", GetLogName(default_network));
897 FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_,
898 DefaultNetworkChanged(default_network));
901 void NetworkStateHandler::NotifyNetworkPropertiesUpdated(
902 const NetworkState* network) {
903 NET_LOG_DEBUG("NOTIFY:NetworkPropertiesUpdated", GetLogName(network));
904 FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_,
905 NetworkPropertiesUpdated(network));
908 void NetworkStateHandler::NotifyDevicePropertiesUpdated(
909 const DeviceState* device) {
910 NET_LOG_DEBUG("NOTIFY:DevicePropertiesUpdated", GetLogName(device));
911 FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_,
912 DevicePropertiesUpdated(device));
915 void NetworkStateHandler::ScanCompleted(const std::string& type) {
916 size_t num_callbacks = scan_complete_callbacks_.count(type);
917 NET_LOG_EVENT("ScanCompleted",
918 base::StringPrintf("%s:%" PRIuS, type.c_str(), num_callbacks));
919 if (num_callbacks == 0)
921 ScanCallbackList& callback_list = scan_complete_callbacks_[type];
922 for (ScanCallbackList::iterator iter = callback_list.begin();
923 iter != callback_list.end(); ++iter) {
926 scan_complete_callbacks_.erase(type);
929 std::string NetworkStateHandler::GetTechnologyForType(
930 const NetworkTypePattern& type) const {
931 if (type.MatchesType(shill::kTypeEthernet))
932 return shill::kTypeEthernet;
934 if (type.MatchesType(shill::kTypeWifi))
935 return shill::kTypeWifi;
937 if (type.Equals(NetworkTypePattern::Wimax()))
938 return shill::kTypeWimax;
940 // Prefer Wimax over Cellular only if it's available.
941 if (type.MatchesType(shill::kTypeWimax) &&
942 shill_property_handler_->IsTechnologyAvailable(shill::kTypeWimax)) {
943 return shill::kTypeWimax;
946 if (type.MatchesType(shill::kTypeCellular))
947 return shill::kTypeCellular;
950 return std::string();
953 ScopedVector<std::string> NetworkStateHandler::GetTechnologiesForType(
954 const NetworkTypePattern& type) const {
955 ScopedVector<std::string> technologies;
956 if (type.MatchesType(shill::kTypeEthernet))
957 technologies.push_back(new std::string(shill::kTypeEthernet));
958 if (type.MatchesType(shill::kTypeWifi))
959 technologies.push_back(new std::string(shill::kTypeWifi));
960 if (type.MatchesType(shill::kTypeWimax))
961 technologies.push_back(new std::string(shill::kTypeWimax));
962 if (type.MatchesType(shill::kTypeCellular))
963 technologies.push_back(new std::string(shill::kTypeCellular));
964 if (type.MatchesType(shill::kTypeBluetooth))
965 technologies.push_back(new std::string(shill::kTypeBluetooth));
966 if (type.MatchesType(shill::kTypeVPN))
967 technologies.push_back(new std::string(shill::kTypeVPN));
969 CHECK_GT(technologies.size(), 0ul);
970 return technologies.Pass();
973 } // namespace chromeos