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 return (network
->connection_state() != prev_connection_state
) &&
34 (network
->connection_state() != shill::kStateIdle
||
35 !prev_connection_state
.empty());
38 std::string
GetManagedStateLogType(const ManagedState
* state
) {
39 switch (state
->managed_type()) {
40 case ManagedState::MANAGED_TYPE_NETWORK
:
42 case ManagedState::MANAGED_TYPE_DEVICE
:
49 std::string
GetLogName(const ManagedState
* state
) {
52 return base::StringPrintf("%s (%s)", state
->name().c_str(),
53 state
->path().c_str());
56 std::string
ValueAsString(const base::Value
& value
) {
58 base::JSONWriter::WriteWithOptions(
59 &value
, base::JSONWriter::OPTIONS_OMIT_BINARY_VALUES
, &vstr
);
60 return vstr
.empty() ? "''" : vstr
;
65 const char NetworkStateHandler::kDefaultCheckPortalList
[] =
66 "ethernet,wifi,cellular";
68 NetworkStateHandler::NetworkStateHandler()
69 : network_list_sorted_(false) {
72 NetworkStateHandler::~NetworkStateHandler() {
73 FOR_EACH_OBSERVER(NetworkStateHandlerObserver
, observers_
, IsShuttingDown());
74 STLDeleteContainerPointers(network_list_
.begin(), network_list_
.end());
75 STLDeleteContainerPointers(device_list_
.begin(), device_list_
.end());
78 void NetworkStateHandler::InitShillPropertyHandler() {
79 shill_property_handler_
.reset(new internal::ShillPropertyHandler(this));
80 shill_property_handler_
->Init();
84 NetworkStateHandler
* NetworkStateHandler::InitializeForTest() {
85 NetworkStateHandler
* handler
= new NetworkStateHandler();
86 handler
->InitShillPropertyHandler();
90 void NetworkStateHandler::AddObserver(
91 NetworkStateHandlerObserver
* observer
,
92 const tracked_objects::Location
& from_here
) {
93 observers_
.AddObserver(observer
);
94 device_event_log::AddEntry(from_here
.file_name(), from_here
.line_number(),
95 device_event_log::LOG_TYPE_NETWORK
,
96 device_event_log::LOG_LEVEL_DEBUG
,
97 "NetworkStateHandler::AddObserver");
100 void NetworkStateHandler::RemoveObserver(
101 NetworkStateHandlerObserver
* observer
,
102 const tracked_objects::Location
& from_here
) {
103 observers_
.RemoveObserver(observer
);
104 device_event_log::AddEntry(from_here
.file_name(), from_here
.line_number(),
105 device_event_log::LOG_TYPE_NETWORK
,
106 device_event_log::LOG_LEVEL_DEBUG
,
107 "NetworkStateHandler::RemoveObserver");
110 NetworkStateHandler::TechnologyState
NetworkStateHandler::GetTechnologyState(
111 const NetworkTypePattern
& type
) const {
112 std::string technology
= GetTechnologyForType(type
);
113 TechnologyState state
;
114 if (shill_property_handler_
->IsTechnologyEnabled(technology
))
115 state
= TECHNOLOGY_ENABLED
;
116 else if (shill_property_handler_
->IsTechnologyEnabling(technology
))
117 state
= TECHNOLOGY_ENABLING
;
118 else if (shill_property_handler_
->IsTechnologyUninitialized(technology
))
119 state
= TECHNOLOGY_UNINITIALIZED
;
120 else if (shill_property_handler_
->IsTechnologyAvailable(technology
))
121 state
= TECHNOLOGY_AVAILABLE
;
123 state
= TECHNOLOGY_UNAVAILABLE
;
124 VLOG(2) << "GetTechnologyState: " << type
.ToDebugString() << " = " << state
;
128 void NetworkStateHandler::SetTechnologyEnabled(
129 const NetworkTypePattern
& type
,
131 const network_handler::ErrorCallback
& error_callback
) {
132 ScopedVector
<std::string
> technologies
= GetTechnologiesForType(type
);
133 for (ScopedVector
<std::string
>::iterator it
= technologies
.begin();
134 it
!= technologies
.end(); ++it
) {
135 std::string
* technology
= *it
;
137 if (!shill_property_handler_
->IsTechnologyAvailable(*technology
))
139 NET_LOG_USER("SetTechnologyEnabled",
140 base::StringPrintf("%s:%d", technology
->c_str(), enabled
));
141 shill_property_handler_
->SetTechnologyEnabled(
142 *technology
, enabled
, error_callback
);
144 // Signal Device/Technology state changed.
145 NotifyDeviceListChanged();
148 const DeviceState
* NetworkStateHandler::GetDeviceState(
149 const std::string
& device_path
) const {
150 const DeviceState
* device
= GetModifiableDeviceState(device_path
);
151 if (device
&& !device
->update_received())
156 const DeviceState
* NetworkStateHandler::GetDeviceStateByType(
157 const NetworkTypePattern
& type
) const {
158 for (ManagedStateList::const_iterator iter
= device_list_
.begin();
159 iter
!= device_list_
.end(); ++iter
) {
160 ManagedState
* device
= *iter
;
161 if (!device
->update_received())
163 if (device
->Matches(type
))
164 return device
->AsDeviceState();
169 bool NetworkStateHandler::GetScanningByType(
170 const NetworkTypePattern
& type
) const {
171 for (ManagedStateList::const_iterator iter
= device_list_
.begin();
172 iter
!= device_list_
.end(); ++iter
) {
173 const DeviceState
* device
= (*iter
)->AsDeviceState();
175 if (!device
->update_received())
177 if (device
->Matches(type
) && device
->scanning())
183 const NetworkState
* NetworkStateHandler::GetNetworkState(
184 const std::string
& service_path
) const {
185 const NetworkState
* network
= GetModifiableNetworkState(service_path
);
186 if (network
&& !network
->update_received())
191 const NetworkState
* NetworkStateHandler::DefaultNetwork() const {
192 if (default_network_path_
.empty())
194 return GetNetworkState(default_network_path_
);
197 const NetworkState
* NetworkStateHandler::ConnectedNetworkByType(
198 const NetworkTypePattern
& type
) const {
199 // Active networks are always listed first by Shill so no need to sort.
200 for (ManagedStateList::const_iterator iter
= network_list_
.begin();
201 iter
!= network_list_
.end(); ++iter
) {
202 const NetworkState
* network
= (*iter
)->AsNetworkState();
204 if (!network
->update_received())
206 if (!network
->IsConnectedState())
207 break; // Connected networks are listed first.
208 if (network
->Matches(type
))
214 const NetworkState
* NetworkStateHandler::ConnectingNetworkByType(
215 const NetworkTypePattern
& type
) const {
216 // Active networks are always listed first by Shill so no need to sort.
217 for (ManagedStateList::const_iterator iter
= network_list_
.begin();
218 iter
!= network_list_
.end(); ++iter
) {
219 const NetworkState
* network
= (*iter
)->AsNetworkState();
221 if (!network
->update_received() || network
->IsConnectedState())
223 if (!network
->IsConnectingState())
224 break; // Connected and connecting networks are listed first.
225 if (network
->Matches(type
))
231 const NetworkState
* NetworkStateHandler::FirstNetworkByType(
232 const NetworkTypePattern
& type
) {
233 if (!network_list_sorted_
)
234 SortNetworkList(); // Sort to ensure visible networks are listed first.
235 for (ManagedStateList::const_iterator iter
= network_list_
.begin();
236 iter
!= network_list_
.end(); ++iter
) {
237 const NetworkState
* network
= (*iter
)->AsNetworkState();
239 if (!network
->update_received())
241 if (!network
->visible())
243 if (network
->Matches(type
))
249 std::string
NetworkStateHandler::FormattedHardwareAddressForType(
250 const NetworkTypePattern
& type
) const {
251 const DeviceState
* device
= NULL
;
252 const NetworkState
* network
= ConnectedNetworkByType(type
);
254 device
= GetDeviceState(network
->device_path());
256 device
= GetDeviceStateByType(type
);
258 return std::string();
259 return network_util::FormattedMacAddress(device
->mac_address());
262 void NetworkStateHandler::GetVisibleNetworkListByType(
263 const NetworkTypePattern
& type
,
264 NetworkStateList
* list
) {
265 GetNetworkListByType(type
,
266 false /* configured_only */,
267 true /* visible_only */,
272 void NetworkStateHandler::GetVisibleNetworkList(NetworkStateList
* list
) {
273 GetVisibleNetworkListByType(NetworkTypePattern::Default(), list
);
276 void NetworkStateHandler::GetNetworkListByType(const NetworkTypePattern
& type
,
277 bool configured_only
,
280 NetworkStateList
* list
) {
284 // Sort the network list if necessary.
285 if (!network_list_sorted_
)
287 for (ManagedStateList::const_iterator iter
= network_list_
.begin();
288 iter
!= network_list_
.end(); ++iter
) {
289 const NetworkState
* network
= (*iter
)->AsNetworkState();
291 if (!network
->update_received() || !network
->Matches(type
))
293 if (configured_only
&& !network
->IsInProfile())
295 if (visible_only
&& !network
->visible())
297 list
->push_back(network
);
298 if (limit
> 0 && ++count
>= limit
)
303 const NetworkState
* NetworkStateHandler::GetNetworkStateFromServicePath(
304 const std::string
& service_path
,
305 bool configured_only
) const {
306 ManagedState
* managed
=
307 GetModifiableManagedState(&network_list_
, service_path
);
310 const NetworkState
* network
= managed
->AsNetworkState();
312 if (!network
->update_received() ||
313 (configured_only
&& !network
->IsInProfile())) {
319 const NetworkState
* NetworkStateHandler::GetNetworkStateFromGuid(
320 const std::string
& guid
) const {
321 DCHECK(!guid
.empty());
322 for (ManagedStateList::const_iterator iter
= network_list_
.begin();
323 iter
!= network_list_
.end(); ++iter
) {
324 const NetworkState
* network
= (*iter
)->AsNetworkState();
325 if (network
->guid() == guid
)
331 void NetworkStateHandler::GetDeviceList(DeviceStateList
* list
) const {
332 GetDeviceListByType(NetworkTypePattern::Default(), list
);
335 void NetworkStateHandler::GetDeviceListByType(const NetworkTypePattern
& type
,
336 DeviceStateList
* list
) const {
339 for (ManagedStateList::const_iterator iter
= device_list_
.begin();
340 iter
!= device_list_
.end(); ++iter
) {
341 const DeviceState
* device
= (*iter
)->AsDeviceState();
343 if (device
->update_received() && device
->Matches(type
))
344 list
->push_back(device
);
348 void NetworkStateHandler::RequestScan() const {
349 NET_LOG_USER("RequestScan", "");
350 shill_property_handler_
->RequestScan();
353 void NetworkStateHandler::RequestUpdateForNetwork(
354 const std::string
& service_path
) {
355 NetworkState
* network
= GetModifiableNetworkState(service_path
);
357 network
->set_update_requested(true);
358 NET_LOG_EVENT("RequestUpdate", service_path
);
359 shill_property_handler_
->RequestProperties(
360 ManagedState::MANAGED_TYPE_NETWORK
, service_path
);
363 void NetworkStateHandler::ClearLastErrorForNetwork(
364 const std::string
& service_path
) {
365 NetworkState
* network
= GetModifiableNetworkState(service_path
);
367 network
->clear_last_error();
370 void NetworkStateHandler::SetCheckPortalList(
371 const std::string
& check_portal_list
) {
372 NET_LOG_EVENT("SetCheckPortalList", check_portal_list
);
373 shill_property_handler_
->SetCheckPortalList(check_portal_list
);
376 void NetworkStateHandler::SetWakeOnLanEnabled(bool enabled
) {
377 NET_LOG_EVENT("SetWakeOnLanEnabled",
378 base::StringPrintf("%s", enabled
? "true" : "false"));
379 shill_property_handler_
->SetWakeOnLanEnabled(enabled
);
382 const NetworkState
* NetworkStateHandler::GetEAPForEthernet(
383 const std::string
& service_path
) {
384 const NetworkState
* network
= GetNetworkState(service_path
);
386 NET_LOG_ERROR("GetEAPForEthernet", "Unknown service path " + service_path
);
389 if (network
->type() != shill::kTypeEthernet
) {
390 NET_LOG_ERROR("GetEAPForEthernet", "Not of type Ethernet: " + service_path
);
393 if (!network
->IsConnectedState())
396 // The same EAP service is shared for all ethernet services/devices.
397 // However EAP is used/enabled per device and only if the connection was
398 // successfully established.
399 const DeviceState
* device
= GetDeviceState(network
->device_path());
403 base::StringPrintf("Unknown device %s of connected ethernet service %s",
404 network
->device_path().c_str(),
405 service_path
.c_str()));
408 if (!device
->eap_authentication_completed())
411 NetworkStateList list
;
412 GetNetworkListByType(NetworkTypePattern::Primitive(shill::kTypeEthernetEap
),
413 true /* configured_only */,
414 false /* visible_only */,
418 NET_LOG_ERROR("GetEAPForEthernet",
420 "Ethernet service %s connected using EAP, but no "
421 "EAP service found.",
422 service_path
.c_str()));
428 //------------------------------------------------------------------------------
429 // ShillPropertyHandler::Delegate overrides
431 void NetworkStateHandler::UpdateManagedList(ManagedState::ManagedType type
,
432 const base::ListValue
& entries
) {
433 ManagedStateList
* managed_list
= GetManagedList(type
);
434 NET_LOG_DEBUG("UpdateManagedList: " + ManagedState::TypeToString(type
),
435 base::StringPrintf("%" PRIuS
, entries
.GetSize()));
436 // Create a map of existing entries. Assumes all entries in |managed_list|
438 typedef std::map
<std::string
, ManagedState
*> ManagedMap
;
439 ManagedMap managed_map
;
440 for (ManagedStateList::iterator iter
= managed_list
->begin();
441 iter
!= managed_list
->end(); ++iter
) {
442 ManagedState
* managed
= *iter
;
443 DCHECK(!ContainsKey(managed_map
, managed
->path()));
444 managed_map
[managed
->path()] = managed
;
446 // Clear the list (pointers are temporarily owned by managed_map).
447 managed_list
->clear();
448 // Updates managed_list and request updates for new entries.
449 std::set
<std::string
> list_entries
;
450 for (base::ListValue::const_iterator iter
= entries
.begin();
451 iter
!= entries
.end(); ++iter
) {
453 (*iter
)->GetAsString(&path
);
454 if (path
.empty() || path
== shill::kFlimflamServicePath
) {
455 NET_LOG_ERROR(base::StringPrintf("Bad path in list:%d", type
), path
);
458 ManagedMap::iterator found
= managed_map
.find(path
);
459 if (found
== managed_map
.end()) {
460 if (list_entries
.count(path
) != 0) {
461 NET_LOG_ERROR("Duplicate entry in list", path
);
464 ManagedState
* managed
= ManagedState::Create(type
, path
);
465 managed_list
->push_back(managed
);
467 managed_list
->push_back(found
->second
);
468 managed_map
.erase(found
);
470 list_entries
.insert(path
);
472 // Delete any remaining entries in managed_map.
473 STLDeleteContainerPairSecondPointers(managed_map
.begin(), managed_map
.end());
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 NetworkState
* network
= (*iter
)->AsNetworkState();
482 shill_property_handler_
->RequestProperties(
483 ManagedState::MANAGED_TYPE_NETWORK
, network
->path());
487 void NetworkStateHandler::UpdateManagedStateProperties(
488 ManagedState::ManagedType type
,
489 const std::string
& path
,
490 const base::DictionaryValue
& properties
) {
491 ManagedStateList
* managed_list
= GetManagedList(type
);
492 ManagedState
* managed
= GetModifiableManagedState(managed_list
, path
);
494 // The network has been removed from the list of networks.
495 NET_LOG_DEBUG("UpdateManagedStateProperties: Not found", path
);
498 managed
->set_update_received();
500 std::string desc
= GetManagedStateLogType(managed
) + " Properties Received";
501 NET_LOG_DEBUG(desc
, GetLogName(managed
));
503 if (type
== ManagedState::MANAGED_TYPE_NETWORK
) {
504 UpdateNetworkStateProperties(managed
->AsNetworkState(), properties
);
507 for (base::DictionaryValue::Iterator
iter(properties
);
508 !iter
.IsAtEnd(); iter
.Advance()) {
509 managed
->PropertyChanged(iter
.key(), iter
.value());
511 managed
->InitialPropertiesReceived(properties
);
513 managed
->set_update_requested(false);
516 void NetworkStateHandler::UpdateNetworkStateProperties(
517 NetworkState
* network
,
518 const base::DictionaryValue
& properties
) {
520 bool network_property_updated
= false;
521 std::string prev_connection_state
= network
->connection_state();
522 for (base::DictionaryValue::Iterator
iter(properties
);
523 !iter
.IsAtEnd(); iter
.Advance()) {
524 if (network
->PropertyChanged(iter
.key(), iter
.value()))
525 network_property_updated
= true;
527 network_property_updated
|= network
->InitialPropertiesReceived(properties
);
529 network_list_sorted_
= false;
531 // Notify observers of NetworkState changes.
532 if (network_property_updated
|| network
->update_requested()) {
533 // Signal connection state changed after all properties have been updated.
534 if (ConnectionStateChanged(network
, prev_connection_state
))
535 OnNetworkConnectionStateChanged(network
);
536 NET_LOG_EVENT("NetworkPropertiesUpdated", GetLogName(network
));
537 NotifyNetworkPropertiesUpdated(network
);
541 void NetworkStateHandler::UpdateNetworkServiceProperty(
542 const std::string
& service_path
,
543 const std::string
& key
,
544 const base::Value
& value
) {
545 bool changed
= false;
546 NetworkState
* network
= GetModifiableNetworkState(service_path
);
549 std::string prev_connection_state
= network
->connection_state();
550 std::string prev_profile_path
= network
->profile_path();
551 changed
|= network
->PropertyChanged(key
, value
);
555 if (key
== shill::kStateProperty
|| key
== shill::kVisibleProperty
) {
556 network_list_sorted_
= false;
557 if (ConnectionStateChanged(network
, prev_connection_state
)) {
558 OnNetworkConnectionStateChanged(network
);
559 // If the connection state changes, other properties such as IPConfig
560 // may have changed, so request a full update.
561 RequestUpdateForNetwork(service_path
);
564 std::string value_str
;
565 value
.GetAsString(&value_str
);
566 // Some property changes are noisy and not interesting:
567 // * Wifi SignalStrength
568 // * WifiFrequencyList updates
569 // * Device property changes to "/" (occurs before a service is removed)
570 if (key
!= shill::kSignalStrengthProperty
&&
571 key
!= shill::kWifiFrequencyListProperty
&&
572 (key
!= shill::kDeviceProperty
|| value_str
!= "/")) {
573 std::string log_event
= "NetworkPropertyUpdated";
574 // Trigger a default network update for interesting changes only.
575 if (network
->path() == default_network_path_
) {
576 NotifyDefaultNetworkChanged(network
);
577 log_event
= "Default" + log_event
;
580 std::string detail
= network
->name() + "." + key
;
581 detail
+= " = " + ValueAsString(value
);
582 device_event_log::LogLevel log_level
;
583 if (key
== shill::kErrorProperty
|| key
== shill::kErrorDetailsProperty
) {
584 log_level
= device_event_log::LOG_LEVEL_ERROR
;
586 log_level
= device_event_log::LOG_LEVEL_EVENT
;
588 NET_LOG_LEVEL(log_level
, log_event
, detail
);
592 // All property updates signal 'NetworkPropertiesUpdated'.
593 NotifyNetworkPropertiesUpdated(network
);
595 // If added to a Profile, request a full update so that a NetworkState
597 if (prev_profile_path
.empty() && !network
->profile_path().empty())
598 RequestUpdateForNetwork(service_path
);
601 void NetworkStateHandler::UpdateDeviceProperty(const std::string
& device_path
,
602 const std::string
& key
,
603 const base::Value
& value
) {
604 DeviceState
* device
= GetModifiableDeviceState(device_path
);
607 if (!device
->PropertyChanged(key
, value
))
610 std::string detail
= device
->name() + "." + key
;
611 detail
+= " = " + ValueAsString(value
);
612 NET_LOG_EVENT("DevicePropertyUpdated", detail
);
614 NotifyDeviceListChanged();
615 NotifyDevicePropertiesUpdated(device
);
617 if (key
== shill::kScanningProperty
&& device
->scanning() == false) {
618 NotifyScanCompleted(device
);
620 if (key
== shill::kEapAuthenticationCompletedProperty
) {
621 // Notify a change for each Ethernet service using this device.
622 NetworkStateList ethernet_services
;
623 GetNetworkListByType(NetworkTypePattern::Ethernet(),
624 false /* configured_only */,
625 false /* visible_only */,
628 for (NetworkStateList::const_iterator it
= ethernet_services
.begin();
629 it
!= ethernet_services
.end(); ++it
) {
630 const NetworkState
* ethernet_service
= *it
;
631 if (ethernet_service
->update_received() ||
632 ethernet_service
->device_path() != device
->path()) {
635 RequestUpdateForNetwork(ethernet_service
->path());
640 void NetworkStateHandler::UpdateIPConfigProperties(
641 ManagedState::ManagedType type
,
642 const std::string
& path
,
643 const std::string
& ip_config_path
,
644 const base::DictionaryValue
& properties
) {
645 if (type
== ManagedState::MANAGED_TYPE_NETWORK
) {
646 NetworkState
* network
= GetModifiableNetworkState(path
);
649 network
->IPConfigPropertiesChanged(properties
);
650 NotifyNetworkPropertiesUpdated(network
);
651 if (network
->path() == default_network_path_
)
652 NotifyDefaultNetworkChanged(network
);
653 } else if (type
== ManagedState::MANAGED_TYPE_DEVICE
) {
654 DeviceState
* device
= GetModifiableDeviceState(path
);
657 device
->IPConfigPropertiesChanged(ip_config_path
, properties
);
658 NotifyDevicePropertiesUpdated(device
);
659 if (!default_network_path_
.empty()) {
660 const NetworkState
* default_network
=
661 GetNetworkState(default_network_path_
);
662 if (default_network
&& default_network
->device_path() == path
)
663 NotifyDefaultNetworkChanged(default_network
);
668 void NetworkStateHandler::CheckPortalListChanged(
669 const std::string
& check_portal_list
) {
670 check_portal_list_
= check_portal_list
;
673 void NetworkStateHandler::TechnologyListChanged() {
674 // Eventually we would like to replace Technology state with Device state.
675 // For now, treat technology state changes as device list changes.
676 NotifyDeviceListChanged();
679 void NetworkStateHandler::ManagedStateListChanged(
680 ManagedState::ManagedType type
) {
681 if (type
== ManagedState::MANAGED_TYPE_NETWORK
) {
683 UpdateNetworkStats();
684 // Notify observers that the list of networks has changed.
685 NET_LOG_EVENT("NOTIFY:NetworkListChanged",
686 base::StringPrintf("Size:%" PRIuS
, network_list_
.size()));
687 FOR_EACH_OBSERVER(NetworkStateHandlerObserver
, observers_
,
688 NetworkListChanged());
689 } else if (type
== ManagedState::MANAGED_TYPE_DEVICE
) {
691 for (ManagedStateList::const_iterator iter
= device_list_
.begin();
692 iter
!= device_list_
.end(); ++iter
) {
693 if (iter
!= device_list_
.begin())
695 devices
+= (*iter
)->name();
697 NET_LOG_EVENT("DeviceList", devices
);
698 NotifyDeviceListChanged();
704 void NetworkStateHandler::SortNetworkList() {
705 // Note: usually active networks will precede inactive networks, however
706 // this may briefly be untrue during state transitions (e.g. a network may
707 // transition to idle before the list is updated).
708 ManagedStateList active
, non_wifi_visible
, wifi_visible
, hidden
, new_networks
;
709 for (ManagedStateList::iterator iter
= network_list_
.begin();
710 iter
!= network_list_
.end(); ++iter
) {
711 NetworkState
* network
= (*iter
)->AsNetworkState();
712 if (!network
->update_received()) {
713 new_networks
.push_back(network
);
716 if (network
->IsConnectedState() || network
->IsConnectingState()) {
717 active
.push_back(network
);
720 if (network
->visible()) {
721 if (NetworkTypePattern::WiFi().MatchesType(network
->type()))
722 wifi_visible
.push_back(network
);
724 non_wifi_visible
.push_back(network
);
726 hidden
.push_back(network
);
729 network_list_
.clear();
730 network_list_
.insert(network_list_
.end(), active
.begin(), active
.end());
731 network_list_
.insert(
732 network_list_
.end(), non_wifi_visible
.begin(), non_wifi_visible
.end());
733 network_list_
.insert(
734 network_list_
.end(), wifi_visible
.begin(), wifi_visible
.end());
735 network_list_
.insert(network_list_
.end(), hidden
.begin(), hidden
.end());
736 network_list_
.insert(
737 network_list_
.end(), new_networks
.begin(), new_networks
.end());
738 network_list_sorted_
= true;
741 void NetworkStateHandler::UpdateNetworkStats() {
742 size_t shared
= 0, unshared
= 0, visible
= 0;
743 for (ManagedStateList::iterator iter
= network_list_
.begin();
744 iter
!= network_list_
.end(); ++iter
) {
745 NetworkState
* network
= (*iter
)->AsNetworkState();
746 if (network
->visible())
748 if (network
->IsInProfile()) {
749 if (network
->IsPrivate())
755 UMA_HISTOGRAM_COUNTS_100("Networks.Visible", visible
);
756 UMA_HISTOGRAM_COUNTS_100("Networks.RememberedShared", shared
);
757 UMA_HISTOGRAM_COUNTS_100("Networks.RememberedUnshared", unshared
);
760 void NetworkStateHandler::DefaultNetworkServiceChanged(
761 const std::string
& service_path
) {
762 // Shill uses '/' for empty service path values; check explicitly for that.
763 const char* kEmptyServicePath
= "/";
764 std::string new_service_path
=
765 (service_path
!= kEmptyServicePath
) ? service_path
: "";
766 if (new_service_path
== default_network_path_
)
769 default_network_path_
= service_path
;
770 NET_LOG_EVENT("DefaultNetworkServiceChanged:", default_network_path_
);
771 const NetworkState
* network
= NULL
;
772 if (!default_network_path_
.empty()) {
773 network
= GetNetworkState(default_network_path_
);
775 // If NetworkState is not available yet, do not notify observers here,
776 // they will be notified when the state is received.
777 NET_LOG_DEBUG("Default NetworkState not available",
778 default_network_path_
);
782 if (network
&& !network
->IsConnectedState()) {
784 "DefaultNetwork is not connected: " + network
->connection_state(),
787 NotifyDefaultNetworkChanged(network
);
790 //------------------------------------------------------------------------------
793 void NetworkStateHandler::UpdateGuid(NetworkState
* network
) {
794 std::string specifier
= network
->GetSpecifier();
795 DCHECK(!specifier
.empty());
796 if (!network
->guid().empty()) {
797 // If the network is saved in a profile, remove the entry from the map.
798 // Otherwise ensure that the entry matches the specified GUID. (e.g. in
799 // case a visible network with a specified guid gets configured with a
801 if (network
->IsInProfile())
802 specifier_guid_map_
.erase(specifier
);
804 specifier_guid_map_
[specifier
] = network
->guid();
807 // Ensure that the NetworkState has a valid GUID.
809 SpecifierGuidMap::iterator iter
= specifier_guid_map_
.find(specifier
);
810 if (iter
!= specifier_guid_map_
.end()) {
813 guid
= base::GenerateGUID();
814 specifier_guid_map_
[specifier
] = guid
;
816 network
->SetGuid(guid
);
819 void NetworkStateHandler::NotifyDeviceListChanged() {
820 NET_LOG_DEBUG("NOTIFY:DeviceListChanged",
821 base::StringPrintf("Size:%" PRIuS
, device_list_
.size()));
822 FOR_EACH_OBSERVER(NetworkStateHandlerObserver
, observers_
,
823 DeviceListChanged());
826 DeviceState
* NetworkStateHandler::GetModifiableDeviceState(
827 const std::string
& device_path
) const {
828 ManagedState
* managed
= GetModifiableManagedState(&device_list_
, device_path
);
831 return managed
->AsDeviceState();
834 NetworkState
* NetworkStateHandler::GetModifiableNetworkState(
835 const std::string
& service_path
) const {
836 ManagedState
* managed
=
837 GetModifiableManagedState(&network_list_
, service_path
);
840 return managed
->AsNetworkState();
843 ManagedState
* NetworkStateHandler::GetModifiableManagedState(
844 const ManagedStateList
* managed_list
,
845 const std::string
& path
) const {
846 for (ManagedStateList::const_iterator iter
= managed_list
->begin();
847 iter
!= managed_list
->end(); ++iter
) {
848 ManagedState
* managed
= *iter
;
849 if (managed
->path() == path
)
855 NetworkStateHandler::ManagedStateList
* NetworkStateHandler::GetManagedList(
856 ManagedState::ManagedType type
) {
858 case ManagedState::MANAGED_TYPE_NETWORK
:
859 return &network_list_
;
860 case ManagedState::MANAGED_TYPE_DEVICE
:
861 return &device_list_
;
867 void NetworkStateHandler::OnNetworkConnectionStateChanged(
868 NetworkState
* network
) {
870 std::string event
= "NetworkConnectionStateChanged";
871 if (network
->path() == default_network_path_
) {
872 event
= "Default" + event
;
873 if (!network
->IsConnectedState()) {
875 "DefaultNetwork is not connected: " + network
->connection_state(),
877 default_network_path_
.clear();
879 NotifyDefaultNetworkChanged(NULL
);
882 NET_LOG_EVENT("NOTIFY:" + event
+ ": " + network
->connection_state(),
883 GetLogName(network
));
884 FOR_EACH_OBSERVER(NetworkStateHandlerObserver
, observers_
,
885 NetworkConnectionStateChanged(network
));
886 if (network
->path() == default_network_path_
)
887 NotifyDefaultNetworkChanged(network
);
890 void NetworkStateHandler::NotifyDefaultNetworkChanged(
891 const NetworkState
* default_network
) {
892 NET_LOG_EVENT("NOTIFY:DefaultNetworkChanged", GetLogName(default_network
));
893 FOR_EACH_OBSERVER(NetworkStateHandlerObserver
, observers_
,
894 DefaultNetworkChanged(default_network
));
897 void NetworkStateHandler::NotifyNetworkPropertiesUpdated(
898 const NetworkState
* network
) {
899 NET_LOG_DEBUG("NOTIFY:NetworkPropertiesUpdated", GetLogName(network
));
900 FOR_EACH_OBSERVER(NetworkStateHandlerObserver
, observers_
,
901 NetworkPropertiesUpdated(network
));
904 void NetworkStateHandler::NotifyDevicePropertiesUpdated(
905 const DeviceState
* device
) {
906 NET_LOG_DEBUG("NOTIFY:DevicePropertiesUpdated", GetLogName(device
));
907 FOR_EACH_OBSERVER(NetworkStateHandlerObserver
, observers_
,
908 DevicePropertiesUpdated(device
));
911 void NetworkStateHandler::NotifyScanCompleted(const DeviceState
* device
) {
912 NET_LOG_DEBUG("NOTIFY:ScanCompleted", GetLogName(device
));
913 FOR_EACH_OBSERVER(NetworkStateHandlerObserver
, observers_
,
914 ScanCompleted(device
));
917 std::string
NetworkStateHandler::GetTechnologyForType(
918 const NetworkTypePattern
& type
) const {
919 if (type
.MatchesType(shill::kTypeEthernet
))
920 return shill::kTypeEthernet
;
922 if (type
.MatchesType(shill::kTypeWifi
))
923 return shill::kTypeWifi
;
925 if (type
.Equals(NetworkTypePattern::Wimax()))
926 return shill::kTypeWimax
;
928 // Prefer Wimax over Cellular only if it's available.
929 if (type
.MatchesType(shill::kTypeWimax
) &&
930 shill_property_handler_
->IsTechnologyAvailable(shill::kTypeWimax
)) {
931 return shill::kTypeWimax
;
934 if (type
.MatchesType(shill::kTypeCellular
))
935 return shill::kTypeCellular
;
938 return std::string();
941 ScopedVector
<std::string
> NetworkStateHandler::GetTechnologiesForType(
942 const NetworkTypePattern
& type
) const {
943 ScopedVector
<std::string
> technologies
;
944 if (type
.MatchesType(shill::kTypeEthernet
))
945 technologies
.push_back(new std::string(shill::kTypeEthernet
));
946 if (type
.MatchesType(shill::kTypeWifi
))
947 technologies
.push_back(new std::string(shill::kTypeWifi
));
948 if (type
.MatchesType(shill::kTypeWimax
))
949 technologies
.push_back(new std::string(shill::kTypeWimax
));
950 if (type
.MatchesType(shill::kTypeCellular
))
951 technologies
.push_back(new std::string(shill::kTypeCellular
));
952 if (type
.MatchesType(shill::kTypeBluetooth
))
953 technologies
.push_back(new std::string(shill::kTypeBluetooth
));
954 if (type
.MatchesType(shill::kTypeVPN
))
955 technologies
.push_back(new std::string(shill::kTypeVPN
));
957 CHECK_GT(technologies
.size(), 0ul);
958 return technologies
.Pass();
961 } // namespace chromeos