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 */, ðernet_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