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.
4 
5 #include "chromeos/network/network_state_handler.h"
6 
7 #include <stddef.h>
8 
9 #include <limits>
10 #include <memory>
11 #include <utility>
12 
13 #include "base/bind.h"
14 #include "base/command_line.h"
15 #include "base/format_macros.h"
16 #include "base/guid.h"
17 #include "base/location.h"
18 #include "base/memory/ptr_util.h"
19 #include "base/metrics/histogram_macros.h"
20 #include "base/strings/string_number_conversions.h"
21 #include "base/strings/string_util.h"
22 #include "base/strings/stringprintf.h"
23 #include "base/values.h"
24 #include "chromeos/constants/chromeos_switches.h"
25 #include "chromeos/network/device_state.h"
26 #include "chromeos/network/network_connection_handler.h"
27 #include "chromeos/network/network_device_handler.h"
28 #include "chromeos/network/network_event_log.h"
29 #include "chromeos/network/network_handler_callbacks.h"
30 #include "chromeos/network/network_state_handler_observer.h"
31 #include "chromeos/network/tether_constants.h"
32 #include "third_party/cros_system_api/dbus/service_constants.h"
33 
34 namespace chromeos {
35 
36 namespace {
37 
38 // Constants used for logging.
39 constexpr char kReasonStateChange[] = "State Change";
40 constexpr char kReasonChange[] = "New Network";
41 constexpr char kReasonUpdate[] = "Update";
42 constexpr char kReasonUpdateIPConfig[] = "UpdateIPConfig";
43 constexpr char kReasonUpdateDeviceIPConfig[] = "UpdateDeviceIPConfig";
44 constexpr char kReasonTether[] = "Tether Change";
45 
ConnectionStateChanged(const NetworkState * network,const std::string & prev_connection_state,NetworkState::PortalState prev_portal_state)46 bool ConnectionStateChanged(const NetworkState* network,
47                             const std::string& prev_connection_state,
48                             NetworkState::PortalState prev_portal_state) {
49   if (network->portal_state() != prev_portal_state)
50     return true;
51   std::string connection_state = network->connection_state();
52   bool prev_idle = prev_connection_state.empty() ||
53                    prev_connection_state == shill::kStateIdle;
54   bool cur_idle = connection_state == shill::kStateIdle;
55   if (prev_idle || cur_idle)
56     return prev_idle != cur_idle;
57   return connection_state != prev_connection_state;
58 }
59 
GetManagedStateLogType(const ManagedState * state)60 std::string GetManagedStateLogType(const ManagedState* state) {
61   switch (state->managed_type()) {
62     case ManagedState::MANAGED_TYPE_NETWORK:
63       return "Network";
64     case ManagedState::MANAGED_TYPE_DEVICE:
65       return "Device";
66   }
67   NOTREACHED();
68   return "";
69 }
70 
GetLogName(const ManagedState * state)71 std::string GetLogName(const ManagedState* state) {
72   if (!state)
73     return "None";
74   const NetworkState* network = state->AsNetworkState();
75   if (network)
76     return NetworkId(network);
77   return state->path();
78 }
79 
ShouldIncludeNetworkInList(const NetworkState * network_state,bool configured_only,bool visible_only)80 bool ShouldIncludeNetworkInList(const NetworkState* network_state,
81                                 bool configured_only,
82                                 bool visible_only) {
83   if (configured_only && !network_state->IsInProfile())
84     return false;
85 
86   if (visible_only && !network_state->visible())
87     return false;
88 
89   if (network_state->type() == shill::kTypeWifi &&
90       !network_state->tether_guid().empty()) {
91     // Wi-Fi networks which are actually underlying Wi-Fi hotspots for a
92     // Tether network should not be included since they should only be shown
93     // to the user as Tether networks.
94     return false;
95   }
96 
97   return true;
98 }
99 
100 // ManagedState entries may not have |type| set when the network is initially
101 // added to a list (i.e. before the initial properties are received). Use this
102 // wrapper anyplace where |managed| might be uninitialized.
TypeMatches(const ManagedState * managed,const NetworkTypePattern & type)103 bool TypeMatches(const ManagedState* managed, const NetworkTypePattern& type) {
104   return !managed->type().empty() && managed->Matches(type);
105 }
106 
107 }  // namespace
108 
109 // Class for tracking properties that affect whether a NetworkState is active.
110 class NetworkStateHandler::ActiveNetworkState {
111  public:
ActiveNetworkState(const NetworkState * network)112   explicit ActiveNetworkState(const NetworkState* network)
113       : guid_(network->guid()),
114         connection_state_(network->connection_state()),
115         activation_state_(network->activation_state()),
116         connect_requested_(network->connect_requested()),
117         signal_strength_(network->signal_strength()),
118         network_technology_(network->network_technology()) {}
119 
MatchesNetworkState(const NetworkState * network)120   bool MatchesNetworkState(const NetworkState* network) {
121     return guid_ == network->guid() &&
122            connection_state_ == network->connection_state() &&
123            activation_state_ == network->activation_state() &&
124            connect_requested_ == network->connect_requested() &&
125            (abs(signal_strength_ - network->signal_strength()) <
126             NetworkState::kSignalStrengthChangeThreshold) &&
127            network_technology_ == network->network_technology();
128   }
129 
130  private:
131   // Unique network identifier.
132   const std::string guid_;
133   // Active networks have a connected or connecting |connection_state_|, see
134   // NetworkState::Is{Connected|Connecting}State.
135   const std::string connection_state_;
136   // Activating Cellular networks are frequently treated like connecting
137   // networks in the UI, so we also track changes to Cellular activation state.
138   const std::string activation_state_;
139   // The connect_requested state affects 'connecting' in the UI.
140   const bool connect_requested_;
141   // We care about signal strength changes to active networks.
142   const int signal_strength_;
143   // Network technology is indicated in network icons in the UI, so we need to
144   // track changes to this value.
145   const std::string network_technology_;
146 };
147 
148 const char NetworkStateHandler::kDefaultCheckPortalList[] =
149     "ethernet,wifi,cellular";
150 
NetworkStateHandler()151 NetworkStateHandler::NetworkStateHandler() {
152   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
153 }
154 
~NetworkStateHandler()155 NetworkStateHandler::~NetworkStateHandler() {
156   // Normally Shutdown() will get called in ~NetworkHandler, however unit
157   // tests do not use that class so this needs to call Shutdown when we
158   // destroy the class.
159   if (!did_shutdown_)
160     Shutdown();
161 }
162 
Shutdown()163 void NetworkStateHandler::Shutdown() {
164   if (did_shutdown_)
165     return;  // May get called twice in tests.
166   did_shutdown_ = true;
167   for (auto& observer : observers_)
168     observer.OnShuttingDown();
169 }
170 
InitShillPropertyHandler()171 void NetworkStateHandler::InitShillPropertyHandler() {
172   shill_property_handler_ =
173       std::make_unique<internal::ShillPropertyHandler>(this);
174   shill_property_handler_->Init();
175 }
176 
UpdateBlockedWifiNetworks(bool only_managed,bool available_only,const std::vector<std::string> & blocked_hex_ssids)177 void NetworkStateHandler::UpdateBlockedWifiNetworks(
178     bool only_managed,
179     bool available_only,
180     const std::vector<std::string>& blocked_hex_ssids) {
181   if (allow_only_policy_networks_to_connect_ == only_managed &&
182       allow_only_policy_networks_to_connect_if_available_ == available_only &&
183       blocked_hex_ssids_ == blocked_hex_ssids) {
184     return;
185   }
186   allow_only_policy_networks_to_connect_ = only_managed;
187   allow_only_policy_networks_to_connect_if_available_ = available_only;
188   blocked_hex_ssids_ = blocked_hex_ssids;
189 
190   UpdateBlockedWifiNetworksInternal();
191 }
192 
GetAvailableManagedWifiNetwork() const193 const NetworkState* NetworkStateHandler::GetAvailableManagedWifiNetwork()
194     const {
195   DeviceState* device =
196       GetModifiableDeviceStateByType(NetworkTypePattern::WiFi());
197   const std::string& available_managed_network_path =
198       device->available_managed_network_path();
199   if (available_managed_network_path.empty())
200     return nullptr;
201   return GetNetworkState(available_managed_network_path);
202 }
203 
OnlyManagedWifiNetworksAllowed() const204 bool NetworkStateHandler::OnlyManagedWifiNetworksAllowed() const {
205   return allow_only_policy_networks_to_connect_ ||
206          (allow_only_policy_networks_to_connect_if_available_ &&
207           GetAvailableManagedWifiNetwork());
208 }
209 
210 // static
InitializeForTest()211 std::unique_ptr<NetworkStateHandler> NetworkStateHandler::InitializeForTest() {
212   auto handler = base::WrapUnique(new NetworkStateHandler());
213   handler->InitShillPropertyHandler();
214   return handler;
215 }
216 
AddObserver(NetworkStateHandlerObserver * observer,const base::Location & from_here)217 void NetworkStateHandler::AddObserver(NetworkStateHandlerObserver* observer,
218                                       const base::Location& from_here) {
219   observers_.AddObserver(observer);
220   device_event_log::AddEntry(
221       from_here.file_name(), from_here.line_number(),
222       device_event_log::LOG_TYPE_NETWORK, device_event_log::LOG_LEVEL_DEBUG,
223       base::StringPrintf("NetworkStateHandler::AddObserver: 0x%p", observer));
224 }
225 
RemoveObserver(NetworkStateHandlerObserver * observer,const base::Location & from_here)226 void NetworkStateHandler::RemoveObserver(NetworkStateHandlerObserver* observer,
227                                          const base::Location& from_here) {
228   observers_.RemoveObserver(observer);
229   device_event_log::AddEntry(
230       from_here.file_name(), from_here.line_number(),
231       device_event_log::LOG_TYPE_NETWORK, device_event_log::LOG_LEVEL_DEBUG,
232       base::StringPrintf("NetworkStateHandler::RemoveObserver: 0x%p",
233                          observer));
234 }
235 
HasObserver(NetworkStateHandlerObserver * observer)236 bool NetworkStateHandler::HasObserver(NetworkStateHandlerObserver* observer) {
237   return observers_.HasObserver(observer);
238 }
239 
GetTechnologyState(const NetworkTypePattern & type) const240 NetworkStateHandler::TechnologyState NetworkStateHandler::GetTechnologyState(
241     const NetworkTypePattern& type) const {
242   std::string technology = GetTechnologyForType(type);
243 
244   if (technology == kTypeTether) {
245     return tether_technology_state_;
246   }
247 
248   // If a technology is not in Shill's 'AvailableTechnologies' list, it is
249   // always unavailable.
250   if (!shill_property_handler_->IsTechnologyAvailable(technology))
251     return TECHNOLOGY_UNAVAILABLE;
252 
253   // Prohibited should take precedence over other states.
254   if (shill_property_handler_->IsTechnologyProhibited(technology))
255     return TECHNOLOGY_PROHIBITED;
256 
257   // Disabling is a pseudostate used by the UI and takes precedence over
258   // enabled.
259   if (shill_property_handler_->IsTechnologyDisabling(technology)) {
260     DCHECK(shill_property_handler_->IsTechnologyEnabled(technology));
261     return TECHNOLOGY_DISABLING;
262   }
263 
264   // Enabled and Uninitialized should be mutually exclusive. 'Enabling', which
265   // is a pseudo state used by the UI, takes precedence over 'Uninitialized',
266   // but not 'Enabled'.
267   if (shill_property_handler_->IsTechnologyEnabled(technology))
268     return TECHNOLOGY_ENABLED;
269   if (shill_property_handler_->IsTechnologyEnabling(technology))
270     return TECHNOLOGY_ENABLING;
271   if (shill_property_handler_->IsTechnologyUninitialized(technology))
272     return TECHNOLOGY_UNINITIALIZED;
273 
274   // Default state is 'Available', which is equivalent to 'Initialized but not
275   // enabled'.
276   return TECHNOLOGY_AVAILABLE;
277 }
278 
SetTechnologyEnabled(const NetworkTypePattern & type,bool enabled,network_handler::ErrorCallback error_callback)279 void NetworkStateHandler::SetTechnologyEnabled(
280     const NetworkTypePattern& type,
281     bool enabled,
282     network_handler::ErrorCallback error_callback) {
283   std::vector<std::string> technologies = GetTechnologiesForType(type);
284   for (const std::string& technology : technologies) {
285     if (technology == kTypeTether) {
286       if (tether_technology_state_ != TECHNOLOGY_ENABLED &&
287           tether_technology_state_ != TECHNOLOGY_AVAILABLE) {
288         NET_LOG(ERROR) << "SetTechnologyEnabled() called for the Tether "
289                        << "DeviceState, but the current state was: "
290                        << tether_technology_state_;
291         network_handler::RunErrorCallback(
292             std::move(error_callback), kTetherDevicePath,
293             NetworkConnectionHandler::kErrorEnabledOrDisabledWhenNotAvailable,
294             "");
295         continue;
296       }
297 
298       // Tether does not exist in Shill, so set |tether_technology_state_| and
299       // skip the below interactions with |shill_property_handler_|.
300       tether_technology_state_ =
301           enabled ? TECHNOLOGY_ENABLED : TECHNOLOGY_AVAILABLE;
302       continue;
303     }
304 
305     if (!shill_property_handler_->IsTechnologyAvailable(technology))
306       continue;
307     NET_LOG(USER) << "SetTechnologyEnabled " << technology << ":" << enabled;
308     shill_property_handler_->SetTechnologyEnabled(technology, enabled,
309                                                   std::move(error_callback));
310   }
311   // Signal Device/Technology state changed.
312   NotifyDeviceListChanged();
313 }
314 
SetTetherTechnologyState(TechnologyState technology_state)315 void NetworkStateHandler::SetTetherTechnologyState(
316     TechnologyState technology_state) {
317   if (tether_technology_state_ == technology_state)
318     return;
319 
320   tether_technology_state_ = technology_state;
321   EnsureTetherDeviceState();
322 
323   // Signal Device/Technology state changed.
324   NotifyDeviceListChanged();
325 }
326 
SetTetherScanState(bool is_scanning)327 void NetworkStateHandler::SetTetherScanState(bool is_scanning) {
328   DeviceState* tether_device_state =
329       GetModifiableDeviceState(kTetherDevicePath);
330   if (!tether_device_state) {
331     NET_LOG(ERROR) << "SetTetherScanState() called when Tether TechnologyState "
332                    << "is UNAVAILABLE; cannot set scanning state.";
333     return;
334   }
335 
336   bool was_scanning = tether_device_state->scanning();
337   tether_device_state->set_scanning(is_scanning);
338 
339   if (was_scanning && !is_scanning) {
340     // If a scan was in progress but has completed, notify observers.
341     NotifyScanCompleted(tether_device_state);
342   } else if (!was_scanning && is_scanning) {
343     // If a scan was started, notify observers.
344     NotifyScanStarted(tether_device_state);
345   }
346 }
347 
SetProhibitedTechnologies(const std::vector<std::string> & prohibited_technologies)348 void NetworkStateHandler::SetProhibitedTechnologies(
349     const std::vector<std::string>& prohibited_technologies) {
350   // Make a copy of |prohibited_technologies| since the list may be edited
351   // within this function.
352   std::vector<std::string> prohibited_technologies_copy =
353       prohibited_technologies;
354 
355   auto it = prohibited_technologies_copy.begin();
356   while (it != prohibited_technologies_copy.end()) {
357     if (*it == kTypeTether) {
358       // If Tether networks are prohibited, set |tether_technology_state_| and
359       // remove |kTypeTether| from the list before passing it to
360       // |shill_property_handler_| below. Shill does not have a concept of
361       // Tether networks, so it cannot prohibit that technology type.
362       tether_technology_state_ = TECHNOLOGY_PROHIBITED;
363       it = prohibited_technologies_copy.erase(it);
364     } else {
365       ++it;
366     }
367   }
368 
369   shill_property_handler_->SetProhibitedTechnologies(
370       prohibited_technologies_copy);
371   // Signal Device/Technology state changed.
372   NotifyDeviceListChanged();
373 }
374 
GetDeviceState(const std::string & device_path) const375 const DeviceState* NetworkStateHandler::GetDeviceState(
376     const std::string& device_path) const {
377   const DeviceState* device = GetModifiableDeviceState(device_path);
378   if (device && !device->update_received()) {
379     NET_LOG(DEBUG) << "Device exists but update not received: " << device_path;
380     return nullptr;
381   }
382   return device;
383 }
384 
GetDeviceStateByType(const NetworkTypePattern & type) const385 const DeviceState* NetworkStateHandler::GetDeviceStateByType(
386     const NetworkTypePattern& type) const {
387   const DeviceState* device = GetModifiableDeviceStateByType(type);
388   if (device && !device->update_received())
389     return nullptr;
390   return device;
391 }
392 
GetScanningByType(const NetworkTypePattern & type) const393 bool NetworkStateHandler::GetScanningByType(
394     const NetworkTypePattern& type) const {
395   for (auto iter = device_list_.begin(); iter != device_list_.end(); ++iter) {
396     const DeviceState* device = (*iter)->AsDeviceState();
397     DCHECK(device);
398     if (!device->update_received())
399       continue;
400     if (device->Matches(type) && device->scanning())
401       return true;
402   }
403   return false;
404 }
405 
GetNetworkState(const std::string & service_path) const406 const NetworkState* NetworkStateHandler::GetNetworkState(
407     const std::string& service_path) const {
408   const NetworkState* network = GetModifiableNetworkState(service_path);
409   if (network && !network->update_received())
410     return nullptr;
411   return network;
412 }
413 
DefaultNetwork() const414 const NetworkState* NetworkStateHandler::DefaultNetwork() const {
415   if (default_network_path_.empty())
416     return nullptr;
417   return GetNetworkState(default_network_path_);
418 }
419 
ConnectedNetworkByType(const NetworkTypePattern & type)420 const NetworkState* NetworkStateHandler::ConnectedNetworkByType(
421     const NetworkTypePattern& type) {
422   NetworkStateList active_networks;
423   GetActiveNetworkListByType(type, &active_networks);
424   for (auto* network : active_networks) {
425     if (network->IsConnectedState())
426       return network;
427   }
428   return nullptr;
429 }
430 
ConnectingNetworkByType(const NetworkTypePattern & type)431 const NetworkState* NetworkStateHandler::ConnectingNetworkByType(
432     const NetworkTypePattern& type) {
433   NetworkStateList active_networks;
434   GetActiveNetworkListByType(type, &active_networks);
435   for (auto* network : active_networks) {
436     if (network->IsConnectingState())
437       return network;
438   }
439   return nullptr;
440 }
441 
ActiveNetworkByType(const NetworkTypePattern & type)442 const NetworkState* NetworkStateHandler::ActiveNetworkByType(
443     const NetworkTypePattern& type) {
444   NetworkStateList active_networks;
445   GetActiveNetworkListByType(type, &active_networks);
446   if (active_networks.size() > 0)
447     return active_networks.front();
448   return nullptr;
449 }
450 
FirstNetworkByType(const NetworkTypePattern & type)451 const NetworkState* NetworkStateHandler::FirstNetworkByType(
452     const NetworkTypePattern& type) {
453   // Sort to ensure visible networks are listed first.
454   if (!network_list_sorted_)
455     SortNetworkList(false /* ensure_cellular */);
456 
457   const NetworkState* first_network = nullptr;
458   for (auto iter = network_list_.begin(); iter != network_list_.end(); ++iter) {
459     const NetworkState* network = (*iter)->AsNetworkState();
460     DCHECK(network);
461     if (!network->update_received())
462       continue;
463     if (!network->visible())
464       break;
465     if (network->Matches(type)) {
466       first_network = network;
467       break;
468     }
469   }
470 
471   // Active Ethernet networks are the highest priority.
472   if (first_network && first_network->type() == shill::kTypeEthernet)
473     return first_network;
474 
475   const NetworkState* first_tether_network =
476       type.MatchesPattern(NetworkTypePattern::Tether()) &&
477               !tether_network_list_.empty()
478           ? tether_network_list_[0]->AsNetworkState()
479           : nullptr;
480 
481   // Active Tether networks are next.
482   if (first_tether_network && first_tether_network->IsConnectingOrConnected())
483     return first_tether_network;
484 
485   // Other active networks are next.
486   if (first_network && first_network->IsConnectingOrConnected())
487     return first_network;
488 
489   // Non-active Tether networks are next.
490   if (first_tether_network)
491     return first_tether_network;
492 
493   // Other networks are last.
494   return first_network;
495 }
496 
SetNetworkConnectRequested(const std::string & service_path,bool connect_requested)497 void NetworkStateHandler::SetNetworkConnectRequested(
498     const std::string& service_path,
499     bool connect_requested) {
500   NetworkState* network = GetModifiableNetworkState(service_path);
501   if (!network)
502     return;
503   network->connect_requested_ = connect_requested;
504   network_list_sorted_ = false;
505   OnNetworkConnectionStateChanged(network);
506 }
507 
SetNetworkChromePortalDetected(const std::string & service_path,bool portal_detected)508 void NetworkStateHandler::SetNetworkChromePortalDetected(
509     const std::string& service_path,
510     bool portal_detected) {
511   NetworkState* network = GetModifiableNetworkState(service_path);
512   if (!network || network->is_chrome_captive_portal_ == portal_detected)
513     return;
514   bool was_captive_portal = network->IsCaptivePortal();
515   network->is_chrome_captive_portal_ = portal_detected;
516   // Only notify a connection state change if IsCaptivePortal() changed.
517   if (was_captive_portal == network->IsCaptivePortal())
518     return;
519   network_list_sorted_ = false;
520   OnNetworkConnectionStateChanged(network);
521 }
522 
FormattedHardwareAddressForType(const NetworkTypePattern & type)523 std::string NetworkStateHandler::FormattedHardwareAddressForType(
524     const NetworkTypePattern& type) {
525   const NetworkState* network = ConnectedNetworkByType(type);
526   if (network && network->type() == kTypeTether) {
527     // If this is a Tether network, get the MAC address corresponding to that
528     // network instead.
529     network = GetNetworkStateFromGuid(network->tether_guid());
530   }
531   const DeviceState* device = network ? GetDeviceState(network->device_path())
532                                       : GetDeviceStateByType(type);
533   if (!device || device->mac_address().empty())
534     return std::string();
535   return network_util::FormattedMacAddress(device->mac_address());
536 }
537 
GetVisibleNetworkListByType(const NetworkTypePattern & type,NetworkStateList * list)538 void NetworkStateHandler::GetVisibleNetworkListByType(
539     const NetworkTypePattern& type,
540     NetworkStateList* list) {
541   GetNetworkListByType(type, false /* configured_only */,
542                        true /* visible_only */, 0 /* no limit */, list);
543 }
544 
GetVisibleNetworkList(NetworkStateList * list)545 void NetworkStateHandler::GetVisibleNetworkList(NetworkStateList* list) {
546   GetVisibleNetworkListByType(NetworkTypePattern::Default(), list);
547 }
548 
GetNetworkListByType(const NetworkTypePattern & type,bool configured_only,bool visible_only,size_t limit,NetworkStateList * list)549 void NetworkStateHandler::GetNetworkListByType(const NetworkTypePattern& type,
550                                                bool configured_only,
551                                                bool visible_only,
552                                                size_t limit,
553                                                NetworkStateList* list) {
554   GetNetworkListByTypeImpl(type, configured_only, visible_only,
555                            false /* active_only */, limit, list);
556 }
557 
GetActiveNetworkListByType(const NetworkTypePattern & type,NetworkStateList * list)558 void NetworkStateHandler::GetActiveNetworkListByType(
559     const NetworkTypePattern& type,
560     NetworkStateList* list) {
561   GetNetworkListByTypeImpl(type, false /* configured_only */,
562                            false /* visible_only */, true /* active_only */,
563                            0 /* no limit */, list);
564 }
565 
GetNetworkListByTypeImpl(const NetworkTypePattern & type,bool configured_only,bool visible_only,bool active_only,size_t limit,NetworkStateList * list)566 void NetworkStateHandler::GetNetworkListByTypeImpl(
567     const NetworkTypePattern& type,
568     bool configured_only,
569     bool visible_only,
570     bool active_only,
571     size_t limit,
572     NetworkStateList* list) {
573   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
574   DCHECK(list);
575   list->clear();
576 
577   // If |limit| is 0, there is no limit. Simplify the calculations below by
578   // setting it to the maximum size_t value.
579   if (limit == 0)
580     limit = std::numeric_limits<size_t>::max();
581 
582   if (!network_list_sorted_)
583     SortNetworkList(false /* ensure_cellular */);
584 
585   // First, add active Tether networks.
586   if (type.MatchesPattern(NetworkTypePattern::Tether()))
587     AppendTetherNetworksToList(true /* get_active */, limit, list);
588 
589   // Second, add active non-Tether networks.
590   for (const auto& managed : network_list_) {
591     const NetworkState* network = managed.get()->AsNetworkState();
592     DCHECK(network);
593     if (!network->update_received() || !network->Matches(type))
594       continue;
595     if (!network->IsActive())
596       break;  // Active networks are listed first.
597     if (!ShouldIncludeNetworkInList(network, configured_only, visible_only))
598       continue;
599 
600     if (network->type() == shill::kTypeEthernet) {
601       // Ethernet networks should always be in front.
602       list->insert(list->begin(), network);
603     } else {
604       list->push_back(network);
605     }
606     if (list->size() >= limit)
607       return;
608   }
609 
610   if (active_only)
611     return;
612 
613   // Third, add inactive Tether networks.
614   if (type.MatchesPattern(NetworkTypePattern::Tether()))
615     AppendTetherNetworksToList(false /* get_active */, limit, list);
616   if (list->size() >= limit)
617     return;
618 
619   // Fourth, add inactive non-Tether networks.
620   for (const auto& managed : network_list_) {
621     const NetworkState* network = managed.get()->AsNetworkState();
622     DCHECK(network);
623     if (!network->update_received() || !network->Matches(type))
624       continue;
625     if (network->IsActive())
626       continue;
627     if (!ShouldIncludeNetworkInList(network, configured_only, visible_only))
628       continue;
629     list->push_back(network);
630     if (list->size() >= limit)
631       return;
632   }
633 }
634 
AppendTetherNetworksToList(bool get_active,size_t limit,NetworkStateList * list)635 void NetworkStateHandler::AppendTetherNetworksToList(bool get_active,
636                                                      size_t limit,
637                                                      NetworkStateList* list) {
638   DCHECK(list);
639   DCHECK_NE(0U, limit);
640   if (!IsTechnologyEnabled(NetworkTypePattern::Tether()))
641     return;
642 
643   for (auto iter = tether_network_list_.begin();
644        iter != tether_network_list_.end() && list->size() < limit; ++iter) {
645     const NetworkState* network = (*iter)->AsNetworkState();
646     DCHECK(network);
647     if (network->IsConnectingOrConnected() != get_active)
648       continue;
649     if (!ShouldIncludeNetworkInList(network, false /* configured_only */,
650                                     false /* visible_only */)) {
651       continue;
652     }
653     list->push_back(network);
654   }
655 }
656 
GetNetworkStateFromServicePath(const std::string & service_path,bool configured_only) const657 const NetworkState* NetworkStateHandler::GetNetworkStateFromServicePath(
658     const std::string& service_path,
659     bool configured_only) const {
660   ManagedState* managed =
661       GetModifiableManagedState(&network_list_, service_path);
662   if (!managed) {
663     managed = GetModifiableManagedState(&tether_network_list_, service_path);
664     if (!managed)
665       return nullptr;
666   }
667   const NetworkState* network = managed->AsNetworkState();
668   DCHECK(network);
669   if (!network->update_received() ||
670       (configured_only && !network->IsInProfile())) {
671     return nullptr;
672   }
673   return network;
674 }
675 
GetNetworkStateFromGuid(const std::string & guid) const676 const NetworkState* NetworkStateHandler::GetNetworkStateFromGuid(
677     const std::string& guid) const {
678   DCHECK(!guid.empty());
679   return GetModifiableNetworkStateFromGuid(guid);
680 }
681 
AddTetherNetworkState(const std::string & guid,const std::string & name,const std::string & carrier,int battery_percentage,int signal_strength,bool has_connected_to_host)682 void NetworkStateHandler::AddTetherNetworkState(const std::string& guid,
683                                                 const std::string& name,
684                                                 const std::string& carrier,
685                                                 int battery_percentage,
686                                                 int signal_strength,
687                                                 bool has_connected_to_host) {
688   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
689   DCHECK(!guid.empty());
690   DCHECK(battery_percentage >= 0 && battery_percentage <= 100);
691   DCHECK(signal_strength >= 0 && signal_strength <= 100);
692 
693   if (tether_technology_state_ != TECHNOLOGY_ENABLED) {
694     NET_LOG(ERROR) << "AddTetherNetworkState() called when Tether networks "
695                    << "are not enabled. Cannot add NetworkState.";
696     return;
697   }
698 
699   // If the network already exists, do nothing.
700   if (GetNetworkStateFromGuid(guid)) {
701     NET_LOG(ERROR) << "AddTetherNetworkState: " << name
702                    << " called with existing guid:" << guid;
703     return;
704   }
705 
706   // Use the GUID as the network's service path.
707   std::unique_ptr<NetworkState> tether_network_state =
708       std::make_unique<NetworkState>(guid /* path */);
709 
710   tether_network_state->set_name(name);
711   tether_network_state->set_type(kTypeTether);
712   tether_network_state->SetGuid(guid);
713   tether_network_state->set_visible(true);
714   tether_network_state->set_update_received();
715   tether_network_state->set_update_requested(false);
716   tether_network_state->set_connectable(true);
717   tether_network_state->set_tether_carrier(carrier);
718   tether_network_state->set_battery_percentage(battery_percentage);
719   tether_network_state->set_tether_has_connected_to_host(has_connected_to_host);
720   tether_network_state->set_signal_strength(signal_strength);
721 
722   tether_network_list_.push_back(std::move(tether_network_state));
723   network_list_sorted_ = false;
724 
725   NotifyNetworkListChanged();
726 }
727 
UpdateTetherNetworkProperties(const std::string & guid,const std::string & carrier,int battery_percentage,int signal_strength)728 bool NetworkStateHandler::UpdateTetherNetworkProperties(
729     const std::string& guid,
730     const std::string& carrier,
731     int battery_percentage,
732     int signal_strength) {
733   if (tether_technology_state_ != TECHNOLOGY_ENABLED) {
734     NET_LOG(ERROR) << "UpdateTetherNetworkProperties() called when Tether "
735                    << "networks are not enabled. Cannot update.";
736     return false;
737   }
738 
739   NetworkState* tether_network_state = GetModifiableNetworkStateFromGuid(guid);
740   if (!tether_network_state) {
741     NET_LOG(ERROR) << "UpdateTetherNetworkProperties(): No NetworkState for "
742                    << "Tether network with GUID \"" << guid << "\".";
743     return false;
744   }
745 
746   tether_network_state->set_tether_carrier(carrier);
747   tether_network_state->set_battery_percentage(battery_percentage);
748   tether_network_state->set_signal_strength(signal_strength);
749   network_list_sorted_ = false;
750 
751   NotifyNetworkPropertiesUpdated(tether_network_state);
752   return true;
753 }
754 
SetTetherNetworkHasConnectedToHost(const std::string & guid)755 bool NetworkStateHandler::SetTetherNetworkHasConnectedToHost(
756     const std::string& guid) {
757   NetworkState* tether_network_state = GetModifiableNetworkStateFromGuid(guid);
758   if (!tether_network_state) {
759     NET_LOG(ERROR) << "SetTetherNetworkHasConnectedToHost(): No NetworkState "
760                    << "for Tether network with GUID \"" << guid << "\".";
761     return false;
762   }
763 
764   if (tether_network_state->tether_has_connected_to_host()) {
765     return false;
766   }
767 
768   tether_network_state->set_tether_has_connected_to_host(true);
769   network_list_sorted_ = false;
770 
771   NotifyNetworkPropertiesUpdated(tether_network_state);
772   return true;
773 }
774 
RemoveTetherNetworkState(const std::string & guid)775 bool NetworkStateHandler::RemoveTetherNetworkState(const std::string& guid) {
776   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
777   CHECK(!notifying_network_observers_);
778   for (auto iter = tether_network_list_.begin();
779        iter != tether_network_list_.end(); ++iter) {
780     if (iter->get()->AsNetworkState()->guid() == guid) {
781       const NetworkState* tether_network = iter->get()->AsNetworkState();
782       bool was_active = tether_network->IsConnectingOrConnected();
783       NetworkState* wifi_network =
784           GetModifiableNetworkStateFromGuid(tether_network->tether_guid());
785       if (wifi_network)
786         wifi_network->set_tether_guid(std::string());
787       tether_network_list_.erase(iter);
788 
789       if (was_active)
790         NotifyIfActiveNetworksChanged();
791       NotifyNetworkListChanged();
792       return true;
793     }
794   }
795   return false;
796 }
797 
DisassociateTetherNetworkStateFromWifiNetwork(const std::string & tether_network_guid)798 bool NetworkStateHandler::DisassociateTetherNetworkStateFromWifiNetwork(
799     const std::string& tether_network_guid) {
800   NetworkState* tether_network_state =
801       GetModifiableNetworkStateFromGuid(tether_network_guid);
802 
803   if (!tether_network_state) {
804     NET_LOG(ERROR) << "DisassociateTetherNetworkStateWithWifiNetwork(): Tether "
805                    << "network with ID " << tether_network_guid
806                    << " not registered; could not remove association.";
807     return false;
808   }
809 
810   std::string wifi_network_guid = tether_network_state->tether_guid();
811   NetworkState* wifi_network_state =
812       GetModifiableNetworkStateFromGuid(wifi_network_guid);
813 
814   if (!wifi_network_state) {
815     NET_LOG(ERROR) << "DisassociateTetherNetworkStateWithWifiNetwork(): Wi-Fi "
816                    << "network with ID " << wifi_network_guid
817                    << " not registered; could not remove association.";
818     return false;
819   }
820 
821   if (wifi_network_state->tether_guid().empty() &&
822       tether_network_state->tether_guid().empty()) {
823     return true;
824   }
825 
826   wifi_network_state->set_tether_guid(std::string());
827   tether_network_state->set_tether_guid(std::string());
828   network_list_sorted_ = false;
829 
830   NotifyNetworkPropertiesUpdated(wifi_network_state);
831   NotifyNetworkPropertiesUpdated(tether_network_state);
832 
833   return true;
834 }
835 
AssociateTetherNetworkStateWithWifiNetwork(const std::string & tether_network_guid,const std::string & wifi_network_guid)836 bool NetworkStateHandler::AssociateTetherNetworkStateWithWifiNetwork(
837     const std::string& tether_network_guid,
838     const std::string& wifi_network_guid) {
839   if (tether_technology_state_ != TECHNOLOGY_ENABLED) {
840     NET_LOG(ERROR) << "AssociateTetherNetworkStateWithWifiNetwork() called "
841                    << "when Tether networks are not enabled. Cannot "
842                    << "associate.";
843     return false;
844   }
845 
846   NetworkState* tether_network_state =
847       GetModifiableNetworkStateFromGuid(tether_network_guid);
848   if (!tether_network_state) {
849     NET_LOG(ERROR) << "Tether network does not exist: " << tether_network_guid;
850     return false;
851   }
852   if (!NetworkTypePattern::Tether().MatchesType(tether_network_state->type())) {
853     NET_LOG(ERROR) << "Network is not a Tether network: "
854                    << tether_network_guid;
855     return false;
856   }
857 
858   NetworkState* wifi_network_state =
859       GetModifiableNetworkStateFromGuid(wifi_network_guid);
860   if (!wifi_network_state) {
861     NET_LOG(ERROR) << "Wi-Fi Network does not exist: " << wifi_network_guid;
862     return false;
863   }
864   if (!NetworkTypePattern::WiFi().MatchesType(wifi_network_state->type())) {
865     NET_LOG(ERROR) << "Network is not a W-Fi network: "
866                    << NetworkId(wifi_network_state);
867     return false;
868   }
869 
870   if (wifi_network_state->tether_guid() == tether_network_guid &&
871       tether_network_state->tether_guid() == wifi_network_guid) {
872     return true;
873   }
874 
875   tether_network_state->set_tether_guid(wifi_network_guid);
876   wifi_network_state->set_tether_guid(tether_network_guid);
877   network_list_sorted_ = false;
878 
879   NotifyNetworkPropertiesUpdated(wifi_network_state);
880   NotifyNetworkPropertiesUpdated(tether_network_state);
881 
882   return true;
883 }
884 
SetTetherNetworkStateDisconnected(const std::string & guid)885 void NetworkStateHandler::SetTetherNetworkStateDisconnected(
886     const std::string& guid) {
887   SetTetherNetworkStateConnectionState(guid, shill::kStateIdle);
888 }
889 
SetTetherNetworkStateConnecting(const std::string & guid)890 void NetworkStateHandler::SetTetherNetworkStateConnecting(
891     const std::string& guid) {
892   // The default network should only be set if there currently is no default
893   // network. Otherwise, the default network should not change unless the
894   // connection completes successfully and the newly-connected network is
895   // prioritized higher than the existing default network. Note that, in
896   // general, a connected Ethernet network is still considered the default
897   // network even if a Tether or Wi-Fi network becomes connected.
898   if (default_network_path_.empty()) {
899     NET_LOG(EVENT) << "Connecting to Tether network when there is currently no "
900                    << "default network; setting as new default network. GUID: "
901                    << guid;
902     SetDefaultNetworkValues(guid, /*metered=*/true);
903   }
904 
905   SetTetherNetworkStateConnectionState(guid, shill::kStateConfiguration);
906 }
907 
SetTetherNetworkStateConnected(const std::string & guid)908 void NetworkStateHandler::SetTetherNetworkStateConnected(
909     const std::string& guid) {
910   // Being connected implies that AssociateTetherNetworkStateWithWifiNetwork()
911   // was already called, so ensure that the association is still intact.
912   DCHECK(GetNetworkStateFromGuid(GetNetworkStateFromGuid(guid)->tether_guid())
913              ->tether_guid() == guid);
914 
915   // At this point, there should be a default network set.
916   DCHECK(!default_network_path_.empty());
917 
918   SetTetherNetworkStateConnectionState(guid, shill::kStateOnline);
919 }
920 
SetTetherNetworkStateConnectionState(const std::string & guid,const std::string & connection_state)921 void NetworkStateHandler::SetTetherNetworkStateConnectionState(
922     const std::string& guid,
923     const std::string& connection_state) {
924   NetworkState* tether_network_state = GetModifiableNetworkStateFromGuid(guid);
925   if (!tether_network_state) {
926     NET_LOG(ERROR) << "SetTetherNetworkStateConnectionState: Tether network "
927                    << "not found: " << guid;
928     return;
929   }
930 
931   DCHECK(
932       NetworkTypePattern::Tether().MatchesType(tether_network_state->type()));
933 
934   std::string prev_connection_state = tether_network_state->connection_state();
935   tether_network_state->SetConnectionState(connection_state);
936   network_list_sorted_ = false;
937 
938   if (ConnectionStateChanged(tether_network_state, prev_connection_state,
939                              tether_network_state->portal_state())) {
940     NET_LOG(EVENT) << "Changing connection state for Tether network with GUID "
941                    << guid << ". Old state: " << prev_connection_state << ", "
942                    << "New state: " << connection_state;
943     if (!tether_network_state->IsConnectingOrConnected() &&
944         tether_network_state->path() == default_network_path_) {
945       SetDefaultNetworkValues(/*path=*/std::string(), /*metered=*/false);
946       NotifyDefaultNetworkChanged(kReasonTether);
947     }
948     OnNetworkConnectionStateChanged(tether_network_state);
949     NotifyNetworkPropertiesUpdated(tether_network_state);
950   }
951 }
952 
EnsureTetherDeviceState()953 void NetworkStateHandler::EnsureTetherDeviceState() {
954   bool should_be_present =
955       tether_technology_state_ != TechnologyState::TECHNOLOGY_UNAVAILABLE;
956 
957   for (auto it = device_list_.begin(); it < device_list_.end(); ++it) {
958     std::string path = (*it)->path();
959     if (path == kTetherDevicePath) {
960       // If the Tether DeviceState is in the list and it should not be, remove
961       // it and return. If it is in the list and it should be, the list is
962       // already valid, so return without removing it.
963       if (!should_be_present)
964         device_list_.erase(it);
965       return;
966     }
967   }
968 
969   if (!should_be_present) {
970     // If the Tether DeviceState was not in the list and it should not be, the
971     // list is already valid, so return.
972     return;
973   }
974 
975   // The Tether DeviceState is not present in the list, but it should be. Since
976   // Tether networks are not recognized by Shill, they will never receive an
977   // update, so set properties on the state here.
978   std::unique_ptr<ManagedState> tether_device_state = ManagedState::Create(
979       ManagedState::ManagedType::MANAGED_TYPE_DEVICE, kTetherDevicePath);
980   tether_device_state->set_update_received();
981   tether_device_state->set_update_requested(false);
982   tether_device_state->set_name(kTetherDeviceName);
983   tether_device_state->set_type(kTypeTether);
984 
985   device_list_.push_back(std::move(tether_device_state));
986 }
987 
UpdateBlockedByPolicy(NetworkState * network) const988 bool NetworkStateHandler::UpdateBlockedByPolicy(NetworkState* network) const {
989   if (!TypeMatches(network, NetworkTypePattern::WiFi()))
990     return false;
991 
992   bool prev_blocked_by_policy = network->blocked_by_policy();
993   bool blocked_by_policy =
994       !network->IsManagedByPolicy() &&
995       (OnlyManagedWifiNetworksAllowed() ||
996        base::Contains(blocked_hex_ssids_, network->GetHexSsid()));
997   network->set_blocked_by_policy(blocked_by_policy);
998   return prev_blocked_by_policy != blocked_by_policy;
999 }
1000 
UpdateManagedWifiNetworkAvailable()1001 void NetworkStateHandler::UpdateManagedWifiNetworkAvailable() {
1002   DeviceState* device =
1003       GetModifiableDeviceStateByType(NetworkTypePattern::WiFi());
1004   if (!device || !device->update_received())
1005     return;  // May be null in tests.
1006 
1007   const std::string prev_available_managed_network_path =
1008       device->available_managed_network_path();
1009   std::string available_managed_network_path;
1010 
1011   NetworkStateHandler::NetworkStateList networks;
1012   GetNetworkListByType(NetworkTypePattern::WiFi(), true, true, 0, &networks);
1013   for (const NetworkState* network : networks) {
1014     if (network->IsManagedByPolicy()) {
1015       available_managed_network_path = network->path();
1016       break;
1017     }
1018   }
1019 
1020   if (prev_available_managed_network_path != available_managed_network_path) {
1021     device->set_available_managed_network_path(available_managed_network_path);
1022     UpdateBlockedWifiNetworksInternal();
1023     NotifyDevicePropertiesUpdated(device);
1024   }
1025 }
1026 
UpdateBlockedWifiNetworksInternal()1027 void NetworkStateHandler::UpdateBlockedWifiNetworksInternal() {
1028   for (auto iter = network_list_.begin(); iter != network_list_.end(); ++iter) {
1029     NetworkState* network = (*iter)->AsNetworkState();
1030     if (!network->Matches(NetworkTypePattern::WiFi()))
1031       continue;
1032     if (UpdateBlockedByPolicy(network))
1033       NotifyNetworkPropertiesUpdated(network);
1034   }
1035 }
1036 
GetDeviceList(DeviceStateList * list) const1037 void NetworkStateHandler::GetDeviceList(DeviceStateList* list) const {
1038   GetDeviceListByType(NetworkTypePattern::Default(), list);
1039 }
1040 
GetDeviceListByType(const NetworkTypePattern & type,DeviceStateList * list) const1041 void NetworkStateHandler::GetDeviceListByType(const NetworkTypePattern& type,
1042                                               DeviceStateList* list) const {
1043   DCHECK(list);
1044   list->clear();
1045 
1046   for (auto iter = device_list_.begin(); iter != device_list_.end(); ++iter) {
1047     const DeviceState* device = (*iter)->AsDeviceState();
1048     DCHECK(device);
1049     if (device->update_received() && device->Matches(type))
1050       list->push_back(device);
1051   }
1052 }
1053 
RequestScan(const NetworkTypePattern & type)1054 void NetworkStateHandler::RequestScan(const NetworkTypePattern& type) {
1055   NET_LOG(USER) << "RequestScan: " << type.ToDebugString();
1056   if (type.MatchesPattern(NetworkTypePattern::WiFi())) {
1057     if (IsTechnologyEnabled(NetworkTypePattern::WiFi()))
1058       shill_property_handler_->RequestScanByType(shill::kTypeWifi);
1059     else if (type.Equals(NetworkTypePattern::WiFi()))
1060       return;  // Skip notify if disabled and wifi only requested.
1061   }
1062 
1063   if (type.Equals(NetworkTypePattern::Cellular())) {
1064     // Only request a Cellular scan if Cellular is requested explicitly.
1065     if (IsTechnologyEnabled(NetworkTypePattern::Cellular()))
1066       shill_property_handler_->RequestScanByType(shill::kTypeCellular);
1067     else
1068       return;  // Skip notify if disabled and cellular only requested.
1069   }
1070 
1071   // Note: for Tether we initiate the scan in the observer.
1072   NotifyScanRequested(type);
1073 }
1074 
RequestUpdateForNetwork(const std::string & service_path)1075 void NetworkStateHandler::RequestUpdateForNetwork(
1076     const std::string& service_path) {
1077   NetworkState* network = GetModifiableNetworkState(service_path);
1078   if (network) {
1079     // Tether networks are not managed by Shill; do not request properties.
1080     if (network->type() == kTypeTether)
1081       return;
1082     // Do not request properties if a condition has already triggered a request.
1083     if (network->update_requested())
1084       return;
1085     network->set_update_requested(true);
1086     NET_LOG(EVENT) << "RequestUpdate for: " << NetworkId(network);
1087   } else {
1088     NET_LOG(EVENT) << "RequestUpdate for: " << NetworkPathId(service_path);
1089   }
1090   shill_property_handler_->RequestProperties(ManagedState::MANAGED_TYPE_NETWORK,
1091                                              service_path);
1092 }
1093 
SendUpdateNotificationForNetwork(const std::string & service_path)1094 void NetworkStateHandler::SendUpdateNotificationForNetwork(
1095     const std::string& service_path) {
1096   const NetworkState* network = GetNetworkState(service_path);
1097   if (!network)
1098     return;
1099   NotifyNetworkPropertiesUpdated(network);
1100 }
1101 
ClearLastErrorForNetwork(const std::string & service_path)1102 void NetworkStateHandler::ClearLastErrorForNetwork(
1103     const std::string& service_path) {
1104   NetworkState* network = GetModifiableNetworkState(service_path);
1105   if (network)
1106     network->ClearError();
1107 }
1108 
SetCheckPortalList(const std::string & check_portal_list)1109 void NetworkStateHandler::SetCheckPortalList(
1110     const std::string& check_portal_list) {
1111   NET_LOG(EVENT) << "SetCheckPortalList: " << check_portal_list;
1112   shill_property_handler_->SetCheckPortalList(check_portal_list);
1113 }
1114 
SetWakeOnLanEnabled(bool enabled)1115 void NetworkStateHandler::SetWakeOnLanEnabled(bool enabled) {
1116   NET_LOG(EVENT) << "SetWakeOnLanEnabled: " << enabled;
1117   shill_property_handler_->SetWakeOnLanEnabled(enabled);
1118 }
1119 
SetHostname(const std::string & hostname)1120 void NetworkStateHandler::SetHostname(const std::string& hostname) {
1121   NET_LOG(EVENT) << "SetHostname: " << hostname;
1122   shill_property_handler_->SetHostname(hostname);
1123 }
1124 
SetNetworkThrottlingStatus(bool enabled,uint32_t upload_rate_kbits,uint32_t download_rate_kbits)1125 void NetworkStateHandler::SetNetworkThrottlingStatus(
1126     bool enabled,
1127     uint32_t upload_rate_kbits,
1128     uint32_t download_rate_kbits) {
1129   if (enabled) {
1130     NET_LOG(EVENT) << "SetNetworkThrottlingStatus: Enabled: "
1131                    << upload_rate_kbits << ", " << download_rate_kbits;
1132   } else {
1133     NET_LOG(EVENT) << "SetNetworkThrottlingStatus: Disabled.";
1134   }
1135   shill_property_handler_->SetNetworkThrottlingStatus(
1136       enabled, upload_rate_kbits, download_rate_kbits);
1137 }
1138 
SetFastTransitionStatus(bool enabled)1139 void NetworkStateHandler::SetFastTransitionStatus(bool enabled) {
1140   NET_LOG(USER) << "SetFastTransitionStatus: " << enabled;
1141   shill_property_handler_->SetFastTransitionStatus(enabled);
1142 }
1143 
GetEAPForEthernet(const std::string & service_path,bool connected_only)1144 const NetworkState* NetworkStateHandler::GetEAPForEthernet(
1145     const std::string& service_path,
1146     bool connected_only) {
1147   const NetworkState* network = GetNetworkState(service_path);
1148   if (!network) {
1149     NET_LOG(ERROR) << "GetEAPForEthernet: Unknown service: "
1150                    << NetworkPathId(service_path);
1151     return nullptr;
1152   }
1153   if (network->type() != shill::kTypeEthernet) {
1154     NET_LOG(ERROR) << "GetEAPForEthernet: Not Ethernet: " << NetworkId(network);
1155     return nullptr;
1156   }
1157   if (connected_only) {
1158     if (!network->IsConnectedState()) {
1159       NET_LOG(DEBUG) << "GetEAPForEthernet: Not connected.";
1160       return nullptr;
1161     }
1162 
1163     // The same EAP service is shared for all ethernet services/devices.
1164     // However EAP is used/enabled per device and only if the connection was
1165     // successfully established.
1166     const DeviceState* device = GetDeviceState(network->device_path());
1167     if (!device) {
1168       NET_LOG(ERROR) << "GetEAPForEthernet: Unknown device "
1169                      << network->device_path()
1170                      << " for connected ethernet service: "
1171                      << NetworkId(network);
1172       return nullptr;
1173     }
1174     if (!device->eap_authentication_completed()) {
1175       NET_LOG(DEBUG) << "GetEAPForEthernet: EAP Authenticaiton not completed.";
1176       return nullptr;
1177     }
1178   }
1179 
1180   NetworkStateList list;
1181   GetNetworkListByType(NetworkTypePattern::Primitive(shill::kTypeEthernetEap),
1182                        true /* configured_only */, false /* visible_only */,
1183                        1 /* limit */, &list);
1184   if (list.empty()) {
1185     if (connected_only) {
1186       NET_LOG(ERROR)
1187           << "GetEAPForEthernet: Connected using EAP but no EAP service found: "
1188           << NetworkId(network);
1189     }
1190     return nullptr;
1191   }
1192   return list.front();
1193 }
1194 
SetErrorForTest(const std::string & service_path,const std::string & error)1195 void NetworkStateHandler::SetErrorForTest(const std::string& service_path,
1196                                           const std::string& error) {
1197   NetworkState* network_state = GetModifiableNetworkState(service_path);
1198   if (!network_state) {
1199     NET_LOG(ERROR) << "No matching NetworkState for: "
1200                    << NetworkPathId(service_path);
1201     return;
1202   }
1203   network_state->last_error_ = error;
1204 }
1205 
SetDeviceStateUpdatedForTest(const std::string & device_path)1206 void NetworkStateHandler::SetDeviceStateUpdatedForTest(
1207     const std::string& device_path) {
1208   DeviceState* device = GetModifiableDeviceState(device_path);
1209   DCHECK(device);
1210   device->set_update_received();
1211 }
1212 
1213 //------------------------------------------------------------------------------
1214 // ShillPropertyHandler::Delegate overrides
1215 
UpdateManagedList(ManagedState::ManagedType type,const base::ListValue & entries)1216 void NetworkStateHandler::UpdateManagedList(ManagedState::ManagedType type,
1217                                             const base::ListValue& entries) {
1218   CHECK(!notifying_network_observers_);
1219   ManagedStateList* managed_list = GetManagedList(type);
1220   NET_LOG(DEBUG) << "UpdateManagedList: " << ManagedState::TypeToString(type)
1221                  << ": " << entries.GetSize();
1222   // Create a map of existing entries. Assumes all entries in |managed_list|
1223   // are unique.
1224   std::map<std::string, std::unique_ptr<ManagedState>> managed_map;
1225   for (auto& item : *managed_list) {
1226     std::string path = item->path();
1227     DCHECK(!base::Contains(managed_map, path));
1228     managed_map[path] = std::move(item);
1229   }
1230   // Clear the list (objects are temporarily owned by managed_map).
1231   managed_list->clear();
1232   // Updates managed_list and request updates for new entries.
1233   std::set<std::string> list_entries;
1234   for (auto& iter : entries) {
1235     std::string path;
1236     iter.GetAsString(&path);
1237     if (path.empty() || path == shill::kFlimflamServicePath) {
1238       NET_LOG(ERROR) << "Bad path in type " << type << " Path: " << path;
1239       continue;
1240     }
1241     auto found = managed_map.find(path);
1242     if (found == managed_map.end()) {
1243       if (list_entries.count(path) != 0) {
1244         NET_LOG(ERROR) << "Duplicate entry in list for " << path;
1245         continue;
1246       }
1247       managed_list->push_back(ManagedState::Create(type, path));
1248     } else {
1249       managed_list->push_back(std::move(found->second));
1250       managed_map.erase(found);
1251     }
1252     list_entries.insert(path);
1253   }
1254 
1255   if (type == ManagedState::ManagedType::MANAGED_TYPE_DEVICE) {
1256     // Also move the Tether DeviceState if it exists. This will not happen as
1257     // part of the loop above since |entries| will never contain the Tether
1258     // path.
1259     auto iter = managed_map.find(kTetherDevicePath);
1260     if (iter != managed_map.end()) {
1261       managed_list->push_back(std::move(iter->second));
1262       managed_map.erase(iter);
1263     }
1264   }
1265 
1266   UpdateManagedWifiNetworkAvailable();
1267 
1268   if (type != ManagedState::ManagedType::MANAGED_TYPE_NETWORK)
1269     return;
1270 
1271   // Remove associations Tether NetworkStates had with now removed Wi-Fi
1272   // NetworkStates.
1273   for (auto& iter : managed_map) {
1274     ManagedState* managed = iter.second.get();
1275     if (!TypeMatches(managed, NetworkTypePattern::WiFi()))
1276       continue;
1277     NetworkState* tether_network = GetModifiableNetworkStateFromGuid(
1278         managed->AsNetworkState()->tether_guid());
1279     if (tether_network)
1280       tether_network->set_tether_guid(std::string());
1281   }
1282 }
1283 
ProfileListChanged()1284 void NetworkStateHandler::ProfileListChanged() {
1285   NET_LOG(EVENT) << "ProfileListChanged. Re-Requesting Network Properties";
1286   for (ManagedStateList::iterator iter = network_list_.begin();
1287        iter != network_list_.end(); ++iter) {
1288     const NetworkState* network = (*iter)->AsNetworkState();
1289     DCHECK(network);
1290     shill_property_handler_->RequestProperties(
1291         ManagedState::MANAGED_TYPE_NETWORK, network->path());
1292   }
1293 }
1294 
UpdateManagedStateProperties(ManagedState::ManagedType type,const std::string & path,const base::Value & properties)1295 void NetworkStateHandler::UpdateManagedStateProperties(
1296     ManagedState::ManagedType type,
1297     const std::string& path,
1298     const base::Value& properties) {
1299   ManagedStateList* managed_list = GetManagedList(type);
1300   ManagedState* managed = GetModifiableManagedState(managed_list, path);
1301   if (!managed) {
1302     // The network has been removed from the list of networks.
1303     NET_LOG(DEBUG) << "UpdateManagedStateProperties: Not found: " << path;
1304     return;
1305   }
1306   managed->set_update_received();
1307 
1308   NET_LOG(DEBUG) << GetManagedStateLogType(managed)
1309                  << " Properties Received: " << GetLogName(managed);
1310 
1311   if (type == ManagedState::MANAGED_TYPE_NETWORK) {
1312     UpdateNetworkStateProperties(managed->AsNetworkState(), properties);
1313   } else {
1314     // Device
1315     for (const auto iter : properties.DictItems())
1316       managed->PropertyChanged(iter.first, iter.second);
1317     managed->InitialPropertiesReceived(properties);
1318   }
1319   managed->set_update_requested(false);
1320 }
1321 
UpdateNetworkStateProperties(NetworkState * network,const base::Value & properties)1322 void NetworkStateHandler::UpdateNetworkStateProperties(
1323     NetworkState* network,
1324     const base::Value& properties) {
1325   DCHECK(network);
1326   bool network_property_updated = false;
1327   std::string prev_connection_state = network->connection_state();
1328   NetworkState::PortalState prev_portal_state = network->portal_state();
1329   bool metered = false;
1330   for (const auto iter : properties.DictItems()) {
1331     if (network->PropertyChanged(iter.first, iter.second))
1332       network_property_updated = true;
1333     if (iter.first == shill::kMeteredProperty)
1334       metered = iter.second.is_bool() && iter.second.GetBool();
1335   }
1336   if (network->path() == default_network_path_)
1337     default_network_is_metered_ = metered && network->IsConnectedState();
1338 
1339   if (network->Matches(NetworkTypePattern::WiFi()))
1340     network_property_updated |= UpdateBlockedByPolicy(network);
1341   network_property_updated |= network->InitialPropertiesReceived(properties);
1342 
1343   UpdateGuid(network);
1344   if (network->Matches(NetworkTypePattern::Cellular()))
1345     UpdateCellularStateFromDevice(network);
1346 
1347   network_list_sorted_ = false;
1348 
1349   // Notify observers of NetworkState changes.
1350   if (network_property_updated || network->update_requested()) {
1351     // Signal connection state changed after all properties have been updated.
1352     if (ConnectionStateChanged(network, prev_connection_state,
1353                                prev_portal_state)) {
1354       // Also notifies that the default network changed if this is the default.
1355       OnNetworkConnectionStateChanged(network);
1356     } else if (network->path() == default_network_path_ &&
1357                network->IsActive()) {
1358       // Always notify that the default network changed for a complete update.
1359       NET_LOG(DEBUG) << "UpdateNetworkStateProperties for default: "
1360                      << NetworkId(network);
1361       NotifyDefaultNetworkChanged(kReasonUpdate);
1362     }
1363     NotifyNetworkPropertiesUpdated(network);
1364   }
1365 }
1366 
UpdateNetworkServiceProperty(const std::string & service_path,const std::string & key,const base::Value & value)1367 void NetworkStateHandler::UpdateNetworkServiceProperty(
1368     const std::string& service_path,
1369     const std::string& key,
1370     const base::Value& value) {
1371   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
1372   SCOPED_NET_LOG_IF_SLOW();
1373   bool changed = false;
1374   NetworkState* network = GetModifiableNetworkState(service_path);
1375   if (!network || !network->update_received()) {
1376     // Shill may send a service property update before processing Chrome's
1377     // initial GetProperties request. If this occurs, the initial request will
1378     // include the changed property value so we can ignore this update.
1379     return;
1380   }
1381   std::string prev_connection_state = network->connection_state();
1382   NetworkState::PortalState prev_portal_state = network->portal_state();
1383   std::string prev_profile_path = network->profile_path();
1384   changed |= network->PropertyChanged(key, value);
1385   changed |= UpdateBlockedByPolicy(network);
1386   if (!changed)
1387     return;
1388 
1389   // If added or removed from a Profile, request a full update so that a
1390   // NetworkState gets created.
1391   bool request_update = prev_profile_path != network->profile_path();
1392   bool sort_networks = false;
1393   bool notify_default = network->path() == default_network_path_;
1394   bool notify_connection_state = false;
1395   bool notify_active = false;
1396 
1397   if (key == shill::kStateProperty || key == shill::kVisibleProperty) {
1398     network_list_sorted_ = false;
1399     if (ConnectionStateChanged(network, prev_connection_state,
1400                                prev_portal_state)) {
1401       notify_connection_state = true;
1402       notify_active = true;
1403       if (notify_default)
1404         notify_default = VerifyDefaultNetworkConnectionStateChange(network);
1405       // If the default network connection state changed, sort networks now
1406       // and ensure that a default cellular network exists.
1407       if (notify_default)
1408         sort_networks = true;
1409 
1410       // If the connection state changes, other properties such as IPConfig
1411       // may have changed, so request a full update.
1412       request_update = true;
1413     }
1414   } else if (key == shill::kActivationStateProperty) {
1415     // Activation state may affect "connecting" state in the UI.
1416     notify_connection_state = true;
1417     network_list_sorted_ = false;
1418   }
1419 
1420   if (request_update) {
1421     RequestUpdateForNetwork(service_path);
1422     notify_default = false;  // Notify will occur when properties are received.
1423   }
1424 
1425   std::string value_str;
1426   value.GetAsString(&value_str);
1427   if (key == shill::kSignalStrengthProperty || key == shill::kWifiBSsid ||
1428       key == shill::kWifiFrequency ||
1429       key == shill::kWifiFrequencyListProperty ||
1430       key == shill::kNetworkTechnologyProperty ||
1431       (key == shill::kDeviceProperty && value_str == "/")) {
1432     // Uninteresting update. This includes 'Device' property changes to "/"
1433     // (occurs just before a service is removed).
1434     // For non active networks do not log or send any notifications.
1435     if (!network->IsActive())
1436       return;
1437     // Otherwise do not trigger 'default network changed'.
1438     notify_default = false;
1439     // Notify signal strength and network technology changes for active
1440     // networks.
1441     if (key == shill::kSignalStrengthProperty ||
1442         key == shill::kNetworkTechnologyProperty) {
1443       notify_active = true;
1444     }
1445   }
1446 
1447   LogPropertyUpdated(network, key, value);
1448   if (notify_connection_state)
1449     NotifyNetworkConnectionStateChanged(network);
1450   if (notify_default) {
1451     std::stringstream logstream;
1452     logstream << std::string(kReasonUpdate) << ":" << key << "=" << value;
1453     NotifyDefaultNetworkChanged(logstream.str());
1454   }
1455   if (notify_active)
1456     NotifyIfActiveNetworksChanged();
1457   NotifyNetworkPropertiesUpdated(network);
1458   if (sort_networks)
1459     SortNetworkList(true /* ensure_cellular */);
1460 }
1461 
UpdateDeviceProperty(const std::string & device_path,const std::string & key,const base::Value & value)1462 void NetworkStateHandler::UpdateDeviceProperty(const std::string& device_path,
1463                                                const std::string& key,
1464                                                const base::Value& value) {
1465   SCOPED_NET_LOG_IF_SLOW();
1466   DeviceState* device = GetModifiableDeviceState(device_path);
1467   if (!device || !device->update_received()) {
1468     // Shill may send a device property update before processing Chrome's
1469     // initial GetProperties request. If this occurs, the initial request will
1470     // include the changed property value so we can ignore this update.
1471     return;
1472   }
1473   if (!device->PropertyChanged(key, value))
1474     return;
1475 
1476   LogPropertyUpdated(device, key, value);
1477   NotifyDevicePropertiesUpdated(device);
1478 
1479   if (key == shill::kScanningProperty && device->scanning() == false) {
1480     if (device->type() == shill::kTypeWifi)
1481       UpdateManagedWifiNetworkAvailable();
1482     NotifyScanCompleted(device);
1483   }
1484   if (key == shill::kEapAuthenticationCompletedProperty) {
1485     // Notify a change for each Ethernet service using this device.
1486     NetworkStateList ethernet_services;
1487     GetNetworkListByType(NetworkTypePattern::Ethernet(),
1488                          false /* configured_only */, false /* visible_only */,
1489                          0 /* no limit */, &ethernet_services);
1490     for (NetworkStateList::const_iterator it = ethernet_services.begin();
1491          it != ethernet_services.end(); ++it) {
1492       const NetworkState* ethernet_service = *it;
1493       if (ethernet_service->update_received() ||
1494           ethernet_service->device_path() != device->path()) {
1495         continue;
1496       }
1497       RequestUpdateForNetwork(ethernet_service->path());
1498     }
1499   }
1500 }
1501 
UpdateIPConfigProperties(ManagedState::ManagedType type,const std::string & path,const std::string & ip_config_path,const base::Value & properties)1502 void NetworkStateHandler::UpdateIPConfigProperties(
1503     ManagedState::ManagedType type,
1504     const std::string& path,
1505     const std::string& ip_config_path,
1506     const base::Value& properties) {
1507   if (type == ManagedState::MANAGED_TYPE_NETWORK) {
1508     NetworkState* network = GetModifiableNetworkState(path);
1509     if (!network)
1510       return;
1511     network->IPConfigPropertiesChanged(properties);
1512     NotifyNetworkPropertiesUpdated(network);
1513     if (network->path() == default_network_path_)
1514       NotifyDefaultNetworkChanged(kReasonUpdateIPConfig);
1515     if (network->IsActive())
1516       NotifyIfActiveNetworksChanged();
1517   } else if (type == ManagedState::MANAGED_TYPE_DEVICE) {
1518     DeviceState* device = GetModifiableDeviceState(path);
1519     if (!device)
1520       return;
1521     device->IPConfigPropertiesChanged(ip_config_path, properties);
1522     NotifyDevicePropertiesUpdated(device);
1523     if (!default_network_path_.empty()) {
1524       const NetworkState* default_network =
1525           GetNetworkState(default_network_path_);
1526       if (default_network && default_network->device_path() == path) {
1527         NotifyNetworkPropertiesUpdated(default_network);
1528         NotifyDefaultNetworkChanged(kReasonUpdateDeviceIPConfig);
1529       }
1530     }
1531   }
1532 }
1533 
CheckPortalListChanged(const std::string & check_portal_list)1534 void NetworkStateHandler::CheckPortalListChanged(
1535     const std::string& check_portal_list) {
1536   check_portal_list_ = check_portal_list;
1537 }
1538 
HostnameChanged(const std::string & hostname)1539 void NetworkStateHandler::HostnameChanged(const std::string& hostname) {
1540   NET_LOG(EVENT) << "HostnameChanged: " << hostname;
1541   hostname_ = hostname;
1542   for (auto& observer : observers_)
1543     observer.HostnameChanged(hostname);
1544 }
1545 
TechnologyListChanged()1546 void NetworkStateHandler::TechnologyListChanged() {
1547   // Eventually we would like to replace Technology state with Device state.
1548   // For now, treat technology state changes as device list changes.
1549   NotifyDeviceListChanged();
1550 }
1551 
ManagedStateListChanged(ManagedState::ManagedType type)1552 void NetworkStateHandler::ManagedStateListChanged(
1553     ManagedState::ManagedType type) {
1554   SCOPED_NET_LOG_IF_SLOW();
1555   switch (type) {
1556     case ManagedState::MANAGED_TYPE_NETWORK:
1557       SortNetworkList(true /* ensure_cellular */);
1558       UpdateNetworkStats();
1559       NotifyIfActiveNetworksChanged();
1560       NotifyNetworkListChanged();
1561       UpdateManagedWifiNetworkAvailable();
1562       return;
1563     case ManagedState::MANAGED_TYPE_DEVICE:
1564       std::string devices;
1565       for (auto iter = device_list_.begin(); iter != device_list_.end();
1566            ++iter) {
1567         if (iter != device_list_.begin())
1568           devices += ", ";
1569         devices += (*iter)->name();
1570       }
1571       NET_LOG(EVENT) << "DeviceList: " << devices;
1572       // A change to the device list may affect the default Cellular network, so
1573       // call SortNetworkList here.
1574       SortNetworkList(true /* ensure_cellular */);
1575       NotifyDeviceListChanged();
1576       return;
1577   }
1578   NOTREACHED();
1579 }
1580 
SortNetworkList(bool ensure_cellular)1581 void NetworkStateHandler::SortNetworkList(bool ensure_cellular) {
1582   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
1583   if (tether_sort_delegate_)
1584     tether_sort_delegate_->SortTetherNetworkList(&tether_network_list_);
1585 
1586   // Note: usually active networks will precede inactive networks, however
1587   // this may briefly be untrue during state transitions (e.g. a network may
1588   // transition to idle before the list is updated). Also separate inactive
1589   // Mobile and VPN networks (see below).
1590   ManagedStateList active, non_wifi_visible, wifi_visible, hidden, new_networks;
1591   int cellular_count = 0;
1592   bool have_default_cellular = false;
1593   for (ManagedStateList::iterator iter = network_list_.begin();
1594        iter != network_list_.end(); ++iter) {
1595     NetworkState* network = (*iter)->AsNetworkState();
1596     // NetworkState entries are created when they appear in the list, but the
1597     // details are not populated until an update is received.
1598     if (!network->update_received()) {
1599       new_networks.push_back(std::move(*iter));
1600       continue;
1601     }
1602     if (NetworkTypePattern::Cellular().MatchesType(network->type())) {
1603       ++cellular_count;
1604       if ((*iter)->AsNetworkState()->IsDefaultCellular())
1605         have_default_cellular = true;
1606     }
1607     if (network->IsActive()) {
1608       active.push_back(std::move(*iter));
1609       continue;
1610     }
1611     if (!network->visible()) {
1612       hidden.push_back(std::move(*iter));
1613       continue;
1614     }
1615     if (NetworkTypePattern::WiFi().MatchesType(network->type()))
1616       wifi_visible.push_back(std::move(*iter));
1617     else
1618       non_wifi_visible.push_back(std::move(*iter));
1619   }
1620 
1621   // List active networks first (will always include Ethernet).
1622   network_list_ = std::move(active);
1623 
1624   // If a default Cellular network is required, add it next.
1625   if (ensure_cellular && cellular_count == 0) {
1626     std::unique_ptr<NetworkState> default_cellular =
1627         MaybeCreateDefaultCellularNetwork();
1628     if (default_cellular)
1629       network_list_.push_back(std::move(default_cellular));
1630   }
1631 
1632   // List non wifi visible networks next (Mobile and VPN).
1633   std::move(non_wifi_visible.begin(), non_wifi_visible.end(),
1634             std::back_inserter(network_list_));
1635   // List WiFi networks last.
1636   std::move(wifi_visible.begin(), wifi_visible.end(),
1637             std::back_inserter(network_list_));
1638   // Include hidden and new networks in the list at the end; they should not
1639   // be shown by the UI.
1640   std::move(hidden.begin(), hidden.end(), std::back_inserter(network_list_));
1641   std::move(new_networks.begin(), new_networks.end(),
1642             std::back_inserter(network_list_));
1643   network_list_sorted_ = true;
1644 
1645   if (ensure_cellular && have_default_cellular) {
1646     // If we have created a default Cellular NetworkState, and we have > 1
1647     // Cellular NetworkState or no Cellular device, remove it.
1648     if (cellular_count > 1 ||
1649         !GetDeviceStateByType(NetworkTypePattern::Cellular())) {
1650       RemoveDefaultCellularNetwork();
1651     }
1652   }
1653 }
1654 
UpdateNetworkStats()1655 void NetworkStateHandler::UpdateNetworkStats() {
1656   size_t shared = 0, unshared = 0, visible = 0;
1657   for (ManagedStateList::iterator iter = network_list_.begin();
1658        iter != network_list_.end(); ++iter) {
1659     const NetworkState* network = (*iter)->AsNetworkState();
1660     if (network->visible())
1661       ++visible;
1662     if (network->IsInProfile()) {
1663       if (network->IsPrivate())
1664         ++unshared;
1665       else
1666         ++shared;
1667     }
1668   }
1669   UMA_HISTOGRAM_COUNTS_100("Networks.Visible", visible);
1670   UMA_HISTOGRAM_COUNTS_100("Networks.RememberedShared", shared);
1671   UMA_HISTOGRAM_COUNTS_100("Networks.RememberedUnshared", unshared);
1672 }
1673 
DefaultNetworkServiceChanged(const std::string & service_path)1674 void NetworkStateHandler::DefaultNetworkServiceChanged(
1675     const std::string& service_path) {
1676   // Shill uses '/' for empty service path values; check explicitly for that.
1677   const char kEmptyServicePath[] = "/";
1678   std::string new_service_path =
1679       (service_path != kEmptyServicePath) ? service_path : "";
1680   if (new_service_path == default_network_path_)
1681     return;
1682 
1683   if (new_service_path.empty()) {
1684     // If Shill reports that there is no longer a default network but there is
1685     // still an active Tether connection corresponding to the default network,
1686     // return early without changing |default_network_path_|. Observers will be
1687     // notified of the default network change due to a subsequent call to
1688     // SetTetherNetworkStateDisconnected().
1689     const NetworkState* old_default_network = DefaultNetwork();
1690     if (old_default_network && old_default_network->type() == kTypeTether)
1691       return;
1692   }
1693 
1694   NET_LOG(EVENT) << "DefaultNetworkServiceChanged: "
1695                  << NetworkPathId(service_path);
1696   if (new_service_path.empty()) {
1697     // Notify that there is no default network.
1698     SetDefaultNetworkValues(/*path=*/std::string(), /*metered=*/false);
1699     NotifyDefaultNetworkChanged(kReasonChange);
1700     return;
1701   }
1702 
1703   const NetworkState* network = GetNetworkState(service_path);
1704   if (!network) {
1705     // If NetworkState is not available yet, do not notify observers here,
1706     // they will be notified when the state is received.
1707     NET_LOG(EVENT) << "Default NetworkState not available: "
1708                    << NetworkPathId(service_path);
1709     // Metered will be updated to the correct value when properties arrive.
1710     SetDefaultNetworkValues(service_path, /*metered=*/false);
1711     return;
1712   }
1713 
1714   if (!network->tether_guid().empty()) {
1715     DCHECK(network->type() == shill::kTypeWifi);
1716 
1717     // If the new default network from Shill's point of view is a Wi-Fi
1718     // network which corresponds to a hotspot for a Tether network, set the
1719     // default network to be the associated Tether network instead.
1720     network = GetNetworkStateFromGuid(network->tether_guid());
1721     if (default_network_path_ != network->path()) {
1722       NET_LOG(DEBUG) << "Tether network is default: " << NetworkId(network);
1723       SetDefaultNetworkValues(network->path(), /*metered=*/true);
1724       NotifyDefaultNetworkChanged(kReasonChange);
1725     }
1726     return;
1727   }
1728 
1729   // Request the updated default network properties which will trigger
1730   // NotifyDefaultNetworkChanged().
1731   // Metered will be updated to the correct value when properties arrive.
1732   SetDefaultNetworkValues(service_path, /*metered=*/false);
1733   RequestUpdateForNetwork(service_path);
1734 }
1735 
1736 //------------------------------------------------------------------------------
1737 // Private methods
1738 
UpdateGuid(NetworkState * network)1739 void NetworkStateHandler::UpdateGuid(NetworkState* network) {
1740   std::string specifier = network->GetSpecifier();
1741   DCHECK(!specifier.empty());
1742   if (!network->guid().empty()) {
1743     // If the network is saved in a profile, remove the entry from the map.
1744     // Otherwise ensure that the entry matches the specified GUID. (e.g. in
1745     // case a visible network with a specified guid gets configured with a
1746     // new guid). Exception: Ethernet and Cellular expect to have a single
1747     // network and a consistent GUID.
1748     if (network->type() != shill::kTypeEthernet &&
1749         network->type() != shill::kTypeCellular && network->IsInProfile()) {
1750       specifier_guid_map_.erase(specifier);
1751     } else {
1752       specifier_guid_map_[specifier] = network->guid();
1753     }
1754     return;
1755   }
1756   // Ensure that the NetworkState has a valid GUID.
1757   std::string guid;
1758   SpecifierGuidMap::iterator guid_iter = specifier_guid_map_.find(specifier);
1759   if (guid_iter != specifier_guid_map_.end()) {
1760     guid = guid_iter->second;
1761   } else {
1762     guid = base::GenerateGUID();
1763     specifier_guid_map_[specifier] = guid;
1764   }
1765   network->SetGuid(guid);
1766 }
1767 
UpdateCellularStateFromDevice(NetworkState * network)1768 void NetworkStateHandler::UpdateCellularStateFromDevice(NetworkState* network) {
1769   const DeviceState* device = GetDeviceState(network->device_path());
1770   if (!device)
1771     return;
1772   network->provider_requires_roaming_ = device->provider_requires_roaming();
1773 }
1774 
1775 std::unique_ptr<NetworkState>
MaybeCreateDefaultCellularNetwork()1776 NetworkStateHandler::MaybeCreateDefaultCellularNetwork() {
1777   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
1778   CHECK(!notifying_network_observers_);
1779   const DeviceState* device =
1780       GetDeviceStateByType(NetworkTypePattern::Cellular());
1781   // If no SIM is present there will not be useful user facing Device
1782   // information, so do not create a default Cellular network.
1783   if (!device || device->IsSimAbsent())
1784     return nullptr;
1785   // Create a default Cellular network. Properties from the associated Device
1786   // will be provided to the UI. Note that the network's name is left empty; UI
1787   // surfaces which attempt to show the network name will fall back to showing
1788   // the network type (i.e., "Cellular") instead.
1789   std::unique_ptr<NetworkState> network =
1790       NetworkState::CreateDefaultCellular(device->path());
1791   UpdateGuid(network.get());
1792   return network;
1793 }
1794 
RemoveDefaultCellularNetwork()1795 void NetworkStateHandler::RemoveDefaultCellularNetwork() {
1796   for (auto iter = network_list_.begin(); iter != network_list_.end(); ++iter) {
1797     if ((*iter)->AsNetworkState()->IsDefaultCellular()) {
1798       network_list_.erase(iter);
1799       return;  // There will only ever be one default Cellular network.
1800     }
1801   }
1802 }
1803 
NotifyNetworkListChanged()1804 void NetworkStateHandler::NotifyNetworkListChanged() {
1805   NET_LOG(EVENT) << "NOTIFY: NetworkListChanged. Size: "
1806                  << network_list_.size();
1807   for (auto& observer : observers_)
1808     observer.NetworkListChanged();
1809 }
1810 
NotifyDeviceListChanged()1811 void NetworkStateHandler::NotifyDeviceListChanged() {
1812   SCOPED_NET_LOG_IF_SLOW();
1813   NET_LOG(EVENT) << "NOTIFY: DeviceListChanged. Size: " << device_list_.size();
1814   for (auto& observer : observers_)
1815     observer.DeviceListChanged();
1816 }
1817 
GetModifiableDeviceState(const std::string & device_path) const1818 DeviceState* NetworkStateHandler::GetModifiableDeviceState(
1819     const std::string& device_path) const {
1820   ManagedState* managed = GetModifiableManagedState(&device_list_, device_path);
1821   if (!managed)
1822     return nullptr;
1823   return managed->AsDeviceState();
1824 }
1825 
GetModifiableDeviceStateByType(const NetworkTypePattern & type) const1826 DeviceState* NetworkStateHandler::GetModifiableDeviceStateByType(
1827     const NetworkTypePattern& type) const {
1828   for (const auto& device : device_list_) {
1829     if (TypeMatches(device.get(), type))
1830       return device->AsDeviceState();
1831   }
1832   return nullptr;
1833 }
1834 
GetModifiableNetworkState(const std::string & service_path) const1835 NetworkState* NetworkStateHandler::GetModifiableNetworkState(
1836     const std::string& service_path) const {
1837   ManagedState* managed =
1838       GetModifiableManagedState(&network_list_, service_path);
1839   if (!managed) {
1840     managed = GetModifiableManagedState(&tether_network_list_, service_path);
1841     if (!managed)
1842       return nullptr;
1843   }
1844   return managed->AsNetworkState();
1845 }
1846 
GetModifiableNetworkStateFromGuid(const std::string & guid) const1847 NetworkState* NetworkStateHandler::GetModifiableNetworkStateFromGuid(
1848     const std::string& guid) const {
1849   for (auto iter = tether_network_list_.begin();
1850        iter != tether_network_list_.end(); ++iter) {
1851     NetworkState* tether_network = (*iter)->AsNetworkState();
1852     if (tether_network->guid() == guid)
1853       return tether_network;
1854   }
1855 
1856   for (auto iter = network_list_.begin(); iter != network_list_.end(); ++iter) {
1857     NetworkState* network = (*iter)->AsNetworkState();
1858     if (network->guid() == guid)
1859       return network;
1860   }
1861 
1862   return nullptr;
1863 }
1864 
GetModifiableManagedState(const ManagedStateList * managed_list,const std::string & path) const1865 ManagedState* NetworkStateHandler::GetModifiableManagedState(
1866     const ManagedStateList* managed_list,
1867     const std::string& path) const {
1868   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
1869   for (auto iter = managed_list->begin(); iter != managed_list->end(); ++iter) {
1870     ManagedState* managed = iter->get();
1871     if (managed->path() == path)
1872       return managed;
1873   }
1874   return nullptr;
1875 }
1876 
GetManagedList(ManagedState::ManagedType type)1877 NetworkStateHandler::ManagedStateList* NetworkStateHandler::GetManagedList(
1878     ManagedState::ManagedType type) {
1879   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
1880   switch (type) {
1881     case ManagedState::MANAGED_TYPE_NETWORK:
1882       return &network_list_;
1883     case ManagedState::MANAGED_TYPE_DEVICE:
1884       return &device_list_;
1885   }
1886   NOTREACHED();
1887   return nullptr;
1888 }
1889 
OnNetworkConnectionStateChanged(NetworkState * network)1890 void NetworkStateHandler::OnNetworkConnectionStateChanged(
1891     NetworkState* network) {
1892   DCHECK(network);
1893   bool default_changed = false;
1894   if (network->path() == default_network_path_)
1895     default_changed = VerifyDefaultNetworkConnectionStateChange(network);
1896   NotifyNetworkConnectionStateChanged(network);
1897   if (default_changed)
1898     NotifyDefaultNetworkChanged(kReasonStateChange);
1899 }
1900 
VerifyDefaultNetworkConnectionStateChange(NetworkState * network)1901 bool NetworkStateHandler::VerifyDefaultNetworkConnectionStateChange(
1902     NetworkState* network) {
1903   DCHECK(network->path() == default_network_path_);
1904   if (network->IsConnectedState() ||
1905       NetworkState::StateIsPortalled(network->connection_state())) {
1906     return true;
1907   }
1908   if (network->IsConnectingState()) {
1909     // Wait until the network is actually connected to notify that the default
1910     // network changed.
1911     NET_LOG(DEBUG) << "Default network is connecting: " << NetworkId(network)
1912                    << "State: " << network->connection_state();
1913     return false;
1914   }
1915   NET_LOG(DEBUG) << "Default network not connected: " << NetworkId(network);
1916   return false;
1917 }
1918 
NotifyNetworkConnectionStateChanged(NetworkState * network)1919 void NetworkStateHandler::NotifyNetworkConnectionStateChanged(
1920     NetworkState* network) {
1921   DCHECK(network);
1922   SCOPED_NET_LOG_IF_SLOW();
1923   std::string desc = "NetworkConnectionStateChanged";
1924   if (network->path() == default_network_path_)
1925     desc = "Default" + desc;
1926   NET_LOG(EVENT) << "NOTIFY: " << desc << ": " << NetworkId(network) << ": "
1927                  << network->connection_state();
1928   notifying_network_observers_ = true;
1929   for (auto& observer : observers_)
1930     observer.NetworkConnectionStateChanged(network);
1931   notifying_network_observers_ = false;
1932   NotifyIfActiveNetworksChanged();
1933 }
1934 
NotifyDefaultNetworkChanged(const std::string & log_reason)1935 void NetworkStateHandler::NotifyDefaultNetworkChanged(
1936     const std::string& log_reason) {
1937   SCOPED_NET_LOG_IF_SLOW();
1938   // If the default network is in an invalid state, |default_network_path_|
1939   // will be cleared; call DefaultNetworkChanged(nullptr).
1940   const NetworkState* default_network;
1941   if (default_network_path_.empty()) {
1942     default_network = nullptr;
1943   } else {
1944     default_network = GetModifiableNetworkState(default_network_path_);
1945     DCHECK(default_network) << "No default network: " << default_network_path_;
1946   }
1947   NET_LOG(EVENT) << "NOTIFY: DefaultNetworkChanged: "
1948                  << NetworkId(default_network) << ": " << log_reason;
1949   notifying_network_observers_ = true;
1950   for (auto& observer : observers_)
1951     observer.DefaultNetworkChanged(default_network);
1952 
1953   if (default_network &&
1954       (default_network->portal_state() != default_network_portal_state_ ||
1955        default_network->proxy_config() != default_network_proxy_config_)) {
1956     default_network_portal_state_ = default_network->portal_state();
1957     default_network_proxy_config_ = default_network->proxy_config().Clone();
1958     for (auto& observer : observers_) {
1959       observer.PortalStateChanged(default_network,
1960                                   default_network_portal_state_);
1961     }
1962   } else if (!default_network && (default_network_portal_state_ !=
1963                                       NetworkState::PortalState::kUnknown ||
1964                                   !default_network_proxy_config_.is_none())) {
1965     default_network_portal_state_ = NetworkState::PortalState::kUnknown;
1966     default_network_proxy_config_ = base::Value();
1967     for (auto& observer : observers_)
1968       observer.PortalStateChanged(nullptr, NetworkState::PortalState::kUnknown);
1969   }
1970   notifying_network_observers_ = false;
1971 }
1972 
ActiveNetworksChanged(const NetworkStateList & active_networks)1973 bool NetworkStateHandler::ActiveNetworksChanged(
1974     const NetworkStateList& active_networks) {
1975   if (active_networks.size() != active_network_list_.size())
1976     return true;
1977   for (size_t i = 0; i < active_network_list_.size(); ++i) {
1978     if (!active_network_list_[i].MatchesNetworkState(active_networks[i]))
1979       return true;
1980   }
1981   return false;
1982 }
1983 
NotifyIfActiveNetworksChanged()1984 void NetworkStateHandler::NotifyIfActiveNetworksChanged() {
1985   SCOPED_NET_LOG_IF_SLOW();
1986   NetworkStateList active_networks;
1987   GetActiveNetworkListByType(NetworkTypePattern::Default(), &active_networks);
1988   if (!ActiveNetworksChanged(active_networks))
1989     return;
1990 
1991   NET_LOG(EVENT) << "NOTIFY:ActiveNetworksChanged";
1992 
1993   active_network_list_.clear();
1994   active_network_list_.reserve(active_networks.size());
1995   for (const NetworkState* network : active_networks)
1996     active_network_list_.emplace_back(network);
1997 
1998   notifying_network_observers_ = true;
1999   for (auto& observer : observers_)
2000     observer.ActiveNetworksChanged(active_networks);
2001   notifying_network_observers_ = false;
2002 }
2003 
NotifyNetworkPropertiesUpdated(const NetworkState * network)2004 void NetworkStateHandler::NotifyNetworkPropertiesUpdated(
2005     const NetworkState* network) {
2006   // Skip property updates before NetworkState::InitialPropertiesReceived.
2007   if (network->type().empty())
2008     return;
2009   SCOPED_NET_LOG_IF_SLOW();
2010   NET_LOG(EVENT) << "NOTIFY: NetworkPropertiesUpdated: " << NetworkId(network);
2011   notifying_network_observers_ = true;
2012   for (auto& observer : observers_)
2013     observer.NetworkPropertiesUpdated(network);
2014   notifying_network_observers_ = false;
2015 }
2016 
NotifyDevicePropertiesUpdated(const DeviceState * device)2017 void NetworkStateHandler::NotifyDevicePropertiesUpdated(
2018     const DeviceState* device) {
2019   SCOPED_NET_LOG_IF_SLOW();
2020   NET_LOG(EVENT) << "NOTIFY: DevicePropertiesUpdated: " << device->path();
2021   for (auto& observer : observers_)
2022     observer.DevicePropertiesUpdated(device);
2023 }
2024 
NotifyScanRequested(const NetworkTypePattern & type)2025 void NetworkStateHandler::NotifyScanRequested(const NetworkTypePattern& type) {
2026   SCOPED_NET_LOG_IF_SLOW();
2027   NET_LOG(EVENT) << "NOTIFY: ScanRequested";
2028   for (auto& observer : observers_)
2029     observer.ScanRequested(type);
2030 }
2031 
NotifyScanCompleted(const DeviceState * device)2032 void NetworkStateHandler::NotifyScanCompleted(const DeviceState* device) {
2033   SCOPED_NET_LOG_IF_SLOW();
2034   NET_LOG(EVENT) << "NOTIFY: ScanCompleted for: " << device->path();
2035   for (auto& observer : observers_)
2036     observer.ScanCompleted(device);
2037 }
2038 
NotifyScanStarted(const DeviceState * device)2039 void NetworkStateHandler::NotifyScanStarted(const DeviceState* device) {
2040   SCOPED_NET_LOG_IF_SLOW();
2041   NET_LOG(EVENT) << "NOTIFY: ScanStarted for: " << device->path();
2042   for (auto& observer : observers_)
2043     observer.ScanStarted(device);
2044 }
2045 
LogPropertyUpdated(const ManagedState * state,const std::string & key,const base::Value & value)2046 void NetworkStateHandler::LogPropertyUpdated(const ManagedState* state,
2047                                              const std::string& key,
2048                                              const base::Value& value) {
2049   std::string type_str =
2050       state->managed_type() == ManagedState::MANAGED_TYPE_DEVICE
2051           ? "Device"
2052           : state->path() == default_network_path_ ? "DefaultNetwork"
2053                                                    : "Network";
2054   device_event_log::LogLevel log_level = device_event_log::LOG_LEVEL_EVENT;
2055   if (key == shill::kErrorProperty || key == shill::kErrorDetailsProperty)
2056     log_level = device_event_log::LOG_LEVEL_ERROR;
2057   else if (key == shill::kSignalStrengthProperty && !state->IsActive())
2058     log_level = device_event_log::LOG_LEVEL_DEBUG;
2059   DEVICE_LOG(::device_event_log::LOG_TYPE_NETWORK, log_level)
2060       << type_str << "PropertyUpdated: " << GetLogName(state) << ", " << key
2061       << " = " << value;
2062 }
2063 
GetTechnologyForType(const NetworkTypePattern & type) const2064 std::string NetworkStateHandler::GetTechnologyForType(
2065     const NetworkTypePattern& type) const {
2066   if (type.MatchesType(shill::kTypeEthernet))
2067     return shill::kTypeEthernet;
2068 
2069   if (type.MatchesType(shill::kTypeWifi))
2070     return shill::kTypeWifi;
2071 
2072   if (type.MatchesType(shill::kTypeCellular))
2073     return shill::kTypeCellular;
2074 
2075   if (type.MatchesType(kTypeTether))
2076     return kTypeTether;
2077 
2078   NET_LOG(ERROR) << "Unexpected Type for technology: " << type.ToDebugString();
2079   return std::string();
2080 }
2081 
GetTechnologiesForType(const NetworkTypePattern & type) const2082 std::vector<std::string> NetworkStateHandler::GetTechnologiesForType(
2083     const NetworkTypePattern& type) const {
2084   std::vector<std::string> technologies;
2085   if (type.MatchesType(shill::kTypeEthernet))
2086     technologies.emplace_back(shill::kTypeEthernet);
2087   if (type.MatchesType(shill::kTypeWifi))
2088     technologies.emplace_back(shill::kTypeWifi);
2089   if (type.MatchesType(shill::kTypeCellular))
2090     technologies.emplace_back(shill::kTypeCellular);
2091   if (type.MatchesType(shill::kTypeVPN))
2092     technologies.emplace_back(shill::kTypeVPN);
2093   if (type.MatchesType(kTypeTether))
2094     technologies.emplace_back(kTypeTether);
2095 
2096   CHECK_GT(technologies.size(), 0ul);
2097   return technologies;
2098 }
2099 
SetDefaultNetworkValues(const std::string & path,bool metered)2100 void NetworkStateHandler::SetDefaultNetworkValues(const std::string& path,
2101                                                   bool metered) {
2102   default_network_path_ = path;
2103   default_network_is_metered_ = metered;
2104 }
2105 
2106 }  // namespace chromeos
2107