blob: fdfa8914c6533ada1c370dfeaeaddc3cfc531467 [file] [log] [blame]
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.server.wifi;
import android.annotation.NonNull;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
import android.util.LocalLog;
import android.util.Pair;
import com.android.server.wifi.hotspot2.PasspointNetworkNominateHelper;
import com.android.server.wifi.util.TelephonyUtil;
import java.util.List;
/**
* This class is the WifiNetworkSelector.NetworkNominator implementation for
* saved networks.
*/
public class SavedNetworkNominator implements WifiNetworkSelector.NetworkNominator {
private static final String NAME = "SavedNetworkNominator";
private final WifiConfigManager mWifiConfigManager;
private final LocalLog mLocalLog;
private final TelephonyUtil mTelephonyUtil;
private final PasspointNetworkNominateHelper mPasspointNetworkNominateHelper;
SavedNetworkNominator(WifiConfigManager configManager,
PasspointNetworkNominateHelper nominateHelper,
LocalLog localLog, TelephonyUtil telephonyUtil) {
mWifiConfigManager = configManager;
mPasspointNetworkNominateHelper = nominateHelper;
mLocalLog = localLog;
mTelephonyUtil = telephonyUtil;
}
private void localLog(String log) {
mLocalLog.log(log);
}
/**
* Get the Nominator type.
*/
@Override
public @NominatorId int getId() {
return NOMINATOR_ID_SAVED;
}
/**
* Get the Nominator name.
*/
@Override
public String getName() {
return NAME;
}
/**
* Update the Nominator.
*/
@Override
public void update(List<ScanDetail> scanDetails) { }
/**
* Run through all scanDetails and nominate all connectable network as candidates.
*
*/
@Override
public void nominateNetworks(List<ScanDetail> scanDetails,
WifiConfiguration currentNetwork, String currentBssid, boolean connected,
boolean untrustedNetworkAllowed,
@NonNull OnConnectableListener onConnectableListener) {
findMatchedSavedNetworks(scanDetails, onConnectableListener);
findMatchedPasspointNetworks(scanDetails, onConnectableListener);
}
private void findMatchedSavedNetworks(List<ScanDetail> scanDetails,
OnConnectableListener onConnectableListener) {
for (ScanDetail scanDetail : scanDetails) {
ScanResult scanResult = scanDetail.getScanResult();
// One ScanResult can be associated with more than one network, hence we calculate all
// the scores and use the highest one as the ScanResult's score.
// TODO(b/112196799): this has side effects, rather not do that in a nominator
WifiConfiguration network =
mWifiConfigManager.getConfiguredNetworkForScanDetailAndCache(scanDetail);
if (network == null) {
continue;
}
/**
* Ignore Passpoint and Ephemeral networks. They are configured networks,
* but without being persisted to the storage. They are nominated by
* {@link PasspointNetworkNominator} and {@link ScoredNetworkNominator}
* respectively.
*/
if (network.isPasspoint() || network.isEphemeral()) {
continue;
}
// Ignore networks that the user has disallowed auto-join for.
if (!network.allowAutojoin) {
continue;
}
WifiConfiguration.NetworkSelectionStatus status =
network.getNetworkSelectionStatus();
// TODO (b/112196799): another side effect
status.setSeenInLastQualifiedNetworkSelection(true);
if (!status.isNetworkEnabled()) {
continue;
} else if (network.BSSID != null && !network.BSSID.equals("any")
&& !network.BSSID.equals(scanResult.BSSID)) {
// App has specified the only BSSID to connect for this
// configuration. So only the matching ScanResult can be a candidate.
localLog("Network " + WifiNetworkSelector.toNetworkString(network)
+ " has specified BSSID " + network.BSSID + ". Skip "
+ scanResult.BSSID);
continue;
} else if (network.enterpriseConfig != null
&& network.enterpriseConfig.isAuthenticationSimBased()) {
int subId = mTelephonyUtil.getBestMatchSubscriptionId(network);
if (!mTelephonyUtil.isSimPresent(subId)) {
// Don't select if security type is EAP SIM/AKA/AKA' when SIM is not present.
localLog("No SIM card is good for Network "
+ WifiNetworkSelector.toNetworkString(network));
continue;
}
}
// If the network is marked to use external scores, or is an open network with
// curate saved open networks enabled, do not consider it for network selection.
if (network.useExternalScores) {
localLog("Network " + WifiNetworkSelector.toNetworkString(network)
+ " has external score.");
continue;
}
onConnectableListener.onConnectable(scanDetail,
mWifiConfigManager.getConfiguredNetwork(network.networkId));
}
}
private void findMatchedPasspointNetworks(List<ScanDetail> scanDetails,
OnConnectableListener onConnectableListener) {
List<Pair<ScanDetail, WifiConfiguration>> candidates =
mPasspointNetworkNominateHelper.getPasspointNetworkCandidates(scanDetails, false);
for (Pair<ScanDetail, WifiConfiguration> candidate : candidates) {
onConnectableListener.onConnectable(candidate.first, candidate.second);
}
}
}