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/json/json_string_value_serializer.h"
11 #include "base/json/json_writer.h"
12 #include "base/location.h"
13 #include "base/logging.h"
14 #include "base/metrics/histogram.h"
15 #include "base/stl_util.h"
16 #include "base/strings/string_util.h"
17 #include "base/strings/stringprintf.h"
18 #include "base/values.h"
19 #include "chromeos/network/device_state.h"
20 #include "chromeos/network/managed_state.h"
21 #include "chromeos/network/network_event_log.h"
22 #include "chromeos/network/network_state.h"
23 #include "chromeos/network/network_state_handler_observer.h"
24 #include "chromeos/network/shill_property_handler.h"
25 #include "third_party/cros_system_api/dbus/service_constants.h"
31 bool ConnectionStateChanged(NetworkState
* network
,
32 const std::string
& prev_connection_state
,
33 bool prev_is_captive_portal
) {
34 return ((network
->connection_state() != prev_connection_state
) &&
35 !((network
->connection_state() == shill::kStateIdle
) &&
36 prev_connection_state
.empty())) ||
37 (network
->is_captive_portal() != prev_is_captive_portal
);
40 std::string
GetManagedStateLogType(const ManagedState
* state
) {
41 switch (state
->managed_type()) {
42 case ManagedState::MANAGED_TYPE_NETWORK
:
44 case ManagedState::MANAGED_TYPE_DEVICE
:
51 std::string
GetLogName(const ManagedState
* state
) {
54 return base::StringPrintf("%s (%s)", state
->name().c_str(),
55 state
->path().c_str());
58 std::string
ValueAsString(const base::Value
& value
) {
60 base::JSONWriter::WriteWithOptions(
61 &value
, base::JSONWriter::OPTIONS_OMIT_BINARY_VALUES
, &vstr
);
62 return vstr
.empty() ? "''" : vstr
;
67 const char NetworkStateHandler::kDefaultCheckPortalList
[] =
68 "ethernet,wifi,cellular";
70 NetworkStateHandler::NetworkStateHandler()
71 : network_list_sorted_(false) {
74 NetworkStateHandler::~NetworkStateHandler() {
75 FOR_EACH_OBSERVER(NetworkStateHandlerObserver
, observers_
, IsShuttingDown());
76 STLDeleteContainerPointers(network_list_
.begin(), network_list_
.end());
77 STLDeleteContainerPointers(device_list_
.begin(), device_list_
.end());
80 void NetworkStateHandler::InitShillPropertyHandler() {
81 shill_property_handler_
.reset(new internal::ShillPropertyHandler(this));
82 shill_property_handler_
->Init();
86 NetworkStateHandler
* NetworkStateHandler::InitializeForTest() {
87 NetworkStateHandler
* handler
= new NetworkStateHandler();
88 handler
->InitShillPropertyHandler();
92 void NetworkStateHandler::AddObserver(
93 NetworkStateHandlerObserver
* observer
,
94 const tracked_objects::Location
& from_here
) {
95 observers_
.AddObserver(observer
);
96 device_event_log::AddEntry(from_here
.file_name(), from_here
.line_number(),
97 device_event_log::LOG_TYPE_NETWORK
,
98 device_event_log::LOG_LEVEL_DEBUG
,
99 "NetworkStateHandler::AddObserver");
102 void NetworkStateHandler::RemoveObserver(
103 NetworkStateHandlerObserver
* observer
,
104 const tracked_objects::Location
& from_here
) {
105 observers_
.RemoveObserver(observer
);
106 device_event_log::AddEntry(from_here
.file_name(), from_here
.line_number(),
107 device_event_log::LOG_TYPE_NETWORK
,
108 device_event_log::LOG_LEVEL_DEBUG
,
109 "NetworkStateHandler::RemoveObserver");
112 NetworkStateHandler::TechnologyState
NetworkStateHandler::GetTechnologyState(
113 const NetworkTypePattern
& type
) const {
114 std::string technology
= GetTechnologyForType(type
);
115 TechnologyState state
;
116 if (shill_property_handler_
->IsTechnologyEnabled(technology
))
117 state
= TECHNOLOGY_ENABLED
;
118 else if (shill_property_handler_
->IsTechnologyEnabling(technology
))
119 state
= TECHNOLOGY_ENABLING
;
120 else if (shill_property_handler_
->IsTechnologyUninitialized(technology
))
121 state
= TECHNOLOGY_UNINITIALIZED
;
122 else if (shill_property_handler_
->IsTechnologyAvailable(technology
))
123 state
= TECHNOLOGY_AVAILABLE
;
125 state
= TECHNOLOGY_UNAVAILABLE
;
126 VLOG(2) << "GetTechnologyState: " << type
.ToDebugString() << " = " << state
;
130 void NetworkStateHandler::SetTechnologyEnabled(
131 const NetworkTypePattern
& type
,
133 const network_handler::ErrorCallback
& error_callback
) {
134 ScopedVector
<std::string
> technologies
= GetTechnologiesForType(type
);
135 for (ScopedVector
<std::string
>::iterator it
= technologies
.begin();
136 it
!= technologies
.end(); ++it
) {
137 std::string
* technology
= *it
;
139 if (!shill_property_handler_
->IsTechnologyAvailable(*technology
))
141 NET_LOG_USER("SetTechnologyEnabled",
142 base::StringPrintf("%s:%d", technology
->c_str(), enabled
));
143 shill_property_handler_
->SetTechnologyEnabled(
144 *technology
, enabled
, error_callback
);
146 // Signal Device/Technology state changed.
147 NotifyDeviceListChanged();
150 const DeviceState
* NetworkStateHandler::GetDeviceState(
151 const std::string
& device_path
) const {
152 const DeviceState
* device
= GetModifiableDeviceState(device_path
);
153 if (device
&& !device
->update_received())
158 const DeviceState
* NetworkStateHandler::GetDeviceStateByType(
159 const NetworkTypePattern
& type
) const {
160 for (ManagedStateList::const_iterator iter
= device_list_
.begin();
161 iter
!= device_list_
.end(); ++iter
) {
162 ManagedState
* device
= *iter
;
163 if (!device
->update_received())
165 if (device
->Matches(type
))
166 return device
->AsDeviceState();
171 bool NetworkStateHandler::GetScanningByType(
172 const NetworkTypePattern
& type
) const {
173 for (ManagedStateList::const_iterator iter
= device_list_
.begin();
174 iter
!= device_list_
.end(); ++iter
) {
175 const DeviceState
* device
= (*iter
)->AsDeviceState();
177 if (!device
->update_received())
179 if (device
->Matches(type
) && device
->scanning())
185 const NetworkState
* NetworkStateHandler::GetNetworkState(
186 const std::string
& service_path
) const {
187 const NetworkState
* network
= GetModifiableNetworkState(service_path
);
188 if (network
&& !network
->update_received())
193 const NetworkState
* NetworkStateHandler::DefaultNetwork() const {
194 if (default_network_path_
.empty())
196 return GetNetworkState(default_network_path_
);
199 const NetworkState
* NetworkStateHandler::ConnectedNetworkByType(
200 const NetworkTypePattern
& type
) const {
201 // Active networks are always listed first by Shill so no need to sort.
202 for (ManagedStateList::const_iterator iter
= network_list_
.begin();
203 iter
!= network_list_
.end(); ++iter
) {
204 const NetworkState
* network
= (*iter
)->AsNetworkState();
206 if (!network
->update_received())
208 if (!network
->IsConnectedState())
209 break; // Connected networks are listed first.
210 if (network
->Matches(type
))
216 const NetworkState
* NetworkStateHandler::ConnectingNetworkByType(
217 const NetworkTypePattern
& type
) const {
218 // Active networks are always listed first by Shill so no need to sort.
219 for (ManagedStateList::const_iterator iter
= network_list_
.begin();
220 iter
!= network_list_
.end(); ++iter
) {
221 const NetworkState
* network
= (*iter
)->AsNetworkState();
223 if (!network
->update_received() || network
->IsConnectedState())
225 if (!network
->IsConnectingState())
226 break; // Connected and connecting networks are listed first.
227 if (network
->Matches(type
))
233 const NetworkState
* NetworkStateHandler::FirstNetworkByType(
234 const NetworkTypePattern
& type
) {
235 if (!network_list_sorted_
)
236 SortNetworkList(); // Sort to ensure visible networks are listed first.
237 for (ManagedStateList::const_iterator iter
= network_list_
.begin();
238 iter
!= network_list_
.end(); ++iter
) {
239 const NetworkState
* network
= (*iter
)->AsNetworkState();
241 if (!network
->update_received())
243 if (!network
->visible())
245 if (network
->Matches(type
))
251 std::string
NetworkStateHandler::FormattedHardwareAddressForType(
252 const NetworkTypePattern
& type
) const {
253 const DeviceState
* device
= NULL
;
254 const NetworkState
* network
= ConnectedNetworkByType(type
);
256 device
= GetDeviceState(network
->device_path());
258 device
= GetDeviceStateByType(type
);
260 return std::string();
261 return network_util::FormattedMacAddress(device
->mac_address());
264 void NetworkStateHandler::GetVisibleNetworkListByType(
265 const NetworkTypePattern
& type
,
266 NetworkStateList
* list
) {
267 GetNetworkListByType(type
,
268 false /* configured_only */,
269 true /* visible_only */,
274 void NetworkStateHandler::GetVisibleNetworkList(NetworkStateList
* list
) {
275 GetVisibleNetworkListByType(NetworkTypePattern::Default(), list
);
278 void NetworkStateHandler::GetNetworkListByType(const NetworkTypePattern
& type
,
279 bool configured_only
,
282 NetworkStateList
* list
) {
286 // Sort the network list if necessary.
287 if (!network_list_sorted_
)
289 for (ManagedStateList::const_iterator iter
= network_list_
.begin();
290 iter
!= network_list_
.end(); ++iter
) {
291 const NetworkState
* network
= (*iter
)->AsNetworkState();
293 if (!network
->update_received() || !network
->Matches(type
))
295 if (configured_only
&& !network
->IsInProfile())
297 if (visible_only
&& !network
->visible())
299 list
->push_back(network
);
300 if (limit
> 0 && ++count
>= limit
)
305 const NetworkState
* NetworkStateHandler::GetNetworkStateFromServicePath(
306 const std::string
& service_path
,
307 bool configured_only
) const {
308 ManagedState
* managed
=
309 GetModifiableManagedState(&network_list_
, service_path
);
312 const NetworkState
* network
= managed
->AsNetworkState();
314 if (!network
->update_received() ||
315 (configured_only
&& !network
->IsInProfile())) {
321 const NetworkState
* NetworkStateHandler::GetNetworkStateFromGuid(
322 const std::string
& guid
) const {
323 DCHECK(!guid
.empty());
324 for (ManagedStateList::const_iterator iter
= network_list_
.begin();
325 iter
!= network_list_
.end(); ++iter
) {
326 const NetworkState
* network
= (*iter
)->AsNetworkState();
327 if (network
->guid() == guid
)
333 void NetworkStateHandler::GetDeviceList(DeviceStateList
* list
) const {
334 GetDeviceListByType(NetworkTypePattern::Default(), list
);
337 void NetworkStateHandler::GetDeviceListByType(const NetworkTypePattern
& type
,
338 DeviceStateList
* list
) const {
341 for (ManagedStateList::const_iterator iter
= device_list_
.begin();
342 iter
!= device_list_
.end(); ++iter
) {
343 const DeviceState
* device
= (*iter
)->AsDeviceState();
345 if (device
->update_received() && device
->Matches(type
))
346 list
->push_back(device
);
350 void NetworkStateHandler::RequestScan() const {
351 NET_LOG_USER("RequestScan", "");
352 shill_property_handler_
->RequestScan();
355 void NetworkStateHandler::RequestUpdateForNetwork(
356 const std::string
& service_path
) {
357 NetworkState
* network
= GetModifiableNetworkState(service_path
);
359 network
->set_update_requested(true);
360 NET_LOG_EVENT("RequestUpdate", service_path
);
361 shill_property_handler_
->RequestProperties(
362 ManagedState::MANAGED_TYPE_NETWORK
, service_path
);
365 void NetworkStateHandler::ClearLastErrorForNetwork(
366 const std::string
& service_path
) {
367 NetworkState
* network
= GetModifiableNetworkState(service_path
);
369 network
->clear_last_error();
372 void NetworkStateHandler::SetCheckPortalList(
373 const std::string
& check_portal_list
) {
374 NET_LOG_EVENT("SetCheckPortalList", check_portal_list
);
375 shill_property_handler_
->SetCheckPortalList(check_portal_list
);
378 void NetworkStateHandler::SetWakeOnLanEnabled(bool enabled
) {
379 NET_LOG_EVENT("SetWakeOnLanEnabled",
380 base::StringPrintf("%s", enabled
? "true" : "false"));
381 shill_property_handler_
->SetWakeOnLanEnabled(enabled
);
384 const NetworkState
* NetworkStateHandler::GetEAPForEthernet(
385 const std::string
& service_path
) {
386 const NetworkState
* network
= GetNetworkState(service_path
);
388 NET_LOG_ERROR("GetEAPForEthernet", "Unknown service path " + service_path
);
391 if (network
->type() != shill::kTypeEthernet
) {
392 NET_LOG_ERROR("GetEAPForEthernet", "Not of type Ethernet: " + service_path
);
395 if (!network
->IsConnectedState())
398 // The same EAP service is shared for all ethernet services/devices.
399 // However EAP is used/enabled per device and only if the connection was
400 // successfully established.
401 const DeviceState
* device
= GetDeviceState(network
->device_path());
405 base::StringPrintf("Unknown device %s of connected ethernet service %s",
406 network
->device_path().c_str(),
407 service_path
.c_str()));
410 if (!device
->eap_authentication_completed())
413 NetworkStateList list
;
414 GetNetworkListByType(NetworkTypePattern::Primitive(shill::kTypeEthernetEap
),
415 true /* configured_only */,
416 false /* visible_only */,
420 NET_LOG_ERROR("GetEAPForEthernet",
422 "Ethernet service %s connected using EAP, but no "
423 "EAP service found.",
424 service_path
.c_str()));
430 //------------------------------------------------------------------------------
431 // ShillPropertyHandler::Delegate overrides
433 void NetworkStateHandler::UpdateManagedList(ManagedState::ManagedType type
,
434 const base::ListValue
& entries
) {
435 ManagedStateList
* managed_list
= GetManagedList(type
);
436 NET_LOG_DEBUG("UpdateManagedList: " + ManagedState::TypeToString(type
),
437 base::StringPrintf("%" PRIuS
, entries
.GetSize()));
438 // Create a map of existing entries. Assumes all entries in |managed_list|
440 typedef std::map
<std::string
, ManagedState
*> ManagedMap
;
441 ManagedMap managed_map
;
442 for (ManagedStateList::iterator iter
= managed_list
->begin();
443 iter
!= managed_list
->end(); ++iter
) {
444 ManagedState
* managed
= *iter
;
445 DCHECK(!ContainsKey(managed_map
, managed
->path()));
446 managed_map
[managed
->path()] = managed
;
448 // Clear the list (pointers are temporarily owned by managed_map).
449 managed_list
->clear();
450 // Updates managed_list and request updates for new entries.
451 std::set
<std::string
> list_entries
;
452 for (base::ListValue::const_iterator iter
= entries
.begin();
453 iter
!= entries
.end(); ++iter
) {
455 (*iter
)->GetAsString(&path
);
456 if (path
.empty() || path
== shill::kFlimflamServicePath
) {
457 NET_LOG_ERROR(base::StringPrintf("Bad path in list:%d", type
), path
);
460 ManagedMap::iterator found
= managed_map
.find(path
);
461 if (found
== managed_map
.end()) {
462 if (list_entries
.count(path
) != 0) {
463 NET_LOG_ERROR("Duplicate entry in list", path
);
466 ManagedState
* managed
= ManagedState::Create(type
, path
);
467 managed_list
->push_back(managed
);
469 managed_list
->push_back(found
->second
);
470 managed_map
.erase(found
);
472 list_entries
.insert(path
);
474 // Delete any remaining entries in managed_map.
475 STLDeleteContainerPairSecondPointers(managed_map
.begin(), managed_map
.end());
478 void NetworkStateHandler::ProfileListChanged() {
479 NET_LOG_EVENT("ProfileListChanged", "Re-Requesting Network Properties");
480 for (ManagedStateList::iterator iter
= network_list_
.begin();
481 iter
!= network_list_
.end(); ++iter
) {
482 NetworkState
* network
= (*iter
)->AsNetworkState();
484 shill_property_handler_
->RequestProperties(
485 ManagedState::MANAGED_TYPE_NETWORK
, network
->path());
489 void NetworkStateHandler::UpdateManagedStateProperties(
490 ManagedState::ManagedType type
,
491 const std::string
& path
,
492 const base::DictionaryValue
& properties
) {
493 ManagedStateList
* managed_list
= GetManagedList(type
);
494 ManagedState
* managed
= GetModifiableManagedState(managed_list
, path
);
496 // The network has been removed from the list of networks.
497 NET_LOG_DEBUG("UpdateManagedStateProperties: Not found", path
);
500 managed
->set_update_received();
502 std::string desc
= GetManagedStateLogType(managed
) + " Properties Received";
503 NET_LOG_DEBUG(desc
, GetLogName(managed
));
505 if (type
== ManagedState::MANAGED_TYPE_NETWORK
) {
506 UpdateNetworkStateProperties(managed
->AsNetworkState(), properties
);
509 for (base::DictionaryValue::Iterator
iter(properties
);
510 !iter
.IsAtEnd(); iter
.Advance()) {
511 managed
->PropertyChanged(iter
.key(), iter
.value());
513 managed
->InitialPropertiesReceived(properties
);
515 managed
->set_update_requested(false);
518 void NetworkStateHandler::UpdateNetworkStateProperties(
519 NetworkState
* network
,
520 const base::DictionaryValue
& properties
) {
522 bool network_property_updated
= false;
523 std::string prev_connection_state
= network
->connection_state();
524 bool prev_is_captive_portal
= network
->is_captive_portal();
525 for (base::DictionaryValue::Iterator
iter(properties
);
526 !iter
.IsAtEnd(); iter
.Advance()) {
527 if (network
->PropertyChanged(iter
.key(), iter
.value()))
528 network_property_updated
= true;
530 network_property_updated
|= network
->InitialPropertiesReceived(properties
);
532 network_list_sorted_
= false;
534 // Notify observers of NetworkState changes.
535 if (network_property_updated
|| network
->update_requested()) {
536 // Signal connection state changed after all properties have been updated.
537 if (ConnectionStateChanged(network
, prev_connection_state
,
538 prev_is_captive_portal
)) {
539 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 SCOPED_NET_LOG_IF_SLOW();
551 bool changed
= false;
552 NetworkState
* network
= GetModifiableNetworkState(service_path
);
555 std::string prev_connection_state
= network
->connection_state();
556 bool prev_is_captive_portal
= network
->is_captive_portal();
557 std::string prev_profile_path
= network
->profile_path();
558 changed
|= network
->PropertyChanged(key
, value
);
562 if (key
== shill::kStateProperty
|| key
== shill::kVisibleProperty
) {
563 network_list_sorted_
= false;
564 if (ConnectionStateChanged(network
, prev_connection_state
,
565 prev_is_captive_portal
)) {
566 OnNetworkConnectionStateChanged(network
);
567 // If the connection state changes, other properties such as IPConfig
568 // may have changed, so request a full update.
569 RequestUpdateForNetwork(service_path
);
572 std::string value_str
;
573 value
.GetAsString(&value_str
);
574 // Some property changes are noisy and not interesting:
575 // * Wifi SignalStrength
576 // * WifiFrequencyList updates
577 // * Device property changes to "/" (occurs before a service is removed)
578 if (key
!= shill::kSignalStrengthProperty
&&
579 key
!= shill::kWifiFrequencyListProperty
&&
580 (key
!= shill::kDeviceProperty
|| value_str
!= "/")) {
581 std::string log_event
= "NetworkPropertyUpdated";
582 // Trigger a default network update for interesting changes only.
583 if (network
->path() == default_network_path_
) {
584 NotifyDefaultNetworkChanged(network
);
585 log_event
= "Default" + log_event
;
588 std::string detail
= network
->name() + "." + key
;
589 detail
+= " = " + ValueAsString(value
);
590 device_event_log::LogLevel log_level
;
591 if (key
== shill::kErrorProperty
|| key
== shill::kErrorDetailsProperty
) {
592 log_level
= device_event_log::LOG_LEVEL_ERROR
;
594 log_level
= device_event_log::LOG_LEVEL_EVENT
;
596 NET_LOG_LEVEL(log_level
, log_event
, detail
);
600 // All property updates signal 'NetworkPropertiesUpdated'.
601 NotifyNetworkPropertiesUpdated(network
);
603 // If added to a Profile, request a full update so that a NetworkState
605 if (prev_profile_path
.empty() && !network
->profile_path().empty())
606 RequestUpdateForNetwork(service_path
);
609 void NetworkStateHandler::UpdateDeviceProperty(const std::string
& device_path
,
610 const std::string
& key
,
611 const base::Value
& value
) {
612 SCOPED_NET_LOG_IF_SLOW();
613 DeviceState
* device
= GetModifiableDeviceState(device_path
);
616 if (!device
->PropertyChanged(key
, value
))
619 std::string detail
= device
->name() + "." + key
;
620 detail
+= " = " + ValueAsString(value
);
621 NET_LOG_EVENT("DevicePropertyUpdated", detail
);
623 NotifyDeviceListChanged();
624 NotifyDevicePropertiesUpdated(device
);
626 if (key
== shill::kScanningProperty
&& device
->scanning() == false) {
627 NotifyScanCompleted(device
);
629 if (key
== shill::kEapAuthenticationCompletedProperty
) {
630 // Notify a change for each Ethernet service using this device.
631 NetworkStateList ethernet_services
;
632 GetNetworkListByType(NetworkTypePattern::Ethernet(),
633 false /* configured_only */,
634 false /* visible_only */,
637 for (NetworkStateList::const_iterator it
= ethernet_services
.begin();
638 it
!= ethernet_services
.end(); ++it
) {
639 const NetworkState
* ethernet_service
= *it
;
640 if (ethernet_service
->update_received() ||
641 ethernet_service
->device_path() != device
->path()) {
644 RequestUpdateForNetwork(ethernet_service
->path());
649 void NetworkStateHandler::UpdateIPConfigProperties(
650 ManagedState::ManagedType type
,
651 const std::string
& path
,
652 const std::string
& ip_config_path
,
653 const base::DictionaryValue
& properties
) {
654 if (type
== ManagedState::MANAGED_TYPE_NETWORK
) {
655 NetworkState
* network
= GetModifiableNetworkState(path
);
658 network
->IPConfigPropertiesChanged(properties
);
659 NotifyNetworkPropertiesUpdated(network
);
660 if (network
->path() == default_network_path_
)
661 NotifyDefaultNetworkChanged(network
);
662 } else if (type
== ManagedState::MANAGED_TYPE_DEVICE
) {
663 DeviceState
* device
= GetModifiableDeviceState(path
);
666 device
->IPConfigPropertiesChanged(ip_config_path
, properties
);
667 NotifyDevicePropertiesUpdated(device
);
668 if (!default_network_path_
.empty()) {
669 const NetworkState
* default_network
=
670 GetNetworkState(default_network_path_
);
671 if (default_network
&& default_network
->device_path() == path
)
672 NotifyDefaultNetworkChanged(default_network
);
677 void NetworkStateHandler::CheckPortalListChanged(
678 const std::string
& check_portal_list
) {
679 check_portal_list_
= check_portal_list
;
682 void NetworkStateHandler::TechnologyListChanged() {
683 // Eventually we would like to replace Technology state with Device state.
684 // For now, treat technology state changes as device list changes.
685 NotifyDeviceListChanged();
688 void NetworkStateHandler::ManagedStateListChanged(
689 ManagedState::ManagedType type
) {
690 SCOPED_NET_LOG_IF_SLOW();
691 if (type
== ManagedState::MANAGED_TYPE_NETWORK
) {
693 UpdateNetworkStats();
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 } else if (type
== ManagedState::MANAGED_TYPE_DEVICE
) {
701 for (ManagedStateList::const_iterator iter
= device_list_
.begin();
702 iter
!= device_list_
.end(); ++iter
) {
703 if (iter
!= device_list_
.begin())
705 devices
+= (*iter
)->name();
707 NET_LOG_EVENT("DeviceList", devices
);
708 NotifyDeviceListChanged();
714 void NetworkStateHandler::SortNetworkList() {
715 // Note: usually active networks will precede inactive networks, however
716 // this may briefly be untrue during state transitions (e.g. a network may
717 // transition to idle before the list is updated).
718 ManagedStateList active
, non_wifi_visible
, wifi_visible
, hidden
, new_networks
;
719 for (ManagedStateList::iterator iter
= network_list_
.begin();
720 iter
!= network_list_
.end(); ++iter
) {
721 NetworkState
* network
= (*iter
)->AsNetworkState();
722 if (!network
->update_received()) {
723 new_networks
.push_back(network
);
726 if (network
->IsConnectedState() || network
->IsConnectingState()) {
727 active
.push_back(network
);
730 if (network
->visible()) {
731 if (NetworkTypePattern::WiFi().MatchesType(network
->type()))
732 wifi_visible
.push_back(network
);
734 non_wifi_visible
.push_back(network
);
736 hidden
.push_back(network
);
739 network_list_
.clear();
740 network_list_
.insert(network_list_
.end(), active
.begin(), active
.end());
741 network_list_
.insert(
742 network_list_
.end(), non_wifi_visible
.begin(), non_wifi_visible
.end());
743 network_list_
.insert(
744 network_list_
.end(), wifi_visible
.begin(), wifi_visible
.end());
745 network_list_
.insert(network_list_
.end(), hidden
.begin(), hidden
.end());
746 network_list_
.insert(
747 network_list_
.end(), new_networks
.begin(), new_networks
.end());
748 network_list_sorted_
= true;
751 void NetworkStateHandler::UpdateNetworkStats() {
752 size_t shared
= 0, unshared
= 0, visible
= 0;
753 for (ManagedStateList::iterator iter
= network_list_
.begin();
754 iter
!= network_list_
.end(); ++iter
) {
755 NetworkState
* network
= (*iter
)->AsNetworkState();
756 if (network
->visible())
758 if (network
->IsInProfile()) {
759 if (network
->IsPrivate())
765 UMA_HISTOGRAM_COUNTS_100("Networks.Visible", visible
);
766 UMA_HISTOGRAM_COUNTS_100("Networks.RememberedShared", shared
);
767 UMA_HISTOGRAM_COUNTS_100("Networks.RememberedUnshared", unshared
);
770 void NetworkStateHandler::DefaultNetworkServiceChanged(
771 const std::string
& service_path
) {
772 // Shill uses '/' for empty service path values; check explicitly for that.
773 const char* kEmptyServicePath
= "/";
774 std::string new_service_path
=
775 (service_path
!= kEmptyServicePath
) ? service_path
: "";
776 if (new_service_path
== default_network_path_
)
779 default_network_path_
= service_path
;
780 NET_LOG_EVENT("DefaultNetworkServiceChanged:", default_network_path_
);
781 const NetworkState
* network
= NULL
;
782 if (!default_network_path_
.empty()) {
783 network
= GetNetworkState(default_network_path_
);
785 // If NetworkState is not available yet, do not notify observers here,
786 // they will be notified when the state is received.
787 NET_LOG_DEBUG("Default NetworkState not available",
788 default_network_path_
);
792 if (network
&& !network
->IsConnectedState()) {
794 "DefaultNetwork is not connected: " + network
->connection_state(),
797 NotifyDefaultNetworkChanged(network
);
800 //------------------------------------------------------------------------------
803 void NetworkStateHandler::UpdateGuid(NetworkState
* network
) {
804 std::string specifier
= network
->GetSpecifier();
805 DCHECK(!specifier
.empty());
806 if (!network
->guid().empty()) {
807 // If the network is saved in a profile, remove the entry from the map.
808 // Otherwise ensure that the entry matches the specified GUID. (e.g. in
809 // case a visible network with a specified guid gets configured with a
811 if (network
->IsInProfile())
812 specifier_guid_map_
.erase(specifier
);
814 specifier_guid_map_
[specifier
] = network
->guid();
817 // Ensure that the NetworkState has a valid GUID.
819 SpecifierGuidMap::iterator iter
= specifier_guid_map_
.find(specifier
);
820 if (iter
!= specifier_guid_map_
.end()) {
823 guid
= base::GenerateGUID();
824 specifier_guid_map_
[specifier
] = guid
;
826 network
->SetGuid(guid
);
829 void NetworkStateHandler::NotifyDeviceListChanged() {
830 SCOPED_NET_LOG_IF_SLOW();
831 NET_LOG_DEBUG("NOTIFY:DeviceListChanged",
832 base::StringPrintf("Size:%" PRIuS
, device_list_
.size()));
833 FOR_EACH_OBSERVER(NetworkStateHandlerObserver
, observers_
,
834 DeviceListChanged());
837 DeviceState
* NetworkStateHandler::GetModifiableDeviceState(
838 const std::string
& device_path
) const {
839 ManagedState
* managed
= GetModifiableManagedState(&device_list_
, device_path
);
842 return managed
->AsDeviceState();
845 NetworkState
* NetworkStateHandler::GetModifiableNetworkState(
846 const std::string
& service_path
) const {
847 ManagedState
* managed
=
848 GetModifiableManagedState(&network_list_
, service_path
);
851 return managed
->AsNetworkState();
854 ManagedState
* NetworkStateHandler::GetModifiableManagedState(
855 const ManagedStateList
* managed_list
,
856 const std::string
& path
) const {
857 for (ManagedStateList::const_iterator iter
= managed_list
->begin();
858 iter
!= managed_list
->end(); ++iter
) {
859 ManagedState
* managed
= *iter
;
860 if (managed
->path() == path
)
866 NetworkStateHandler::ManagedStateList
* NetworkStateHandler::GetManagedList(
867 ManagedState::ManagedType type
) {
869 case ManagedState::MANAGED_TYPE_NETWORK
:
870 return &network_list_
;
871 case ManagedState::MANAGED_TYPE_DEVICE
:
872 return &device_list_
;
878 void NetworkStateHandler::OnNetworkConnectionStateChanged(
879 NetworkState
* network
) {
880 SCOPED_NET_LOG_IF_SLOW();
882 std::string event
= "NetworkConnectionStateChanged";
883 if (network
->path() == default_network_path_
) {
884 event
= "Default" + event
;
885 if (!network
->IsConnectedState()) {
887 "DefaultNetwork is not connected: " + network
->connection_state(),
889 default_network_path_
.clear();
891 NotifyDefaultNetworkChanged(NULL
);
894 NET_LOG_EVENT("NOTIFY:" + event
+ ": " + network
->connection_state(),
895 GetLogName(network
));
896 FOR_EACH_OBSERVER(NetworkStateHandlerObserver
, observers_
,
897 NetworkConnectionStateChanged(network
));
898 if (network
->path() == default_network_path_
)
899 NotifyDefaultNetworkChanged(network
);
902 void NetworkStateHandler::NotifyDefaultNetworkChanged(
903 const NetworkState
* default_network
) {
904 SCOPED_NET_LOG_IF_SLOW();
905 NET_LOG_EVENT("NOTIFY:DefaultNetworkChanged", GetLogName(default_network
));
906 FOR_EACH_OBSERVER(NetworkStateHandlerObserver
, observers_
,
907 DefaultNetworkChanged(default_network
));
910 void NetworkStateHandler::NotifyNetworkPropertiesUpdated(
911 const NetworkState
* network
) {
912 SCOPED_NET_LOG_IF_SLOW();
913 NET_LOG_DEBUG("NOTIFY:NetworkPropertiesUpdated", GetLogName(network
));
914 FOR_EACH_OBSERVER(NetworkStateHandlerObserver
, observers_
,
915 NetworkPropertiesUpdated(network
));
918 void NetworkStateHandler::NotifyDevicePropertiesUpdated(
919 const DeviceState
* device
) {
920 SCOPED_NET_LOG_IF_SLOW();
921 NET_LOG_DEBUG("NOTIFY:DevicePropertiesUpdated", GetLogName(device
));
922 FOR_EACH_OBSERVER(NetworkStateHandlerObserver
, observers_
,
923 DevicePropertiesUpdated(device
));
926 void NetworkStateHandler::NotifyScanCompleted(const DeviceState
* device
) {
927 SCOPED_NET_LOG_IF_SLOW();
928 NET_LOG_DEBUG("NOTIFY:ScanCompleted", GetLogName(device
));
929 FOR_EACH_OBSERVER(NetworkStateHandlerObserver
, observers_
,
930 ScanCompleted(device
));
933 std::string
NetworkStateHandler::GetTechnologyForType(
934 const NetworkTypePattern
& type
) const {
935 if (type
.MatchesType(shill::kTypeEthernet
))
936 return shill::kTypeEthernet
;
938 if (type
.MatchesType(shill::kTypeWifi
))
939 return shill::kTypeWifi
;
941 if (type
.Equals(NetworkTypePattern::Wimax()))
942 return shill::kTypeWimax
;
944 // Prefer Wimax over Cellular only if it's available.
945 if (type
.MatchesType(shill::kTypeWimax
) &&
946 shill_property_handler_
->IsTechnologyAvailable(shill::kTypeWimax
)) {
947 return shill::kTypeWimax
;
950 if (type
.MatchesType(shill::kTypeCellular
))
951 return shill::kTypeCellular
;
954 return std::string();
957 ScopedVector
<std::string
> NetworkStateHandler::GetTechnologiesForType(
958 const NetworkTypePattern
& type
) const {
959 ScopedVector
<std::string
> technologies
;
960 if (type
.MatchesType(shill::kTypeEthernet
))
961 technologies
.push_back(new std::string(shill::kTypeEthernet
));
962 if (type
.MatchesType(shill::kTypeWifi
))
963 technologies
.push_back(new std::string(shill::kTypeWifi
));
964 if (type
.MatchesType(shill::kTypeWimax
))
965 technologies
.push_back(new std::string(shill::kTypeWimax
));
966 if (type
.MatchesType(shill::kTypeCellular
))
967 technologies
.push_back(new std::string(shill::kTypeCellular
));
968 if (type
.MatchesType(shill::kTypeBluetooth
))
969 technologies
.push_back(new std::string(shill::kTypeBluetooth
));
970 if (type
.MatchesType(shill::kTypeVPN
))
971 technologies
.push_back(new std::string(shill::kTypeVPN
));
973 CHECK_GT(technologies
.size(), 0ul);
974 return technologies
.Pass();
977 } // namespace chromeos