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"
9 #include "base/location.h"
10 #include "base/logging.h"
11 #include "base/metrics/histogram.h"
12 #include "base/stl_util.h"
13 #include "base/strings/string_util.h"
14 #include "base/strings/stringprintf.h"
15 #include "base/values.h"
16 #include "chromeos/network/device_state.h"
17 #include "chromeos/network/favorite_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 "chromeos/network/shill_property_util.h"
24 #include "third_party/cros_system_api/dbus/service_constants.h"
30 bool ConnectionStateChanged(NetworkState
* network
,
31 const std::string
& prev_connection_state
) {
32 return (network
->connection_state() != prev_connection_state
) &&
33 (network
->connection_state() != shill::kStateIdle
||
34 !prev_connection_state
.empty());
37 std::string
GetManagedStateLogType(const ManagedState
* state
) {
38 switch (state
->managed_type()) {
39 case ManagedState::MANAGED_TYPE_NETWORK
:
41 case ManagedState::MANAGED_TYPE_FAVORITE
:
43 case ManagedState::MANAGED_TYPE_DEVICE
:
50 std::string
GetManagedStateLogName(const ManagedState
* state
) {
53 return base::StringPrintf("%s (%s)", state
->name().c_str(),
54 state
->path().c_str());
59 const char NetworkStateHandler::kDefaultCheckPortalList
[] =
60 "ethernet,wifi,cellular";
62 NetworkStateHandler::NetworkStateHandler() {
65 NetworkStateHandler::~NetworkStateHandler() {
66 STLDeleteContainerPointers(network_list_
.begin(), network_list_
.end());
67 STLDeleteContainerPointers(favorite_list_
.begin(), favorite_list_
.end());
68 STLDeleteContainerPointers(device_list_
.begin(), device_list_
.end());
71 void NetworkStateHandler::InitShillPropertyHandler() {
72 shill_property_handler_
.reset(new internal::ShillPropertyHandler(this));
73 shill_property_handler_
->Init();
77 NetworkStateHandler
* NetworkStateHandler::InitializeForTest() {
78 NetworkStateHandler
* handler
= new NetworkStateHandler();
79 handler
->InitShillPropertyHandler();
83 void NetworkStateHandler::AddObserver(
84 NetworkStateHandlerObserver
* observer
,
85 const tracked_objects::Location
& from_here
) {
86 observers_
.AddObserver(observer
);
87 network_event_log::internal::AddEntry(
88 from_here
.file_name(), from_here
.line_number(),
89 network_event_log::LOG_LEVEL_DEBUG
,
90 "NetworkStateHandler::AddObserver", "");
93 void NetworkStateHandler::RemoveObserver(
94 NetworkStateHandlerObserver
* observer
,
95 const tracked_objects::Location
& from_here
) {
96 observers_
.RemoveObserver(observer
);
97 network_event_log::internal::AddEntry(
98 from_here
.file_name(), from_here
.line_number(),
99 network_event_log::LOG_LEVEL_DEBUG
,
100 "NetworkStateHandler::RemoveObserver", "");
103 void NetworkStateHandler::UpdateManagerProperties() {
104 NET_LOG_USER("UpdateManagerProperties", "");
105 shill_property_handler_
->UpdateManagerProperties();
108 NetworkStateHandler::TechnologyState
NetworkStateHandler::GetTechnologyState(
109 const NetworkTypePattern
& type
) const {
110 std::string technology
= GetTechnologyForType(type
);
111 TechnologyState state
;
112 if (shill_property_handler_
->IsTechnologyEnabled(technology
))
113 state
= TECHNOLOGY_ENABLED
;
114 else if (shill_property_handler_
->IsTechnologyEnabling(technology
))
115 state
= TECHNOLOGY_ENABLING
;
116 else if (shill_property_handler_
->IsTechnologyUninitialized(technology
))
117 state
= TECHNOLOGY_UNINITIALIZED
;
118 else if (shill_property_handler_
->IsTechnologyAvailable(technology
))
119 state
= TECHNOLOGY_AVAILABLE
;
121 state
= TECHNOLOGY_UNAVAILABLE
;
122 VLOG(2) << "GetTechnologyState: " << type
.ToDebugString() << " = " << state
;
126 void NetworkStateHandler::SetTechnologyEnabled(
127 const NetworkTypePattern
& type
,
129 const network_handler::ErrorCallback
& error_callback
) {
130 std::string technology
= GetTechnologyForType(type
);
131 NET_LOG_USER("SetTechnologyEnabled",
132 base::StringPrintf("%s:%d", technology
.c_str(), enabled
));
133 shill_property_handler_
->SetTechnologyEnabled(
134 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 FavoriteState
* NetworkStateHandler::DefaultFavoriteNetwork() const {
189 const NetworkState
* default_network
= DefaultNetwork();
190 if (!default_network
)
192 const FavoriteState
* default_favorite
=
193 GetFavoriteState(default_network
->path());
194 DCHECK(default_network
->type() != shill::kTypeWifi
||
195 default_favorite
) << "No favorite for: " << default_network
->path();
196 DCHECK(!default_favorite
|| default_favorite
->update_received())
197 << "No update received for: " << default_network
->path();
198 return default_favorite
;
201 const NetworkState
* NetworkStateHandler::ConnectedNetworkByType(
202 const NetworkTypePattern
& type
) const {
203 for (ManagedStateList::const_iterator iter
= network_list_
.begin();
204 iter
!= network_list_
.end(); ++iter
) {
205 const NetworkState
* network
= (*iter
)->AsNetworkState();
207 if (!network
->update_received())
209 if (!network
->IsConnectedState())
210 break; // Connected networks are listed first.
211 if (network
->Matches(type
))
217 const NetworkState
* NetworkStateHandler::ConnectingNetworkByType(
218 const NetworkTypePattern
& type
) const {
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
) const {
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
->Matches(type
))
247 std::string
NetworkStateHandler::FormattedHardwareAddressForType(
248 const NetworkTypePattern
& type
) const {
249 const DeviceState
* device
= NULL
;
250 const NetworkState
* network
= ConnectedNetworkByType(type
);
252 device
= GetDeviceState(network
->device_path());
254 device
= GetDeviceStateByType(type
);
256 return std::string();
257 return device
->GetFormattedMacAddress();
260 void NetworkStateHandler::GetNetworkList(NetworkStateList
* list
) const {
261 GetNetworkListByType(NetworkTypePattern::Default(), list
);
264 void NetworkStateHandler::GetNetworkListByType(const NetworkTypePattern
& type
,
265 NetworkStateList
* list
) const {
268 for (ManagedStateList::const_iterator iter
= network_list_
.begin();
269 iter
!= network_list_
.end(); ++iter
) {
270 const NetworkState
* network
= (*iter
)->AsNetworkState();
272 if (network
->update_received() && network
->Matches(type
))
273 list
->push_back(network
);
277 void NetworkStateHandler::GetDeviceList(DeviceStateList
* list
) const {
278 GetDeviceListByType(NetworkTypePattern::Default(), list
);
281 void NetworkStateHandler::GetDeviceListByType(const NetworkTypePattern
& type
,
282 DeviceStateList
* list
) const {
285 for (ManagedStateList::const_iterator iter
= device_list_
.begin();
286 iter
!= device_list_
.end(); ++iter
) {
287 const DeviceState
* device
= (*iter
)->AsDeviceState();
289 if (device
->update_received() && device
->Matches(type
))
290 list
->push_back(device
);
294 void NetworkStateHandler::GetFavoriteList(FavoriteStateList
* list
) const {
295 GetFavoriteListByType(NetworkTypePattern::Default(), list
);
298 void NetworkStateHandler::GetFavoriteListByType(const NetworkTypePattern
& type
,
299 FavoriteStateList
* list
) const {
301 FavoriteStateList result
;
303 for (ManagedStateList::const_iterator iter
= favorite_list_
.begin();
304 iter
!= favorite_list_
.end(); ++iter
) {
305 const FavoriteState
* favorite
= (*iter
)->AsFavoriteState();
307 if (favorite
->update_received() && favorite
->is_favorite() &&
308 favorite
->Matches(type
)) {
309 list
->push_back(favorite
);
314 const FavoriteState
* NetworkStateHandler::GetFavoriteState(
315 const std::string
& service_path
) const {
316 ManagedState
* managed
=
317 GetModifiableManagedState(&favorite_list_
, service_path
);
320 const FavoriteState
* favorite
= managed
->AsFavoriteState();
322 if (!favorite
->update_received() || !favorite
->is_favorite())
327 void NetworkStateHandler::RequestScan() const {
328 NET_LOG_USER("RequestScan", "");
329 shill_property_handler_
->RequestScan();
332 void NetworkStateHandler::WaitForScan(const std::string
& type
,
333 const base::Closure
& callback
) {
334 scan_complete_callbacks_
[type
].push_back(callback
);
335 if (!GetScanningByType(NetworkTypePattern::Primitive(type
)))
339 void NetworkStateHandler::ConnectToBestWifiNetwork() {
340 NET_LOG_USER("ConnectToBestWifiNetwork", "");
341 WaitForScan(shill::kTypeWifi
,
342 base::Bind(&internal::ShillPropertyHandler::ConnectToBestServices
,
343 shill_property_handler_
->AsWeakPtr()));
346 void NetworkStateHandler::RequestUpdateForNetwork(
347 const std::string
& service_path
) {
348 NetworkState
* network
= GetModifiableNetworkState(service_path
);
350 network
->set_update_requested(true);
351 NET_LOG_EVENT("RequestUpdate", service_path
);
352 shill_property_handler_
->RequestProperties(
353 ManagedState::MANAGED_TYPE_NETWORK
, service_path
);
356 void NetworkStateHandler::RequestUpdateForAllNetworks() {
357 NET_LOG_EVENT("RequestUpdateForAllNetworks", "");
358 for (ManagedStateList::iterator iter
= network_list_
.begin();
359 iter
!= network_list_
.end(); ++iter
) {
360 ManagedState
* network
= *iter
;
361 network
->set_update_requested(true);
362 shill_property_handler_
->RequestProperties(
363 ManagedState::MANAGED_TYPE_NETWORK
, network
->path());
367 void NetworkStateHandler::SetCheckPortalList(
368 const std::string
& check_portal_list
) {
369 NET_LOG_EVENT("SetCheckPortalList", check_portal_list
);
370 shill_property_handler_
->SetCheckPortalList(check_portal_list
);
373 const FavoriteState
* NetworkStateHandler::GetEAPForEthernet(
374 const std::string
& service_path
) const {
375 const NetworkState
* network
= GetNetworkState(service_path
);
377 NET_LOG_ERROR("GetEAPForEthernet", "Unknown service path " + service_path
);
380 if (network
->type() != shill::kTypeEthernet
) {
381 NET_LOG_ERROR("GetEAPForEthernet", "Not of type Ethernet: " + service_path
);
384 if (!network
->IsConnectedState())
387 // The same EAP service is shared for all ethernet services/devices.
388 // However EAP is used/enabled per device and only if the connection was
389 // successfully established.
390 const DeviceState
* device
= GetDeviceState(network
->device_path());
394 base::StringPrintf("Unknown device %s of connected ethernet service %s",
395 network
->device_path().c_str(),
396 service_path
.c_str()));
399 if (!device
->eap_authentication_completed())
402 FavoriteStateList list
;
403 GetFavoriteListByType(NetworkTypePattern::Primitive(shill::kTypeEthernetEap
),
406 NET_LOG_ERROR("GetEAPForEthernet",
408 "Ethernet service %s connected using EAP, but no "
409 "EAP service found.",
410 service_path
.c_str()));
413 DCHECK(list
.size() == 1);
417 void NetworkStateHandler::GetNetworkStatePropertiesForTest(
418 base::DictionaryValue
* dictionary
) const {
419 for (ManagedStateList::const_iterator iter
= network_list_
.begin();
420 iter
!= network_list_
.end(); ++iter
) {
421 base::DictionaryValue
* network_dict
= new base::DictionaryValue
;
422 (*iter
)->AsNetworkState()->GetProperties(network_dict
);
423 dictionary
->SetWithoutPathExpansion((*iter
)->path(), network_dict
);
427 //------------------------------------------------------------------------------
428 // ShillPropertyHandler::Delegate overrides
430 void NetworkStateHandler::UpdateManagedList(ManagedState::ManagedType type
,
431 const base::ListValue
& entries
) {
432 ManagedStateList
* managed_list
= GetManagedList(type
);
433 NET_LOG_DEBUG(base::StringPrintf("UpdateManagedList:%d", type
),
434 base::StringPrintf("%" PRIuS
, entries
.GetSize()));
435 // Create a map of existing entries. Assumes all entries in |managed_list|
437 std::map
<std::string
, ManagedState
*> managed_map
;
438 for (ManagedStateList::iterator iter
= managed_list
->begin();
439 iter
!= managed_list
->end(); ++iter
) {
440 ManagedState
* managed
= *iter
;
441 DCHECK(!ContainsKey(managed_map
, managed
->path()));
442 managed_map
[managed
->path()] = managed
;
444 // Clear the list (pointers are temporarily owned by managed_map).
445 managed_list
->clear();
446 // Updates managed_list and request updates for new entries.
447 std::set
<std::string
> list_entries
;
448 for (base::ListValue::const_iterator iter
= entries
.begin();
449 iter
!= entries
.end(); ++iter
) {
451 (*iter
)->GetAsString(&path
);
452 if (path
.empty() || path
== shill::kFlimflamServicePath
) {
453 NET_LOG_ERROR(base::StringPrintf("Bad path in list:%d", type
), path
);
456 std::map
<std::string
, ManagedState
*>::iterator found
=
457 managed_map
.find(path
);
458 ManagedState
* managed
;
459 if (found
== managed_map
.end()) {
460 if (list_entries
.count(path
) != 0) {
461 NET_LOG_ERROR("Duplicate entry in list", path
);
464 managed
= ManagedState::Create(type
, path
);
465 managed_list
->push_back(managed
);
467 managed
= found
->second
;
468 managed_list
->push_back(managed
);
469 managed_map
.erase(found
);
471 list_entries
.insert(path
);
473 // Delete any remaining entries in managed_map.
474 STLDeleteContainerPairSecondPointers(managed_map
.begin(), managed_map
.end());
477 void NetworkStateHandler::ProfileListChanged() {
478 NET_LOG_EVENT("ProfileListChanged", "Re-Requesting Network Properties");
479 for (ManagedStateList::iterator iter
= network_list_
.begin();
480 iter
!= network_list_
.end(); ++iter
) {
481 shill_property_handler_
->RequestProperties(
482 ManagedState::MANAGED_TYPE_NETWORK
, (*iter
)->path());
486 void NetworkStateHandler::UpdateManagedStateProperties(
487 ManagedState::ManagedType type
,
488 const std::string
& path
,
489 const base::DictionaryValue
& properties
) {
490 ManagedStateList
* managed_list
= GetManagedList(type
);
491 ManagedState
* managed
= GetModifiableManagedState(managed_list
, path
);
493 if (type
!= ManagedState::MANAGED_TYPE_FAVORITE
) {
494 // The network has been removed from the list of visible networks.
495 NET_LOG_DEBUG("UpdateManagedStateProperties: Not found", path
);
498 // A Favorite may not have been created yet if it was added later (e.g.
499 // through ConfigureService) since ServiceCompleteList updates are not
500 // emitted. Add and update the state here.
501 managed
= new FavoriteState(path
);
502 managed_list
->push_back(managed
);
504 managed
->set_update_received();
506 std::string desc
= GetManagedStateLogType(managed
) + " PropertiesReceived";
507 NET_LOG_DEBUG(desc
, GetManagedStateLogName(managed
));
509 if (type
== ManagedState::MANAGED_TYPE_NETWORK
) {
510 UpdateNetworkStateProperties(managed
->AsNetworkState(), properties
);
513 for (base::DictionaryValue::Iterator
iter(properties
);
514 !iter
.IsAtEnd(); iter
.Advance()) {
515 managed
->PropertyChanged(iter
.key(), iter
.value());
517 managed
->InitialPropertiesReceived(properties
);
519 managed
->set_update_requested(false);
522 void NetworkStateHandler::UpdateNetworkStateProperties(
523 NetworkState
* network
,
524 const base::DictionaryValue
& properties
) {
526 bool network_property_updated
= false;
527 std::string prev_connection_state
= network
->connection_state();
528 for (base::DictionaryValue::Iterator
iter(properties
);
529 !iter
.IsAtEnd(); iter
.Advance()) {
530 if (network
->PropertyChanged(iter
.key(), iter
.value()))
531 network_property_updated
= true;
533 network_property_updated
|= network
->InitialPropertiesReceived(properties
);
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 OnNetworkConnectionStateChanged(network
);
539 NET_LOG_EVENT("NetworkPropertiesUpdated", GetManagedStateLogName(network
));
540 NotifyNetworkPropertiesUpdated(network
);
544 void NetworkStateHandler::UpdateNetworkServiceProperty(
545 const std::string
& service_path
,
546 const std::string
& key
,
547 const base::Value
& value
) {
548 // Update any associated FavoriteState.
549 ManagedState
* favorite
=
550 GetModifiableManagedState(&favorite_list_
, service_path
);
551 bool changed
= false;
553 changed
|= favorite
->PropertyChanged(key
, value
);
555 // Update the NetworkState.
556 NetworkState
* network
= GetModifiableNetworkState(service_path
);
559 std::string prev_connection_state
= network
->connection_state();
560 std::string prev_profile_path
= network
->profile_path();
561 changed
|= network
->PropertyChanged(key
, value
);
565 if (key
== shill::kStateProperty
) {
566 if (ConnectionStateChanged(network
, prev_connection_state
)) {
567 OnNetworkConnectionStateChanged(network
);
568 // If the connection state changes, other properties such as IPConfig
569 // may have changed, so request a full update.
570 RequestUpdateForNetwork(service_path
);
573 std::string value_str
;
574 value
.GetAsString(&value_str
);
575 // Some property changes are noisy and not interesting:
576 // * Wifi SignalStrength
577 // * WifiFrequencyList updates
578 // * Device property changes to "/" (occurs before a service is removed)
579 if (key
!= shill::kSignalStrengthProperty
&&
580 key
!= shill::kWifiFrequencyListProperty
&&
581 (key
!= shill::kDeviceProperty
|| value_str
!= "/")) {
582 std::string log_event
= "NetworkPropertyUpdated";
583 // Trigger a default network update for interesting changes only.
584 if (network
->path() == default_network_path_
) {
585 NotifyDefaultNetworkChanged(network
);
586 log_event
= "Default" + log_event
;
589 std::string detail
= network
->name() + "." + key
;
590 detail
+= " = " + network_event_log::ValueAsString(value
);
591 network_event_log::LogLevel log_level
;
592 if (key
== shill::kErrorProperty
|| key
== shill::kErrorDetailsProperty
) {
593 log_level
= network_event_log::LOG_LEVEL_ERROR
;
595 log_level
= network_event_log::LOG_LEVEL_EVENT
;
597 NET_LOG_LEVEL(log_level
, log_event
, detail
);
601 // All property updates signal 'NetworkPropertiesUpdated'.
602 NotifyNetworkPropertiesUpdated(network
);
604 // If added to a Profile, request a full update so that a FavoriteState
606 if (prev_profile_path
.empty() && !network
->profile_path().empty())
607 RequestUpdateForNetwork(service_path
);
610 void NetworkStateHandler::UpdateDeviceProperty(const std::string
& device_path
,
611 const std::string
& key
,
612 const base::Value
& value
) {
613 DeviceState
* device
= GetModifiableDeviceState(device_path
);
616 if (!device
->PropertyChanged(key
, value
))
619 std::string detail
= device
->name() + "." + key
;
620 detail
+= " = " + network_event_log::ValueAsString(value
);
621 NET_LOG_EVENT("DevicePropertyUpdated", detail
);
623 NotifyDeviceListChanged();
625 if (key
== shill::kScanningProperty
&& device
->scanning() == false)
626 ScanCompleted(device
->type());
627 if (key
== shill::kEapAuthenticationCompletedProperty
) {
628 // Notify a change for each Ethernet service using this device.
629 NetworkStateList ethernet_services
;
630 GetNetworkListByType(NetworkTypePattern::Ethernet(), ðernet_services
);
631 for (NetworkStateList::const_iterator it
= ethernet_services
.begin();
632 it
!= ethernet_services
.end(); ++it
) {
633 const NetworkState
* ethernet_service
= *it
;
634 if (ethernet_service
->update_received() ||
635 ethernet_service
->device_path() != device
->path()) {
638 RequestUpdateForNetwork(ethernet_service
->path());
643 void NetworkStateHandler::CheckPortalListChanged(
644 const std::string
& check_portal_list
) {
645 check_portal_list_
= check_portal_list
;
648 void NetworkStateHandler::TechnologyListChanged() {
649 // Eventually we would like to replace Technology state with Device state.
650 // For now, treat technology state changes as device list changes.
651 NotifyDeviceListChanged();
654 void NetworkStateHandler::ManagedStateListChanged(
655 ManagedState::ManagedType type
) {
656 if (type
== ManagedState::MANAGED_TYPE_NETWORK
) {
657 // Notify observers that the list of networks has changed.
658 NET_LOG_EVENT("NetworkListChanged",
659 base::StringPrintf("Size:%" PRIuS
, network_list_
.size()));
660 FOR_EACH_OBSERVER(NetworkStateHandlerObserver
, observers_
,
661 NetworkListChanged());
663 UMA_HISTOGRAM_COUNTS_100("Networks.Visible", network_list_
.size());
664 } else if (type
== ManagedState::MANAGED_TYPE_FAVORITE
) {
665 NET_LOG_DEBUG("FavoriteListChanged",
666 base::StringPrintf("Size:%" PRIuS
, favorite_list_
.size()));
667 // The FavoriteState list only changes when the NetworkState list changes,
668 // so no need to signal observers here again.
671 size_t shared
= 0, unshared
= 0;
672 for (ManagedStateList::iterator iter
= favorite_list_
.begin();
673 iter
!= favorite_list_
.end(); ++iter
) {
674 FavoriteState
* favorite
= (*iter
)->AsFavoriteState();
675 if (!favorite
->is_favorite())
677 if (favorite
->IsPrivate())
682 UMA_HISTOGRAM_COUNTS_100("Networks.RememberedShared", shared
);
683 UMA_HISTOGRAM_COUNTS_100("Networks.RememberedUnshared", unshared
);
684 } else if (type
== ManagedState::MANAGED_TYPE_DEVICE
) {
685 NotifyDeviceListChanged();
691 void NetworkStateHandler::DefaultNetworkServiceChanged(
692 const std::string
& service_path
) {
693 // Shill uses '/' for empty service path values; check explicitly for that.
694 const char* kEmptyServicePath
= "/";
695 if (service_path
== kEmptyServicePath
)
696 default_network_path_
.clear();
698 default_network_path_
= service_path
;
699 NET_LOG_EVENT("DefaultNetworkServiceChanged:", default_network_path_
);
700 const NetworkState
* network
= NULL
;
701 if (!default_network_path_
.empty()) {
702 network
= GetNetworkState(default_network_path_
);
704 // If NetworkState is not available yet, do not notify observers here,
705 // they will be notified when the state is received.
706 NET_LOG_DEBUG("Default NetworkState not available",
707 default_network_path_
);
711 if (network
&& !network
->IsConnectedState()) {
713 "DefaultNetwork is not connected: " + network
->connection_state(),
716 NotifyDefaultNetworkChanged(network
);
719 //------------------------------------------------------------------------------
722 void NetworkStateHandler::NotifyDeviceListChanged() {
723 NET_LOG_DEBUG("NotifyDeviceListChanged",
724 base::StringPrintf("Size:%" PRIuS
, device_list_
.size()));
725 FOR_EACH_OBSERVER(NetworkStateHandlerObserver
, observers_
,
726 DeviceListChanged());
729 DeviceState
* NetworkStateHandler::GetModifiableDeviceState(
730 const std::string
& device_path
) const {
731 ManagedState
* managed
= GetModifiableManagedState(&device_list_
, device_path
);
734 return managed
->AsDeviceState();
737 NetworkState
* NetworkStateHandler::GetModifiableNetworkState(
738 const std::string
& service_path
) const {
739 ManagedState
* managed
=
740 GetModifiableManagedState(&network_list_
, service_path
);
743 return managed
->AsNetworkState();
746 ManagedState
* NetworkStateHandler::GetModifiableManagedState(
747 const ManagedStateList
* managed_list
,
748 const std::string
& path
) const {
749 for (ManagedStateList::const_iterator iter
= managed_list
->begin();
750 iter
!= managed_list
->end(); ++iter
) {
751 ManagedState
* managed
= *iter
;
752 if (managed
->path() == path
)
758 NetworkStateHandler::ManagedStateList
* NetworkStateHandler::GetManagedList(
759 ManagedState::ManagedType type
) {
761 case ManagedState::MANAGED_TYPE_NETWORK
:
762 return &network_list_
;
763 case ManagedState::MANAGED_TYPE_FAVORITE
:
764 return &favorite_list_
;
765 case ManagedState::MANAGED_TYPE_DEVICE
:
766 return &device_list_
;
772 void NetworkStateHandler::OnNetworkConnectionStateChanged(
773 NetworkState
* network
) {
775 std::string event
= "NetworkConnectionStateChanged";
776 if (network
->path() == default_network_path_
) {
777 event
= "Default" + event
;
778 if (!network
->IsConnectedState()) {
780 "DefaultNetwork is not connected: " + network
->connection_state(),
784 NET_LOG_EVENT(event
+ ": " + network
->connection_state(),
785 GetManagedStateLogName(network
));
786 FOR_EACH_OBSERVER(NetworkStateHandlerObserver
, observers_
,
787 NetworkConnectionStateChanged(network
));
788 if (network
->path() == default_network_path_
)
789 NotifyDefaultNetworkChanged(network
);
792 void NetworkStateHandler::NotifyDefaultNetworkChanged(
793 const NetworkState
* default_network
) {
794 FOR_EACH_OBSERVER(NetworkStateHandlerObserver
, observers_
,
795 DefaultNetworkChanged(default_network
));
798 void NetworkStateHandler::NotifyNetworkPropertiesUpdated(
799 const NetworkState
* network
) {
800 FOR_EACH_OBSERVER(NetworkStateHandlerObserver
, observers_
,
801 NetworkPropertiesUpdated(network
));
804 void NetworkStateHandler::ScanCompleted(const std::string
& type
) {
805 size_t num_callbacks
= scan_complete_callbacks_
.count(type
);
806 NET_LOG_EVENT("ScanCompleted",
807 base::StringPrintf("%s:%" PRIuS
, type
.c_str(), num_callbacks
));
808 if (num_callbacks
== 0)
810 ScanCallbackList
& callback_list
= scan_complete_callbacks_
[type
];
811 for (ScanCallbackList::iterator iter
= callback_list
.begin();
812 iter
!= callback_list
.end(); ++iter
) {
815 scan_complete_callbacks_
.erase(type
);
818 std::string
NetworkStateHandler::GetTechnologyForType(
819 const NetworkTypePattern
& type
) const {
820 if (type
.MatchesType(shill::kTypeEthernet
))
821 return shill::kTypeEthernet
;
823 if (type
.MatchesType(shill::kTypeWifi
))
824 return shill::kTypeWifi
;
826 if (type
.Equals(NetworkTypePattern::Wimax()))
827 return shill::kTypeWimax
;
829 // Prefer Wimax over Cellular only if it's available.
830 if (type
.MatchesType(shill::kTypeWimax
) &&
831 shill_property_handler_
->IsTechnologyAvailable(shill::kTypeWimax
)) {
832 return shill::kTypeWimax
;
835 if (type
.MatchesType(shill::kTypeCellular
))
836 return shill::kTypeCellular
;
839 return std::string();
842 } // namespace chromeos