/* * 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 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(mWifiConfigManager.isSimPresent()).thenReturn(true); when(mTelephonyManager.getSimOperator()).thenReturn("123456"); when(mTelephonyManager.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 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 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 scanDetails = Arrays.asList(new ScanDetail[] { generateScanDetail(TEST_SSID1, TEST_BSSID1), generateScanDetail(TEST_SSID2, TEST_BSSID2)}); // Setup matching providers for ScanDetail with TEST_SSID1. Pair 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 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 scanDetails = Arrays.asList(new ScanDetail[] { generateScanDetail(TEST_SSID1, TEST_BSSID1), generateScanDetail(TEST_SSID2, TEST_BSSID2)}); // Setup matching providers for ScanDetail with TEST_SSID1. Pair 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 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 scanDetails = Arrays.asList(new ScanDetail[] { generateScanDetail(TEST_SSID1, TEST_BSSID1), generateScanDetail(TEST_SSID2, TEST_BSSID2)}); // Setup matching providers for ScanDetail with TEST_SSID1. Pair homeProvider = Pair.create( TEST_PROVIDER1, PasspointMatch.HomeProvider); Pair 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 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 scanDetails = Arrays.asList(new ScanDetail[] { generateScanDetail(TEST_SSID1, TEST_BSSID1), generateScanDetail(TEST_SSID2, TEST_BSSID2)}); // Setup matching providers for both ScanDetail. Pair 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 scanDetails = Arrays.asList(new ScanDetail[] { generateScanDetail(TEST_SSID1, TEST_BSSID1)}); PasspointProvider testProvider = mock(PasspointProvider.class); Pair 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 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 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 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 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 scanDetails = Arrays.asList(new ScanDetail[]{ generateScanDetail(TEST_SSID1, TEST_BSSID1)}); when(mTelephonyManager.getSimState()).thenReturn(TelephonyManager.SIM_STATE_READY); // MVNO carrier is enabled. when(mTelephonyManager.getCarrierIdFromSimMccMnc()).thenReturn(1); when(mTelephonyManager.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 scanDetails = Arrays.asList(new ScanDetail[]{ generateScanDetail(TEST_SSID1, TEST_BSSID1)}); when(mTelephonyManager.getSimState()).thenReturn(TelephonyManager.SIM_STATE_READY); when(mTelephonyManager.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 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 scanDetails = Arrays.asList(new ScanDetail[]{ generateScanDetail(TEST_SSID1, TEST_BSSID1)}); when(mTelephonyManager.getSimState()).thenReturn(TelephonyManager.SIM_STATE_READY); // MNO carrier is enabled. when(mTelephonyManager.getCarrierIdFromSimMccMnc()).thenReturn(1); when(mTelephonyManager.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 scanDetails = Arrays.asList(new ScanDetail[]{ generateScanDetail(TEST_SSID1, TEST_BSSID1)}); when(mTelephonyManager.getSimState()).thenReturn(TelephonyManager.SIM_STATE_READY); // MNO carrier is enabled. when(mTelephonyManager.getCarrierIdFromSimMccMnc()).thenReturn(1); when(mTelephonyManager.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 scanDetails = Arrays.asList(new ScanDetail[] { generateScanDetail(TEST_SSID1, TEST_BSSID2)}); // Setup matching provider. Pair 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 updatedCandidateScanResult = ArgumentCaptor.forClass(ScanResult.class); verify(mWifiConfigManager).setNetworkCandidateScanResult(eq(TEST_NETWORK_ID), updatedCandidateScanResult.capture(), anyInt()); assertEquals(TEST_BSSID2, updatedCandidateScanResult.getValue().BSSID); ArgumentCaptor 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 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 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 scanDetails = Arrays.asList(new ScanDetail[]{ generateScanDetail(TEST_SSID1, TEST_BSSID1)}); // Setup matching providers for ScanDetail with TEST_SSID1. Pair 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()); } }