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 ScopedVector<std::string> technologies = GetTechnologiesForType(type);
131 for (ScopedVector<std::string>::iterator it = technologies.begin();
132 it != technologies.end(); ++it) {
133 std::string* technology = *it;
135 NET_LOG_USER("SetTechnologyEnabled",
136 base::StringPrintf("%s:%d", technology->c_str(), enabled));
137 shill_property_handler_->SetTechnologyEnabled(
138 *technology, enabled, error_callback);
140 // Signal Device/Technology state changed.
141 NotifyDeviceListChanged();
144 const DeviceState* NetworkStateHandler::GetDeviceState(
145 const std::string& device_path) const {
146 const DeviceState* device = GetModifiableDeviceState(device_path);
147 if (device && !device->update_received())
152 const DeviceState* NetworkStateHandler::GetDeviceStateByType(
153 const NetworkTypePattern& type) const {
154 for (ManagedStateList::const_iterator iter = device_list_.begin();
155 iter != device_list_.end(); ++iter) {
156 ManagedState* device = *iter;
157 if (!device->update_received())
159 if (device->Matches(type))
160 return device->AsDeviceState();
165 bool NetworkStateHandler::GetScanningByType(
166 const NetworkTypePattern& type) const {
167 for (ManagedStateList::const_iterator iter = device_list_.begin();
168 iter != device_list_.end(); ++iter) {
169 const DeviceState* device = (*iter)->AsDeviceState();
171 if (!device->update_received())
173 if (device->Matches(type) && device->scanning())
179 const NetworkState* NetworkStateHandler::GetNetworkState(
180 const std::string& service_path) const {
181 const NetworkState* network = GetModifiableNetworkState(service_path);
182 if (network && !network->update_received())
187 const NetworkState* NetworkStateHandler::DefaultNetwork() const {
188 if (default_network_path_.empty())
190 return GetNetworkState(default_network_path_);
193 const FavoriteState* NetworkStateHandler::DefaultFavoriteNetwork() const {
194 const NetworkState* default_network = DefaultNetwork();
195 if (!default_network)
197 const FavoriteState* default_favorite =
198 GetFavoriteState(default_network->path());
199 DCHECK(default_network->type() != shill::kTypeWifi ||
200 default_favorite) << "No favorite for: " << default_network->path();
201 DCHECK(!default_favorite || default_favorite->update_received())
202 << "No update received for: " << default_network->path();
203 return default_favorite;
206 const NetworkState* NetworkStateHandler::ConnectedNetworkByType(
207 const NetworkTypePattern& type) const {
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())
214 if (!network->IsConnectedState())
215 break; // Connected networks are listed first.
216 if (network->Matches(type))
222 const NetworkState* NetworkStateHandler::ConnectingNetworkByType(
223 const NetworkTypePattern& type) const {
224 for (ManagedStateList::const_iterator iter = network_list_.begin();
225 iter != network_list_.end(); ++iter) {
226 const NetworkState* network = (*iter)->AsNetworkState();
228 if (!network->update_received() || network->IsConnectedState())
230 if (!network->IsConnectingState())
231 break; // Connected and connecting networks are listed first.
232 if (network->Matches(type))
238 const NetworkState* NetworkStateHandler::FirstNetworkByType(
239 const NetworkTypePattern& type) const {
240 for (ManagedStateList::const_iterator iter = network_list_.begin();
241 iter != network_list_.end(); ++iter) {
242 const NetworkState* network = (*iter)->AsNetworkState();
244 if (!network->update_received())
246 if (network->Matches(type))
252 std::string NetworkStateHandler::FormattedHardwareAddressForType(
253 const NetworkTypePattern& type) const {
254 const DeviceState* device = NULL;
255 const NetworkState* network = ConnectedNetworkByType(type);
257 device = GetDeviceState(network->device_path());
259 device = GetDeviceStateByType(type);
261 return std::string();
262 return device->GetFormattedMacAddress();
265 void NetworkStateHandler::GetNetworkList(NetworkStateList* list) const {
266 GetNetworkListByType(NetworkTypePattern::Default(), list);
269 void NetworkStateHandler::GetNetworkListByType(const NetworkTypePattern& type,
270 NetworkStateList* list) const {
273 for (ManagedStateList::const_iterator iter = network_list_.begin();
274 iter != network_list_.end(); ++iter) {
275 const NetworkState* network = (*iter)->AsNetworkState();
277 if (network->update_received() && network->Matches(type))
278 list->push_back(network);
282 void NetworkStateHandler::GetDeviceList(DeviceStateList* list) const {
283 GetDeviceListByType(NetworkTypePattern::Default(), list);
286 void NetworkStateHandler::GetDeviceListByType(const NetworkTypePattern& type,
287 DeviceStateList* list) const {
290 for (ManagedStateList::const_iterator iter = device_list_.begin();
291 iter != device_list_.end(); ++iter) {
292 const DeviceState* device = (*iter)->AsDeviceState();
294 if (device->update_received() && device->Matches(type))
295 list->push_back(device);
299 void NetworkStateHandler::GetFavoriteList(FavoriteStateList* list) const {
300 GetFavoriteListByType(NetworkTypePattern::Default(), list);
303 void NetworkStateHandler::GetFavoriteListByType(const NetworkTypePattern& type,
304 FavoriteStateList* list) const {
306 FavoriteStateList result;
308 for (ManagedStateList::const_iterator iter = favorite_list_.begin();
309 iter != favorite_list_.end(); ++iter) {
310 const FavoriteState* favorite = (*iter)->AsFavoriteState();
312 if (favorite->update_received() && favorite->IsFavorite() &&
313 favorite->Matches(type)) {
314 list->push_back(favorite);
319 const FavoriteState* NetworkStateHandler::GetFavoriteState(
320 const std::string& service_path) const {
321 ManagedState* managed =
322 GetModifiableManagedState(&favorite_list_, service_path);
325 const FavoriteState* favorite = managed->AsFavoriteState();
327 if (!favorite->update_received() || !favorite->IsFavorite())
332 void NetworkStateHandler::RequestScan() const {
333 NET_LOG_USER("RequestScan", "");
334 shill_property_handler_->RequestScan();
337 void NetworkStateHandler::WaitForScan(const std::string& type,
338 const base::Closure& callback) {
339 scan_complete_callbacks_[type].push_back(callback);
340 if (!GetScanningByType(NetworkTypePattern::Primitive(type)))
344 void NetworkStateHandler::ConnectToBestWifiNetwork() {
345 NET_LOG_USER("ConnectToBestWifiNetwork", "");
346 WaitForScan(shill::kTypeWifi,
347 base::Bind(&internal::ShillPropertyHandler::ConnectToBestServices,
348 shill_property_handler_->AsWeakPtr()));
351 void NetworkStateHandler::RequestUpdateForNetwork(
352 const std::string& service_path) {
353 NetworkState* network = GetModifiableNetworkState(service_path);
355 network->set_update_requested(true);
356 NET_LOG_EVENT("RequestUpdate", service_path);
357 shill_property_handler_->RequestProperties(
358 ManagedState::MANAGED_TYPE_NETWORK, service_path);
361 void NetworkStateHandler::ClearLastErrorForNetwork(
362 const std::string& service_path) {
363 NetworkState* network = GetModifiableNetworkState(service_path);
365 network->clear_last_error();
368 void NetworkStateHandler::SetCheckPortalList(
369 const std::string& check_portal_list) {
370 NET_LOG_EVENT("SetCheckPortalList", check_portal_list);
371 shill_property_handler_->SetCheckPortalList(check_portal_list);
374 const FavoriteState* NetworkStateHandler::GetEAPForEthernet(
375 const std::string& service_path) const {
376 const NetworkState* network = GetNetworkState(service_path);
378 NET_LOG_ERROR("GetEAPForEthernet", "Unknown service path " + service_path);
381 if (network->type() != shill::kTypeEthernet) {
382 NET_LOG_ERROR("GetEAPForEthernet", "Not of type Ethernet: " + service_path);
385 if (!network->IsConnectedState())
388 // The same EAP service is shared for all ethernet services/devices.
389 // However EAP is used/enabled per device and only if the connection was
390 // successfully established.
391 const DeviceState* device = GetDeviceState(network->device_path());
395 base::StringPrintf("Unknown device %s of connected ethernet service %s",
396 network->device_path().c_str(),
397 service_path.c_str()));
400 if (!device->eap_authentication_completed())
403 FavoriteStateList list;
404 GetFavoriteListByType(NetworkTypePattern::Primitive(shill::kTypeEthernetEap),
407 NET_LOG_ERROR("GetEAPForEthernet",
409 "Ethernet service %s connected using EAP, but no "
410 "EAP service found.",
411 service_path.c_str()));
414 DCHECK(list.size() == 1);
418 //------------------------------------------------------------------------------
419 // ShillPropertyHandler::Delegate overrides
421 void NetworkStateHandler::UpdateManagedList(ManagedState::ManagedType type,
422 const base::ListValue& entries) {
423 ManagedStateList* managed_list = GetManagedList(type);
424 NET_LOG_DEBUG(base::StringPrintf("UpdateManagedList:%d", type),
425 base::StringPrintf("%" PRIuS, entries.GetSize()));
426 // Create a map of existing entries. Assumes all entries in |managed_list|
428 std::map<std::string, ManagedState*> managed_map;
429 for (ManagedStateList::iterator iter = managed_list->begin();
430 iter != managed_list->end(); ++iter) {
431 ManagedState* managed = *iter;
432 DCHECK(!ContainsKey(managed_map, managed->path()));
433 managed_map[managed->path()] = managed;
435 // Clear the list (pointers are temporarily owned by managed_map).
436 managed_list->clear();
437 // Updates managed_list and request updates for new entries.
438 std::set<std::string> list_entries;
439 for (base::ListValue::const_iterator iter = entries.begin();
440 iter != entries.end(); ++iter) {
442 (*iter)->GetAsString(&path);
443 if (path.empty() || path == shill::kFlimflamServicePath) {
444 NET_LOG_ERROR(base::StringPrintf("Bad path in list:%d", type), path);
447 std::map<std::string, ManagedState*>::iterator found =
448 managed_map.find(path);
449 ManagedState* managed;
450 if (found == managed_map.end()) {
451 if (list_entries.count(path) != 0) {
452 NET_LOG_ERROR("Duplicate entry in list", path);
455 managed = ManagedState::Create(type, path);
456 managed_list->push_back(managed);
458 managed = found->second;
459 managed_list->push_back(managed);
460 managed_map.erase(found);
462 list_entries.insert(path);
464 // Delete any remaining entries in managed_map.
465 STLDeleteContainerPairSecondPointers(managed_map.begin(), managed_map.end());
468 void NetworkStateHandler::ProfileListChanged() {
469 NET_LOG_EVENT("ProfileListChanged", "Re-Requesting Network Properties");
470 for (ManagedStateList::iterator iter = favorite_list_.begin();
471 iter != favorite_list_.end(); ++iter) {
472 shill_property_handler_->RequestProperties(
473 ManagedState::MANAGED_TYPE_NETWORK, (*iter)->path());
477 void NetworkStateHandler::UpdateManagedStateProperties(
478 ManagedState::ManagedType type,
479 const std::string& path,
480 const base::DictionaryValue& properties) {
481 ManagedStateList* managed_list = GetManagedList(type);
482 ManagedState* managed = GetModifiableManagedState(managed_list, path);
484 if (type != ManagedState::MANAGED_TYPE_FAVORITE) {
485 // The network has been removed from the list of visible networks.
486 NET_LOG_DEBUG("UpdateManagedStateProperties: Not found", path);
489 // A Favorite may not have been created yet if it was added later (e.g.
490 // through ConfigureService) since ServiceCompleteList updates are not
491 // emitted. Add and update the state here.
492 managed = new FavoriteState(path);
493 managed_list->push_back(managed);
495 managed->set_update_received();
497 std::string desc = GetManagedStateLogType(managed) + " Properties Received";
498 NET_LOG_DEBUG(desc, GetManagedStateLogName(managed));
500 if (type == ManagedState::MANAGED_TYPE_NETWORK) {
501 UpdateNetworkStateProperties(managed->AsNetworkState(), properties);
504 for (base::DictionaryValue::Iterator iter(properties);
505 !iter.IsAtEnd(); iter.Advance()) {
506 managed->PropertyChanged(iter.key(), iter.value());
508 managed->InitialPropertiesReceived(properties);
510 managed->set_update_requested(false);
513 void NetworkStateHandler::UpdateNetworkStateProperties(
514 NetworkState* network,
515 const base::DictionaryValue& properties) {
517 bool network_property_updated = false;
518 std::string prev_connection_state = network->connection_state();
519 for (base::DictionaryValue::Iterator iter(properties);
520 !iter.IsAtEnd(); iter.Advance()) {
521 if (network->PropertyChanged(iter.key(), iter.value()))
522 network_property_updated = true;
524 network_property_updated |= network->InitialPropertiesReceived(properties);
525 // Notify observers of NetworkState changes.
526 if (network_property_updated || network->update_requested()) {
527 // Signal connection state changed after all properties have been updated.
528 if (ConnectionStateChanged(network, prev_connection_state))
529 OnNetworkConnectionStateChanged(network);
530 NET_LOG_EVENT("NetworkPropertiesUpdated", GetManagedStateLogName(network));
531 NotifyNetworkPropertiesUpdated(network);
535 void NetworkStateHandler::UpdateNetworkServiceProperty(
536 const std::string& service_path,
537 const std::string& key,
538 const base::Value& value) {
539 // Update any associated FavoriteState.
540 ManagedState* favorite =
541 GetModifiableManagedState(&favorite_list_, service_path);
542 bool changed = false;
544 changed |= favorite->PropertyChanged(key, value);
546 // Update the NetworkState.
547 NetworkState* network = GetModifiableNetworkState(service_path);
550 std::string prev_connection_state = network->connection_state();
551 std::string prev_profile_path = network->profile_path();
552 changed |= network->PropertyChanged(key, value);
556 if (key == shill::kStateProperty) {
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 += " = " + network_event_log::ValueAsString(value);
582 network_event_log::LogLevel log_level;
583 if (key == shill::kErrorProperty || key == shill::kErrorDetailsProperty) {
584 log_level = network_event_log::LOG_LEVEL_ERROR;
586 log_level = network_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 FavoriteState
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 += " = " + network_event_log::ValueAsString(value);
612 NET_LOG_EVENT("DevicePropertyUpdated", detail);
614 NotifyDeviceListChanged();
616 if (key == shill::kScanningProperty && device->scanning() == false)
617 ScanCompleted(device->type());
618 if (key == shill::kEapAuthenticationCompletedProperty) {
619 // Notify a change for each Ethernet service using this device.
620 NetworkStateList ethernet_services;
621 GetNetworkListByType(NetworkTypePattern::Ethernet(), ðernet_services);
622 for (NetworkStateList::const_iterator it = ethernet_services.begin();
623 it != ethernet_services.end(); ++it) {
624 const NetworkState* ethernet_service = *it;
625 if (ethernet_service->update_received() ||
626 ethernet_service->device_path() != device->path()) {
629 RequestUpdateForNetwork(ethernet_service->path());
634 void NetworkStateHandler::UpdateIPConfigProperties(
635 ManagedState::ManagedType type,
636 const std::string& path,
637 const std::string& ip_config_path,
638 const base::DictionaryValue& properties) {
639 if (type == ManagedState::MANAGED_TYPE_NETWORK) {
640 NetworkState* network = GetModifiableNetworkState(path);
643 network->IPConfigPropertiesChanged(properties);
644 } else if (type == ManagedState::MANAGED_TYPE_DEVICE) {
645 DeviceState* device = GetModifiableDeviceState(path);
648 device->IPConfigPropertiesChanged(ip_config_path, properties);
652 void NetworkStateHandler::CheckPortalListChanged(
653 const std::string& check_portal_list) {
654 check_portal_list_ = check_portal_list;
657 void NetworkStateHandler::TechnologyListChanged() {
658 // Eventually we would like to replace Technology state with Device state.
659 // For now, treat technology state changes as device list changes.
660 NotifyDeviceListChanged();
663 void NetworkStateHandler::ManagedStateListChanged(
664 ManagedState::ManagedType type) {
665 if (type == ManagedState::MANAGED_TYPE_NETWORK) {
666 // Notify observers that the list of networks has changed.
667 NET_LOG_EVENT("NetworkListChanged",
668 base::StringPrintf("Size:%" PRIuS, network_list_.size()));
669 FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_,
670 NetworkListChanged());
672 UMA_HISTOGRAM_COUNTS_100("Networks.Visible", network_list_.size());
673 } else if (type == ManagedState::MANAGED_TYPE_FAVORITE) {
674 NET_LOG_DEBUG("FavoriteListChanged",
675 base::StringPrintf("Size:%" PRIuS, favorite_list_.size()));
676 // The FavoriteState list only changes when the NetworkState list changes,
677 // so no need to signal observers here again.
680 size_t shared = 0, unshared = 0;
681 for (ManagedStateList::iterator iter = favorite_list_.begin();
682 iter != favorite_list_.end(); ++iter) {
683 FavoriteState* favorite = (*iter)->AsFavoriteState();
684 if (!favorite->IsFavorite())
686 if (favorite->IsPrivate())
691 UMA_HISTOGRAM_COUNTS_100("Networks.RememberedShared", shared);
692 UMA_HISTOGRAM_COUNTS_100("Networks.RememberedUnshared", unshared);
693 } else if (type == ManagedState::MANAGED_TYPE_DEVICE) {
694 NotifyDeviceListChanged();
700 void NetworkStateHandler::DefaultNetworkServiceChanged(
701 const std::string& service_path) {
702 // Shill uses '/' for empty service path values; check explicitly for that.
703 const char* kEmptyServicePath = "/";
704 if (service_path == kEmptyServicePath)
705 default_network_path_.clear();
707 default_network_path_ = service_path;
708 NET_LOG_EVENT("DefaultNetworkServiceChanged:", default_network_path_);
709 const NetworkState* network = NULL;
710 if (!default_network_path_.empty()) {
711 network = GetNetworkState(default_network_path_);
713 // If NetworkState is not available yet, do not notify observers here,
714 // they will be notified when the state is received.
715 NET_LOG_DEBUG("Default NetworkState not available",
716 default_network_path_);
720 if (network && !network->IsConnectedState()) {
722 "DefaultNetwork is not connected: " + network->connection_state(),
725 NotifyDefaultNetworkChanged(network);
728 //------------------------------------------------------------------------------
731 void NetworkStateHandler::NotifyDeviceListChanged() {
732 NET_LOG_DEBUG("NotifyDeviceListChanged",
733 base::StringPrintf("Size:%" PRIuS, device_list_.size()));
734 FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_,
735 DeviceListChanged());
738 DeviceState* NetworkStateHandler::GetModifiableDeviceState(
739 const std::string& device_path) const {
740 ManagedState* managed = GetModifiableManagedState(&device_list_, device_path);
743 return managed->AsDeviceState();
746 NetworkState* NetworkStateHandler::GetModifiableNetworkState(
747 const std::string& service_path) const {
748 ManagedState* managed =
749 GetModifiableManagedState(&network_list_, service_path);
752 return managed->AsNetworkState();
755 ManagedState* NetworkStateHandler::GetModifiableManagedState(
756 const ManagedStateList* managed_list,
757 const std::string& path) const {
758 for (ManagedStateList::const_iterator iter = managed_list->begin();
759 iter != managed_list->end(); ++iter) {
760 ManagedState* managed = *iter;
761 if (managed->path() == path)
767 NetworkStateHandler::ManagedStateList* NetworkStateHandler::GetManagedList(
768 ManagedState::ManagedType type) {
770 case ManagedState::MANAGED_TYPE_NETWORK:
771 return &network_list_;
772 case ManagedState::MANAGED_TYPE_FAVORITE:
773 return &favorite_list_;
774 case ManagedState::MANAGED_TYPE_DEVICE:
775 return &device_list_;
781 void NetworkStateHandler::OnNetworkConnectionStateChanged(
782 NetworkState* network) {
784 std::string event = "NetworkConnectionStateChanged";
785 if (network->path() == default_network_path_) {
786 event = "Default" + event;
787 if (!network->IsConnectedState()) {
789 "DefaultNetwork is not connected: " + network->connection_state(),
793 NET_LOG_EVENT(event + ": " + network->connection_state(),
794 GetManagedStateLogName(network));
795 FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_,
796 NetworkConnectionStateChanged(network));
797 if (network->path() == default_network_path_)
798 NotifyDefaultNetworkChanged(network);
801 void NetworkStateHandler::NotifyDefaultNetworkChanged(
802 const NetworkState* default_network) {
803 FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_,
804 DefaultNetworkChanged(default_network));
807 void NetworkStateHandler::NotifyNetworkPropertiesUpdated(
808 const NetworkState* network) {
809 FOR_EACH_OBSERVER(NetworkStateHandlerObserver, observers_,
810 NetworkPropertiesUpdated(network));
813 void NetworkStateHandler::ScanCompleted(const std::string& type) {
814 size_t num_callbacks = scan_complete_callbacks_.count(type);
815 NET_LOG_EVENT("ScanCompleted",
816 base::StringPrintf("%s:%" PRIuS, type.c_str(), num_callbacks));
817 if (num_callbacks == 0)
819 ScanCallbackList& callback_list = scan_complete_callbacks_[type];
820 for (ScanCallbackList::iterator iter = callback_list.begin();
821 iter != callback_list.end(); ++iter) {
824 scan_complete_callbacks_.erase(type);
827 std::string NetworkStateHandler::GetTechnologyForType(
828 const NetworkTypePattern& type) const {
829 if (type.MatchesType(shill::kTypeEthernet))
830 return shill::kTypeEthernet;
832 if (type.MatchesType(shill::kTypeWifi))
833 return shill::kTypeWifi;
835 if (type.Equals(NetworkTypePattern::Wimax()))
836 return shill::kTypeWimax;
838 // Prefer Wimax over Cellular only if it's available.
839 if (type.MatchesType(shill::kTypeWimax) &&
840 shill_property_handler_->IsTechnologyAvailable(shill::kTypeWimax)) {
841 return shill::kTypeWimax;
844 if (type.MatchesType(shill::kTypeCellular))
845 return shill::kTypeCellular;
848 return std::string();
851 ScopedVector<std::string> NetworkStateHandler::GetTechnologiesForType(
852 const NetworkTypePattern& type) const {
853 ScopedVector<std::string> technologies;
854 if (type.MatchesType(shill::kTypeEthernet))
855 technologies.push_back(new std::string(shill::kTypeEthernet));
856 if (type.MatchesType(shill::kTypeWifi))
857 technologies.push_back(new std::string(shill::kTypeWifi));
858 if (type.MatchesType(shill::kTypeWimax))
859 technologies.push_back(new std::string(shill::kTypeWimax));
860 if (type.MatchesType(shill::kTypeCellular))
861 technologies.push_back(new std::string(shill::kTypeCellular));
862 if (type.MatchesType(shill::kTypeBluetooth))
863 technologies.push_back(new std::string(shill::kTypeBluetooth));
864 if (type.MatchesType(shill::kTypeVPN))
865 technologies.push_back(new std::string(shill::kTypeVPN));
867 CHECK_GT(technologies.size(), 0ul);
868 return technologies.Pass();
871 } // namespace chromeos