blob: f9d6a1c8d824c05fb949f2279c542b7308f0d5d9 [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.hotspot2;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.mockito.MockitoAnnotations.initMocks;
import android.net.wifi.EAPConstants;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiEnterpriseConfig;
import android.net.wifi.hotspot2.PasspointConfiguration;
import android.net.wifi.hotspot2.pps.HomeSp;
import android.telephony.TelephonyManager;
import android.util.LocalLog;
import android.util.Pair;
import androidx.test.filters.SmallTest;
import com.android.server.wifi.CarrierNetworkConfig;
import com.android.server.wifi.NetworkUpdateResult;
import com.android.server.wifi.ScanDetail;
import com.android.server.wifi.WifiConfigManager;
import com.android.server.wifi.WifiConfigurationTestUtil;
import com.android.server.wifi.WifiInjector;
import com.android.server.wifi.WifiNetworkSelector.NetworkEvaluator.OnConnectableListener;
import com.android.server.wifi.util.ScanResultUtil;
import com.android.server.wifi.util.TelephonyUtil;
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import java.util.Arrays;
import java.util.List;
/**
* Unit tests for {@link com.android.server.wifi.hotspot2.PasspointNetworkEvaluator}.
*/
@SmallTest
public class PasspointNetworkEvaluatorTest {
private static final int TEST_NETWORK_ID = 1;
private static final String TEST_SSID1 = "ssid1";
private static final String TEST_SSID2 = "ssid2";
private static final String TEST_BSSID1 = "01:23:45:56:78:9a";
private static final String TEST_BSSID2 = "23:12:34:90:81:12";
private static final String TEST_FQDN1 = "test1.com";
private static final String TEST_FQDN2 = "test2.com";
private static final WifiConfiguration TEST_CONFIG1 = generateWifiConfig(TEST_FQDN1);
private static final WifiConfiguration TEST_CONFIG2 = generateWifiConfig(TEST_FQDN2);
private static final PasspointProvider TEST_PROVIDER1 = generateProvider(TEST_CONFIG1);
private static final PasspointProvider TEST_PROVIDER2 = generateProvider(TEST_CONFIG2);
@Mock PasspointManager mPasspointManager;
@Mock PasspointConfiguration mPasspointConfiguration;
@Mock WifiConfigManager mWifiConfigManager;
@Mock OnConnectableListener mOnConnectableListener;
@Mock TelephonyManager mTelephonyManager;
@Mock TelephonyManager mDataTelephonyManager;
@Mock CarrierNetworkConfig mCarrierNetworkConfig;
@Mock WifiInjector mWifiInjector;
LocalLog mLocalLog;
PasspointNetworkEvaluator mEvaluator;
/**
* Helper function for generating {@link WifiConfiguration} for testing.
*
* @param fqdn The FQDN associated with the configuration
* @return {@link WifiConfiguration}
*/
private static WifiConfiguration generateWifiConfig(String fqdn) {
WifiConfiguration config = new WifiConfiguration();
config.FQDN = fqdn;
return config;
}
/**
* Helper function for generating {@link PasspointProvider} for testing.
*
* @param config The WifiConfiguration associated with the provider
* @return {@link PasspointProvider}
*/
private static PasspointProvider generateProvider(WifiConfiguration config) {
PasspointProvider provider = mock(PasspointProvider.class);
PasspointConfiguration passpointConfig = new PasspointConfiguration();
HomeSp homeSp = new HomeSp();
homeSp.setFqdn(config.FQDN);
passpointConfig.setHomeSp(homeSp);
when(provider.getConfig()).thenReturn(passpointConfig);
when(provider.getWifiConfig()).thenReturn(config);
return provider;
}
/**
* Helper function for generating {@link ScanDetail} for testing.
*
* @param ssid The SSID associated with the scan
* @param bssid The BSSID associated with the scan
* @return {@link ScanDetail}
*/
private static ScanDetail generateScanDetail(String ssid, String bssid) {
NetworkDetail networkDetail = mock(NetworkDetail.class);
when(networkDetail.isInterworking()).thenReturn(true);
when(networkDetail.getAnt()).thenReturn(NetworkDetail.Ant.FreePublic);
ScanDetail scanDetail = mock(ScanDetail.class);
ScanResult scanResult = new ScanResult();
scanResult.SSID = ssid;
scanResult.BSSID = bssid;
when(scanDetail.getSSID()).thenReturn(ssid);
when(scanDetail.getBSSIDString()).thenReturn(bssid);
when(scanDetail.getScanResult()).thenReturn(scanResult);
when(scanDetail.getNetworkDetail()).thenReturn(networkDetail);
return scanDetail;
}
/**
* Test setup.
*/
@Before
public void setUp() throws Exception {
initMocks(this);
mLocalLog = new LocalLog(512);
mEvaluator = new PasspointNetworkEvaluator(mPasspointManager, mWifiConfigManager, mLocalLog,
mCarrierNetworkConfig, mWifiInjector);
when(mWifiInjector.makeTelephonyManager()).thenReturn(mTelephonyManager);
when(mTelephonyManager.createForSubscriptionId(anyInt())).thenReturn(mDataTelephonyManager);
when(mWifiConfigManager.isSimPresent()).thenReturn(true);
when(mDataTelephonyManager.getSimOperator()).thenReturn("123456");
when(mDataTelephonyManager.getSimState()).thenReturn(TelephonyManager.SIM_STATE_READY);
}
/**
* Verify that null will be returned when evaluating scans without any matching providers.
*
* @throws Exception
*/
@Test
public void evaluateScansWithNoMatch() throws Exception {
List<ScanDetail> scanDetails = Arrays.asList(new ScanDetail[] {
generateScanDetail(TEST_SSID1, TEST_BSSID1),
generateScanDetail(TEST_SSID2, TEST_BSSID2)});
when(mPasspointManager.matchProvider(any(ScanResult.class))).thenReturn(null);
assertEquals(null, mEvaluator.evaluateNetworks(
scanDetails, null, null, false, false, mOnConnectableListener));
verify(mOnConnectableListener, never()).onConnectable(any(), any(), anyInt());
}
/**
* Verify that provider matching will not be performed when evaluating scans with no
* interworking support, and null will be returned.
*
* @throws Exception
*/
@Test
public void evaulateScansWithNoInterworkingAP() throws Exception {
NetworkDetail networkDetail = mock(NetworkDetail.class);
when(networkDetail.isInterworking()).thenReturn(false);
ScanDetail scanDetail = mock(ScanDetail.class);
when(scanDetail.getNetworkDetail()).thenReturn(networkDetail);
List<ScanDetail> scanDetails = Arrays.asList(new ScanDetail[] {scanDetail});
assertEquals(null, mEvaluator.evaluateNetworks(
scanDetails, null, null, false, false, mOnConnectableListener));
verify(mOnConnectableListener, never()).onConnectable(any(), any(), anyInt());
// Verify that no provider matching is performed.
verify(mPasspointManager, never()).matchProvider(any(ScanResult.class));
}
/**
* Verify that when a network matches a home provider is found, the correct network
* information (WifiConfiguration) is setup and returned.
*
* @throws Exception
*/
@Test
public void evaluateScansWithNetworkMatchingHomeProvider() throws Exception {
List<ScanDetail> scanDetails = Arrays.asList(new ScanDetail[] {
generateScanDetail(TEST_SSID1, TEST_BSSID1),
generateScanDetail(TEST_SSID2, TEST_BSSID2)});
// Setup matching providers for ScanDetail with TEST_SSID1.
Pair<PasspointProvider, PasspointMatch> homeProvider = Pair.create(
TEST_PROVIDER1, PasspointMatch.HomeProvider);
// Return homeProvider for the first ScanDetail (TEST_SSID1) and a null (no match) for
// for the second (TEST_SSID2);
when(mPasspointManager.matchProvider(any(ScanResult.class))).thenReturn(homeProvider)
.thenReturn(null);
when(mWifiConfigManager.addOrUpdateNetwork(any(WifiConfiguration.class), anyInt()))
.thenReturn(new NetworkUpdateResult(TEST_NETWORK_ID));
when(mWifiConfigManager.getConfiguredNetwork(TEST_NETWORK_ID)).thenReturn(TEST_CONFIG1);
assertNotNull(mEvaluator.evaluateNetworks(scanDetails, null, null, false,
false, mOnConnectableListener));
verify(mOnConnectableListener).onConnectable(any(), any(), anyInt());
// Verify the content of the WifiConfiguration that was added to WifiConfigManager.
ArgumentCaptor<WifiConfiguration> addedConfig =
ArgumentCaptor.forClass(WifiConfiguration.class);
verify(mWifiConfigManager).addOrUpdateNetwork(addedConfig.capture(), anyInt());
assertEquals(ScanResultUtil.createQuotedSSID(TEST_SSID1), addedConfig.getValue().SSID);
assertEquals(TEST_FQDN1, addedConfig.getValue().FQDN);
assertNotNull(addedConfig.getValue().enterpriseConfig);
assertEquals("", addedConfig.getValue().enterpriseConfig.getAnonymousIdentity());
assertTrue(addedConfig.getValue().isHomeProviderNetwork);
verify(mWifiConfigManager).enableNetwork(eq(TEST_NETWORK_ID), eq(false), anyInt());
verify(mWifiConfigManager).setNetworkCandidateScanResult(
eq(TEST_NETWORK_ID), any(ScanResult.class), anyInt());
verify(mWifiConfigManager).updateScanDetailForNetwork(
eq(TEST_NETWORK_ID), any(ScanDetail.class));
}
/**
* Verify that when a network matches a roaming provider is found, the correct network
* information (WifiConfiguration) is setup and returned.
*
* @throws Exception
*/
@Test
public void evaluateScansWithNetworkMatchingRoamingProvider() throws Exception {
List<ScanDetail> scanDetails = Arrays.asList(new ScanDetail[] {
generateScanDetail(TEST_SSID1, TEST_BSSID1),
generateScanDetail(TEST_SSID2, TEST_BSSID2)});
// Setup matching providers for ScanDetail with TEST_SSID1.
Pair<PasspointProvider, PasspointMatch> roamingProvider = Pair.create(
TEST_PROVIDER1, PasspointMatch.RoamingProvider);
// Return roamingProvider for the first ScanDetail (TEST_SSID1) and a null (no match) for
// for the second (TEST_SSID2);
when(mPasspointManager.matchProvider(any(ScanResult.class))).thenReturn(roamingProvider)
.thenReturn(null);
when(mWifiConfigManager.addOrUpdateNetwork(any(WifiConfiguration.class), anyInt()))
.thenReturn(new NetworkUpdateResult(TEST_NETWORK_ID));
when(mWifiConfigManager.getConfiguredNetwork(TEST_NETWORK_ID)).thenReturn(TEST_CONFIG1);
assertNotNull(mEvaluator.evaluateNetworks(scanDetails, null, null, false,
false, mOnConnectableListener));
verify(mOnConnectableListener).onConnectable(any(), any(), anyInt());
// Verify the content of the WifiConfiguration that was added to WifiConfigManager.
ArgumentCaptor<WifiConfiguration> addedConfig =
ArgumentCaptor.forClass(WifiConfiguration.class);
verify(mWifiConfigManager).addOrUpdateNetwork(addedConfig.capture(), anyInt());
assertEquals(ScanResultUtil.createQuotedSSID(TEST_SSID1), addedConfig.getValue().SSID);
assertEquals(TEST_FQDN1, addedConfig.getValue().FQDN);
assertNotNull(addedConfig.getValue().enterpriseConfig);
assertEquals("", addedConfig.getValue().enterpriseConfig.getAnonymousIdentity());
assertFalse(addedConfig.getValue().isHomeProviderNetwork);
verify(mWifiConfigManager).enableNetwork(eq(TEST_NETWORK_ID), eq(false), anyInt());
verify(mWifiConfigManager).setNetworkCandidateScanResult(
eq(TEST_NETWORK_ID), any(ScanResult.class), anyInt());
verify(mWifiConfigManager).updateScanDetailForNetwork(
eq(TEST_NETWORK_ID), any(ScanDetail.class));
}
/**
* Verify that when a network matches a home provider and another network matches a roaming
* provider are found, the network that matched to a home provider is preferred.
*
* @throws Exception
*/
@Test
public void evaluateScansWithHomeProviderNewtorkAndRoamingProviderNetwork() throws Exception {
List<ScanDetail> scanDetails = Arrays.asList(new ScanDetail[] {
generateScanDetail(TEST_SSID1, TEST_BSSID1),
generateScanDetail(TEST_SSID2, TEST_BSSID2)});
// Setup matching providers for ScanDetail with TEST_SSID1.
Pair<PasspointProvider, PasspointMatch> homeProvider = Pair.create(
TEST_PROVIDER1, PasspointMatch.HomeProvider);
Pair<PasspointProvider, PasspointMatch> roamingProvider = Pair.create(
TEST_PROVIDER2, PasspointMatch.RoamingProvider);
// Return homeProvider for the first ScanDetail (TEST_SSID1) and
// roamingProvider for the second (TEST_SSID2);
when(mPasspointManager.matchProvider(any(ScanResult.class)))
.thenReturn(homeProvider).thenReturn(roamingProvider);
when(mWifiConfigManager.addOrUpdateNetwork(any(WifiConfiguration.class), anyInt()))
.thenReturn(new NetworkUpdateResult(TEST_NETWORK_ID));
when(mWifiConfigManager.getConfiguredNetwork(TEST_NETWORK_ID)).thenReturn(TEST_CONFIG1);
assertNotNull(mEvaluator.evaluateNetworks(scanDetails, null, null, false,
false, mOnConnectableListener));
verify(mOnConnectableListener).onConnectable(any(), any(), anyInt());
// Verify the content of the WifiConfiguration that was added to WifiConfigManager.
ArgumentCaptor<WifiConfiguration> addedConfig =
ArgumentCaptor.forClass(WifiConfiguration.class);
verify(mWifiConfigManager).addOrUpdateNetwork(addedConfig.capture(), anyInt());
assertEquals(ScanResultUtil.createQuotedSSID(TEST_SSID1), addedConfig.getValue().SSID);
assertEquals(TEST_FQDN1, addedConfig.getValue().FQDN);
assertNotNull(addedConfig.getValue().enterpriseConfig);
assertEquals("", addedConfig.getValue().enterpriseConfig.getAnonymousIdentity());
assertTrue(addedConfig.getValue().isHomeProviderNetwork);
verify(mWifiConfigManager).enableNetwork(eq(TEST_NETWORK_ID), eq(false), anyInt());
verify(mWifiConfigManager).setNetworkCandidateScanResult(
eq(TEST_NETWORK_ID), any(ScanResult.class), anyInt());
verify(mWifiConfigManager).updateScanDetailForNetwork(
eq(TEST_NETWORK_ID), any(ScanDetail.class));
}
/**
* Verify that when two networks both matches a home provider, with one of them being the
* active network, the active network is preferred.
*
* @throws Exception
*/
@Test
public void evaluateScansWithActiveNetworkMatchingHomeProvider() throws Exception {
List<ScanDetail> scanDetails = Arrays.asList(new ScanDetail[] {
generateScanDetail(TEST_SSID1, TEST_BSSID1),
generateScanDetail(TEST_SSID2, TEST_BSSID2)});
// Setup matching providers for both ScanDetail.
Pair<PasspointProvider, PasspointMatch> homeProvider = Pair.create(
TEST_PROVIDER1, PasspointMatch.HomeProvider);
// Setup currently connected network
WifiConfiguration currentNetwork = new WifiConfiguration();
currentNetwork.networkId = TEST_NETWORK_ID;
currentNetwork.SSID = ScanResultUtil.createQuotedSSID(TEST_SSID2);
String currentBssid = TEST_BSSID2;
// Returning the same matching provider for both ScanDetail.
when(mPasspointManager.matchProvider(any(ScanResult.class)))
.thenReturn(homeProvider).thenReturn(homeProvider);
WifiConfiguration config = mEvaluator.evaluateNetworks(scanDetails, currentNetwork,
currentBssid, true, false, mOnConnectableListener);
verify(mOnConnectableListener).onConnectable(any(), any(), anyInt());
// Verify no new network is added to WifiConfigManager.
verify(mWifiConfigManager, never()).addOrUpdateNetwork(
any(WifiConfiguration.class), anyInt());
// Verify current active network is returned.
assertEquals(ScanResultUtil.createQuotedSSID(TEST_SSID2), config.SSID);
assertEquals(TEST_NETWORK_ID, config.networkId);
}
/**
* Verify that null will be returned when matching a SIM credential provider without SIM
* card installed.
*
* @throws Exception
*/
@Test
public void evaluateScanMatchingSIMProviderWithoutSIMCard() throws Exception {
// Setup ScanDetail and match providers.
List<ScanDetail> scanDetails = Arrays.asList(new ScanDetail[] {
generateScanDetail(TEST_SSID1, TEST_BSSID1)});
PasspointProvider testProvider = mock(PasspointProvider.class);
Pair<PasspointProvider, PasspointMatch> homeProvider = Pair.create(
testProvider, PasspointMatch.HomeProvider);
when(mPasspointManager.matchProvider(any(ScanResult.class))).thenReturn(homeProvider);
when(testProvider.isSimCredential()).thenReturn(true);
when(mWifiConfigManager.isSimPresent()).thenReturn(false);
assertEquals(null, mEvaluator.evaluateNetworks(
scanDetails, null, null, false, false, mOnConnectableListener));
verify(mOnConnectableListener, never()).onConnectable(any(), any(), anyInt());
verify(testProvider, never()).getWifiConfig();
}
/**
* Verify that anonymous identity is configured when matching a SIM credential provider with a
* network that supports encryptedIMSI and anonymous identity.
*
* @throws Exception
*/
@Test
public void evaluateSIMProviderWithNetworkSupportingEncryptedIMSIAnonymousIdentity()
throws Exception {
// Setup ScanDetail and match providers.
List<ScanDetail> scanDetails = Arrays.asList(new ScanDetail[]{
generateScanDetail(TEST_SSID1, TEST_BSSID1)});
WifiConfiguration config = WifiConfigurationTestUtil.createEapNetwork(
WifiEnterpriseConfig.Eap.SIM, WifiEnterpriseConfig.Phase2.NONE);
config.networkId = TEST_NETWORK_ID;
PasspointProvider testProvider = generateProvider(config);
Pair<PasspointProvider, PasspointMatch> homeProvider = Pair.create(
testProvider, PasspointMatch.HomeProvider);
String expectedAnonymousIdentity = TelephonyUtil.getAnonymousIdentityWith3GppRealm(
mTelephonyManager);
when(mPasspointManager.matchProvider(any(ScanResult.class))).thenReturn(homeProvider);
when(testProvider.isSimCredential()).thenReturn(true);
when(mWifiConfigManager.isSimPresent()).thenReturn(true);
when(mCarrierNetworkConfig.isCarrierEncryptionInfoAvailable()).thenReturn(true);
when(mCarrierNetworkConfig.isSupportAnonymousIdentity()).thenReturn(true);
when(mWifiConfigManager.addOrUpdateNetwork(any(WifiConfiguration.class), anyInt()))
.thenReturn(new NetworkUpdateResult(TEST_NETWORK_ID));
when(mWifiConfigManager.getConfiguredNetwork(TEST_NETWORK_ID)).thenReturn(config);
WifiConfiguration result = mEvaluator.evaluateNetworks(scanDetails, null, null, false,
false, mOnConnectableListener);
assertNotNull(result);
assertNotNull(result.enterpriseConfig);
assertEquals(expectedAnonymousIdentity, result.enterpriseConfig.getAnonymousIdentity());
}
/**
* Verify that it never creates an ephemeral Passpoint Configuration when the carrier does not
* support encrypted IMSI.
*/
@Test
public void skipCreateEphemeralPasspointConfigurationWhenNoSupportEncryptedIMSI() {
// Setup ScanDetail and match providers.
List<ScanDetail> scanDetails = Arrays.asList(new ScanDetail[] {
generateScanDetail(TEST_SSID1, TEST_BSSID1)});
when(mCarrierNetworkConfig.isCarrierEncryptionInfoAvailable()).thenReturn(false);
when(mPasspointManager.hasCarrierProvider(anyString())).thenReturn(false);
assertEquals(null, mEvaluator.evaluateNetworks(
scanDetails, null, null, false, false, mOnConnectableListener));
verify(mPasspointManager, never()).createEphemeralPasspointConfigForCarrier(anyInt());
}
/**
* Verify that it never creates an ephemeral Passpoint Configuration when there is no SIM on the
* device.
*/
@Test
public void skipCreateEphemeralPasspointConfigurationWithoutSIMCard() {
// Setup ScanDetail and match providers.
List<ScanDetail> scanDetails = Arrays.asList(new ScanDetail[] {
generateScanDetail(TEST_SSID1, TEST_BSSID1)});
when(mWifiConfigManager.isSimPresent()).thenReturn(false);
when(mPasspointManager.hasCarrierProvider(anyString())).thenReturn(false);
when(mCarrierNetworkConfig.isCarrierEncryptionInfoAvailable()).thenReturn(true);
assertEquals(null, mEvaluator.evaluateNetworks(
scanDetails, null, null, false, false, mOnConnectableListener));
verify(mPasspointManager, never()).createEphemeralPasspointConfigForCarrier(anyInt());
}
/**
* Verify that it never creates an ephemeral Passpoint Configuration when the carrier is not
* MNO.
*/
@Test
public void skipCreateEphemeralPasspointConfigurationForNonMNO() {
// Setup ScanDetail and match providers.
List<ScanDetail> scanDetails = Arrays.asList(new ScanDetail[]{
generateScanDetail(TEST_SSID1, TEST_BSSID1)});
when(mDataTelephonyManager.getSimState()).thenReturn(TelephonyManager.SIM_STATE_READY);
// MVNO carrier is enabled.
when(mDataTelephonyManager.getCarrierIdFromSimMccMnc()).thenReturn(1);
when(mDataTelephonyManager.getSimCarrierId()).thenReturn(20);
when(mCarrierNetworkConfig.isCarrierEncryptionInfoAvailable()).thenReturn(true);
when(mPasspointManager.hasCarrierProvider(anyString())).thenReturn(false);
when(mPasspointManager.findEapMethodFromNAIRealmMatchedWithCarrier(
any(List.class))).thenReturn(
EAPConstants.EAP_AKA);
assertEquals(null, mEvaluator.evaluateNetworks(
scanDetails, null, null, false, false, mOnConnectableListener));
verify(mPasspointManager, never()).createEphemeralPasspointConfigForCarrier(anyInt());
}
/**
* Verify that it never creates an ephemeral Passpoint Configuration when the scan result is the
* one disconnected by user.
*/
@Test
public void skipCreateEphemeralPasspointConfigurationForApDisconnectedByUser() {
// Setup ScanDetail and match providers.
List<ScanDetail> scanDetails = Arrays.asList(new ScanDetail[]{
generateScanDetail(TEST_SSID1, TEST_BSSID1)});
when(mDataTelephonyManager.getSimState()).thenReturn(TelephonyManager.SIM_STATE_READY);
when(mDataTelephonyManager.getSimCarrierId()).thenReturn(20);
when(mCarrierNetworkConfig.isCarrierEncryptionInfoAvailable()).thenReturn(true);
when(mPasspointManager.hasCarrierProvider(anyString())).thenReturn(false);
when(mPasspointManager.findEapMethodFromNAIRealmMatchedWithCarrier(
any(List.class))).thenReturn(
EAPConstants.EAP_AKA);
when(mWifiConfigManager.wasEphemeralNetworkDeleted("\"" + TEST_SSID1 + "\""))
.thenReturn(true);
assertEquals(null, mEvaluator.evaluateNetworks(
scanDetails, null, null, false, false, mOnConnectableListener));
verify(mPasspointManager, never()).createEphemeralPasspointConfigForCarrier(anyInt());
}
/**
* Verify that it never creates an ephemeral Passpoint Configuration when the profile for the
* carrier already exists.
*/
@Test
public void skipCreateEphemeralPasspointConfigurationWhenProfileExists() {
// Setup ScanDetail and match providers.
List<ScanDetail> scanDetails = Arrays.asList(new ScanDetail[] {
generateScanDetail(TEST_SSID1, TEST_BSSID1)});
when(mCarrierNetworkConfig.isCarrierEncryptionInfoAvailable()).thenReturn(true);
when(mPasspointManager.hasCarrierProvider(anyString())).thenReturn(true);
assertEquals(null, mEvaluator.evaluateNetworks(
scanDetails, null, null, false, false, mOnConnectableListener));
verify(mPasspointManager, never()).createEphemeralPasspointConfigForCarrier(anyInt());
}
/**
* Verify that it creates an ephemeral Passpoint Configuration when a EAP-Method is found from
* NAI realms matched with the carrier.
*/
@Test
public void createEphemeralPasspointConfigurationWhenEapMethodIsFoundFromMatchingNAIRealm() {
// Setup ScanDetail
List<ScanDetail> scanDetails = Arrays.asList(new ScanDetail[]{
generateScanDetail(TEST_SSID1, TEST_BSSID1)});
when(mDataTelephonyManager.getSimState()).thenReturn(TelephonyManager.SIM_STATE_READY);
// MNO carrier is enabled.
when(mDataTelephonyManager.getCarrierIdFromSimMccMnc()).thenReturn(1);
when(mDataTelephonyManager.getSimCarrierId()).thenReturn(1);
when(mCarrierNetworkConfig.isCarrierEncryptionInfoAvailable()).thenReturn(true);
when(mPasspointManager.hasCarrierProvider(anyString())).thenReturn(false);
when(mPasspointManager.findEapMethodFromNAIRealmMatchedWithCarrier(
any(List.class))).thenReturn(
EAPConstants.EAP_AKA);
assertEquals(null, mEvaluator.evaluateNetworks(
scanDetails, null, null, false, false, mOnConnectableListener));
verify(mPasspointManager).findEapMethodFromNAIRealmMatchedWithCarrier(any(List.class));
verify(mPasspointManager).createEphemeralPasspointConfigForCarrier(
eq(EAPConstants.EAP_AKA));
}
/**
* Verify that it installs the ephemeral configuration when the config is created for the
* carrier.
*/
@Test
public void installEphemeralPasspointConfiguration() {
// Setup ScanDetail
List<ScanDetail> scanDetails = Arrays.asList(new ScanDetail[]{
generateScanDetail(TEST_SSID1, TEST_BSSID1)});
when(mDataTelephonyManager.getSimState()).thenReturn(TelephonyManager.SIM_STATE_READY);
// MNO carrier is enabled.
when(mDataTelephonyManager.getCarrierIdFromSimMccMnc()).thenReturn(1);
when(mDataTelephonyManager.getSimCarrierId()).thenReturn(1);
when(mCarrierNetworkConfig.isCarrierEncryptionInfoAvailable()).thenReturn(true);
when(mPasspointManager.hasCarrierProvider(anyString())).thenReturn(false);
when(mPasspointManager.findEapMethodFromNAIRealmMatchedWithCarrier(
any(List.class))).thenReturn(
EAPConstants.EAP_AKA);
when(mPasspointManager.createEphemeralPasspointConfigForCarrier(
EAPConstants.EAP_AKA)).thenReturn(mPasspointConfiguration);
assertEquals(null, mEvaluator.evaluateNetworks(
scanDetails, null, null, false, false, mOnConnectableListener));
verify(mPasspointManager).installEphemeralPasspointConfigForCarrier(
eq(mPasspointConfiguration));
}
/**
* Verify that when the current active network is matched, the scan info associated with
* the network is updated.
*
* @throws Exception
*/
@Test
public void evaluateScansMatchingActiveNetworkWithDifferentBSS() throws Exception {
List<ScanDetail> scanDetails = Arrays.asList(new ScanDetail[] {
generateScanDetail(TEST_SSID1, TEST_BSSID2)});
// Setup matching provider.
Pair<PasspointProvider, PasspointMatch> homeProvider = Pair.create(
TEST_PROVIDER1, PasspointMatch.HomeProvider);
// Setup currently connected network.
WifiConfiguration currentNetwork = new WifiConfiguration();
currentNetwork.networkId = TEST_NETWORK_ID;
currentNetwork.SSID = ScanResultUtil.createQuotedSSID(TEST_SSID1);
String currentBssid = TEST_BSSID1;
// Match the current connected network to a home provider.
when(mPasspointManager.matchProvider(any(ScanResult.class))).thenReturn(homeProvider);
assertNotNull(mEvaluator.evaluateNetworks(scanDetails, currentNetwork,
currentBssid, true, false, mOnConnectableListener));
verify(mOnConnectableListener).onConnectable(any(), any(), anyInt());
// Verify network candidate information is updated.
ArgumentCaptor<ScanResult> updatedCandidateScanResult =
ArgumentCaptor.forClass(ScanResult.class);
verify(mWifiConfigManager).setNetworkCandidateScanResult(eq(TEST_NETWORK_ID),
updatedCandidateScanResult.capture(), anyInt());
assertEquals(TEST_BSSID2, updatedCandidateScanResult.getValue().BSSID);
ArgumentCaptor<ScanDetail> updatedCandidateScanDetail =
ArgumentCaptor.forClass(ScanDetail.class);
verify(mWifiConfigManager).updateScanDetailForNetwork(eq(TEST_NETWORK_ID),
updatedCandidateScanDetail.capture());
assertEquals(TEST_BSSID2, updatedCandidateScanDetail.getValue().getBSSIDString());
}
/**
* Verify that the current configuration for the passpoint network is disabled, it returns
* {@null} for the candidate.
*/
@Test
public void evaluateNetworkWithDisabledWifiConfig() {
List<ScanDetail> scanDetails = Arrays.asList(new ScanDetail[]{
generateScanDetail(TEST_SSID1, TEST_BSSID1),
generateScanDetail(TEST_SSID2, TEST_BSSID2)});
WifiConfiguration disableConfig = new WifiConfiguration();
WifiConfiguration.NetworkSelectionStatus selectionStatus =
new WifiConfiguration.NetworkSelectionStatus();
selectionStatus.setNetworkSelectionDisableReason(
WifiConfiguration.NetworkSelectionStatus.DISABLED_DHCP_FAILURE);
selectionStatus.setNetworkSelectionStatus(
WifiConfiguration.NetworkSelectionStatus.NETWORK_SELECTION_TEMPORARY_DISABLED);
disableConfig.setNetworkSelectionStatus(selectionStatus);
disableConfig.networkId = TEST_NETWORK_ID;
TEST_CONFIG1.networkId = TEST_NETWORK_ID;
// Setup matching providers for ScanDetail with TEST_SSID1.
Pair<PasspointProvider, PasspointMatch> homeProvider = Pair.create(
TEST_PROVIDER1, PasspointMatch.HomeProvider);
// Return homeProvider for the first ScanDetail (TEST_SSID1) and a null (no match) for
// for the second (TEST_SSID2);
when(mPasspointManager.matchProvider(any(ScanResult.class))).thenReturn(homeProvider)
.thenReturn(null);
when(mWifiConfigManager.getConfiguredNetwork(anyString())).thenReturn(disableConfig);
assertNull(mEvaluator.evaluateNetworks(scanDetails, null, null, false,
false, mOnConnectableListener));
verify(mWifiConfigManager, never()).addOrUpdateNetwork(any(WifiConfiguration.class),
anyInt());
verify(mOnConnectableListener, never()).onConnectable(any(), any(), anyInt());
}
/**
* Verify that when a network matching a home provider is found, but the network was
* disconnected previously by user, it returns {@code null} for candidate.
*/
@Test
public void evaluateScanResultWithHomeMatchButPreviouslyUserDisconnected() {
List<ScanDetail> scanDetails = Arrays.asList(new ScanDetail[]{
generateScanDetail(TEST_SSID1, TEST_BSSID1)});
// Setup matching providers for ScanDetail with TEST_SSID1.
Pair<PasspointProvider, PasspointMatch> homeProvider = Pair.create(
TEST_PROVIDER1, PasspointMatch.HomeProvider);
// Return homeProvider for the first ScanDetail (TEST_SSID1).
when(mPasspointManager.matchProvider(any(ScanResult.class))).thenReturn(homeProvider);
when(mWifiConfigManager.addOrUpdateNetwork(any(WifiConfiguration.class), anyInt()))
.thenReturn(new NetworkUpdateResult(TEST_NETWORK_ID));
when(mWifiConfigManager.getConfiguredNetwork(TEST_NETWORK_ID)).thenReturn(TEST_CONFIG1);
when(mWifiConfigManager.wasEphemeralNetworkDeleted("\"" + TEST_SSID1 + "\""))
.thenReturn(true);
assertEquals(null, mEvaluator.evaluateNetworks(
scanDetails, null, null, false, false, mOnConnectableListener));
verify(mOnConnectableListener, never()).onConnectable(any(), any(), anyInt());
}
}