| Index: chromeos/network/network_state_handler.cc
|
| diff --git a/chromeos/network/network_state_handler.cc b/chromeos/network/network_state_handler.cc
|
| index e95ba4f933e7f194fb4f7a195450912dac57e161..1f322ba6bc812168a0e683ec1a4152c3285a087b 100644
|
| --- a/chromeos/network/network_state_handler.cc
|
| +++ b/chromeos/network/network_state_handler.cc
|
| @@ -67,6 +67,32 @@ std::string ValueAsString(const base::Value& value) {
|
| return vstr.empty() ? "''" : vstr;
|
| }
|
|
|
| +bool ShouldIncludeNetworkInList(const NetworkState* network_state,
|
| + bool configured_only,
|
| + bool visible_only,
|
| + bool get_active) {
|
| + if (configured_only && !network_state->IsInProfile())
|
| + return false;
|
| +
|
| + if (visible_only && !network_state->visible())
|
| + 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 &&
|
| + !network_state->tether_guid().empty()) {
|
| + // Wi-Fi networks which are actually underlying Wi-Fi hotspots for a
|
| + // Tether network should not be included since they should only be shown
|
| + // to the user as Tether networks.
|
| + return false;
|
| + }
|
| +
|
| + return true;
|
| +}
|
| +
|
| } // namespace
|
|
|
| const char NetworkStateHandler::kDefaultCheckPortalList[] =
|
| @@ -414,62 +440,80 @@ void NetworkStateHandler::GetVisibleNetworkList(NetworkStateList* list) {
|
| void NetworkStateHandler::GetNetworkListByType(const NetworkTypePattern& type,
|
| bool configured_only,
|
| bool visible_only,
|
| - int limit,
|
| + size_t limit,
|
| NetworkStateList* list) {
|
| DCHECK(list);
|
| list->clear();
|
|
|
| - // Sort the network list if necessary.
|
| + // If |limit| is 0, there is no limit. Simplify the calculations below by
|
| + // setting it to the maximum size_t value.
|
| + if (limit == 0)
|
| + limit = std::numeric_limits<size_t>::max();
|
| +
|
| if (!network_list_sorted_)
|
| SortNetworkList();
|
|
|
| + // First, add active Tether networks.
|
| if (type.MatchesPattern(NetworkTypePattern::Tether()))
|
| - GetTetherNetworkList(limit, list);
|
| + AppendTetherNetworksToList(true /* get_active */, limit, list);
|
|
|
| - int count = list->size();
|
| -
|
| - if (type.Equals(NetworkTypePattern::Tether()) ||
|
| - (limit != 0 && count >= limit)) {
|
| - // If only searching for Tether networks, there is no need to continue
|
| - // searching through other network types; likewise, if the limit has already
|
| - // been reached, there is no need to continue searching.
|
| - return;
|
| - }
|
| -
|
| - for (auto iter = network_list_.begin(); iter != network_list_.end(); ++iter) {
|
| + // Second, add active non-Tether networks.
|
| + for (auto iter = network_list_.begin();
|
| + iter != network_list_.end() && list->size() < limit; ++iter) {
|
| const NetworkState* network = (*iter)->AsNetworkState();
|
| DCHECK(network);
|
| if (!network->update_received() || !network->Matches(type))
|
| continue;
|
| - if (configured_only && !network->IsInProfile())
|
| - continue;
|
| - if (visible_only && !network->visible())
|
| + if (!ShouldIncludeNetworkInList(network, configured_only, visible_only,
|
| + true /* get_active */)) {
|
| continue;
|
| + }
|
| if (network->type() == shill::kTypeEthernet) {
|
| // Ethernet networks should always be in front.
|
| list->insert(list->begin(), network);
|
| } else {
|
| list->push_back(network);
|
| }
|
| - if (limit > 0 && ++count >= limit)
|
| - break;
|
| + }
|
| +
|
| + // Third, add inactive Tether networks.
|
| + if (type.MatchesPattern(NetworkTypePattern::Tether()))
|
| + AppendTetherNetworksToList(false /* get_active */, limit, list);
|
| +
|
| + // Fourth, add inactive non-Tether networks.
|
| + for (auto iter = network_list_.begin();
|
| + iter != network_list_.end() && list->size() < limit; ++iter) {
|
| + const NetworkState* network = (*iter)->AsNetworkState();
|
| + DCHECK(network);
|
| + if (!network->update_received() || !network->Matches(type))
|
| + continue;
|
| + if (!ShouldIncludeNetworkInList(network, configured_only, visible_only,
|
| + false /* get_active */)) {
|
| + continue;
|
| + }
|
| + list->push_back(network);
|
| }
|
| }
|
|
|
| -void NetworkStateHandler::GetTetherNetworkList(int limit,
|
| - NetworkStateList* list) {
|
| +void NetworkStateHandler::AppendTetherNetworksToList(bool get_active,
|
| + size_t limit,
|
| + NetworkStateList* list) {
|
| DCHECK(list);
|
| - list->clear();
|
| -
|
| + DCHECK(limit != 0);
|
| if (!IsTechnologyEnabled(NetworkTypePattern::Tether()))
|
| return;
|
|
|
| - int count = 0;
|
| for (auto iter = tether_network_list_.begin();
|
| - iter != tether_network_list_.end(); ++iter) {
|
| - list->push_back((*iter)->AsNetworkState());
|
| - if (limit > 0 && ++count >= limit)
|
| - return;
|
| + iter != tether_network_list_.end() && list->size() < limit; ++iter) {
|
| + const NetworkState* network = (*iter)->AsNetworkState();
|
| + DCHECK(network);
|
| +
|
| + if (!ShouldIncludeNetworkInList(network, false /* configured_only */,
|
| + false /* visible_only */, get_active)) {
|
| + continue;
|
| + }
|
| +
|
| + list->push_back(network);
|
| }
|
| }
|
|
|
| @@ -538,6 +582,8 @@ void NetworkStateHandler::AddTetherNetworkState(const std::string& guid,
|
| tether_network_state->set_signal_strength(signal_strength);
|
|
|
| tether_network_list_.push_back(std::move(tether_network_state));
|
| + network_list_sorted_ = false;
|
| +
|
| NotifyNetworkListChanged();
|
| }
|
|
|
| @@ -562,6 +608,7 @@ bool NetworkStateHandler::UpdateTetherNetworkProperties(
|
| tether_network_state->set_carrier(carrier);
|
| tether_network_state->set_battery_percentage(battery_percentage);
|
| tether_network_state->set_signal_strength(signal_strength);
|
| + network_list_sorted_ = false;
|
|
|
| NotifyNetworkPropertiesUpdated(tether_network_state);
|
| return true;
|
| @@ -581,6 +628,7 @@ bool NetworkStateHandler::SetTetherNetworkHasConnectedToHost(
|
| }
|
|
|
| tether_network_state->set_tether_has_connected_to_host(true);
|
| + network_list_sorted_ = false;
|
|
|
| NotifyNetworkPropertiesUpdated(tether_network_state);
|
| return true;
|
| @@ -634,6 +682,7 @@ bool NetworkStateHandler::DisassociateTetherNetworkStateFromWifiNetwork(
|
|
|
| wifi_network_state->set_tether_guid(std::string());
|
| tether_network_state->set_tether_guid(std::string());
|
| + network_list_sorted_ = false;
|
|
|
| NotifyNetworkPropertiesUpdated(wifi_network_state);
|
| NotifyNetworkPropertiesUpdated(tether_network_state);
|
| @@ -681,6 +730,7 @@ bool NetworkStateHandler::AssociateTetherNetworkStateWithWifiNetwork(
|
|
|
| tether_network_state->set_tether_guid(wifi_network_guid);
|
| wifi_network_state->set_tether_guid(tether_network_guid);
|
| + network_list_sorted_ = false;
|
|
|
| NotifyNetworkPropertiesUpdated(wifi_network_state);
|
| NotifyNetworkPropertiesUpdated(tether_network_state);
|
| @@ -739,8 +789,9 @@ void NetworkStateHandler::SetTetherNetworkStateConnectionState(
|
|
|
| std::string prev_connection_state = tether_network_state->connection_state();
|
| tether_network_state->set_connection_state(connection_state);
|
| - DCHECK(!tether_network_state->is_captive_portal());
|
| + network_list_sorted_ = false;
|
|
|
| + DCHECK(!tether_network_state->is_captive_portal());
|
| if (ConnectionStateChanged(tether_network_state, prev_connection_state,
|
| false /* prev_is_captive_portal */)) {
|
| NET_LOG(EVENT) << "Changing connection state for Tether network with GUID "
|
| @@ -1207,8 +1258,10 @@ void NetworkStateHandler::ManagedStateListChanged(
|
| }
|
| }
|
|
|
| -// TODO(khorimoto): Add sorting for the Tether network list as well.
|
| void NetworkStateHandler::SortNetworkList() {
|
| + if (tether_sort_delegate_)
|
| + tether_sort_delegate_->SortTetherNetworkList(&tether_network_list_);
|
| +
|
| // Note: usually active networks will precede inactive networks, however
|
| // this may briefly be untrue during state transitions (e.g. a network may
|
| // transition to idle before the list is updated).
|
|
|