| /* |
| * 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 static com.android.server.wifi.WifiConfigurationTestUtil.SECURITY_NONE; |
| import static com.android.server.wifi.WifiConfigurationTestUtil.SECURITY_PSK; |
| |
| import static org.junit.Assert.*; |
| import static org.mockito.Mockito.*; |
| |
| import android.content.Context; |
| import android.content.res.Resources; |
| import android.net.wifi.ScanResult; |
| import android.net.wifi.WifiConfiguration; |
| import android.net.wifi.WifiConfiguration.NetworkSelectionStatus; |
| import android.net.wifi.WifiInfo; |
| import android.os.SystemClock; |
| import android.test.suitebuilder.annotation.SmallTest; |
| import android.util.Pair; |
| |
| import com.android.internal.R; |
| import com.android.server.wifi.WifiNetworkSelectorTestUtil.ScanDetailsAndWifiConfigs; |
| |
| import org.junit.After; |
| import org.junit.Before; |
| import org.junit.Test; |
| import org.mockito.Mock; |
| import org.mockito.MockitoAnnotations; |
| |
| import java.util.List; |
| |
| /** |
| * Unit tests for {@link com.android.server.wifi.WifiNetworkSelector}. |
| */ |
| @SmallTest |
| public class WifiNetworkSelectorTest { |
| |
| /** Sets up test. */ |
| @Before |
| public void setUp() throws Exception { |
| MockitoAnnotations.initMocks(this); |
| setupContext(); |
| setupResources(); |
| setupWifiConfigManager(); |
| setupWifiInfo(); |
| |
| mWifiNetworkSelector = new WifiNetworkSelector(mContext, mWifiConfigManager, mClock); |
| mWifiNetworkSelector.registerNetworkEvaluator(mDummyEvaluator, 1); |
| when(mClock.getElapsedSinceBootMillis()).thenReturn(SystemClock.elapsedRealtime()); |
| |
| mThresholdMinimumRssi2G = mResource.getInteger( |
| R.integer.config_wifi_framework_wifi_score_bad_rssi_threshold_24GHz); |
| mThresholdMinimumRssi5G = mResource.getInteger( |
| R.integer.config_wifi_framework_wifi_score_bad_rssi_threshold_5GHz); |
| mThresholdQualifiedRssi2G = mResource.getInteger( |
| R.integer.config_wifi_framework_wifi_score_low_rssi_threshold_24GHz); |
| mThresholdQualifiedRssi5G = mResource.getInteger( |
| R.integer.config_wifi_framework_wifi_score_low_rssi_threshold_5GHz); |
| } |
| |
| /** Cleans up test. */ |
| @After |
| public void cleanup() { |
| validateMockitoUsage(); |
| } |
| |
| /** |
| * All this dummy network evaluator does is to pick the very first network |
| * in the scan results. |
| */ |
| public class DummyNetworkEvaluator implements WifiNetworkSelector.NetworkEvaluator { |
| private static final String NAME = "DummyNetworkEvaluator"; |
| |
| @Override |
| public String getName() { |
| return NAME; |
| } |
| |
| @Override |
| public void update(List<ScanDetail> scanDetails) {} |
| |
| /** |
| * Always return the first network in the scan results for connection. |
| */ |
| @Override |
| public WifiConfiguration evaluateNetworks(List<ScanDetail> scanDetails, |
| WifiConfiguration currentNetwork, String currentBssid, boolean connected, |
| boolean untrustedNetworkAllowed, |
| List<Pair<ScanDetail, WifiConfiguration>> connectableNetworks) { |
| ScanDetail scanDetail = scanDetails.get(0); |
| mWifiConfigManager.setNetworkCandidateScanResult(0, scanDetail.getScanResult(), 100); |
| |
| return mWifiConfigManager.getSavedNetworkForScanDetailAndCache(scanDetail); |
| } |
| } |
| |
| private WifiNetworkSelector mWifiNetworkSelector = null; |
| private DummyNetworkEvaluator mDummyEvaluator = new DummyNetworkEvaluator(); |
| @Mock private WifiConfigManager mWifiConfigManager; |
| @Mock private Context mContext; |
| @Mock private Resources mResource; |
| @Mock private WifiInfo mWifiInfo; |
| @Mock private Clock mClock; |
| private int mThresholdMinimumRssi2G; |
| private int mThresholdMinimumRssi5G; |
| private int mThresholdQualifiedRssi2G; |
| private int mThresholdQualifiedRssi5G; |
| |
| private void setupContext() { |
| when(mContext.getResources()).thenReturn(mResource); |
| } |
| |
| private void setupResources() { |
| when(mResource.getBoolean( |
| R.bool.config_wifi_framework_enable_associated_network_selection)).thenReturn(true); |
| when(mResource.getInteger( |
| R.integer.config_wifi_framework_wifi_score_low_rssi_threshold_5GHz)) |
| .thenReturn(-70); |
| when(mResource.getInteger( |
| R.integer.config_wifi_framework_wifi_score_low_rssi_threshold_24GHz)) |
| .thenReturn(-73); |
| when(mResource.getInteger( |
| R.integer.config_wifi_framework_wifi_score_bad_rssi_threshold_5GHz)) |
| .thenReturn(-82); |
| when(mResource.getInteger( |
| R.integer.config_wifi_framework_wifi_score_bad_rssi_threshold_24GHz)) |
| .thenReturn(-85); |
| } |
| |
| private void setupWifiInfo() { |
| // simulate a disconnected state |
| when(mWifiInfo.is24GHz()).thenReturn(true); |
| when(mWifiInfo.is5GHz()).thenReturn(false); |
| when(mWifiInfo.getRssi()).thenReturn(-70); |
| when(mWifiInfo.getNetworkId()).thenReturn(WifiConfiguration.INVALID_NETWORK_ID); |
| when(mWifiInfo.getBSSID()).thenReturn(null); |
| } |
| |
| private void setupWifiConfigManager() { |
| when(mWifiConfigManager.getLastSelectedNetwork()) |
| .thenReturn(WifiConfiguration.INVALID_NETWORK_ID); |
| } |
| |
| /** |
| * No network selection if scan result is empty. |
| * |
| * WifiStateMachine is in disconnected state. |
| * scanDetails is empty. |
| * |
| * Expected behavior: no network recommended by Network Selector |
| */ |
| @Test |
| public void emptyScanResults() { |
| String[] ssids = new String[0]; |
| String[] bssids = new String[0]; |
| int[] freqs = new int[0]; |
| String[] caps = new String[0]; |
| int[] levels = new int[0]; |
| int[] securities = new int[0]; |
| |
| ScanDetailsAndWifiConfigs scanDetailsAndConfigs = |
| WifiNetworkSelectorTestUtil.setupScanDetailsAndConfigStore(ssids, bssids, |
| freqs, caps, levels, securities, mWifiConfigManager, mClock); |
| List<ScanDetail> scanDetails = scanDetailsAndConfigs.getScanDetails(); |
| WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(scanDetails, |
| mWifiInfo, false, true, false); |
| assertEquals("Expect null configuration", null, candidate); |
| } |
| |
| |
| /** |
| * No network selection if the RSSI values in scan result are too low. |
| * |
| * WifiStateMachine is in disconnected state. |
| * scanDetails contains a 2.4GHz and a 5GHz network, but both with RSSI lower than |
| * the threshold |
| * |
| * Expected behavior: no network recommended by Network Selector |
| */ |
| @Test |
| public void verifyMinimumRssiThreshold() { |
| String[] ssids = {"\"test1\"", "\"test2\""}; |
| String[] bssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4"}; |
| int[] freqs = {2437, 5180}; |
| String[] caps = {"[WPA2-EAP-CCMP][ESS]", "[WPA2-EAP-CCMP][ESS]"}; |
| int[] levels = {mThresholdMinimumRssi2G - 1, mThresholdMinimumRssi5G - 1}; |
| int[] securities = {SECURITY_PSK, SECURITY_PSK}; |
| |
| ScanDetailsAndWifiConfigs scanDetailsAndConfigs = |
| WifiNetworkSelectorTestUtil.setupScanDetailsAndConfigStore(ssids, bssids, |
| freqs, caps, levels, securities, mWifiConfigManager, mClock); |
| List<ScanDetail> scanDetails = scanDetailsAndConfigs.getScanDetails(); |
| WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(scanDetails, |
| mWifiInfo, false, true, false); |
| assertEquals("Expect null configuration", null, candidate); |
| } |
| |
| /** |
| * No network selection if WiFi is connected and it is too short from last |
| * network selection. |
| * |
| * WifiStateMachine is in connected state. |
| * scanDetails contains two valid networks. |
| * Perform a network seletion right after the first one. |
| * |
| * Expected behavior: no network recommended by Network Selector |
| */ |
| @Test |
| public void verifyMinimumTimeGapWhenConnected() { |
| String[] ssids = {"\"test1\"", "\"test2\""}; |
| String[] bssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4"}; |
| int[] freqs = {2437, 5180}; |
| String[] caps = {"[WPA2-EAP-CCMP][ESS]", "[WPA2-EAP-CCMP][ESS]"}; |
| int[] levels = {mThresholdMinimumRssi2G + 1, mThresholdMinimumRssi5G + 1}; |
| int[] securities = {SECURITY_PSK, SECURITY_PSK}; |
| |
| // Make a network selection. |
| ScanDetailsAndWifiConfigs scanDetailsAndConfigs = |
| WifiNetworkSelectorTestUtil.setupScanDetailsAndConfigStore(ssids, bssids, |
| freqs, caps, levels, securities, mWifiConfigManager, mClock); |
| List<ScanDetail> scanDetails = scanDetailsAndConfigs.getScanDetails(); |
| WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(scanDetails, |
| mWifiInfo, false, true, false); |
| |
| when(mClock.getElapsedSinceBootMillis()).thenReturn(SystemClock.elapsedRealtime() |
| + WifiNetworkSelector.MINIMUM_NETWORK_SELECTION_INTERVAL_MS - 2000); |
| |
| // Do another network selection with WSM in CONNECTED state. |
| candidate = mWifiNetworkSelector.selectNetwork(scanDetails, |
| mWifiInfo, true, false, false); |
| |
| assertEquals("Expect null configuration", null, candidate); |
| } |
| |
| /** |
| * Perform network selection if WiFi is disconnected even if it is too short from last |
| * network selection. |
| * |
| * WifiStateMachine is in disconnected state. |
| * scanDetails contains two valid networks. |
| * Perform a network seletion right after the first one. |
| * |
| * Expected behavior: the first network is recommended by Network Selector |
| */ |
| @Test |
| public void verifyNoMinimumTimeGapWhenDisconnected() { |
| String[] ssids = {"\"test1\"", "\"test2\""}; |
| String[] bssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4"}; |
| int[] freqs = {2437, 5180}; |
| String[] caps = {"[WPA2-EAP-CCMP][ESS]", "[WPA2-EAP-CCMP][ESS]"}; |
| int[] levels = {mThresholdMinimumRssi2G + 1, mThresholdMinimumRssi5G + 1}; |
| int[] securities = {SECURITY_PSK, SECURITY_PSK}; |
| |
| // Make a network selection. |
| ScanDetailsAndWifiConfigs scanDetailsAndConfigs = |
| WifiNetworkSelectorTestUtil.setupScanDetailsAndConfigStore(ssids, bssids, |
| freqs, caps, levels, securities, mWifiConfigManager, mClock); |
| List<ScanDetail> scanDetails = scanDetailsAndConfigs.getScanDetails(); |
| WifiConfiguration[] savedConfigs = scanDetailsAndConfigs.getWifiConfigs(); |
| WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(scanDetails, |
| mWifiInfo, false, true, false); |
| WifiConfigurationTestUtil.assertConfigurationEqual(savedConfigs[0], candidate); |
| |
| when(mClock.getElapsedSinceBootMillis()).thenReturn(SystemClock.elapsedRealtime() |
| + WifiNetworkSelector.MINIMUM_NETWORK_SELECTION_INTERVAL_MS - 2000); |
| |
| // Do another network selection with WSM in DISCONNECTED state. |
| candidate = mWifiNetworkSelector.selectNetwork(scanDetails, |
| mWifiInfo, false, true, false); |
| |
| ScanResult chosenScanResult = scanDetails.get(0).getScanResult(); |
| WifiConfigurationTestUtil.assertConfigurationEqual(savedConfigs[0], candidate); |
| WifiNetworkSelectorTestUtil.verifySelectedScanResult(mWifiConfigManager, |
| chosenScanResult, candidate); |
| } |
| |
| /** |
| * No network selection if the currently connected on is already sufficient. |
| * |
| * WifiStateMachine is connected to a qualified (5G, secure, good RSSI) network. |
| * scanDetails contains a valid network. |
| * Perform a network seletion after the first one. |
| * |
| * Expected behavior: no network recommended by Network Selector |
| */ |
| @Test |
| public void noNetworkSelectionWhenCurrentOneIsSufficient() { |
| String[] ssids = {"\"test1\""}; |
| String[] bssids = {"6c:f3:7f:ae:8c:f3"}; |
| int[] freqs = {5180}; |
| String[] caps = {"[WPA2-EAP-CCMP][ESS]"}; |
| int[] levels = {mThresholdQualifiedRssi5G + 8}; |
| int[] securities = {SECURITY_PSK}; |
| |
| ScanDetailsAndWifiConfigs scanDetailsAndConfigs = |
| WifiNetworkSelectorTestUtil.setupScanDetailsAndConfigStore(ssids, bssids, |
| freqs, caps, levels, securities, mWifiConfigManager, mClock); |
| List<ScanDetail> scanDetails = scanDetailsAndConfigs.getScanDetails(); |
| |
| // connect to test1 |
| mWifiNetworkSelector.selectNetwork(scanDetails, mWifiInfo, false, true, false); |
| when(mWifiInfo.getNetworkId()).thenReturn(0); |
| when(mWifiInfo.getBSSID()).thenReturn(bssids[0]); |
| when(mWifiInfo.is24GHz()).thenReturn(false); |
| |
| when(mClock.getElapsedSinceBootMillis()).thenReturn(SystemClock.elapsedRealtime() |
| + WifiNetworkSelector.MINIMUM_NETWORK_SELECTION_INTERVAL_MS + 2000); |
| |
| levels[0] = mThresholdQualifiedRssi5G + 20; |
| scanDetailsAndConfigs = |
| WifiNetworkSelectorTestUtil.setupScanDetailsAndConfigStore(ssids, bssids, |
| freqs, caps, levels, securities, mWifiConfigManager, mClock); |
| scanDetails = scanDetailsAndConfigs.getScanDetails(); |
| |
| WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(scanDetails, |
| mWifiInfo, true, false, false); |
| assertEquals("Expect null configuration", null, candidate); |
| } |
| |
| /** |
| * New network selection is performed if the currently connected network |
| * band is 2G. |
| * |
| * WifiStateMachine is connected to a 2G network. |
| * scanDetails contains a valid networks. |
| * Perform a network seletion after the first one. |
| * |
| * Expected behavior: the first network is recommended by Network Selector |
| */ |
| @Test |
| public void band2GNetworkIsNotSufficient() { |
| String[] ssids = {"\"test1\""}; |
| String[] bssids = {"6c:f3:7f:ae:8c:f3"}; |
| int[] freqs = {2470}; |
| String[] caps = {"[WPA2-EAP-CCMP][ESS]"}; |
| int[] levels = {mThresholdQualifiedRssi2G + 8}; |
| int[] securities = {SECURITY_PSK}; |
| |
| ScanDetailsAndWifiConfigs scanDetailsAndConfigs = |
| WifiNetworkSelectorTestUtil.setupScanDetailsAndConfigStore(ssids, bssids, |
| freqs, caps, levels, securities, mWifiConfigManager, mClock); |
| List<ScanDetail> scanDetails = scanDetailsAndConfigs.getScanDetails(); |
| WifiConfiguration[] savedConfigs = scanDetailsAndConfigs.getWifiConfigs(); |
| |
| // connect to test1 |
| mWifiNetworkSelector.selectNetwork(scanDetails, mWifiInfo, false, true, false); |
| when(mWifiInfo.getNetworkId()).thenReturn(0); |
| when(mWifiInfo.getBSSID()).thenReturn(bssids[0]); |
| when(mWifiInfo.is24GHz()).thenReturn(true); |
| |
| when(mClock.getElapsedSinceBootMillis()).thenReturn(SystemClock.elapsedRealtime() |
| + WifiNetworkSelector.MINIMUM_NETWORK_SELECTION_INTERVAL_MS + 2000); |
| |
| // Do another network selection. |
| WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(scanDetails, |
| mWifiInfo, true, false, false); |
| |
| ScanResult chosenScanResult = scanDetails.get(0).getScanResult(); |
| WifiConfigurationTestUtil.assertConfigurationEqual(savedConfigs[0], candidate); |
| WifiNetworkSelectorTestUtil.verifySelectedScanResult(mWifiConfigManager, |
| chosenScanResult, candidate); |
| } |
| |
| |
| /** |
| * New network selection is performed if the currently connected network |
| * is a open one. |
| * |
| * WifiStateMachine is connected to a open network. |
| * scanDetails contains a valid networks. |
| * Perform a network seletion after the first one. |
| * |
| * Expected behavior: the first network is recommended by Network Selector |
| */ |
| @Test |
| public void openNetworkIsNotSufficient() { |
| String[] ssids = {"\"test1\""}; |
| String[] bssids = {"6c:f3:7f:ae:8c:f3"}; |
| int[] freqs = {5180}; |
| String[] caps = {"[ESS]"}; |
| int[] levels = {mThresholdQualifiedRssi5G + 8}; |
| int[] securities = {SECURITY_NONE}; |
| |
| ScanDetailsAndWifiConfigs scanDetailsAndConfigs = |
| WifiNetworkSelectorTestUtil.setupScanDetailsAndConfigStore(ssids, bssids, |
| freqs, caps, levels, securities, mWifiConfigManager, mClock); |
| List<ScanDetail> scanDetails = scanDetailsAndConfigs.getScanDetails(); |
| WifiConfiguration[] savedConfigs = scanDetailsAndConfigs.getWifiConfigs(); |
| |
| // connect to test1 |
| mWifiNetworkSelector.selectNetwork(scanDetails, mWifiInfo, false, true, false); |
| when(mWifiInfo.getNetworkId()).thenReturn(0); |
| when(mWifiInfo.getBSSID()).thenReturn(bssids[0]); |
| when(mWifiInfo.is24GHz()).thenReturn(false); |
| when(mWifiInfo.is5GHz()).thenReturn(true); |
| |
| when(mClock.getElapsedSinceBootMillis()).thenReturn(SystemClock.elapsedRealtime() |
| + WifiNetworkSelector.MINIMUM_NETWORK_SELECTION_INTERVAL_MS + 2000); |
| |
| // Do another network selection. |
| WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(scanDetails, |
| mWifiInfo, true, false, false); |
| |
| ScanResult chosenScanResult = scanDetails.get(0).getScanResult(); |
| WifiConfigurationTestUtil.assertConfigurationEqual(savedConfigs[0], candidate); |
| WifiNetworkSelectorTestUtil.verifySelectedScanResult(mWifiConfigManager, |
| chosenScanResult, candidate); |
| } |
| |
| /** |
| * New network selection is performed if the currently connected network |
| * has low RSSI value. |
| * |
| * WifiStateMachine is connected to a low RSSI 5GHz network. |
| * scanDetails contains a valid networks. |
| * Perform a network seletion after the first one. |
| * |
| * Expected behavior: the first network is recommended by Network Selector |
| */ |
| @Test |
| public void lowRssi5GNetworkIsNotSufficient() { |
| String[] ssids = {"\"test1\""}; |
| String[] bssids = {"6c:f3:7f:ae:8c:f3"}; |
| int[] freqs = {5180}; |
| String[] caps = {"[WPA2-EAP-CCMP][ESS]"}; |
| int[] levels = {mThresholdQualifiedRssi5G - 2}; |
| int[] securities = {SECURITY_PSK}; |
| |
| ScanDetailsAndWifiConfigs scanDetailsAndConfigs = |
| WifiNetworkSelectorTestUtil.setupScanDetailsAndConfigStore(ssids, bssids, |
| freqs, caps, levels, securities, mWifiConfigManager, mClock); |
| List<ScanDetail> scanDetails = scanDetailsAndConfigs.getScanDetails(); |
| WifiConfiguration[] savedConfigs = scanDetailsAndConfigs.getWifiConfigs(); |
| |
| // connect to test1 |
| mWifiNetworkSelector.selectNetwork(scanDetails, mWifiInfo, false, true, false); |
| when(mWifiInfo.getNetworkId()).thenReturn(0); |
| when(mWifiInfo.getBSSID()).thenReturn(bssids[0]); |
| when(mWifiInfo.is24GHz()).thenReturn(false); |
| when(mWifiInfo.is5GHz()).thenReturn(true); |
| when(mWifiInfo.getRssi()).thenReturn(levels[0]); |
| |
| when(mClock.getElapsedSinceBootMillis()).thenReturn(SystemClock.elapsedRealtime() |
| + WifiNetworkSelector.MINIMUM_NETWORK_SELECTION_INTERVAL_MS + 2000); |
| |
| // Do another network selection. |
| WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(scanDetails, |
| mWifiInfo, true, false, false); |
| |
| ScanResult chosenScanResult = scanDetails.get(0).getScanResult(); |
| WifiConfigurationTestUtil.assertConfigurationEqual(savedConfigs[0], candidate); |
| WifiNetworkSelectorTestUtil.verifySelectedScanResult(mWifiConfigManager, |
| chosenScanResult, candidate); |
| } |
| |
| /** |
| * Blacklisted BSSID is filtered out for network selection. |
| * |
| * WifiStateMachine is disconnected. |
| * scanDetails contains a network which is blacklisted. |
| * |
| * Expected behavior: no network recommended by Network Selector |
| */ |
| @Test |
| public void filterOutBlacklistedBssid() { |
| String[] ssids = {"\"test1\""}; |
| String[] bssids = {"6c:f3:7f:ae:8c:f3"}; |
| int[] freqs = {5180}; |
| String[] caps = {"[WPA2-EAP-CCMP][ESS]"}; |
| int[] levels = {mThresholdQualifiedRssi5G + 8}; |
| int[] securities = {SECURITY_PSK}; |
| |
| ScanDetailsAndWifiConfigs scanDetailsAndConfigs = |
| WifiNetworkSelectorTestUtil.setupScanDetailsAndConfigStore(ssids, bssids, |
| freqs, caps, levels, securities, mWifiConfigManager, mClock); |
| List<ScanDetail> scanDetails = scanDetailsAndConfigs.getScanDetails(); |
| |
| // Disable this network for BSSID_BLACKLIST_THRESHOLD times so it gets |
| // blacklisted by WNS. |
| for (int i = 0; i < WifiNetworkSelector.BSSID_BLACKLIST_THRESHOLD; i++) { |
| mWifiNetworkSelector.enableBssidForNetworkSelection(bssids[0], false, 1); |
| } |
| |
| WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(scanDetails, |
| mWifiInfo, false, true, false); |
| assertEquals("Expect null configuration", null, candidate); |
| } |
| |
| /** |
| * Wifi network selector doesn't recommend any network if the currently connected one |
| * doesn't show up in the scan results. |
| * |
| * WifiStateMachine is under connected state and 2.4GHz test1 is connected. |
| * The second scan results contains only test2 which now has a stronger RSSI than test1. |
| * Test1 is not in the second scan results. |
| * |
| * Expected behavior: no network recommended by Network Selector |
| */ |
| @Test |
| public void noSelectionWhenCurrentNetworkNotInScanResults() { |
| String[] ssids = {"\"test1\"", "\"test2\""}; |
| String[] bssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4"}; |
| int[] freqs = {2437, 2457}; |
| String[] caps = {"[WPA2-EAP-CCMP][ESS]", "[WPA2-EAP-CCMP][ESS]"}; |
| int[] levels = {mThresholdMinimumRssi2G + 20, mThresholdMinimumRssi2G + 1}; |
| int[] securities = {SECURITY_PSK, SECURITY_PSK}; |
| |
| // Make a network selection to connect to test1. |
| ScanDetailsAndWifiConfigs scanDetailsAndConfigs = |
| WifiNetworkSelectorTestUtil.setupScanDetailsAndConfigStore(ssids, bssids, |
| freqs, caps, levels, securities, mWifiConfigManager, mClock); |
| List<ScanDetail> scanDetails = scanDetailsAndConfigs.getScanDetails(); |
| WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(scanDetails, |
| mWifiInfo, false, true, false); |
| |
| when(mWifiInfo.getNetworkId()).thenReturn(0); |
| when(mWifiInfo.getBSSID()).thenReturn(bssids[0]); |
| when(mWifiInfo.is24GHz()).thenReturn(true); |
| when(mWifiInfo.is5GHz()).thenReturn(false); |
| when(mWifiInfo.getRssi()).thenReturn(levels[0]); |
| when(mClock.getElapsedSinceBootMillis()).thenReturn(SystemClock.elapsedRealtime() |
| + WifiNetworkSelector.MINIMUM_NETWORK_SELECTION_INTERVAL_MS + 2000); |
| |
| // Prepare the second scan results which have no test1. |
| String[] ssidsNew = {"\"test2\""}; |
| String[] bssidsNew = {"6c:f3:7f:ae:8c:f4"}; |
| int[] freqsNew = {2457}; |
| String[] capsNew = {"[WPA2-EAP-CCMP][ESS]"}; |
| int[] levelsNew = {mThresholdMinimumRssi2G + 40}; |
| scanDetails = WifiNetworkSelectorTestUtil.buildScanDetails(ssidsNew, bssidsNew, |
| freqsNew, capsNew, levelsNew, mClock); |
| candidate = mWifiNetworkSelector.selectNetwork(scanDetails, mWifiInfo, true, false, false); |
| |
| // The second network selection is skipped since current connected network is |
| // missing from the scan results. |
| assertEquals("Expect null configuration", null, candidate); |
| } |
| |
| /** |
| * Ensures that settings the user connect choice updates the |
| * NetworkSelectionStatus#mConnectChoice for all other WifiConfigurations in range in the last |
| * round of network selection. |
| * |
| * Expected behavior: WifiConfiguration.NetworkSelectionStatus#mConnectChoice is set to |
| * test1's configkey for test2. test3's WifiConfiguration is unchanged. |
| */ |
| @Test |
| public void setUserConnectChoice() { |
| String[] ssids = {"\"test1\"", "\"test2\"", "\"test3\""}; |
| String[] bssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4", "6c:f3:7f:ae:8c:f5"}; |
| int[] freqs = {2437, 5180, 5181}; |
| String[] caps = {"[WPA2-EAP-CCMP][ESS]", "[WPA2-EAP-CCMP][ESS]", "[WPA2-EAP-CCMP][ESS]"}; |
| int[] levels = {mThresholdMinimumRssi2G + 1, mThresholdMinimumRssi5G + 1, |
| mThresholdMinimumRssi5G + 1}; |
| int[] securities = {SECURITY_PSK, SECURITY_PSK, SECURITY_PSK}; |
| |
| ScanDetailsAndWifiConfigs scanDetailsAndConfigs = |
| WifiNetworkSelectorTestUtil.setupScanDetailsAndConfigStore(ssids, bssids, |
| freqs, caps, levels, securities, mWifiConfigManager, mClock); |
| |
| WifiConfiguration selectedWifiConfig = scanDetailsAndConfigs.getWifiConfigs()[0]; |
| selectedWifiConfig.getNetworkSelectionStatus() |
| .setCandidate(scanDetailsAndConfigs.getScanDetails().get(0).getScanResult()); |
| selectedWifiConfig.getNetworkSelectionStatus().setNetworkSelectionStatus( |
| NetworkSelectionStatus.NETWORK_SELECTION_PERMANENTLY_DISABLED); |
| selectedWifiConfig.getNetworkSelectionStatus().setConnectChoice("bogusKey"); |
| |
| WifiConfiguration configInLastNetworkSelection = scanDetailsAndConfigs.getWifiConfigs()[1]; |
| configInLastNetworkSelection.getNetworkSelectionStatus() |
| .setSeenInLastQualifiedNetworkSelection(true); |
| |
| WifiConfiguration configNotInLastNetworkSelection = |
| scanDetailsAndConfigs.getWifiConfigs()[2]; |
| |
| assertTrue(mWifiNetworkSelector.setUserConnectChoice(selectedWifiConfig.networkId)); |
| |
| verify(mWifiConfigManager).updateNetworkSelectionStatus(selectedWifiConfig.networkId, |
| NetworkSelectionStatus.NETWORK_SELECTION_ENABLE); |
| verify(mWifiConfigManager).clearNetworkConnectChoice(selectedWifiConfig.networkId); |
| verify(mWifiConfigManager).setNetworkConnectChoice(configInLastNetworkSelection.networkId, |
| selectedWifiConfig.configKey(), mClock.getWallClockMillis()); |
| verify(mWifiConfigManager, never()).setNetworkConnectChoice( |
| configNotInLastNetworkSelection.networkId, selectedWifiConfig.configKey(), |
| mClock.getWallClockMillis()); |
| } |
| |
| /** |
| * If two qualified networks, test1 and test2, are in range when the user selects test2 over |
| * test1, WifiNetworkSelector will override the NetworkSelector's choice to connect to test1 |
| * with test2. |
| * |
| * Expected behavior: test2 is the recommended network |
| */ |
| @Test |
| public void userConnectChoiceOverridesNetworkEvaluators() { |
| String[] ssids = {"\"test1\"", "\"test2\""}; |
| String[] bssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4"}; |
| int[] freqs = {2437, 5180}; |
| String[] caps = {"[WPA2-EAP-CCMP][ESS]", "[WPA2-EAP-CCMP][ESS]"}; |
| int[] levels = {mThresholdMinimumRssi2G + 1, mThresholdMinimumRssi5G + 1}; |
| int[] securities = {SECURITY_PSK, SECURITY_PSK}; |
| |
| ScanDetailsAndWifiConfigs scanDetailsAndConfigs = |
| WifiNetworkSelectorTestUtil.setupScanDetailsAndConfigStore(ssids, bssids, |
| freqs, caps, levels, securities, mWifiConfigManager, mClock); |
| List<ScanDetail> scanDetails = scanDetailsAndConfigs.getScanDetails(); |
| |
| // DummyEvaluator always selects the first network in the list. |
| WifiConfiguration networkSelectorChoice = scanDetailsAndConfigs.getWifiConfigs()[0]; |
| networkSelectorChoice.getNetworkSelectionStatus() |
| .setSeenInLastQualifiedNetworkSelection(true); |
| |
| WifiConfiguration userChoice = scanDetailsAndConfigs.getWifiConfigs()[1]; |
| userChoice.getNetworkSelectionStatus() |
| .setCandidate(scanDetailsAndConfigs.getScanDetails().get(1).getScanResult()); |
| |
| // With no user choice set, networkSelectorChoice should be chosen. |
| WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(scanDetails, |
| mWifiInfo, false, true, false); |
| |
| WifiConfigurationTestUtil.assertConfigurationEqual(networkSelectorChoice, candidate); |
| |
| when(mClock.getElapsedSinceBootMillis()).thenReturn(SystemClock.elapsedRealtime() |
| + WifiNetworkSelector.MINIMUM_NETWORK_SELECTION_INTERVAL_MS + 2000); |
| |
| assertTrue(mWifiNetworkSelector.setUserConnectChoice(userChoice.networkId)); |
| |
| // After user connect choice is set, userChoice should override networkSelectorChoice. |
| candidate = mWifiNetworkSelector.selectNetwork(scanDetails, |
| mWifiInfo, false, true, false); |
| |
| WifiConfigurationTestUtil.assertConfigurationEqual(userChoice, candidate); |
| } |
| |
| /** |
| * Wifi network selector blacklists a BSSID immediately if it's unable to handle |
| * new stations. |
| * |
| * Expected behavior: no network recommended by Network Selector |
| */ |
| @Test |
| public void blacklistNetworkImmediatelyIfApHasNoCapacityForNewStation() { |
| String[] ssids = {"\"test1\""}; |
| String[] bssids = {"6c:f3:7f:ae:99:f3"}; |
| int[] freqs = {2437}; |
| String[] caps = {"[WPA2-EAP-CCMP][ESS]"}; |
| int[] levels = {mThresholdMinimumRssi2G + 20}; |
| int[] securities = {SECURITY_PSK}; |
| |
| // Disable test1 with reason code indicating it is unable to handle new stations. |
| mWifiNetworkSelector.enableBssidForNetworkSelection(bssids[0], false, |
| WifiNetworkSelector.REASON_CODE_AP_UNABLE_TO_HANDLE_NEW_STA); |
| |
| // Make a network selection with test1 in the scan results. |
| ScanDetailsAndWifiConfigs scanDetailsAndConfigs = |
| WifiNetworkSelectorTestUtil.setupScanDetailsAndConfigStore(ssids, bssids, |
| freqs, caps, levels, securities, mWifiConfigManager, mClock); |
| List<ScanDetail> scanDetails = scanDetailsAndConfigs.getScanDetails(); |
| WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(scanDetails, |
| mWifiInfo, false, true, false); |
| |
| // No network recommended by WNS as test1 is blacklisted. |
| assertEquals("Expect null configuration", null, candidate); |
| } |
| } |