Commit 70159a3b authored by Steven Bennetts's avatar Steven Bennetts Committed by Commit Bot

Add NetworkStateHandler::GetActiveNetworkListByType and observer

This introduces:
* NetworkStateHandler::GetActiveNetworkListByType()
* NetworkStateHandler::ActiveNetworkByType()
* NetworkStateHandlerObserver::ActiveNetworksChanged()

For cros_network_config.mojo we are planning to use "active" (connected
or connecting) networks instead of "default" network (which can be a
VPN, and doesn't tell the whole story when, e.g. WiFi and Cellular are
both connected). This adds the concept to NetworkStateHandler and
implements it in two places where it is a straightforward improvement.

Bug: 862420
Change-Id: Ie49efd5d886f994cb24cd22bf361dd404450e96c
Reviewed-on: https://chromium-review.googlesource.com/c/1433113Reviewed-by: default avatarToni Baržić <tbarzic@chromium.org>
Reviewed-by: default avatarKyle Horimoto <khorimoto@chromium.org>
Commit-Queue: Steven Bennetts <stevenjb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#629179}
parent 3407712d
...@@ -30,8 +30,7 @@ bool IsWifiEnabled() { ...@@ -30,8 +30,7 @@ bool IsWifiEnabled() {
namespace ash { namespace ash {
TrayNetworkStateObserver::TrayNetworkStateObserver(Delegate* delegate) TrayNetworkStateObserver::TrayNetworkStateObserver(Delegate* delegate)
: delegate_(delegate), : delegate_(delegate), update_frequency_(kUpdateFrequencyMs) {
update_frequency_(kUpdateFrequencyMs) {
if (ui::ScopedAnimationDurationScaleMode::duration_scale_mode() != if (ui::ScopedAnimationDurationScaleMode::duration_scale_mode() !=
ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION) { ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION) {
update_frequency_ = 0; // Send updates immediately for tests. update_frequency_ = 0; // Send updates immediately for tests.
...@@ -64,18 +63,8 @@ void TrayNetworkStateObserver::DeviceListChanged() { ...@@ -64,18 +63,8 @@ void TrayNetworkStateObserver::DeviceListChanged() {
SignalUpdate(false /* notify_a11y */); SignalUpdate(false /* notify_a11y */);
} }
// Any change to the Default (primary connected) network, including Strength void TrayNetworkStateObserver::ActiveNetworksChanged(
// changes, should trigger a NetworkStateChanged update. const std::vector<const chromeos::NetworkState*>& active_networks) {
void TrayNetworkStateObserver::DefaultNetworkChanged(
const chromeos::NetworkState* network) {
SignalUpdate(true /* notify_a11y */);
}
// Any change to the Connection State should trigger a NetworkStateChanged
// update. This is important when both a VPN and a physical network are
// connected.
void TrayNetworkStateObserver::NetworkConnectionStateChanged(
const chromeos::NetworkState* network) {
SignalUpdate(true /* notify_a11y */); SignalUpdate(true /* notify_a11y */);
} }
......
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
#ifndef ASH_SYSTEM_NETWORK_TRAY_NETWORK_STATE_OBSERVER_H_ #ifndef ASH_SYSTEM_NETWORK_TRAY_NETWORK_STATE_OBSERVER_H_
#define ASH_SYSTEM_NETWORK_TRAY_NETWORK_STATE_OBSERVER_H_ #define ASH_SYSTEM_NETWORK_TRAY_NETWORK_STATE_OBSERVER_H_
#include <vector>
#include "base/macros.h" #include "base/macros.h"
#include "base/timer/timer.h" #include "base/timer/timer.h"
#include "chromeos/network/network_state_handler_observer.h" #include "chromeos/network/network_state_handler_observer.h"
...@@ -33,9 +35,8 @@ class TrayNetworkStateObserver ...@@ -33,9 +35,8 @@ class TrayNetworkStateObserver
// NetworkStateHandlerObserver // NetworkStateHandlerObserver
void NetworkListChanged() override; void NetworkListChanged() override;
void DeviceListChanged() override; void DeviceListChanged() override;
void DefaultNetworkChanged(const chromeos::NetworkState* network) override; void ActiveNetworksChanged(const std::vector<const chromeos::NetworkState*>&
void NetworkConnectionStateChanged( active_networks) override;
const chromeos::NetworkState* network) override;
void NetworkPropertiesUpdated(const chromeos::NetworkState* network) override; void NetworkPropertiesUpdated(const chromeos::NetworkState* network) override;
// NetworkPortalDetector::Observer // NetworkPortalDetector::Observer
......
...@@ -134,13 +134,15 @@ const char NetworkStateNotifier::kNetworkActivateNotificationId[] = ...@@ -134,13 +134,15 @@ const char NetworkStateNotifier::kNetworkActivateNotificationId[] =
const char NetworkStateNotifier::kNetworkOutOfCreditsNotificationId[] = const char NetworkStateNotifier::kNetworkOutOfCreditsNotificationId[] =
"chrome://settings/internet/out-of-credits"; "chrome://settings/internet/out-of-credits";
NetworkStateNotifier::NetworkStateNotifier() NetworkStateNotifier::NetworkStateNotifier() : weak_ptr_factory_(this) {
: did_show_out_of_credits_(false), weak_ptr_factory_(this) {
if (!NetworkHandler::IsInitialized()) if (!NetworkHandler::IsInitialized())
return; return;
NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler(); NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler();
handler->AddObserver(this, FROM_HERE); handler->AddObserver(this, FROM_HERE);
UpdateDefaultNetwork(handler->DefaultNetwork()); NetworkStateHandler::NetworkStateList active_networks;
handler->GetActiveNetworkListByType(NetworkTypePattern::Default(),
&active_networks);
ActiveNetworksChanged(active_networks);
NetworkHandler::Get()->network_connection_handler()->AddObserver(this); NetworkHandler::Get()->network_connection_handler()->AddObserver(this);
} }
...@@ -158,7 +160,7 @@ void NetworkStateNotifier::ConnectToNetworkRequested( ...@@ -158,7 +160,7 @@ void NetworkStateNotifier::ConnectToNetworkRequested(
NetworkHandler::Get()->network_state_handler()->GetNetworkState( NetworkHandler::Get()->network_state_handler()->GetNetworkState(
service_path); service_path);
if (network && network->type() == shill::kTypeVPN) if (network && network->type() == shill::kTypeVPN)
connected_vpn_.clear(); connected_vpn_guid_.clear();
RemoveConnectNotification(); RemoveConnectNotification();
} }
...@@ -186,105 +188,113 @@ void NetworkStateNotifier::DisconnectRequested( ...@@ -186,105 +188,113 @@ void NetworkStateNotifier::DisconnectRequested(
NetworkHandler::Get()->network_state_handler()->GetNetworkState( NetworkHandler::Get()->network_state_handler()->GetNetworkState(
service_path); service_path);
if (network && network->type() == shill::kTypeVPN) if (network && network->type() == shill::kTypeVPN)
connected_vpn_.clear(); connected_vpn_guid_.clear();
} }
void NetworkStateNotifier::DefaultNetworkChanged(const NetworkState* network) { void NetworkStateNotifier::ActiveNetworksChanged(
if (!UpdateDefaultNetwork(network)) const std::vector<const NetworkState*>& active_networks) {
return; std::string active_non_vpn_network_guid;
// If the default network changes to another network, allow the out of for (const auto* network : active_networks) {
// credits notification to be shown again. A delay prevents the notification if (network->type() == shill::kTypeVPN)
// from being shown too frequently (see below). UpdateVpnConnectionState(network);
if (network) else if (active_non_vpn_network_guid.empty())
active_non_vpn_network_guid = network->guid();
}
// If the default network changes, allow the out of credits notification to be
// shown again. A delay prevents the notification from being shown too
// frequently (see below).
if (active_non_vpn_network_guid != active_non_vpn_network_guid_) {
active_non_vpn_network_guid_ = active_non_vpn_network_guid;
did_show_out_of_credits_ = false; did_show_out_of_credits_ = false;
} UpdateCellularOutOfCredits();
}
void NetworkStateNotifier::NetworkConnectionStateChanged(
const NetworkState* network) {
if (network->type() == shill::kTypeVPN)
UpdateVpnConnectionState(network);
} }
void NetworkStateNotifier::NetworkPropertiesUpdated( void NetworkStateNotifier::NetworkPropertiesUpdated(
const NetworkState* network) { const NetworkState* network) {
if (network->type() != shill::kTypeCellular) if (network->type() != shill::kTypeCellular)
return; return;
UpdateCellularOutOfCredits(network); if (network->cellular_out_of_credits())
UpdateCellularOutOfCredits();
UpdateCellularActivating(network); UpdateCellularActivating(network);
} }
bool NetworkStateNotifier::UpdateDefaultNetwork(const NetworkState* network) {
std::string default_network_path;
if (network)
default_network_path = network->path();
if (default_network_path != last_default_network_) {
last_default_network_ = default_network_path;
return true;
}
return false;
}
void NetworkStateNotifier::UpdateVpnConnectionState(const NetworkState* vpn) { void NetworkStateNotifier::UpdateVpnConnectionState(const NetworkState* vpn) {
if (vpn->path() == connected_vpn_) { if (vpn->guid() == connected_vpn_guid_) {
if (!vpn->IsConnectedState() && !vpn->IsConnectingState()) { if (!vpn->IsConnectingOrConnected()) {
if (vpn->GetVpnProviderType() != shill::kProviderArcVpn) { if (vpn->GetVpnProviderType() != shill::kProviderArcVpn) {
ShowVpnDisconnectedNotification(vpn); ShowVpnDisconnectedNotification(vpn);
} }
connected_vpn_.clear(); connected_vpn_guid_.clear();
} }
} else if (vpn->IsConnectedState()) { } else if (vpn->IsConnectedState()) {
connected_vpn_ = vpn->path(); connected_vpn_guid_ = vpn->guid();
} }
} }
void NetworkStateNotifier::UpdateCellularOutOfCredits( void NetworkStateNotifier::UpdateCellularOutOfCredits() {
const NetworkState* cellular) { // Only show the notification once (reset when the primary network changes).
// Only display a notification if we are out of credits and have not already if (did_show_out_of_credits_)
// shown a notification (or have since connected to another network type).
if (!cellular->cellular_out_of_credits() || did_show_out_of_credits_)
return; return;
// Only display a notification if not connected, connecting, or waiting to // Don't display notification if the UI has requested a network connection.
// connect to another network. if (NetworkHandler::Get()
NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler();
const NetworkState* default_network = handler->DefaultNetwork();
if (default_network && default_network != cellular)
return;
if (handler->ConnectingNetworkByType(NetworkTypePattern::NonVirtual()) ||
NetworkHandler::Get()
->network_connection_handler() ->network_connection_handler()
->HasPendingConnectRequest()) ->HasPendingConnectRequest()) {
return; return;
}
NetworkStateHandler::NetworkStateList active_networks;
NetworkHandler::Get()->network_state_handler()->GetActiveNetworkListByType(
NetworkTypePattern::NonVirtual(), &active_networks);
const NetworkState* primary_network = nullptr;
for (const auto* network : active_networks) {
// Don't display notification if any network is connecting.
if (network->IsConnectingState())
return;
if (!primary_network)
primary_network = network;
}
if (!primary_network ||
!primary_network->Matches(NetworkTypePattern::Cellular()) ||
!primary_network->cellular_out_of_credits()) {
return;
}
did_show_out_of_credits_ = true; did_show_out_of_credits_ = true;
base::TimeDelta dtime = base::Time::Now() - out_of_credits_notify_time_; base::TimeDelta dtime = base::Time::Now() - out_of_credits_notify_time_;
if (dtime.InSeconds() > kMinTimeBetweenOutOfCreditsNotifySeconds) { if (dtime.InSeconds() > kMinTimeBetweenOutOfCreditsNotifySeconds) {
out_of_credits_notify_time_ = base::Time::Now(); out_of_credits_notify_time_ = base::Time::Now();
base::string16 error_msg = l10n_util::GetStringFUTF16( base::string16 error_msg =
IDS_NETWORK_OUT_OF_CREDITS_BODY, base::UTF8ToUTF16(cellular->name())); l10n_util::GetStringFUTF16(IDS_NETWORK_OUT_OF_CREDITS_BODY,
base::UTF8ToUTF16(primary_network->name()));
ShowErrorNotification( ShowErrorNotification(
cellular->path(), kNetworkOutOfCreditsNotificationId, cellular->type(), primary_network->path(), kNetworkOutOfCreditsNotificationId,
primary_network->type(),
l10n_util::GetStringUTF16(IDS_NETWORK_OUT_OF_CREDITS_TITLE), error_msg, l10n_util::GetStringUTF16(IDS_NETWORK_OUT_OF_CREDITS_TITLE), error_msg,
base::Bind(&NetworkStateNotifier::ShowMobileSetup, base::Bind(&NetworkStateNotifier::ShowMobileSetup,
weak_ptr_factory_.GetWeakPtr(), cellular->guid())); weak_ptr_factory_.GetWeakPtr(), primary_network->guid()));
} }
} }
void NetworkStateNotifier::UpdateCellularActivating( void NetworkStateNotifier::UpdateCellularActivating(
const NetworkState* cellular) { const NetworkState* cellular) {
const std::string cellular_guid = cellular->guid();
// Keep track of any activating cellular network. // Keep track of any activating cellular network.
std::string activation_state = cellular->activation_state(); std::string activation_state = cellular->activation_state();
if (activation_state == shill::kActivationStateActivating) { if (activation_state == shill::kActivationStateActivating) {
cellular_activating_.insert(cellular->path()); cellular_activating_guids_.insert(cellular_guid);
return; return;
} }
// Only display a notification if this network was activating and is now // Only display a notification if this network was activating and is now
// activated. // activated.
if (!cellular_activating_.count(cellular->path()) || if (!cellular_activating_guids_.count(cellular_guid) ||
activation_state != shill::kActivationStateActivated) activation_state != shill::kActivationStateActivated) {
return; return;
}
cellular_activating_.erase(cellular->path()); cellular_activating_guids_.erase(cellular_guid);
std::unique_ptr<message_center::Notification> notification = std::unique_ptr<message_center::Notification> notification =
ash::CreateSystemNotification( ash::CreateSystemNotification(
message_center::NOTIFICATION_TYPE_SIMPLE, message_center::NOTIFICATION_TYPE_SIMPLE,
...@@ -298,7 +308,7 @@ void NetworkStateNotifier::UpdateCellularActivating( ...@@ -298,7 +308,7 @@ void NetworkStateNotifier::UpdateCellularActivating(
{}, {},
new message_center::HandleNotificationClickDelegate( new message_center::HandleNotificationClickDelegate(
base::Bind(&NetworkStateNotifier::ShowNetworkSettings, base::Bind(&NetworkStateNotifier::ShowNetworkSettings,
weak_ptr_factory_.GetWeakPtr(), cellular->guid())), weak_ptr_factory_.GetWeakPtr(), cellular_guid)),
ash::kNotificationMobileDataIcon, ash::kNotificationMobileDataIcon,
message_center::SystemNotificationWarningLevel::CRITICAL_WARNING); message_center::SystemNotificationWarningLevel::CRITICAL_WARNING);
notification->set_priority(message_center::SYSTEM_PRIORITY); notification->set_priority(message_center::SYSTEM_PRIORITY);
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include <memory> #include <memory>
#include <set> #include <set>
#include <string> #include <string>
#include <vector>
#include "base/compiler_specific.h" #include "base/compiler_specific.h"
#include "base/macros.h" #include "base/macros.h"
...@@ -62,8 +63,8 @@ class NetworkStateNotifier : public NetworkConnectionObserver, ...@@ -62,8 +63,8 @@ class NetworkStateNotifier : public NetworkConnectionObserver,
void DisconnectRequested(const std::string& service_path) override; void DisconnectRequested(const std::string& service_path) override;
// NetworkStateHandlerObserver // NetworkStateHandlerObserver
void DefaultNetworkChanged(const NetworkState* network) override; void ActiveNetworksChanged(
void NetworkConnectionStateChanged(const NetworkState* network) override; const std::vector<const NetworkState*>& active_networks) override;
void NetworkPropertiesUpdated(const NetworkState* network) override; void NetworkPropertiesUpdated(const NetworkState* network) override;
void ConnectErrorPropertiesSucceeded( void ConnectErrorPropertiesSucceeded(
...@@ -89,7 +90,7 @@ class NetworkStateNotifier : public NetworkConnectionObserver, ...@@ -89,7 +90,7 @@ class NetworkStateNotifier : public NetworkConnectionObserver,
// Helper methods to update state and check for notifications. // Helper methods to update state and check for notifications.
void UpdateVpnConnectionState(const NetworkState* vpn); void UpdateVpnConnectionState(const NetworkState* vpn);
void UpdateCellularOutOfCredits(const NetworkState* cellular); void UpdateCellularOutOfCredits();
void UpdateCellularActivating(const NetworkState* cellular); void UpdateCellularActivating(const NetworkState* cellular);
// Shows the network settings for |network_id|. // Shows the network settings for |network_id|.
...@@ -98,11 +99,19 @@ class NetworkStateNotifier : public NetworkConnectionObserver, ...@@ -98,11 +99,19 @@ class NetworkStateNotifier : public NetworkConnectionObserver,
// Shows the mobile setup dialog for |network_id|. // Shows the mobile setup dialog for |network_id|.
void ShowMobileSetup(const std::string& network_id); void ShowMobileSetup(const std::string& network_id);
std::string last_default_network_; // Set to the GUID of the connected VPN network if any, otherwise empty.
bool did_show_out_of_credits_; // Used for displaying VPN disconnected notification.
std::string connected_vpn_guid_;
// Tracks state for out of credits notification.
bool did_show_out_of_credits_ = false;
base::Time out_of_credits_notify_time_; base::Time out_of_credits_notify_time_;
std::set<std::string> cellular_activating_; // Set to the GUID of the active non VPN network if any, otherwise empty.
std::string connected_vpn_; std::string active_non_vpn_network_guid_;
// Tracks GUIDs of activating cellular networks for activation notification.
std::set<std::string> cellular_activating_guids_;
base::WeakPtrFactory<NetworkStateNotifier> weak_ptr_factory_; base::WeakPtrFactory<NetworkStateNotifier> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(NetworkStateNotifier); DISALLOW_COPY_AND_ASSIGN(NetworkStateNotifier);
......
...@@ -72,19 +72,13 @@ std::string GetLogName(const ManagedState* state) { ...@@ -72,19 +72,13 @@ std::string GetLogName(const ManagedState* state) {
bool ShouldIncludeNetworkInList(const NetworkState* network_state, bool ShouldIncludeNetworkInList(const NetworkState* network_state,
bool configured_only, bool configured_only,
bool visible_only, bool visible_only) {
bool get_active) {
if (configured_only && !network_state->IsInProfile()) if (configured_only && !network_state->IsInProfile())
return false; return false;
if (visible_only && !network_state->visible()) if (visible_only && !network_state->visible())
return false; return false;
bool is_network_active =
network_state->IsConnectedState() || network_state->IsConnectingState();
if (is_network_active != get_active)
return false;
if (network_state->type() == shill::kTypeWifi && if (network_state->type() == shill::kTypeWifi &&
!network_state->tether_guid().empty()) { !network_state->tether_guid().empty()) {
// Wi-Fi networks which are actually underlying Wi-Fi hotspots for a // Wi-Fi networks which are actually underlying Wi-Fi hotspots for a
...@@ -98,6 +92,26 @@ bool ShouldIncludeNetworkInList(const NetworkState* network_state, ...@@ -98,6 +92,26 @@ bool ShouldIncludeNetworkInList(const NetworkState* network_state,
} // namespace } // namespace
// Class for tracking properties that affect whether a NetworkState is active.
class NetworkStateHandler::ActiveNetworkState {
public:
explicit ActiveNetworkState(const NetworkState* network)
: guid_(network->guid()),
connection_state_(network->connection_state()) {}
bool MatchesNetworkState(const NetworkState* network) {
return guid_ == network->guid() &&
connection_state_ == network->connection_state();
}
private:
// Unique network identifier.
const std::string guid_;
// Active networks have a connected or connecting |connection_state_|, see
// NetworkState::Is{Connected|Connecting}State.
const std::string connection_state_;
};
const char NetworkStateHandler::kDefaultCheckPortalList[] = const char NetworkStateHandler::kDefaultCheckPortalList[] =
"ethernet,wifi,cellular"; "ethernet,wifi,cellular";
...@@ -357,79 +371,33 @@ const NetworkState* NetworkStateHandler::DefaultNetwork() const { ...@@ -357,79 +371,33 @@ const NetworkState* NetworkStateHandler::DefaultNetwork() const {
const NetworkState* NetworkStateHandler::ConnectedNetworkByType( const NetworkState* NetworkStateHandler::ConnectedNetworkByType(
const NetworkTypePattern& type) { const NetworkTypePattern& type) {
// Sort to ensure visible networks are listed first. NetworkStateList active_networks;
if (!network_list_sorted_) GetActiveNetworkListByType(type, &active_networks);
SortNetworkList(false /* ensure_cellular */); for (auto* network : active_networks) {
if (network->IsConnectedState())
const NetworkState* connected_network = nullptr; return network;
for (auto iter = network_list_.begin(); iter != network_list_.end(); ++iter) {
const NetworkState* network = (*iter)->AsNetworkState();
DCHECK(network);
if (!network->update_received())
continue;
if (!network->IsConnectedState())
break; // Connected networks are listed first.
if (network->Matches(type)) {
connected_network = network;
break;
}
}
// Ethernet networks are prioritized over Tether networks.
if (connected_network && connected_network->type() == shill::kTypeEthernet) {
return connected_network;
}
// Tether networks are prioritized over non-Ethernet networks.
if (type.MatchesPattern(NetworkTypePattern::Tether())) {
for (auto iter = tether_network_list_.begin();
iter != tether_network_list_.end(); ++iter) {
const NetworkState* network = (*iter)->AsNetworkState();
DCHECK(network);
if (network->IsConnectedState())
return network;
}
} }
return nullptr;
return connected_network;
} }
const NetworkState* NetworkStateHandler::ConnectingNetworkByType( const NetworkState* NetworkStateHandler::ConnectingNetworkByType(
const NetworkTypePattern& type) const { const NetworkTypePattern& type) {
const NetworkState* connecting_network = nullptr; NetworkStateList active_networks;
GetActiveNetworkListByType(type, &active_networks);
// Active networks are always listed first by Shill so no need to sort. for (auto* network : active_networks) {
for (auto iter = network_list_.begin(); iter != network_list_.end(); ++iter) { if (network->IsConnectingState())
const NetworkState* network = (*iter)->AsNetworkState(); return network;
DCHECK(network);
if (!network->update_received() || network->IsConnectedState())
continue;
if (!network->IsConnectingState())
break; // Connected and connecting networks are listed first.
if (network->Matches(type)) {
connecting_network = network;
break;
}
}
// Ethernet networks are prioritized over Tether networks.
if (connecting_network &&
connecting_network->type() == shill::kTypeEthernet) {
return connecting_network;
}
// Tether networks are prioritized over non-Ethernet networks.
if (type.MatchesPattern(NetworkTypePattern::Tether())) {
for (auto iter = tether_network_list_.begin();
iter != tether_network_list_.end(); ++iter) {
const NetworkState* network = (*iter)->AsNetworkState();
DCHECK(network);
if (network->IsConnectingState())
return network;
}
} }
return nullptr;
}
return connecting_network; const NetworkState* NetworkStateHandler::ActiveNetworkByType(
const NetworkTypePattern& type) {
NetworkStateList active_networks;
GetActiveNetworkListByType(type, &active_networks);
if (active_networks.size() > 0)
return active_networks.front();
return nullptr;
} }
const NetworkState* NetworkStateHandler::FirstNetworkByType( const NetworkState* NetworkStateHandler::FirstNetworkByType(
...@@ -509,6 +477,25 @@ void NetworkStateHandler::GetNetworkListByType(const NetworkTypePattern& type, ...@@ -509,6 +477,25 @@ void NetworkStateHandler::GetNetworkListByType(const NetworkTypePattern& type,
bool visible_only, bool visible_only,
size_t limit, size_t limit,
NetworkStateList* list) { NetworkStateList* list) {
GetNetworkListByTypeImpl(type, configured_only, visible_only,
false /* active_only */, limit, list);
}
void NetworkStateHandler::GetActiveNetworkListByType(
const NetworkTypePattern& type,
NetworkStateList* list) {
GetNetworkListByTypeImpl(type, false /* configured_only */,
false /* visible_only */, true /* active_only */,
0 /* no limit */, list);
}
void NetworkStateHandler::GetNetworkListByTypeImpl(
const NetworkTypePattern& type,
bool configured_only,
bool visible_only,
bool active_only,
size_t limit,
NetworkStateList* list) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(list); DCHECK(list);
list->clear(); list->clear();
...@@ -526,40 +513,48 @@ void NetworkStateHandler::GetNetworkListByType(const NetworkTypePattern& type, ...@@ -526,40 +513,48 @@ void NetworkStateHandler::GetNetworkListByType(const NetworkTypePattern& type,
AppendTetherNetworksToList(true /* get_active */, limit, list); AppendTetherNetworksToList(true /* get_active */, limit, list);
// Second, add active non-Tether networks. // Second, add active non-Tether networks.
for (auto iter = network_list_.begin(); for (const auto& managed : network_list_) {
iter != network_list_.end() && list->size() < limit; ++iter) { const NetworkState* network = managed.get()->AsNetworkState();
const NetworkState* network = (*iter)->AsNetworkState();
DCHECK(network); DCHECK(network);
if (!network->update_received() || !network->Matches(type)) if (!network->update_received() || !network->Matches(type))
continue; continue;
if (!ShouldIncludeNetworkInList(network, configured_only, visible_only, if (!network->IsConnectingOrConnected())
true /* get_active */)) { break; // Shill lists active networks first.
if (!ShouldIncludeNetworkInList(network, configured_only, visible_only))
continue; continue;
}
if (network->type() == shill::kTypeEthernet) { if (network->type() == shill::kTypeEthernet) {
// Ethernet networks should always be in front. // Ethernet networks should always be in front.
list->insert(list->begin(), network); list->insert(list->begin(), network);
} else { } else {
list->push_back(network); list->push_back(network);
} }
if (list->size() >= limit)
return;
} }
if (active_only)
return;
// Third, add inactive Tether networks. // Third, add inactive Tether networks.
if (type.MatchesPattern(NetworkTypePattern::Tether())) if (type.MatchesPattern(NetworkTypePattern::Tether()))
AppendTetherNetworksToList(false /* get_active */, limit, list); AppendTetherNetworksToList(false /* get_active */, limit, list);
if (list->size() >= limit)
return;
// Fourth, add inactive non-Tether networks. // Fourth, add inactive non-Tether networks.
for (auto iter = network_list_.begin(); for (const auto& managed : network_list_) {
iter != network_list_.end() && list->size() < limit; ++iter) { const NetworkState* network = managed.get()->AsNetworkState();
const NetworkState* network = (*iter)->AsNetworkState();
DCHECK(network); DCHECK(network);
if (!network->update_received() || !network->Matches(type)) if (!network->update_received() || !network->Matches(type))
continue; continue;
if (!ShouldIncludeNetworkInList(network, configured_only, visible_only, if (network->IsConnectingOrConnected())
false /* get_active */)) { continue;
if (!ShouldIncludeNetworkInList(network, configured_only, visible_only))
continue; continue;
}
list->push_back(network); list->push_back(network);
if (list->size() >= limit)
return;
} }
} }
...@@ -575,12 +570,12 @@ void NetworkStateHandler::AppendTetherNetworksToList(bool get_active, ...@@ -575,12 +570,12 @@ void NetworkStateHandler::AppendTetherNetworksToList(bool get_active,
iter != tether_network_list_.end() && list->size() < limit; ++iter) { iter != tether_network_list_.end() && list->size() < limit; ++iter) {
const NetworkState* network = (*iter)->AsNetworkState(); const NetworkState* network = (*iter)->AsNetworkState();
DCHECK(network); DCHECK(network);
if (network->IsConnectingOrConnected() != get_active)
continue;
if (!ShouldIncludeNetworkInList(network, false /* configured_only */, if (!ShouldIncludeNetworkInList(network, false /* configured_only */,
false /* visible_only */, get_active)) { false /* visible_only */)) {
continue; continue;
} }
list->push_back(network); list->push_back(network);
} }
} }
...@@ -709,14 +704,17 @@ bool NetworkStateHandler::RemoveTetherNetworkState(const std::string& guid) { ...@@ -709,14 +704,17 @@ bool NetworkStateHandler::RemoveTetherNetworkState(const std::string& guid) {
for (auto iter = tether_network_list_.begin(); for (auto iter = tether_network_list_.begin();
iter != tether_network_list_.end(); ++iter) { iter != tether_network_list_.end(); ++iter) {
if (iter->get()->AsNetworkState()->guid() == guid) { if (iter->get()->AsNetworkState()->guid() == guid) {
NetworkState* wifi_network = GetModifiableNetworkStateFromGuid( NetworkState* tether_network = iter->get()->AsNetworkState();
iter->get()->AsNetworkState()->tether_guid()); bool was_active = tether_network->IsConnectingOrConnected();
NetworkState* wifi_network =
GetModifiableNetworkStateFromGuid(tether_network->tether_guid());
if (wifi_network) if (wifi_network)
wifi_network->set_tether_guid(std::string()); wifi_network->set_tether_guid(std::string());
tether_network_list_.erase(iter); tether_network_list_.erase(iter);
NotifyNetworkListChanged();
if (was_active)
NotifyIfActiveNetworksChanged();
NotifyNetworkListChanged();
return true; return true;
} }
} }
...@@ -1394,6 +1392,8 @@ void NetworkStateHandler::UpdateIPConfigProperties( ...@@ -1394,6 +1392,8 @@ void NetworkStateHandler::UpdateIPConfigProperties(
NotifyNetworkPropertiesUpdated(network); NotifyNetworkPropertiesUpdated(network);
if (network->path() == default_network_path_) if (network->path() == default_network_path_)
NotifyDefaultNetworkChanged(); NotifyDefaultNetworkChanged();
if (network->IsConnectingOrConnected())
NotifyIfActiveNetworksChanged();
} else if (type == ManagedState::MANAGED_TYPE_DEVICE) { } else if (type == ManagedState::MANAGED_TYPE_DEVICE) {
DeviceState* device = GetModifiableDeviceState(path); DeviceState* device = GetModifiableDeviceState(path);
if (!device) if (!device)
...@@ -1428,6 +1428,7 @@ void NetworkStateHandler::ManagedStateListChanged( ...@@ -1428,6 +1428,7 @@ void NetworkStateHandler::ManagedStateListChanged(
if (type == ManagedState::MANAGED_TYPE_NETWORK) { if (type == ManagedState::MANAGED_TYPE_NETWORK) {
SortNetworkList(true /* ensure_cellular */); SortNetworkList(true /* ensure_cellular */);
UpdateNetworkStats(); UpdateNetworkStats();
NotifyIfActiveNetworksChanged();
NotifyNetworkListChanged(); NotifyNetworkListChanged();
UpdateManagedWifiNetworkAvailable(); UpdateManagedWifiNetworkAvailable();
} else if (type == ManagedState::MANAGED_TYPE_DEVICE) { } else if (type == ManagedState::MANAGED_TYPE_DEVICE) {
...@@ -1803,6 +1804,7 @@ void NetworkStateHandler::NotifyNetworkConnectionStateChanged( ...@@ -1803,6 +1804,7 @@ void NetworkStateHandler::NotifyNetworkConnectionStateChanged(
for (auto& observer : observers_) for (auto& observer : observers_)
observer.NetworkConnectionStateChanged(network); observer.NetworkConnectionStateChanged(network);
notifying_network_observers_ = false; notifying_network_observers_ = false;
NotifyIfActiveNetworksChanged();
} }
void NetworkStateHandler::NotifyDefaultNetworkChanged() { void NetworkStateHandler::NotifyDefaultNetworkChanged() {
...@@ -1823,6 +1825,36 @@ void NetworkStateHandler::NotifyDefaultNetworkChanged() { ...@@ -1823,6 +1825,36 @@ void NetworkStateHandler::NotifyDefaultNetworkChanged() {
notifying_network_observers_ = false; notifying_network_observers_ = false;
} }
bool NetworkStateHandler::ActiveNetworksChanged(
const NetworkStateList& active_networks) {
if (active_networks.size() != active_network_list_.size())
return true;
for (size_t i = 0; i < active_network_list_.size(); ++i) {
if (!active_network_list_[i].MatchesNetworkState(active_networks[i]))
return true;
}
return false;
}
void NetworkStateHandler::NotifyIfActiveNetworksChanged() {
SCOPED_NET_LOG_IF_SLOW();
NET_LOG(EVENT) << "NOTIFY:ActiveNetworksChanged";
NetworkStateList active_networks;
GetActiveNetworkListByType(NetworkTypePattern::Default(), &active_networks);
if (!ActiveNetworksChanged(active_networks))
return;
active_network_list_.clear();
active_network_list_.reserve(active_networks.size());
for (const NetworkState* network : active_networks)
active_network_list_.emplace_back(network);
notifying_network_observers_ = true;
for (auto& observer : observers_)
observer.ActiveNetworksChanged(active_networks);
notifying_network_observers_ = false;
}
void NetworkStateHandler::NotifyNetworkPropertiesUpdated( void NetworkStateHandler::NotifyNetworkPropertiesUpdated(
const NetworkState* network) { const NetworkState* network) {
SCOPED_NET_LOG_IF_SLOW(); SCOPED_NET_LOG_IF_SLOW();
......
...@@ -161,12 +161,15 @@ class COMPONENT_EXPORT(CHROMEOS_NETWORK) NetworkStateHandler ...@@ -161,12 +161,15 @@ class COMPONENT_EXPORT(CHROMEOS_NETWORK) NetworkStateHandler
// differ. // differ.
const NetworkState* DefaultNetwork() const; const NetworkState* DefaultNetwork() const;
// Returns the primary connected network of matching |type|, otherwise NULL. // Returns the primary connected network matching |type|, otherwise null.
const NetworkState* ConnectedNetworkByType(const NetworkTypePattern& type); const NetworkState* ConnectedNetworkByType(const NetworkTypePattern& type);
// Like ConnectedNetworkByType() but returns a connecting network or NULL. // Returns the primary connecting network matching |type|, otherwise null.
const NetworkState* ConnectingNetworkByType( const NetworkState* ConnectingNetworkByType(const NetworkTypePattern& type);
const NetworkTypePattern& type) const;
// Returns the primary active network of matching |type|, otherwise null.
// See also GetActiveNetworkListByType.
const NetworkState* ActiveNetworkByType(const NetworkTypePattern& type);
// Like ConnectedNetworkByType() but returns any matching visible network or // Like ConnectedNetworkByType() but returns any matching visible network or
// NULL. Mostly useful for mobile networks where there is generally only one // NULL. Mostly useful for mobile networks where there is generally only one
...@@ -200,6 +203,14 @@ class COMPONENT_EXPORT(CHROMEOS_NETWORK) NetworkStateHandler ...@@ -200,6 +203,14 @@ class COMPONENT_EXPORT(CHROMEOS_NETWORK) NetworkStateHandler
size_t limit, size_t limit,
NetworkStateList* list); NetworkStateList* list);
// Sets |list| to contain the active networks matching |type|. An 'active'
// network is connecting or connected, and the first connected active network
// is the primary or 'default' network providing connectivity (which may be a
// VPN, use NetworkTypePattern::NonVirtual() to ignore VPNs). See
// GetNetworkListByType for notes on |list| results.
void GetActiveNetworkListByType(const NetworkTypePattern& type,
NetworkStateList* list);
// Finds and returns the NetworkState associated with |service_path| or NULL // Finds and returns the NetworkState associated with |service_path| or NULL
// if not found. If |configured_only| is true, only returns saved entries // if not found. If |configured_only| is true, only returns saved entries
// (IsInProfile is true). // (IsInProfile is true).
...@@ -452,6 +463,14 @@ class COMPONENT_EXPORT(CHROMEOS_NETWORK) NetworkStateHandler ...@@ -452,6 +463,14 @@ class COMPONENT_EXPORT(CHROMEOS_NETWORK) NetworkStateHandler
FRIEND_TEST_ALL_PREFIXES(NetworkStateHandlerTest, FRIEND_TEST_ALL_PREFIXES(NetworkStateHandlerTest,
BlockedByPolicyOnlyManagedIfAvailable); BlockedByPolicyOnlyManagedIfAvailable);
// Implementation for GetNetworkListByType and GetActiveNetworkListByType.
void GetNetworkListByTypeImpl(const NetworkTypePattern& type,
bool configured_only,
bool visible_only,
bool active_only,
size_t limit,
NetworkStateList* list);
// Sorts the network list. Called when all network updates have been received, // Sorts the network list. Called when all network updates have been received,
// or when the network list is requested but the list is in an unsorted state. // or when the network list is requested but the list is in an unsorted state.
// Networks are sorted as follows, maintaining the existing relative ordering: // Networks are sorted as follows, maintaining the existing relative ordering:
...@@ -527,6 +546,11 @@ class COMPONENT_EXPORT(CHROMEOS_NETWORK) NetworkStateHandler ...@@ -527,6 +546,11 @@ class COMPONENT_EXPORT(CHROMEOS_NETWORK) NetworkStateHandler
// Notifies observers when the default network or its properties change. // Notifies observers when the default network or its properties change.
void NotifyDefaultNetworkChanged(); void NotifyDefaultNetworkChanged();
// Notifies observers when the active state of any current or previously
// active network changes, or the active networks order changes.
bool ActiveNetworksChanged(const NetworkStateList& active_networks);
void NotifyIfActiveNetworksChanged();
// Notifies observers about changes to |network|, including IPConfg. // Notifies observers about changes to |network|, including IPConfg.
void NotifyNetworkPropertiesUpdated(const NetworkState* network); void NotifyNetworkPropertiesUpdated(const NetworkState* network);
...@@ -600,6 +624,10 @@ class COMPONENT_EXPORT(CHROMEOS_NETWORK) NetworkStateHandler ...@@ -600,6 +624,10 @@ class COMPONENT_EXPORT(CHROMEOS_NETWORK) NetworkStateHandler
// |network_list_|. // |network_list_|.
ManagedStateList tether_network_list_; ManagedStateList tether_network_list_;
// List of active networks, used to limit ActiveNetworksChanged events.
class ActiveNetworkState;
std::vector<ActiveNetworkState> active_network_list_;
// Set to true when the network list is sorted, cleared when network updates // Set to true when the network list is sorted, cleared when network updates
// arrive. Used to trigger sorting when needed. // arrive. Used to trigger sorting when needed.
bool network_list_sorted_ = false; bool network_list_sorted_ = false;
......
...@@ -10,33 +10,29 @@ NetworkStateHandlerObserver::NetworkStateHandlerObserver() = default; ...@@ -10,33 +10,29 @@ NetworkStateHandlerObserver::NetworkStateHandlerObserver() = default;
NetworkStateHandlerObserver::~NetworkStateHandlerObserver() = default; NetworkStateHandlerObserver::~NetworkStateHandlerObserver() = default;
void NetworkStateHandlerObserver::NetworkListChanged() { void NetworkStateHandlerObserver::NetworkListChanged() {}
}
void NetworkStateHandlerObserver::DeviceListChanged() { void NetworkStateHandlerObserver::DeviceListChanged() {}
}
void NetworkStateHandlerObserver::DefaultNetworkChanged( void NetworkStateHandlerObserver::DefaultNetworkChanged(
const NetworkState* network) { const NetworkState* network) {}
}
void NetworkStateHandlerObserver::NetworkConnectionStateChanged( void NetworkStateHandlerObserver::NetworkConnectionStateChanged(
const NetworkState* network) { const NetworkState* network) {}
}
void NetworkStateHandlerObserver::ActiveNetworksChanged(
const std::vector<const NetworkState*>& active_networks) {}
void NetworkStateHandlerObserver::NetworkPropertiesUpdated( void NetworkStateHandlerObserver::NetworkPropertiesUpdated(
const NetworkState* network) { const NetworkState* network) {}
}
void NetworkStateHandlerObserver::DevicePropertiesUpdated( void NetworkStateHandlerObserver::DevicePropertiesUpdated(
const chromeos::DeviceState* device) { const chromeos::DeviceState* device) {}
}
void NetworkStateHandlerObserver::ScanRequested( void NetworkStateHandlerObserver::ScanRequested(
const NetworkTypePattern& type) {} const NetworkTypePattern& type) {}
void NetworkStateHandlerObserver::ScanCompleted(const DeviceState* device) { void NetworkStateHandlerObserver::ScanCompleted(const DeviceState* device) {}
}
void NetworkStateHandlerObserver::OnShuttingDown() {} void NetworkStateHandlerObserver::OnShuttingDown() {}
......
...@@ -41,6 +41,12 @@ class COMPONENT_EXPORT(CHROMEOS_NETWORK) NetworkStateHandlerObserver { ...@@ -41,6 +41,12 @@ class COMPONENT_EXPORT(CHROMEOS_NETWORK) NetworkStateHandlerObserver {
// The connection state of |network| changed. // The connection state of |network| changed.
virtual void NetworkConnectionStateChanged(const NetworkState* network); virtual void NetworkConnectionStateChanged(const NetworkState* network);
// Triggered when the connection state of any current or previously active
// (connected or connecting) network changes. Provides the current list of
// active networks, which may include a VPN.
virtual void ActiveNetworksChanged(
const std::vector<const NetworkState*>& active_networks);
// One or more properties of |network| have been updated. Note: this will get // One or more properties of |network| have been updated. Note: this will get
// called in *addition* to NetworkConnectionStateChanged() when the // called in *addition* to NetworkConnectionStateChanged() when the
// connection state property changes. Use this to track properties like // connection state property changes. Use this to track properties like
......
...@@ -40,11 +40,6 @@ namespace chromeos { ...@@ -40,11 +40,6 @@ namespace chromeos {
namespace { namespace {
void ErrorCallbackFunction(const std::string& error_name,
const std::string& error_message) {
LOG(ERROR) << "Shill Error: " << error_name << " : " << error_message;
}
const char kShillManagerClientStubWifiDevice[] = "/device/stub_wifi_device1"; const char kShillManagerClientStubWifiDevice[] = "/device/stub_wifi_device1";
const char kShillManagerClientStubCellularDevice[] = const char kShillManagerClientStubCellularDevice[] =
"/device/stub_cellular_device1"; "/device/stub_cellular_device1";
...@@ -71,21 +66,22 @@ const bool kTetherHasConnectedToHost2 = false; ...@@ -71,21 +66,22 @@ const bool kTetherHasConnectedToHost2 = false;
const char kProfilePath[] = "/network/test"; const char kProfilePath[] = "/network/test";
using chromeos::DeviceState; void ErrorCallbackFunction(const std::string& error_name,
using chromeos::NetworkState; const std::string& error_message) {
using chromeos::NetworkStateHandler; LOG(ERROR) << "Shill Error: " << error_name << " : " << error_message;
}
std::vector<std::string> GetNetworkPaths(
const std::vector<const NetworkState*>& networks) {
std::vector<std::string> result;
for (const auto* network : networks)
result.push_back(network->path());
return result;
}
class TestObserver final : public chromeos::NetworkStateHandlerObserver { class TestObserver final : public chromeos::NetworkStateHandlerObserver {
public: public:
explicit TestObserver(NetworkStateHandler* handler) explicit TestObserver(NetworkStateHandler* handler) : handler_(handler) {}
: handler_(handler),
device_list_changed_count_(0),
device_count_(0),
network_list_changed_count_(0),
network_count_(0),
default_network_change_count_(0),
scan_completed_count_(0) {}
~TestObserver() override = default; ~TestObserver() override = default;
void DeviceListChanged() override { void DeviceListChanged() override {
...@@ -103,10 +99,6 @@ class TestObserver final : public chromeos::NetworkStateHandlerObserver { ...@@ -103,10 +99,6 @@ class TestObserver final : public chromeos::NetworkStateHandlerObserver {
0 /* no limit */, 0 /* no limit */,
&networks); &networks);
network_count_ = networks.size(); network_count_ = networks.size();
if (network_count_ == 0) {
default_network_ = "";
default_network_connection_state_ = "";
}
++network_list_changed_count_; ++network_list_changed_count_;
} }
...@@ -125,6 +117,12 @@ class TestObserver final : public chromeos::NetworkStateHandlerObserver { ...@@ -125,6 +117,12 @@ class TestObserver final : public chromeos::NetworkStateHandlerObserver {
connection_state_changes_[network->path()]++; connection_state_changes_[network->path()]++;
} }
void ActiveNetworksChanged(
const std::vector<const NetworkState*>& active_networks) override {
++active_network_change_count_;
active_network_paths_ = GetNetworkPaths(active_networks);
}
void NetworkPropertiesUpdated(const NetworkState* network) override { void NetworkPropertiesUpdated(const NetworkState* network) override {
DCHECK(network); DCHECK(network);
property_updates_[network->path()]++; property_updates_[network->path()]++;
...@@ -144,13 +142,14 @@ class TestObserver final : public chromeos::NetworkStateHandlerObserver { ...@@ -144,13 +142,14 @@ class TestObserver final : public chromeos::NetworkStateHandlerObserver {
scan_completed_count_++; scan_completed_count_++;
} }
size_t active_network_change_count() { return active_network_change_count_; }
size_t default_network_change_count() {
return default_network_change_count_;
}
size_t device_list_changed_count() { return device_list_changed_count_; } size_t device_list_changed_count() { return device_list_changed_count_; }
size_t device_count() { return device_count_; } size_t device_count() { return device_count_; }
size_t network_list_changed_count() { return network_list_changed_count_; } size_t network_list_changed_count() { return network_list_changed_count_; }
size_t network_count() { return network_count_; } size_t network_count() { return network_count_; }
size_t default_network_change_count() {
return default_network_change_count_;
}
size_t scan_requested_count() { return scan_requests_.size(); } size_t scan_requested_count() { return scan_requests_.size(); }
const std::vector<NetworkTypePattern>& scan_requests() { const std::vector<NetworkTypePattern>& scan_requests() {
return scan_requests_; return scan_requests_;
...@@ -158,6 +157,7 @@ class TestObserver final : public chromeos::NetworkStateHandlerObserver { ...@@ -158,6 +157,7 @@ class TestObserver final : public chromeos::NetworkStateHandlerObserver {
size_t scan_completed_count() { return scan_completed_count_; } size_t scan_completed_count() { return scan_completed_count_; }
void reset_change_counts() { void reset_change_counts() {
VLOG(1) << "=== RESET CHANGE COUNTS ==="; VLOG(1) << "=== RESET CHANGE COUNTS ===";
active_network_change_count_ = 0;
default_network_change_count_ = 0; default_network_change_count_ = 0;
device_list_changed_count_ = 0; device_list_changed_count_ = 0;
network_list_changed_count_ = 0; network_list_changed_count_ = 0;
...@@ -169,6 +169,9 @@ class TestObserver final : public chromeos::NetworkStateHandlerObserver { ...@@ -169,6 +169,9 @@ class TestObserver final : public chromeos::NetworkStateHandlerObserver {
property_updates_.clear(); property_updates_.clear();
device_property_updates_.clear(); device_property_updates_.clear();
} }
const std::vector<std::string>& active_network_paths() {
return active_network_paths_;
}
std::string default_network() { return default_network_; } std::string default_network() { return default_network_; }
std::string default_network_connection_state() { std::string default_network_connection_state() {
return default_network_connection_state_; return default_network_connection_state_;
...@@ -193,13 +196,15 @@ class TestObserver final : public chromeos::NetworkStateHandlerObserver { ...@@ -193,13 +196,15 @@ class TestObserver final : public chromeos::NetworkStateHandlerObserver {
private: private:
NetworkStateHandler* handler_; NetworkStateHandler* handler_;
size_t device_list_changed_count_; size_t active_network_change_count_ = 0;
size_t device_count_; size_t default_network_change_count_ = 0;
size_t network_list_changed_count_; size_t device_list_changed_count_ = 0;
size_t network_count_; size_t device_count_ = 0;
size_t default_network_change_count_; size_t network_list_changed_count_ = 0;
size_t network_count_ = 0;
std::vector<NetworkTypePattern> scan_requests_; std::vector<NetworkTypePattern> scan_requests_;
size_t scan_completed_count_; size_t scan_completed_count_ = 0;
std::vector<std::string> active_network_paths_;
std::string default_network_; std::string default_network_;
std::string default_network_connection_state_; std::string default_network_connection_state_;
std::map<std::string, int> property_updates_; std::map<std::string, int> property_updates_;
...@@ -396,6 +401,31 @@ TEST_F(NetworkStateHandlerTest, NetworkStateHandlerStub) { ...@@ -396,6 +401,31 @@ TEST_F(NetworkStateHandlerTest, NetworkStateHandlerStub) {
test_observer_->default_network_connection_state()); test_observer_->default_network_connection_state());
} }
TEST_F(NetworkStateHandlerTest, NetworkStateHandlerStubActiveNetworks) {
NetworkStateHandler::NetworkStateList active_networks;
network_state_handler_->GetActiveNetworkListByType(
NetworkTypePattern::Default(), &active_networks);
std::vector<std::string> active_network_paths =
GetNetworkPaths(active_networks);
const std::vector<std::string> expected_active_network_paths = {
kShillManagerClientStubDefaultService,
kShillManagerClientStubDefaultWifi};
EXPECT_EQ(expected_active_network_paths, active_network_paths);
EXPECT_EQ(
kShillManagerClientStubDefaultService,
network_state_handler_->ActiveNetworkByType(NetworkTypePattern::Default())
->path());
EXPECT_EQ(kShillManagerClientStubDefaultService,
network_state_handler_
->ActiveNetworkByType(NetworkTypePattern::Ethernet())
->path());
EXPECT_EQ(
kShillManagerClientStubDefaultWifi,
network_state_handler_->ActiveNetworkByType(NetworkTypePattern::WiFi())
->path());
}
TEST_F(NetworkStateHandlerTest, GetNetworkList) { TEST_F(NetworkStateHandlerTest, GetNetworkList) {
network_state_handler_->SetTetherTechnologyState( network_state_handler_->SetTetherTechnologyState(
NetworkStateHandler::TECHNOLOGY_ENABLED); NetworkStateHandler::TECHNOLOGY_ENABLED);
...@@ -639,6 +669,19 @@ TEST_F(NetworkStateHandlerTest, ...@@ -639,6 +669,19 @@ TEST_F(NetworkStateHandlerTest,
EXPECT_EQ(cellular, list[2]->path()); EXPECT_EQ(cellular, list[2]->path());
EXPECT_EQ(kTetherGuid2, list[3]->guid()); EXPECT_EQ(kTetherGuid2, list[3]->guid());
EXPECT_EQ(wifi2, list[4]->path()); EXPECT_EQ(wifi2, list[4]->path());
// Get active networks.
network_state_handler_->GetActiveNetworkListByType(
NetworkTypePattern::Default(), &list);
std::vector<std::string> active_network_paths = GetNetworkPaths(list);
const std::vector<std::string> expected_active_network_paths = {
kShillManagerClientStubDefaultService, kTetherGuid1,
kShillManagerClientStubCellular};
EXPECT_EQ(expected_active_network_paths, active_network_paths);
EXPECT_EQ(
kTetherGuid1,
network_state_handler_->ActiveNetworkByType(NetworkTypePattern::Tether())
->path());
} }
TEST_F(NetworkStateHandlerTest, NetworkListChanged) { TEST_F(NetworkStateHandlerTest, NetworkListChanged) {
...@@ -855,6 +898,7 @@ TEST_F(NetworkStateHandlerTest, ServicePropertyChangedDefaultNetwork) { ...@@ -855,6 +898,7 @@ TEST_F(NetworkStateHandlerTest, ServicePropertyChangedDefaultNetwork) {
EXPECT_EQ("", ethernet->security_class()); EXPECT_EQ("", ethernet->security_class());
EXPECT_EQ(1, test_observer_->PropertyUpdatesForService(eth1)); EXPECT_EQ(1, test_observer_->PropertyUpdatesForService(eth1));
EXPECT_EQ(0u, test_observer_->default_network_change_count()); EXPECT_EQ(0u, test_observer_->default_network_change_count());
EXPECT_EQ(0u, test_observer_->active_network_change_count());
base::Value security_class_value("TestSecurityClass"); base::Value security_class_value("TestSecurityClass");
SetServiceProperty(eth1, shill::kSecurityClassProperty, security_class_value); SetServiceProperty(eth1, shill::kSecurityClassProperty, security_class_value);
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
...@@ -878,6 +922,7 @@ TEST_F(NetworkStateHandlerTest, ServicePropertyChangedNotIneterstingActive) { ...@@ -878,6 +922,7 @@ TEST_F(NetworkStateHandlerTest, ServicePropertyChangedNotIneterstingActive) {
EXPECT_EQ(1, wifi->signal_strength()); EXPECT_EQ(1, wifi->signal_strength());
EXPECT_EQ(1, test_observer_->PropertyUpdatesForService(wifi1)); EXPECT_EQ(1, test_observer_->PropertyUpdatesForService(wifi1));
EXPECT_EQ(0u, test_observer_->default_network_change_count()); EXPECT_EQ(0u, test_observer_->default_network_change_count());
EXPECT_EQ(0u, test_observer_->active_network_change_count());
base::Value signal_strength_value(11); base::Value signal_strength_value(11);
SetServiceProperty(wifi1, shill::kSignalStrengthProperty, SetServiceProperty(wifi1, shill::kSignalStrengthProperty,
signal_strength_value); signal_strength_value);
...@@ -887,6 +932,7 @@ TEST_F(NetworkStateHandlerTest, ServicePropertyChangedNotIneterstingActive) { ...@@ -887,6 +932,7 @@ TEST_F(NetworkStateHandlerTest, ServicePropertyChangedNotIneterstingActive) {
// The change should trigger an additional properties updated event. // The change should trigger an additional properties updated event.
EXPECT_EQ(2, test_observer_->PropertyUpdatesForService(wifi1)); EXPECT_EQ(2, test_observer_->PropertyUpdatesForService(wifi1));
EXPECT_EQ(0u, test_observer_->default_network_change_count()); EXPECT_EQ(0u, test_observer_->default_network_change_count());
EXPECT_EQ(0u, test_observer_->active_network_change_count());
} }
TEST_F(NetworkStateHandlerTest, ServicePropertyChangedNotIneterstingInactive) { TEST_F(NetworkStateHandlerTest, ServicePropertyChangedNotIneterstingInactive) {
...@@ -1546,6 +1592,81 @@ TEST_F(NetworkStateHandlerTest, NetworkConnectionStateChanged) { ...@@ -1546,6 +1592,81 @@ TEST_F(NetworkStateHandlerTest, NetworkConnectionStateChanged) {
EXPECT_EQ(1, test_observer_->ConnectionStateChangesForService(eth1)); EXPECT_EQ(1, test_observer_->ConnectionStateChangesForService(eth1));
} }
TEST_F(NetworkStateHandlerTest, NetworkActiveNetworksStateChanged) {
// Initial state is just connected to Ethernet.
std::vector<std::string> expected_active_network_paths = {
kShillManagerClientStubDefaultService,
kShillManagerClientStubDefaultWifi};
EXPECT_EQ(expected_active_network_paths,
test_observer_->active_network_paths());
// Remove Ethernet.
service_test_->RemoveService(kShillManagerClientStubDefaultService);
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1u, test_observer_->active_network_change_count());
expected_active_network_paths = {kShillManagerClientStubDefaultWifi};
EXPECT_EQ(expected_active_network_paths,
test_observer_->active_network_paths());
// Disconnect Wifi1.
test_observer_->reset_change_counts();
service_test_->SetServiceProperty(kShillManagerClientStubDefaultWifi,
shill::kStateProperty,
base::Value(shill::kStateIdle));
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1u, test_observer_->active_network_change_count());
expected_active_network_paths = {};
EXPECT_EQ(expected_active_network_paths,
test_observer_->active_network_paths());
// Confirm that changing the connection state to the same value does *not*
// signal the observer.
service_test_->SetServiceProperty(kShillManagerClientStubDefaultWifi,
shill::kStateProperty,
base::Value(shill::kStateIdle));
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1u, test_observer_->active_network_change_count());
// Add two Tether networks.
test_observer_->reset_change_counts();
network_state_handler_->SetTetherTechnologyState(
NetworkStateHandler::TECHNOLOGY_ENABLED);
network_state_handler_->AddTetherNetworkState(
kTetherGuid1, kTetherName1, kTetherCarrier1, kTetherBatteryPercentage1,
kTetherSignalStrength1, kTetherHasConnectedToHost1);
network_state_handler_->AddTetherNetworkState(
kTetherGuid2, kTetherName2, kTetherCarrier2, kTetherBatteryPercentage2,
kTetherSignalStrength2, kTetherHasConnectedToHost2);
network_state_handler_->SetTetherNetworkStateConnecting(kTetherGuid1);
network_state_handler_->AssociateTetherNetworkStateWithWifiNetwork(
kTetherGuid1, "wifi2_guid");
service_test_->SetServiceProperty(kShillManagerClientStubWifi2,
shill::kStateProperty,
base::Value(shill::kStateOnline));
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1u, test_observer_->active_network_change_count());
// Connect the first Tether network.
test_observer_->reset_change_counts();
network_state_handler_->SetTetherNetworkStateConnected(kTetherGuid1);
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1u, test_observer_->active_network_change_count());
expected_active_network_paths = {kTetherGuid1};
EXPECT_EQ(expected_active_network_paths,
test_observer_->active_network_paths());
// Reconnect Ethernet
test_observer_->reset_change_counts();
AddService(kShillManagerClientStubDefaultService, "eth1_guid", "eth1",
shill::kTypeEthernet, shill::kStateOnline);
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1u, test_observer_->active_network_change_count());
expected_active_network_paths = {kShillManagerClientStubDefaultService,
kTetherGuid1};
EXPECT_EQ(expected_active_network_paths,
test_observer_->active_network_paths());
}
TEST_F(NetworkStateHandlerTest, DefaultServiceDisconnected) { TEST_F(NetworkStateHandlerTest, DefaultServiceDisconnected) {
const std::string eth1 = kShillManagerClientStubDefaultService; const std::string eth1 = kShillManagerClientStubDefaultService;
const std::string wifi1 = kShillManagerClientStubDefaultWifi; const std::string wifi1 = kShillManagerClientStubDefaultWifi;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment