10e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan/*
20e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan * Copyright (C) 2016 The Android Open Source Project
30e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan *
40e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan * Licensed under the Apache License, Version 2.0 (the "License");
50e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan * you may not use this file except in compliance with the License.
60e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan * You may obtain a copy of the License at
70e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan *
80e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan *      http://www.apache.org/licenses/LICENSE-2.0
90e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan *
100e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan * Unless required by applicable law or agreed to in writing, software
110e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan * distributed under the License is distributed on an "AS IS" BASIS,
120e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan * See the License for the specific language governing permissions and
140e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan * limitations under the License.
150e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan */
160e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan
170e3cc5f112670c455029e89c93c1f122b897f6e2Randy Panpackage com.android.server.wifi;
180e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan
190e3cc5f112670c455029e89c93c1f122b897f6e2Randy Panimport static com.android.server.wifi.WifiConfigurationTestUtil.SECURITY_NONE;
200e3cc5f112670c455029e89c93c1f122b897f6e2Randy Panimport static com.android.server.wifi.WifiConfigurationTestUtil.SECURITY_PSK;
210e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan
220e3cc5f112670c455029e89c93c1f122b897f6e2Randy Panimport static org.junit.Assert.*;
230e3cc5f112670c455029e89c93c1f122b897f6e2Randy Panimport static org.mockito.Mockito.*;
240e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan
250e3cc5f112670c455029e89c93c1f122b897f6e2Randy Panimport android.content.Context;
260e3cc5f112670c455029e89c93c1f122b897f6e2Randy Panimport android.net.wifi.ScanResult;
270e3cc5f112670c455029e89c93c1f122b897f6e2Randy Panimport android.net.wifi.WifiConfiguration;
28235642dba4359c1e68618f27c949e744765cbbccAmin Shaikhimport android.net.wifi.WifiConfiguration.NetworkSelectionStatus;
290e3cc5f112670c455029e89c93c1f122b897f6e2Randy Panimport android.net.wifi.WifiInfo;
300e3cc5f112670c455029e89c93c1f122b897f6e2Randy Panimport android.os.SystemClock;
31fac6568cbb329e06b22bfe07993acb263f3762abMichael Plassimport android.test.mock.MockResources;
320e3cc5f112670c455029e89c93c1f122b897f6e2Randy Panimport android.test.suitebuilder.annotation.SmallTest;
3317c2a7b30e5680b11fc0073ce322ee7bc14ef2c5Randy Panimport android.util.LocalLog;
340e3cc5f112670c455029e89c93c1f122b897f6e2Randy Panimport android.util.Pair;
350e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan
360e3cc5f112670c455029e89c93c1f122b897f6e2Randy Panimport com.android.internal.R;
370e3cc5f112670c455029e89c93c1f122b897f6e2Randy Panimport com.android.server.wifi.WifiNetworkSelectorTestUtil.ScanDetailsAndWifiConfigs;
380e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan
390e3cc5f112670c455029e89c93c1f122b897f6e2Randy Panimport org.junit.After;
400e3cc5f112670c455029e89c93c1f122b897f6e2Randy Panimport org.junit.Before;
410e3cc5f112670c455029e89c93c1f122b897f6e2Randy Panimport org.junit.Test;
42235642dba4359c1e68618f27c949e744765cbbccAmin Shaikhimport org.mockito.Mock;
43235642dba4359c1e68618f27c949e744765cbbccAmin Shaikhimport org.mockito.MockitoAnnotations;
44fac6568cbb329e06b22bfe07993acb263f3762abMichael Plassimport org.mockito.Spy;
450e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan
46eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chenimport java.util.ArrayList;
47167b90b5e002698378728a54a417a08c317d29dcRandy Panimport java.util.HashSet;
480e3cc5f112670c455029e89c93c1f122b897f6e2Randy Panimport java.util.List;
490e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan
500e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan/**
510e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan * Unit tests for {@link com.android.server.wifi.WifiNetworkSelector}.
520e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan */
530e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan@SmallTest
540e3cc5f112670c455029e89c93c1f122b897f6e2Randy Panpublic class WifiNetworkSelectorTest {
550e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan
56fac6568cbb329e06b22bfe07993acb263f3762abMichael Plass    private static final int RSSI_BUMP = 1;
57fac6568cbb329e06b22bfe07993acb263f3762abMichael Plass
580e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan    /** Sets up test. */
590e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan    @Before
600e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan    public void setUp() throws Exception {
61235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh        MockitoAnnotations.initMocks(this);
62235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh        setupContext();
63235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh        setupResources();
64235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh        setupWifiConfigManager();
65235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh        setupWifiInfo();
6617c2a7b30e5680b11fc0073ce322ee7bc14ef2c5Randy Pan        mLocalLog = new LocalLog(512);
670e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan
6817c2a7b30e5680b11fc0073ce322ee7bc14ef2c5Randy Pan        mWifiNetworkSelector = new WifiNetworkSelector(mContext, mWifiConfigManager, mClock,
6917c2a7b30e5680b11fc0073ce322ee7bc14ef2c5Randy Pan                mLocalLog);
700e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        mWifiNetworkSelector.registerNetworkEvaluator(mDummyEvaluator, 1);
71eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen        mDummyEvaluator.setEvaluatorToSelectCandidate(true);
720e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        when(mClock.getElapsedSinceBootMillis()).thenReturn(SystemClock.elapsedRealtime());
730e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan
740e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan    }
750e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan
760e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan    /** Cleans up test. */
770e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan    @After
780e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan    public void cleanup() {
790e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        validateMockitoUsage();
800e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan    }
810e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan
820e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan    /**
830e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan     * All this dummy network evaluator does is to pick the very first network
840e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan     * in the scan results.
850e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan     */
860e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan    public class DummyNetworkEvaluator implements WifiNetworkSelector.NetworkEvaluator {
870e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        private static final String NAME = "DummyNetworkEvaluator";
880e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan
89eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen        private boolean mEvaluatorShouldSelectCandidate = true;
90eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen
91235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh        @Override
920e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        public String getName() {
930e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan            return NAME;
940e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        }
950e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan
96235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh        @Override
97235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh        public void update(List<ScanDetail> scanDetails) {}
980e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan
990e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        /**
100eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen         * Sets whether the evaluator should return a candidate for connection or null.
101eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen         */
102eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen        public void setEvaluatorToSelectCandidate(boolean shouldSelectCandidate) {
103eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen            mEvaluatorShouldSelectCandidate = shouldSelectCandidate;
104eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen        }
105eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen
106eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen        /**
107eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen         * This NetworkEvaluator can be configured to return a candidate or null.  If returning a
108eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen         * candidate, the first entry in the provided scanDetails will be selected. This requires
109eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen         * that the mock WifiConfigManager be set up to return a WifiConfiguration for the first
110eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen         * scanDetail entry, through
111eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen         * {@link WifiNetworkSelectorTestUtil#setupScanDetailsAndConfigStore}.
1120e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan         */
113235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh        @Override
1140e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        public WifiConfiguration evaluateNetworks(List<ScanDetail> scanDetails,
1150e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan                    WifiConfiguration currentNetwork, String currentBssid, boolean connected,
1160e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan                    boolean untrustedNetworkAllowed,
1170e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan                    List<Pair<ScanDetail, WifiConfiguration>> connectableNetworks) {
118eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen            if (!mEvaluatorShouldSelectCandidate) {
119eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen                return null;
120eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen            }
1210e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan            ScanDetail scanDetail = scanDetails.get(0);
1220e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan            mWifiConfigManager.setNetworkCandidateScanResult(0, scanDetail.getScanResult(), 100);
123eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen
1243b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold            assertNotNull("Saved network must not be null",
1253b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold                    mWifiConfigManager.getConfiguredNetworkForScanDetailAndCache(scanDetail));
126eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen
12703c23584f072aef576736044c1fa12ddcb2d882bRoshan Pius            return mWifiConfigManager.getConfiguredNetworkForScanDetailAndCache(scanDetail);
1280e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        }
1290e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan    }
1300e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan
1310e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan    private WifiNetworkSelector mWifiNetworkSelector = null;
1320e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan    private DummyNetworkEvaluator mDummyEvaluator = new DummyNetworkEvaluator();
133235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh    @Mock private WifiConfigManager mWifiConfigManager;
134235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh    @Mock private Context mContext;
135fac6568cbb329e06b22bfe07993acb263f3762abMichael Plass
136fac6568cbb329e06b22bfe07993acb263f3762abMichael Plass    // For simulating the resources, we use a Spy on a MockResource
137fac6568cbb329e06b22bfe07993acb263f3762abMichael Plass    // (which is really more of a stub than a mock, in spite if its name).
138fac6568cbb329e06b22bfe07993acb263f3762abMichael Plass    // This is so that we get errors on any calls that we have not explicitly set up.
139fac6568cbb329e06b22bfe07993acb263f3762abMichael Plass    @Spy private MockResources mResource = new MockResources();
140235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh    @Mock private WifiInfo mWifiInfo;
141235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh    @Mock private Clock mClock;
14217c2a7b30e5680b11fc0073ce322ee7bc14ef2c5Randy Pan    private LocalLog mLocalLog;
1430e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan    private int mThresholdMinimumRssi2G;
1440e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan    private int mThresholdMinimumRssi5G;
1450e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan    private int mThresholdQualifiedRssi2G;
1460e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan    private int mThresholdQualifiedRssi5G;
1473cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang    private int mStayOnNetworkMinimumTxRate;
1483cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang    private int mStayOnNetworkMinimumRxRate;
1490e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan
150235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh    private void setupContext() {
151235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh        when(mContext.getResources()).thenReturn(mResource);
1520e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan    }
1530e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan
154fac6568cbb329e06b22bfe07993acb263f3762abMichael Plass    private int setupIntegerResource(int resourceName, int value) {
155fac6568cbb329e06b22bfe07993acb263f3762abMichael Plass        doReturn(value).when(mResource).getInteger(resourceName);
156fac6568cbb329e06b22bfe07993acb263f3762abMichael Plass        return value;
157fac6568cbb329e06b22bfe07993acb263f3762abMichael Plass    }
158fac6568cbb329e06b22bfe07993acb263f3762abMichael Plass
159235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh    private void setupResources() {
160fac6568cbb329e06b22bfe07993acb263f3762abMichael Plass        doReturn(true).when(mResource).getBoolean(
161fac6568cbb329e06b22bfe07993acb263f3762abMichael Plass                R.bool.config_wifi_framework_enable_associated_network_selection);
162fac6568cbb329e06b22bfe07993acb263f3762abMichael Plass
163fac6568cbb329e06b22bfe07993acb263f3762abMichael Plass        mThresholdMinimumRssi2G = setupIntegerResource(
164fac6568cbb329e06b22bfe07993acb263f3762abMichael Plass                R.integer.config_wifi_framework_wifi_score_entry_rssi_threshold_24GHz, -79);
165fac6568cbb329e06b22bfe07993acb263f3762abMichael Plass        mThresholdMinimumRssi5G = setupIntegerResource(
166fac6568cbb329e06b22bfe07993acb263f3762abMichael Plass                R.integer.config_wifi_framework_wifi_score_entry_rssi_threshold_5GHz, -76);
167fac6568cbb329e06b22bfe07993acb263f3762abMichael Plass        mThresholdQualifiedRssi2G = setupIntegerResource(
168fac6568cbb329e06b22bfe07993acb263f3762abMichael Plass                R.integer.config_wifi_framework_wifi_score_low_rssi_threshold_24GHz, -73);
169fac6568cbb329e06b22bfe07993acb263f3762abMichael Plass        mThresholdQualifiedRssi5G = setupIntegerResource(
170fac6568cbb329e06b22bfe07993acb263f3762abMichael Plass                R.integer.config_wifi_framework_wifi_score_low_rssi_threshold_5GHz, -70);
171fac6568cbb329e06b22bfe07993acb263f3762abMichael Plass        mStayOnNetworkMinimumTxRate = setupIntegerResource(
172fac6568cbb329e06b22bfe07993acb263f3762abMichael Plass                R.integer.config_wifi_framework_min_tx_rate_for_staying_on_network, 16);
173fac6568cbb329e06b22bfe07993acb263f3762abMichael Plass        mStayOnNetworkMinimumRxRate = setupIntegerResource(
174fac6568cbb329e06b22bfe07993acb263f3762abMichael Plass                R.integer.config_wifi_framework_min_rx_rate_for_staying_on_network, 16);
1750e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan    }
1760e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan
177235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh    private void setupWifiInfo() {
1780e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        // simulate a disconnected state
179235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh        when(mWifiInfo.is24GHz()).thenReturn(true);
180235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh        when(mWifiInfo.is5GHz()).thenReturn(false);
181235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh        when(mWifiInfo.getRssi()).thenReturn(-70);
182235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh        when(mWifiInfo.getNetworkId()).thenReturn(WifiConfiguration.INVALID_NETWORK_ID);
183235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh        when(mWifiInfo.getBSSID()).thenReturn(null);
1840e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan    }
1850e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan
186235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh    private void setupWifiConfigManager() {
187235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh        when(mWifiConfigManager.getLastSelectedNetwork())
1880e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan                .thenReturn(WifiConfiguration.INVALID_NETWORK_ID);
1890e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan    }
1900e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan
1910e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan    /**
1920e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan     * No network selection if scan result is empty.
1930e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan     *
1940e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan     * WifiStateMachine is in disconnected state.
1950e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan     * scanDetails is empty.
1960e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan     *
1970e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan     * Expected behavior: no network recommended by Network Selector
1980e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan     */
1990e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan    @Test
2000e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan    public void emptyScanResults() {
2010e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        String[] ssids = new String[0];
2020e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        String[] bssids = new String[0];
2030e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        int[] freqs = new int[0];
2040e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        String[] caps = new String[0];
2050e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        int[] levels = new int[0];
2060e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        int[] securities = new int[0];
2070e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan
2080e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        ScanDetailsAndWifiConfigs scanDetailsAndConfigs =
2090e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan                WifiNetworkSelectorTestUtil.setupScanDetailsAndConfigStore(ssids, bssids,
2100e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan                    freqs, caps, levels, securities, mWifiConfigManager, mClock);
2110e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        List<ScanDetail> scanDetails = scanDetailsAndConfigs.getScanDetails();
212167b90b5e002698378728a54a417a08c317d29dcRandy Pan        HashSet<String> blacklist = new HashSet<String>();
2130e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(scanDetails,
214167b90b5e002698378728a54a417a08c317d29dcRandy Pan                blacklist, mWifiInfo, false, true, false);
2150e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        assertEquals("Expect null configuration", null, candidate);
216eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen        assertTrue(mWifiNetworkSelector.getConnectableScanDetails().isEmpty());
2170e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan    }
2180e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan
2190e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan
2200e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan    /**
2210e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan     * No network selection if the RSSI values in scan result are too low.
2220e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan     *
2230e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan     * WifiStateMachine is in disconnected state.
2240e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan     * scanDetails contains a 2.4GHz and a 5GHz network, but both with RSSI lower than
2250e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan     * the threshold
2260e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan     *
2270e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan     * Expected behavior: no network recommended by Network Selector
2280e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan     */
2290e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan    @Test
2300e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan    public void verifyMinimumRssiThreshold() {
2310e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        String[] ssids = {"\"test1\"", "\"test2\""};
2320e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        String[] bssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4"};
2330e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        int[] freqs = {2437, 5180};
2340e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        String[] caps = {"[WPA2-EAP-CCMP][ESS]", "[WPA2-EAP-CCMP][ESS]"};
2350e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        int[] levels = {mThresholdMinimumRssi2G - 1, mThresholdMinimumRssi5G - 1};
2360e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        int[] securities = {SECURITY_PSK, SECURITY_PSK};
2370e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan
2380e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        ScanDetailsAndWifiConfigs scanDetailsAndConfigs =
2390e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan                WifiNetworkSelectorTestUtil.setupScanDetailsAndConfigStore(ssids, bssids,
2400e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan                    freqs, caps, levels, securities, mWifiConfigManager, mClock);
2410e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        List<ScanDetail> scanDetails = scanDetailsAndConfigs.getScanDetails();
242167b90b5e002698378728a54a417a08c317d29dcRandy Pan        HashSet<String> blacklist = new HashSet<String>();
2430e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(scanDetails,
244167b90b5e002698378728a54a417a08c317d29dcRandy Pan                blacklist, mWifiInfo, false, true, false);
2450e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        assertEquals("Expect null configuration", null, candidate);
246eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen        assertTrue(mWifiNetworkSelector.getConnectableScanDetails().isEmpty());
2470e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan    }
2480e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan
2490e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan    /**
2500e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan     * No network selection if WiFi is connected and it is too short from last
2510e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan     * network selection.
2520e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan     *
2530e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan     * WifiStateMachine is in connected state.
2540e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan     * scanDetails contains two valid networks.
2550e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan     * Perform a network seletion right after the first one.
2560e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan     *
2570e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan     * Expected behavior: no network recommended by Network Selector
2580e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan     */
2590e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan    @Test
2600e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan    public void verifyMinimumTimeGapWhenConnected() {
2610e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        String[] ssids = {"\"test1\"", "\"test2\""};
2620e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        String[] bssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4"};
2630e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        int[] freqs = {2437, 5180};
2640e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        String[] caps = {"[WPA2-EAP-CCMP][ESS]", "[WPA2-EAP-CCMP][ESS]"};
265fac6568cbb329e06b22bfe07993acb263f3762abMichael Plass        int[] levels = {mThresholdMinimumRssi2G + RSSI_BUMP, mThresholdMinimumRssi5G + RSSI_BUMP};
2660e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        int[] securities = {SECURITY_PSK, SECURITY_PSK};
2670e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan
2680e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        // Make a network selection.
2690e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        ScanDetailsAndWifiConfigs scanDetailsAndConfigs =
2700e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan                WifiNetworkSelectorTestUtil.setupScanDetailsAndConfigStore(ssids, bssids,
2710e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan                    freqs, caps, levels, securities, mWifiConfigManager, mClock);
2720e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        List<ScanDetail> scanDetails = scanDetailsAndConfigs.getScanDetails();
273167b90b5e002698378728a54a417a08c317d29dcRandy Pan        HashSet<String> blacklist = new HashSet<String>();
2740e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(scanDetails,
275167b90b5e002698378728a54a417a08c317d29dcRandy Pan                blacklist, mWifiInfo, false, true, false);
2760e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan
2770e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        when(mClock.getElapsedSinceBootMillis()).thenReturn(SystemClock.elapsedRealtime()
2780e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan                + WifiNetworkSelector.MINIMUM_NETWORK_SELECTION_INTERVAL_MS - 2000);
2790e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan
2800e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        // Do another network selection with WSM in CONNECTED state.
2810e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        candidate = mWifiNetworkSelector.selectNetwork(scanDetails,
282167b90b5e002698378728a54a417a08c317d29dcRandy Pan                blacklist, mWifiInfo, true, false, false);
2830e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan
2840e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        assertEquals("Expect null configuration", null, candidate);
285eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen        assertTrue(mWifiNetworkSelector.getConnectableScanDetails().isEmpty());
2860e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan    }
2870e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan
2880e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan    /**
2890e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan     * Perform network selection if WiFi is disconnected even if it is too short from last
2900e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan     * network selection.
2910e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan     *
2920e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan     * WifiStateMachine is in disconnected state.
2930e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan     * scanDetails contains two valid networks.
2940e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan     * Perform a network seletion right after the first one.
2950e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan     *
2960e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan     * Expected behavior: the first network is recommended by Network Selector
2970e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan     */
2980e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan    @Test
2990e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan    public void verifyNoMinimumTimeGapWhenDisconnected() {
3000e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        String[] ssids = {"\"test1\"", "\"test2\""};
3010e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        String[] bssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4"};
3020e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        int[] freqs = {2437, 5180};
3030e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        String[] caps = {"[WPA2-EAP-CCMP][ESS]", "[WPA2-EAP-CCMP][ESS]"};
304fac6568cbb329e06b22bfe07993acb263f3762abMichael Plass        int[] levels = {mThresholdMinimumRssi2G + RSSI_BUMP, mThresholdMinimumRssi5G + RSSI_BUMP};
3050e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        int[] securities = {SECURITY_PSK, SECURITY_PSK};
3060e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan
3070e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        // Make a network selection.
3080e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        ScanDetailsAndWifiConfigs scanDetailsAndConfigs =
3090e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan                WifiNetworkSelectorTestUtil.setupScanDetailsAndConfigStore(ssids, bssids,
3100e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan                    freqs, caps, levels, securities, mWifiConfigManager, mClock);
3110e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        List<ScanDetail> scanDetails = scanDetailsAndConfigs.getScanDetails();
3120e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        WifiConfiguration[] savedConfigs = scanDetailsAndConfigs.getWifiConfigs();
313167b90b5e002698378728a54a417a08c317d29dcRandy Pan        HashSet<String> blacklist = new HashSet<String>();
3140e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(scanDetails,
315167b90b5e002698378728a54a417a08c317d29dcRandy Pan                blacklist, mWifiInfo, false, true, false);
316235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh        WifiConfigurationTestUtil.assertConfigurationEqual(savedConfigs[0], candidate);
3170e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan
3180e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        when(mClock.getElapsedSinceBootMillis()).thenReturn(SystemClock.elapsedRealtime()
3190e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan                + WifiNetworkSelector.MINIMUM_NETWORK_SELECTION_INTERVAL_MS - 2000);
3200e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan
3210e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        // Do another network selection with WSM in DISCONNECTED state.
3220e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        candidate = mWifiNetworkSelector.selectNetwork(scanDetails,
323167b90b5e002698378728a54a417a08c317d29dcRandy Pan                blacklist, mWifiInfo, false, true, false);
3240e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan
3250e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        ScanResult chosenScanResult = scanDetails.get(0).getScanResult();
3260e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        WifiConfigurationTestUtil.assertConfigurationEqual(savedConfigs[0], candidate);
3270e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        WifiNetworkSelectorTestUtil.verifySelectedScanResult(mWifiConfigManager,
3280e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan                chosenScanResult, candidate);
3290e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan    }
3300e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan
3310e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan    /**
3320e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan     * New network selection is performed if the currently connected network
3330e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan     * is a open one.
3340e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan     *
3350e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan     * WifiStateMachine is connected to a open network.
3360e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan     * scanDetails contains a valid networks.
3370e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan     * Perform a network seletion after the first one.
3380e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan     *
3390e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan     * Expected behavior: the first network is recommended by Network Selector
3400e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan     */
3410e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan    @Test
3420e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan    public void openNetworkIsNotSufficient() {
3430e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        String[] ssids = {"\"test1\""};
3440e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        String[] bssids = {"6c:f3:7f:ae:8c:f3"};
3450e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        int[] freqs = {5180};
3460e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        String[] caps = {"[ESS]"};
3470e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        int[] levels = {mThresholdQualifiedRssi5G + 8};
3480e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        int[] securities = {SECURITY_NONE};
3490e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan
3500e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        ScanDetailsAndWifiConfigs scanDetailsAndConfigs =
3510e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan                WifiNetworkSelectorTestUtil.setupScanDetailsAndConfigStore(ssids, bssids,
3520e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan                    freqs, caps, levels, securities, mWifiConfigManager, mClock);
3530e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        List<ScanDetail> scanDetails = scanDetailsAndConfigs.getScanDetails();
354167b90b5e002698378728a54a417a08c317d29dcRandy Pan        HashSet<String> blacklist = new HashSet<String>();
3550e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        WifiConfiguration[] savedConfigs = scanDetailsAndConfigs.getWifiConfigs();
3560e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan
3570e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        // connect to test1
358167b90b5e002698378728a54a417a08c317d29dcRandy Pan        mWifiNetworkSelector.selectNetwork(scanDetails, blacklist, mWifiInfo, false, true, false);
3590e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        when(mWifiInfo.getNetworkId()).thenReturn(0);
3600e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        when(mWifiInfo.getBSSID()).thenReturn(bssids[0]);
3610e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        when(mWifiInfo.is24GHz()).thenReturn(false);
3620e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        when(mWifiInfo.is5GHz()).thenReturn(true);
3630e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan
3640e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        when(mClock.getElapsedSinceBootMillis()).thenReturn(SystemClock.elapsedRealtime()
3650e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan                + WifiNetworkSelector.MINIMUM_NETWORK_SELECTION_INTERVAL_MS + 2000);
3660e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan
3670e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        // Do another network selection.
3680e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(scanDetails,
369167b90b5e002698378728a54a417a08c317d29dcRandy Pan                blacklist, mWifiInfo, true, false, false);
3700e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan
3710e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        ScanResult chosenScanResult = scanDetails.get(0).getScanResult();
3720e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        WifiConfigurationTestUtil.assertConfigurationEqual(savedConfigs[0], candidate);
3730e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        WifiNetworkSelectorTestUtil.verifySelectedScanResult(mWifiConfigManager,
3740e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan                chosenScanResult, candidate);
3750e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan    }
3760e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan
3770e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan    /**
3780e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan     * New network selection is performed if the currently connected network
3790e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan     * has low RSSI value.
3800e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan     *
3810e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan     * WifiStateMachine is connected to a low RSSI 5GHz network.
3820e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan     * scanDetails contains a valid networks.
3830e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan     * Perform a network seletion after the first one.
3840e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan     *
3850e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan     * Expected behavior: the first network is recommended by Network Selector
3860e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan     */
3870e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan    @Test
3880e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan    public void lowRssi5GNetworkIsNotSufficient() {
3890e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        String[] ssids = {"\"test1\""};
3900e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        String[] bssids = {"6c:f3:7f:ae:8c:f3"};
3910e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        int[] freqs = {5180};
3920e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        String[] caps = {"[WPA2-EAP-CCMP][ESS]"};
3930e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        int[] levels = {mThresholdQualifiedRssi5G - 2};
3940e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        int[] securities = {SECURITY_PSK};
3950e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan
3960e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        ScanDetailsAndWifiConfigs scanDetailsAndConfigs =
3970e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan                WifiNetworkSelectorTestUtil.setupScanDetailsAndConfigStore(ssids, bssids,
3980e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan                    freqs, caps, levels, securities, mWifiConfigManager, mClock);
3990e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        List<ScanDetail> scanDetails = scanDetailsAndConfigs.getScanDetails();
400167b90b5e002698378728a54a417a08c317d29dcRandy Pan        HashSet<String> blacklist = new HashSet<String>();
4010e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        WifiConfiguration[] savedConfigs = scanDetailsAndConfigs.getWifiConfigs();
4020e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan
4030e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        // connect to test1
404167b90b5e002698378728a54a417a08c317d29dcRandy Pan        mWifiNetworkSelector.selectNetwork(scanDetails, blacklist, mWifiInfo, false, true, false);
4050e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        when(mWifiInfo.getNetworkId()).thenReturn(0);
4060e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        when(mWifiInfo.getBSSID()).thenReturn(bssids[0]);
4070e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        when(mWifiInfo.is24GHz()).thenReturn(false);
4080e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        when(mWifiInfo.is5GHz()).thenReturn(true);
4090e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        when(mWifiInfo.getRssi()).thenReturn(levels[0]);
4100e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan
4110e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        when(mClock.getElapsedSinceBootMillis()).thenReturn(SystemClock.elapsedRealtime()
4120e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan                + WifiNetworkSelector.MINIMUM_NETWORK_SELECTION_INTERVAL_MS + 2000);
4130e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan
4140e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        // Do another network selection.
4150e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(scanDetails,
416167b90b5e002698378728a54a417a08c317d29dcRandy Pan                blacklist, mWifiInfo, true, false, false);
4170e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan
4180e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        ScanResult chosenScanResult = scanDetails.get(0).getScanResult();
4190e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan        WifiNetworkSelectorTestUtil.verifySelectedScanResult(mWifiConfigManager,
4200e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan                chosenScanResult, candidate);
4210e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan    }
422bab1104d9cdce66688e45aa04f49d36966bc49e0Randy Pan
423bab1104d9cdce66688e45aa04f49d36966bc49e0Randy Pan    /**
4246491dffa5242829ccafa59a9a7243d56beafe7e6Randy Pan     * Blacklisted BSSID is filtered out for network selection.
425bab1104d9cdce66688e45aa04f49d36966bc49e0Randy Pan     *
426bab1104d9cdce66688e45aa04f49d36966bc49e0Randy Pan     * WifiStateMachine is disconnected.
427bab1104d9cdce66688e45aa04f49d36966bc49e0Randy Pan     * scanDetails contains a network which is blacklisted.
428bab1104d9cdce66688e45aa04f49d36966bc49e0Randy Pan     *
429bab1104d9cdce66688e45aa04f49d36966bc49e0Randy Pan     * Expected behavior: no network recommended by Network Selector
430bab1104d9cdce66688e45aa04f49d36966bc49e0Randy Pan     */
431bab1104d9cdce66688e45aa04f49d36966bc49e0Randy Pan    @Test
432bab1104d9cdce66688e45aa04f49d36966bc49e0Randy Pan    public void filterOutBlacklistedBssid() {
433bab1104d9cdce66688e45aa04f49d36966bc49e0Randy Pan        String[] ssids = {"\"test1\""};
434bab1104d9cdce66688e45aa04f49d36966bc49e0Randy Pan        String[] bssids = {"6c:f3:7f:ae:8c:f3"};
435bab1104d9cdce66688e45aa04f49d36966bc49e0Randy Pan        int[] freqs = {5180};
436bab1104d9cdce66688e45aa04f49d36966bc49e0Randy Pan        String[] caps = {"[WPA2-EAP-CCMP][ESS]"};
437bab1104d9cdce66688e45aa04f49d36966bc49e0Randy Pan        int[] levels = {mThresholdQualifiedRssi5G + 8};
438bab1104d9cdce66688e45aa04f49d36966bc49e0Randy Pan        int[] securities = {SECURITY_PSK};
439bab1104d9cdce66688e45aa04f49d36966bc49e0Randy Pan
440bab1104d9cdce66688e45aa04f49d36966bc49e0Randy Pan        ScanDetailsAndWifiConfigs scanDetailsAndConfigs =
441bab1104d9cdce66688e45aa04f49d36966bc49e0Randy Pan                WifiNetworkSelectorTestUtil.setupScanDetailsAndConfigStore(ssids, bssids,
442bab1104d9cdce66688e45aa04f49d36966bc49e0Randy Pan                    freqs, caps, levels, securities, mWifiConfigManager, mClock);
443bab1104d9cdce66688e45aa04f49d36966bc49e0Randy Pan        List<ScanDetail> scanDetails = scanDetailsAndConfigs.getScanDetails();
444167b90b5e002698378728a54a417a08c317d29dcRandy Pan        HashSet<String> blacklist = new HashSet<String>();
445167b90b5e002698378728a54a417a08c317d29dcRandy Pan        blacklist.add(bssids[0]);
446bab1104d9cdce66688e45aa04f49d36966bc49e0Randy Pan
447bab1104d9cdce66688e45aa04f49d36966bc49e0Randy Pan        WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(scanDetails,
448167b90b5e002698378728a54a417a08c317d29dcRandy Pan                blacklist, mWifiInfo, false, true, false);
449bab1104d9cdce66688e45aa04f49d36966bc49e0Randy Pan        assertEquals("Expect null configuration", null, candidate);
450eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen        assertTrue(mWifiNetworkSelector.getConnectableScanDetails().isEmpty());
451bab1104d9cdce66688e45aa04f49d36966bc49e0Randy Pan    }
4526491dffa5242829ccafa59a9a7243d56beafe7e6Randy Pan
4536491dffa5242829ccafa59a9a7243d56beafe7e6Randy Pan    /**
4546491dffa5242829ccafa59a9a7243d56beafe7e6Randy Pan     * Wifi network selector doesn't recommend any network if the currently connected one
4556491dffa5242829ccafa59a9a7243d56beafe7e6Randy Pan     * doesn't show up in the scan results.
4566491dffa5242829ccafa59a9a7243d56beafe7e6Randy Pan     *
4576491dffa5242829ccafa59a9a7243d56beafe7e6Randy Pan     * WifiStateMachine is under connected state and 2.4GHz test1 is connected.
4586491dffa5242829ccafa59a9a7243d56beafe7e6Randy Pan     * The second scan results contains only test2 which now has a stronger RSSI than test1.
4596491dffa5242829ccafa59a9a7243d56beafe7e6Randy Pan     * Test1 is not in the second scan results.
4606491dffa5242829ccafa59a9a7243d56beafe7e6Randy Pan     *
4616491dffa5242829ccafa59a9a7243d56beafe7e6Randy Pan     * Expected behavior: no network recommended by Network Selector
4626491dffa5242829ccafa59a9a7243d56beafe7e6Randy Pan     */
4636491dffa5242829ccafa59a9a7243d56beafe7e6Randy Pan    @Test
4646491dffa5242829ccafa59a9a7243d56beafe7e6Randy Pan    public void noSelectionWhenCurrentNetworkNotInScanResults() {
4656491dffa5242829ccafa59a9a7243d56beafe7e6Randy Pan        String[] ssids = {"\"test1\"", "\"test2\""};
4666491dffa5242829ccafa59a9a7243d56beafe7e6Randy Pan        String[] bssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4"};
4676491dffa5242829ccafa59a9a7243d56beafe7e6Randy Pan        int[] freqs = {2437, 2457};
4686491dffa5242829ccafa59a9a7243d56beafe7e6Randy Pan        String[] caps = {"[WPA2-EAP-CCMP][ESS]", "[WPA2-EAP-CCMP][ESS]"};
469fac6568cbb329e06b22bfe07993acb263f3762abMichael Plass        int[] levels = {mThresholdMinimumRssi2G + 20, mThresholdMinimumRssi2G + RSSI_BUMP};
4706491dffa5242829ccafa59a9a7243d56beafe7e6Randy Pan        int[] securities = {SECURITY_PSK, SECURITY_PSK};
4716491dffa5242829ccafa59a9a7243d56beafe7e6Randy Pan
4726491dffa5242829ccafa59a9a7243d56beafe7e6Randy Pan        // Make a network selection to connect to test1.
4736491dffa5242829ccafa59a9a7243d56beafe7e6Randy Pan        ScanDetailsAndWifiConfigs scanDetailsAndConfigs =
4746491dffa5242829ccafa59a9a7243d56beafe7e6Randy Pan                WifiNetworkSelectorTestUtil.setupScanDetailsAndConfigStore(ssids, bssids,
4756491dffa5242829ccafa59a9a7243d56beafe7e6Randy Pan                    freqs, caps, levels, securities, mWifiConfigManager, mClock);
4766491dffa5242829ccafa59a9a7243d56beafe7e6Randy Pan        List<ScanDetail> scanDetails = scanDetailsAndConfigs.getScanDetails();
477167b90b5e002698378728a54a417a08c317d29dcRandy Pan        HashSet<String> blacklist = new HashSet<String>();
4786491dffa5242829ccafa59a9a7243d56beafe7e6Randy Pan        WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(scanDetails,
479167b90b5e002698378728a54a417a08c317d29dcRandy Pan                blacklist, mWifiInfo, false, true, false);
4806491dffa5242829ccafa59a9a7243d56beafe7e6Randy Pan
4816491dffa5242829ccafa59a9a7243d56beafe7e6Randy Pan        when(mWifiInfo.getNetworkId()).thenReturn(0);
4826491dffa5242829ccafa59a9a7243d56beafe7e6Randy Pan        when(mWifiInfo.getBSSID()).thenReturn(bssids[0]);
4836491dffa5242829ccafa59a9a7243d56beafe7e6Randy Pan        when(mWifiInfo.is24GHz()).thenReturn(true);
4846491dffa5242829ccafa59a9a7243d56beafe7e6Randy Pan        when(mWifiInfo.is5GHz()).thenReturn(false);
4856491dffa5242829ccafa59a9a7243d56beafe7e6Randy Pan        when(mWifiInfo.getRssi()).thenReturn(levels[0]);
4866491dffa5242829ccafa59a9a7243d56beafe7e6Randy Pan        when(mClock.getElapsedSinceBootMillis()).thenReturn(SystemClock.elapsedRealtime()
4876491dffa5242829ccafa59a9a7243d56beafe7e6Randy Pan                + WifiNetworkSelector.MINIMUM_NETWORK_SELECTION_INTERVAL_MS + 2000);
4886491dffa5242829ccafa59a9a7243d56beafe7e6Randy Pan
4896491dffa5242829ccafa59a9a7243d56beafe7e6Randy Pan        // Prepare the second scan results which have no test1.
4906491dffa5242829ccafa59a9a7243d56beafe7e6Randy Pan        String[] ssidsNew = {"\"test2\""};
4916491dffa5242829ccafa59a9a7243d56beafe7e6Randy Pan        String[] bssidsNew = {"6c:f3:7f:ae:8c:f4"};
4926491dffa5242829ccafa59a9a7243d56beafe7e6Randy Pan        int[] freqsNew = {2457};
4936491dffa5242829ccafa59a9a7243d56beafe7e6Randy Pan        String[] capsNew = {"[WPA2-EAP-CCMP][ESS]"};
4946491dffa5242829ccafa59a9a7243d56beafe7e6Randy Pan        int[] levelsNew = {mThresholdMinimumRssi2G + 40};
4956491dffa5242829ccafa59a9a7243d56beafe7e6Randy Pan        scanDetails = WifiNetworkSelectorTestUtil.buildScanDetails(ssidsNew, bssidsNew,
4966491dffa5242829ccafa59a9a7243d56beafe7e6Randy Pan                freqsNew, capsNew, levelsNew, mClock);
497167b90b5e002698378728a54a417a08c317d29dcRandy Pan        candidate = mWifiNetworkSelector.selectNetwork(scanDetails, blacklist, mWifiInfo,
498167b90b5e002698378728a54a417a08c317d29dcRandy Pan                true, false, false);
4996491dffa5242829ccafa59a9a7243d56beafe7e6Randy Pan
5006491dffa5242829ccafa59a9a7243d56beafe7e6Randy Pan        // The second network selection is skipped since current connected network is
5016491dffa5242829ccafa59a9a7243d56beafe7e6Randy Pan        // missing from the scan results.
5026491dffa5242829ccafa59a9a7243d56beafe7e6Randy Pan        assertEquals("Expect null configuration", null, candidate);
503eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen        assertTrue(mWifiNetworkSelector.getConnectableScanDetails().isEmpty());
5046491dffa5242829ccafa59a9a7243d56beafe7e6Randy Pan    }
505805966beca772f5755be73ac1fe0819142ec294bRandy Pan
506805966beca772f5755be73ac1fe0819142ec294bRandy Pan    /**
507235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh     * Ensures that settings the user connect choice updates the
508235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh     * NetworkSelectionStatus#mConnectChoice for all other WifiConfigurations in range in the last
509235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh     * round of network selection.
510235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh     *
511235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh     * Expected behavior: WifiConfiguration.NetworkSelectionStatus#mConnectChoice is set to
512235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh     *                    test1's configkey for test2. test3's WifiConfiguration is unchanged.
513235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh     */
514235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh    @Test
515235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh    public void setUserConnectChoice() {
516235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh        String[] ssids = {"\"test1\"", "\"test2\"", "\"test3\""};
517235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh        String[] bssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4", "6c:f3:7f:ae:8c:f5"};
518235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh        int[] freqs = {2437, 5180, 5181};
519235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh        String[] caps = {"[WPA2-EAP-CCMP][ESS]", "[WPA2-EAP-CCMP][ESS]", "[WPA2-EAP-CCMP][ESS]"};
520fac6568cbb329e06b22bfe07993acb263f3762abMichael Plass        int[] levels = {mThresholdMinimumRssi2G + RSSI_BUMP, mThresholdMinimumRssi5G + RSSI_BUMP,
521fac6568cbb329e06b22bfe07993acb263f3762abMichael Plass                mThresholdMinimumRssi5G + RSSI_BUMP};
522235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh        int[] securities = {SECURITY_PSK, SECURITY_PSK, SECURITY_PSK};
523235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh
524235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh        ScanDetailsAndWifiConfigs scanDetailsAndConfigs =
525235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh                WifiNetworkSelectorTestUtil.setupScanDetailsAndConfigStore(ssids, bssids,
526235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh                        freqs, caps, levels, securities, mWifiConfigManager, mClock);
527235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh
528235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh        WifiConfiguration selectedWifiConfig = scanDetailsAndConfigs.getWifiConfigs()[0];
529235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh        selectedWifiConfig.getNetworkSelectionStatus()
530235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh                .setCandidate(scanDetailsAndConfigs.getScanDetails().get(0).getScanResult());
531235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh        selectedWifiConfig.getNetworkSelectionStatus().setNetworkSelectionStatus(
532235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh                NetworkSelectionStatus.NETWORK_SELECTION_PERMANENTLY_DISABLED);
533235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh        selectedWifiConfig.getNetworkSelectionStatus().setConnectChoice("bogusKey");
534235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh
535235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh        WifiConfiguration configInLastNetworkSelection = scanDetailsAndConfigs.getWifiConfigs()[1];
536235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh        configInLastNetworkSelection.getNetworkSelectionStatus()
537235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh                .setSeenInLastQualifiedNetworkSelection(true);
538235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh
539235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh        WifiConfiguration configNotInLastNetworkSelection =
540235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh                scanDetailsAndConfigs.getWifiConfigs()[2];
541235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh
542235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh        assertTrue(mWifiNetworkSelector.setUserConnectChoice(selectedWifiConfig.networkId));
543235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh
544235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh        verify(mWifiConfigManager).updateNetworkSelectionStatus(selectedWifiConfig.networkId,
545235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh                NetworkSelectionStatus.NETWORK_SELECTION_ENABLE);
546235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh        verify(mWifiConfigManager).clearNetworkConnectChoice(selectedWifiConfig.networkId);
547235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh        verify(mWifiConfigManager).setNetworkConnectChoice(configInLastNetworkSelection.networkId,
548235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh                selectedWifiConfig.configKey(), mClock.getWallClockMillis());
549235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh        verify(mWifiConfigManager, never()).setNetworkConnectChoice(
550235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh                configNotInLastNetworkSelection.networkId, selectedWifiConfig.configKey(),
551235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh                mClock.getWallClockMillis());
552235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh    }
553235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh
554235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh    /**
555235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh     * If two qualified networks, test1 and test2, are in range when the user selects test2 over
556235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh     * test1, WifiNetworkSelector will override the NetworkSelector's choice to connect to test1
557235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh     * with test2.
558235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh     *
559235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh     * Expected behavior: test2 is the recommended network
560235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh     */
561235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh    @Test
562235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh    public void userConnectChoiceOverridesNetworkEvaluators() {
563235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh        String[] ssids = {"\"test1\"", "\"test2\""};
564235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh        String[] bssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4"};
565235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh        int[] freqs = {2437, 5180};
566235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh        String[] caps = {"[WPA2-EAP-CCMP][ESS]", "[WPA2-EAP-CCMP][ESS]"};
567fac6568cbb329e06b22bfe07993acb263f3762abMichael Plass        int[] levels = {mThresholdMinimumRssi2G + RSSI_BUMP, mThresholdMinimumRssi5G + RSSI_BUMP};
568235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh        int[] securities = {SECURITY_PSK, SECURITY_PSK};
569235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh
570235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh        ScanDetailsAndWifiConfigs scanDetailsAndConfigs =
571235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh                WifiNetworkSelectorTestUtil.setupScanDetailsAndConfigStore(ssids, bssids,
572235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh                        freqs, caps, levels, securities, mWifiConfigManager, mClock);
573235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh        List<ScanDetail> scanDetails = scanDetailsAndConfigs.getScanDetails();
574167b90b5e002698378728a54a417a08c317d29dcRandy Pan        HashSet<String> blacklist = new HashSet<String>();
575235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh
576235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh        // DummyEvaluator always selects the first network in the list.
577235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh        WifiConfiguration networkSelectorChoice = scanDetailsAndConfigs.getWifiConfigs()[0];
578235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh        networkSelectorChoice.getNetworkSelectionStatus()
579235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh                .setSeenInLastQualifiedNetworkSelection(true);
580235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh
581235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh        WifiConfiguration userChoice = scanDetailsAndConfigs.getWifiConfigs()[1];
582235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh        userChoice.getNetworkSelectionStatus()
583235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh                .setCandidate(scanDetailsAndConfigs.getScanDetails().get(1).getScanResult());
584235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh
585235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh        // With no user choice set, networkSelectorChoice should be chosen.
586235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh        WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(scanDetails,
587167b90b5e002698378728a54a417a08c317d29dcRandy Pan                blacklist, mWifiInfo, false, true, false);
588235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh
589235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh        WifiConfigurationTestUtil.assertConfigurationEqual(networkSelectorChoice, candidate);
590235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh
591235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh        when(mClock.getElapsedSinceBootMillis()).thenReturn(SystemClock.elapsedRealtime()
592235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh                + WifiNetworkSelector.MINIMUM_NETWORK_SELECTION_INTERVAL_MS + 2000);
593235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh
594235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh        assertTrue(mWifiNetworkSelector.setUserConnectChoice(userChoice.networkId));
595235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh
596235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh        // After user connect choice is set, userChoice should override networkSelectorChoice.
597235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh        candidate = mWifiNetworkSelector.selectNetwork(scanDetails,
598167b90b5e002698378728a54a417a08c317d29dcRandy Pan                blacklist, mWifiInfo, false, true, false);
599235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh
600235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh        WifiConfigurationTestUtil.assertConfigurationEqual(userChoice, candidate);
601235642dba4359c1e68618f27c949e744765cbbccAmin Shaikh    }
6023b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold
6033b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold    /**
6043b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold     * Wifi network selector doesn't recommend any network if the currently connected 2.4Ghz
6053b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold     * network is high quality and no 5GHz networks are available
6063b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold     *
6073b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold     * WifiStateMachine is under connected state and 2.4GHz test1 is connected.
6083b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold     *
6093b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold     * Expected behavior: no network selection is performed
6103b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold     */
6113b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold    @Test
6123b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold    public void test2GhzQualifiedNo5GhzAvailable() {
6133cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        // Rssi after connected.
6143cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        when(mWifiInfo.getRssi()).thenReturn(mThresholdQualifiedRssi2G + 1);
6153cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        // No streaming traffic.
6163cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        when(mWifiInfo.getTxSuccessRatePps()).thenReturn(0.0);
6173cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        when(mWifiInfo.getRxSuccessRatePps()).thenReturn(0.0);
6183cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang
6193b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold        // Do not perform selection on 2GHz if current network is good and no 5GHz available
6203cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        testStayOrTryToSwitch(
6213cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang                mThresholdQualifiedRssi2G + 1 /* rssi before connected */,
6223cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang                false /* not a 5G network */,
6233cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang                false /* not open network */,
6243cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang                // Should not try to switch.
6253cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang                false);
6263b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold    }
6273b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold
6283b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold    /**
6293b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold     * Wifi network selector performs network selection even when the 2Ghz network is high
6303b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold     * quality whenever 5Ghz networks are available.
6313b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold     *
6323b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold     * WifiStateMachine is under connected state and 2.4GHz test1 is connected.
6333b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold     * The scan results contain a 5Ghz network, which forces network selection.
6343b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold     * Test1 is not in the second scan results.
6353b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold     *
6363b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold     * Expected behavior: network selection is performed
6373b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold     */
6383b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold    @Test
6393b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold    public void test2GhzHighQuality5GhzAvailable() {
6403cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        // Rssi after connected.
6413cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        when(mWifiInfo.getRssi()).thenReturn(mThresholdQualifiedRssi2G + 1);
6423cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        // No streaming traffic.
6433cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        when(mWifiInfo.getTxSuccessRatePps()).thenReturn(0.0);
6443cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        when(mWifiInfo.getRxSuccessRatePps()).thenReturn(0.0);
6453b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold
6463cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        // When on 2GHz, even with "good" signal strength, run selection if 5GHz available
6473cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        testStayOrTryToSwitch(
6483cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang                // Parameters for network1:
6493cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang                mThresholdQualifiedRssi2G + 1 /* rssi before connected */,
6503cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang                false /* not a 5G network */,
6513cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang                false /* not open network */,
6523cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang                // Parameters for network2:
6533cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang                mThresholdQualifiedRssi5G + 1 /* rssi */,
6543cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang                true /* a 5G network */,
6553cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang                false /* not open network */,
6563cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang                // Should try to switch.
6573cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang                true);
6583b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold    }
6593b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold
6603b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold    /**
6613b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold     * Wifi network selector performs network selection when connected to a 5Ghz network that
6623b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold     * has an insufficient RSSI.
6633b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold     *
6643b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold     * WifiStateMachine is under connected state and 5GHz test1 is connected.
6653b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold     *
6663b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold     * Expected behavior: network selection is performed
6673b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold     */
6683b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold    @Test
6693b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold    public void test5GhzNotQualifiedLowRssi() {
6703cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        // Rssi after connected.
6713cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        when(mWifiInfo.getRssi()).thenReturn(mThresholdQualifiedRssi5G - 1);
6723cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        // No streaming traffic.
6733cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        when(mWifiInfo.getTxSuccessRatePps()).thenReturn(0.0);
6743cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        when(mWifiInfo.getRxSuccessRatePps()).thenReturn(0.0);
6753cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang
6763cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        // Run Selection when the current 5Ghz network has low RSSI.
6773cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        testStayOrTryToSwitch(
6783cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang                mThresholdQualifiedRssi5G + 1 /* rssi before connected */,
6793cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang                true /* a 5G network */,
6803cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang                false /* not open network */,
6813cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang                // Should try to switch.
6823cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang                true);
6833b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold    }
6843b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold
6853b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold    /**
6863b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold     * Wifi network selector will not run selection when on a 5Ghz network that is of sufficent
6873b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold     * Quality (high-enough RSSI).
6883b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold     *
6893b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold     * WifiStateMachine is under connected state and 5GHz test1 is connected.
6903b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold     *
6913b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold     * Expected behavior: network selection is not performed
6923b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold     */
6933b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold    @Test
6943b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold    public void test5GhzQualified() {
6953cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        // Rssi after connected.
6963cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        when(mWifiInfo.getRssi()).thenReturn(mThresholdQualifiedRssi5G + 1);
6973cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        // No streaming traffic.
6983cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        when(mWifiInfo.getTxSuccessRatePps()).thenReturn(0.0);
6993cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        when(mWifiInfo.getRxSuccessRatePps()).thenReturn(0.0);
7003cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang
7013b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold        // Connected to a high quality 5Ghz network, so the other result is irrelevant
7023cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        testStayOrTryToSwitch(
7033cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang                mThresholdQualifiedRssi5G + 1 /* rssi before connected */,
7043cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang                true /* a 5G network */,
7053cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang                false /* not open network */,
7063cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang                // Should not try to switch.
7073cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang                false);
7083cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang    }
7093cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang
7103cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang    /**
7113cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang     * New network selection is performed if the currently connected network
7123cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang     * band is 2G and there is no sign of streaming traffic.
7133cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang     *
7143cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang     * Expected behavior: Network Selector perform network selection after connected
7153cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang     * to the first one.
7163cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang     */
7173cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang    @Test
7183cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang    public void band2GNetworkIsNotSufficientWhenNoOngoingTrafficAnd5GhzAvailable() {
7193cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        // Rssi after connected.
7203cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        when(mWifiInfo.getRssi()).thenReturn(mThresholdQualifiedRssi2G + 1);
7213cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        // No streaming traffic.
7223cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        when(mWifiInfo.getTxSuccessRatePps()).thenReturn(0.0);
7233cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        when(mWifiInfo.getRxSuccessRatePps()).thenReturn(0.0);
7243cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang
7253cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        testStayOrTryToSwitch(
7263cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang                // Parameters for network1:
7273cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang                mThresholdQualifiedRssi2G + 1 /* rssi before connected */,
7283cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang                false /* not a 5G network */,
7293cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang                false /* not open network */,
7303cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang                // Parameters for network2:
7313cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang                mThresholdQualifiedRssi5G + 1 /* rssi */,
7323cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang                true /* a 5G network */,
7333cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang                false /* not open network */,
7343cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang                // Should try to switch.
7353cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang                true);
7363cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang    }
7373cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang
7383cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang    /**
7393cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang     * New network selection is performed if the currently connected network
7403cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang     * band is 2G with bad rssi.
7413cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang     *
7423cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang     * Expected behavior: Network Selector perform network selection after connected
7433cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang     * to the first one.
7443cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang     */
7453cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang    @Test
7463cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang    public void band2GNetworkIsNotSufficientWithBadRssi() {
7473cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        // Rssi after connected.
7483cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        when(mWifiInfo.getRssi()).thenReturn(mThresholdQualifiedRssi2G - 1);
7493cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        // No streaming traffic.
7503cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        when(mWifiInfo.getTxSuccessRatePps()).thenReturn(0.0);
7513cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        when(mWifiInfo.getRxSuccessRatePps()).thenReturn(0.0);
7523cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang
7533cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        testStayOrTryToSwitch(
7543cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang                mThresholdQualifiedRssi2G + 1 /* rssi before connected */,
7553cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang                false /* not a 5G network */,
7563cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang                false /* not open network */,
7573cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang                // Should try to switch.
7583cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang                true);
7593cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang    }
7603cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang
7613cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang    /**
7623cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang     * New network selection is not performed if the currently connected 2G network
7633cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang     * has good Rssi and sign of streaming tx traffic.
7643cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang     *
7653cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang     * Expected behavior: Network selector does not perform network selection.
7663cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang     */
7673cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang    @Test
7683cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang    public void band2GNetworkIsSufficientWhenOnGoingTxTrafficCombinedWithGoodRssi() {
7693cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        // Rssi after connected.
7703cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        when(mWifiInfo.getRssi()).thenReturn(mThresholdQualifiedRssi2G + 1);
7713cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        // Streaming traffic
7723cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        when(mWifiInfo.getTxSuccessRatePps()).thenReturn(
7733cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang                (double) (mStayOnNetworkMinimumTxRate + 1));
7743cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        when(mWifiInfo.getRxSuccessRatePps()).thenReturn(0.0);
7753cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang
7763cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        testStayOrTryToSwitch(
7773cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang                mThresholdQualifiedRssi2G + 1 /* rssi before connected */,
7783cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang                false /* not a 5G network */,
7793cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang                true /* open network */,
7803cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang                // Should not try to switch.
7813cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang                false);
7823cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang    }
7833cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang
7843cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang    /**
7853cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang     * New network selection is not performed if the currently connected 2G network
7863cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang     * has good Rssi and sign of streaming rx traffic.
7873cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang     *
7883cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang     * Expected behavior: Network selector does not perform network selection.
7893cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang     */
7903cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang    @Test
7913cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang    public void band2GNetworkIsSufficientWhenOnGoingRxTrafficCombinedWithGoodRssi() {
7923cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        // Rssi after connected.
7933cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        when(mWifiInfo.getRssi()).thenReturn(mThresholdQualifiedRssi2G + 1);
7943cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        // Streaming traffic
7953cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        when(mWifiInfo.getTxSuccessRatePps()).thenReturn(0.0);
7963cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        when(mWifiInfo.getRxSuccessRatePps()).thenReturn(
7973cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang                (double) (mStayOnNetworkMinimumRxRate + 1));
7983cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang
7993cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        testStayOrTryToSwitch(
8003cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang                mThresholdQualifiedRssi2G + 1 /* rssi before connected */,
8013cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang                false /* not a 5G network */,
8023cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang                true /* open network */,
8033cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang                // Should not try to switch.
8043cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang                false);
8053cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang    }
8063cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang
8073cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang    /**
8083cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang     * New network selection is not performed if the currently connected 5G network
8093cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang     * has good Rssi and sign of streaming tx traffic.
8103cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang     *
8113cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang     * Expected behavior: Network selector does not perform network selection.
8123cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang     */
8133cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang    @Test
8143cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang    public void band5GNetworkIsSufficientWhenOnGoingTxTrafficCombinedWithGoodRssi() {
8153cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        // Rssi after connected.
8163cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        when(mWifiInfo.getRssi()).thenReturn(mThresholdQualifiedRssi5G + 1);
8173cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        // Streaming traffic
8183cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        when(mWifiInfo.getTxSuccessRatePps()).thenReturn(
8193cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang                (double) (mStayOnNetworkMinimumTxRate + 1));
8203cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        when(mWifiInfo.getRxSuccessRatePps()).thenReturn(0.0);
8213cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang
8223cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        testStayOrTryToSwitch(
8233cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang                mThresholdQualifiedRssi5G + 1 /* rssi before connected */,
8243cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang                true /* a 5G network */,
8253cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang                true /* open network */,
8263cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang                // Should not try to switch.
8273cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang                false);
8283cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang    }
8293cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang
8303cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang    /**
8313cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang     * New network selection is not performed if the currently connected 5G network
8323cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang     * has good Rssi and sign of streaming rx traffic.
8333cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang     *
8343cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang     * Expected behavior: Network selector does not perform network selection.
8353cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang     */
8363cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang    @Test
8373cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang    public void band5GNetworkIsSufficientWhenOnGoingRxTrafficCombinedWithGoodRssi() {
8383cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        // Rssi after connected.
8393cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        when(mWifiInfo.getRssi()).thenReturn(mThresholdQualifiedRssi5G + 1);
8403cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        // Streaming traffic
8413cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        when(mWifiInfo.getTxSuccessRatePps()).thenReturn(0.0);
8423cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        when(mWifiInfo.getRxSuccessRatePps()).thenReturn(
8433cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang                (double) (mStayOnNetworkMinimumRxRate + 1));
8443cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang
8453cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        testStayOrTryToSwitch(
8463cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang                mThresholdQualifiedRssi5G + 1 /* rssi before connected */,
8473cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang                true /* a 5G network */,
8483cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang                true /* open network */,
8493cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang                // Should not try to switch.
8503cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang                false);
8513b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold    }
8523b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold
8533b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold    /**
8543b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold     * This is a meta-test that given two scan results of various types, will
8553b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold     * determine whether or not network selection should be performed.
8563b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold     *
8573b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold     * It sets up two networks, connects to the first, and then ensures that
8583b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold     * both are available in the scan results for the NetworkSelector.
8593b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold     */
8603cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang    private void testStayOrTryToSwitch(
8613cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang            int rssiNetwork1, boolean is5GHzNetwork1, boolean isOpenNetwork1,
8623cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang            int rssiNetwork2, boolean is5GHzNetwork2, boolean isOpenNetwork2,
8633cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang            boolean shouldSelect) {
8643b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold        String[] ssids = {"\"test1\"", "\"test2\""};
8653b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold        String[] bssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4"};
8663cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        int[] freqs = {is5GHzNetwork1 ? 5180 : 2437, is5GHzNetwork2 ? 5180 : 2437};
8673cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        String[] caps = {isOpenNetwork1 ? "[ESS]" : "[WPA2-EAP-CCMP][ESS]",
8683cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang                         isOpenNetwork2 ? "[ESS]" : "[WPA2-EAP-CCMP][ESS]"};
8693cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        int[] levels = {rssiNetwork1, rssiNetwork2};
8703cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        int[] securities = {isOpenNetwork1 ? SECURITY_NONE : SECURITY_PSK,
8713cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang                            isOpenNetwork2 ? SECURITY_NONE : SECURITY_PSK};
8723cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        testStayOrTryToSwitchImpl(ssids, bssids, freqs, caps, levels, securities, shouldSelect);
8733cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang    }
8743b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold
8753cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang    /**
8763cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang     * This is a meta-test that given one scan results, will
8773cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang     * determine whether or not network selection should be performed.
8783cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang     *
8793cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang     * It sets up two networks, connects to the first, and then ensures that
8803cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang     * the scan results for the NetworkSelector.
8813cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang     */
8823cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang    private void testStayOrTryToSwitch(
8833cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang            int rssi, boolean is5GHz, boolean isOpenNetwork,
8843cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang            boolean shouldSelect) {
8853cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        String[] ssids = {"\"test1\""};
8863cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        String[] bssids = {"6c:f3:7f:ae:8c:f3"};
8873cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        int[] freqs = {is5GHz ? 5180 : 2437};
8883cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        String[] caps = {isOpenNetwork ? "[ESS]" : "[WPA2-EAP-CCMP][ESS]"};
8893cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        int[] levels = {rssi};
8903cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        int[] securities = {isOpenNetwork ? SECURITY_NONE : SECURITY_PSK};
8913cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        testStayOrTryToSwitchImpl(ssids, bssids, freqs, caps, levels, securities, shouldSelect);
8923cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang    }
8933cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang
8943cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang    private void testStayOrTryToSwitchImpl(String[] ssids, String[] bssids, int[] freqs,
8953cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang            String[] caps, int[] levels, int[] securities,
8963cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang            boolean shouldSelect) {
8973b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold        // Make a network selection to connect to test1.
8983b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold        ScanDetailsAndWifiConfigs scanDetailsAndConfigs =
8993b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold                WifiNetworkSelectorTestUtil.setupScanDetailsAndConfigStore(ssids, bssids,
900eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen                        freqs, caps, levels, securities, mWifiConfigManager, mClock);
9013b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold        List<ScanDetail> scanDetails = scanDetailsAndConfigs.getScanDetails();
9023b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold        HashSet<String> blacklist = new HashSet<String>();
9033cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        // DummyNetworkEvaluator always return the first network in the scan results
9043cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        // for connection, so this should connect to the first network.
9053cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(
9063cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang                scanDetails,
9073cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang                blacklist, mWifiInfo, false, true, true);
9083cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        assertNotNull("Result should be not null", candidate);
9093cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        WifiNetworkSelectorTestUtil.verifySelectedScanResult(mWifiConfigManager,
9103cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang                scanDetails.get(0).getScanResult(), candidate);
9113b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold
9123b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold        when(mWifiInfo.getNetworkId()).thenReturn(0);
9133b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold        when(mWifiInfo.getBSSID()).thenReturn(bssids[0]);
9143cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        when(mWifiInfo.is24GHz()).thenReturn(!ScanResult.is5GHz(freqs[0]));
9153cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        when(mWifiInfo.is5GHz()).thenReturn(ScanResult.is5GHz(freqs[0]));
9163cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang
9173b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold        when(mClock.getElapsedSinceBootMillis()).thenReturn(SystemClock.elapsedRealtime()
9183b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold                + WifiNetworkSelector.MINIMUM_NETWORK_SELECTION_INTERVAL_MS + 2000);
9193b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold
9203b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold        candidate = mWifiNetworkSelector.selectNetwork(scanDetails, blacklist, mWifiInfo,
9213b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold                true, false, false);
9223b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold
9233cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        // DummyNetworkEvaluator always return the first network in the scan results
9243cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        // for connection, so if nework selection is performed, the first network should
9253cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        // be returned as candidate.
9263cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        if (shouldSelect) {
9273b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold            assertNotNull("Result should be not null", candidate);
9283b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold            WifiNetworkSelectorTestUtil.verifySelectedScanResult(mWifiConfigManager,
9293cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang                    scanDetails.get(0).getScanResult(), candidate);
9303cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang        } else {
9313cf27a7144be15b7ca400412e4f1bc31daa8be13Ningyuan Wang            assertEquals("Expect null configuration", null, candidate);
9323b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold        }
9333b518300cd177eb84b9fb65c98e2e52ab959d123Nathan Harold    }
934eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen
935eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen    /**
936eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen     * {@link WifiNetworkSelector#getFilteredScanDetailsForOpenUnsavedNetworks()} should filter out
937eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen     * networks that are not open after network selection is made.
938eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen     *
939eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen     * Expected behavior: return open networks only
940eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen     */
941eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen    @Test
942eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen    public void getfilterOpenUnsavedNetworks_filtersForOpenNetworks() {
943eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen        String[] ssids = {"\"test1\"", "\"test2\""};
944eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen        String[] bssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4"};
945eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen        int[] freqs = {2437, 5180};
946eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen        String[] caps = {"[WPA2-EAP-CCMP][ESS]", "[ESS]"};
947fac6568cbb329e06b22bfe07993acb263f3762abMichael Plass        int[] levels = {mThresholdMinimumRssi2G + RSSI_BUMP, mThresholdMinimumRssi5G + RSSI_BUMP};
948eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen        mDummyEvaluator.setEvaluatorToSelectCandidate(false);
949eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen
950eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen        List<ScanDetail> scanDetails = WifiNetworkSelectorTestUtil.buildScanDetails(
951eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen                ssids, bssids, freqs, caps, levels, mClock);
952eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen        HashSet<String> blacklist = new HashSet<>();
953eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen
954eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen        mWifiNetworkSelector.selectNetwork(scanDetails, blacklist, mWifiInfo, false, true, false);
955eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen        List<ScanDetail> expectedOpenUnsavedNetworks = new ArrayList<>();
956eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen        expectedOpenUnsavedNetworks.add(scanDetails.get(1));
957eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen        assertEquals("Expect open unsaved networks",
958eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen                expectedOpenUnsavedNetworks,
959eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen                mWifiNetworkSelector.getFilteredScanDetailsForOpenUnsavedNetworks());
960eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen    }
961eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen
962eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen    /**
963eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen     * {@link WifiNetworkSelector#getFilteredScanDetailsForOpenUnsavedNetworks()} should filter out
964eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen     * saved networks after network selection is made. This should return an empty list when there
965eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen     * are no unsaved networks available.
966eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen     *
967eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen     * Expected behavior: return unsaved networks only. Return empty list if there are no unsaved
968eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen     * networks.
969eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen     */
970eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen    @Test
971eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen    public void getfilterOpenUnsavedNetworks_filtersOutSavedNetworks() {
972eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen        String[] ssids = {"\"test1\""};
973eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen        String[] bssids = {"6c:f3:7f:ae:8c:f3"};
974eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen        int[] freqs = {2437, 5180};
975eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen        String[] caps = {"[ESS]"};
976fac6568cbb329e06b22bfe07993acb263f3762abMichael Plass        int[] levels = {mThresholdMinimumRssi2G + RSSI_BUMP};
977eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen        int[] securities = {SECURITY_NONE};
978eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen        mDummyEvaluator.setEvaluatorToSelectCandidate(false);
979eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen
980eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen        List<ScanDetail> unSavedScanDetails = WifiNetworkSelectorTestUtil.buildScanDetails(
981eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen                ssids, bssids, freqs, caps, levels, mClock);
982eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen        HashSet<String> blacklist = new HashSet<>();
983eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen
984eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen        mWifiNetworkSelector.selectNetwork(
985eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen                unSavedScanDetails, blacklist, mWifiInfo, false, true, false);
986eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen        assertEquals("Expect open unsaved networks",
987eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen                unSavedScanDetails,
988eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen                mWifiNetworkSelector.getFilteredScanDetailsForOpenUnsavedNetworks());
989eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen
990eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen        ScanDetailsAndWifiConfigs scanDetailsAndConfigs =
991eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen                WifiNetworkSelectorTestUtil.setupScanDetailsAndConfigStore(ssids, bssids,
992eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen                        freqs, caps, levels, securities, mWifiConfigManager, mClock);
993eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen        List<ScanDetail> savedScanDetails = scanDetailsAndConfigs.getScanDetails();
994eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen
995eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen        mWifiNetworkSelector.selectNetwork(
996eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen                savedScanDetails, blacklist, mWifiInfo, false, true, false);
997eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen        // Saved networks are filtered out.
998eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen        assertTrue(mWifiNetworkSelector.getFilteredScanDetailsForOpenUnsavedNetworks().isEmpty());
999eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen    }
1000eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen
1001eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen    /**
1002eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen     * {@link WifiNetworkSelector#getFilteredScanDetailsForOpenUnsavedNetworks()} should filter out
1003eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen     * bssid blacklisted networks.
1004eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen     *
1005eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen     * Expected behavior: do not return blacklisted network
1006eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen     */
1007eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen    @Test
1008eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen    public void getfilterOpenUnsavedNetworks_filtersOutBlacklistedNetworks() {
1009eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen        String[] ssids = {"\"test1\"", "\"test2\""};
1010eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen        String[] bssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4"};
1011eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen        int[] freqs = {2437, 5180};
1012eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen        String[] caps = {"[ESS]", "[ESS]"};
1013fac6568cbb329e06b22bfe07993acb263f3762abMichael Plass        int[] levels = {mThresholdMinimumRssi2G + RSSI_BUMP, mThresholdMinimumRssi5G + RSSI_BUMP};
1014eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen        mDummyEvaluator.setEvaluatorToSelectCandidate(false);
1015eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen
1016eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen        List<ScanDetail> scanDetails = WifiNetworkSelectorTestUtil.buildScanDetails(
1017eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen                ssids, bssids, freqs, caps, levels, mClock);
1018eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen        HashSet<String> blacklist = new HashSet<>();
1019eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen        blacklist.add(bssids[0]);
1020eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen
1021eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen        mWifiNetworkSelector.selectNetwork(scanDetails, blacklist, mWifiInfo, false, true, false);
1022eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen        List<ScanDetail> expectedOpenUnsavedNetworks = new ArrayList<>();
1023eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen        expectedOpenUnsavedNetworks.add(scanDetails.get(1));
1024eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen        assertEquals("Expect open unsaved networks",
1025eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen                expectedOpenUnsavedNetworks,
1026eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen                mWifiNetworkSelector.getFilteredScanDetailsForOpenUnsavedNetworks());
1027eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen    }
1028eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen
1029eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen    /**
1030eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen     * {@link WifiNetworkSelector#getFilteredScanDetailsForOpenUnsavedNetworks()} should return
1031eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen     * empty list when there are no open networks after network selection is made.
1032eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen     *
1033eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen     * Expected behavior: return empty list
1034eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen     */
1035eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen    @Test
1036eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen    public void getfilterOpenUnsavedNetworks_returnsEmptyListWhenNoOpenNetworksPresent() {
1037eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen        String[] ssids = {"\"test1\"", "\"test2\""};
1038eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen        String[] bssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4"};
1039eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen        int[] freqs = {2437, 5180};
1040eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen        String[] caps = {"[WPA2-EAP-CCMP][ESS]", "[WPA2-EAP-CCMP][ESS]"};
1041fac6568cbb329e06b22bfe07993acb263f3762abMichael Plass        int[] levels = {mThresholdMinimumRssi2G + RSSI_BUMP, mThresholdMinimumRssi5G + RSSI_BUMP};
1042eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen        mDummyEvaluator.setEvaluatorToSelectCandidate(false);
1043eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen
1044eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen        List<ScanDetail> scanDetails = WifiNetworkSelectorTestUtil.buildScanDetails(
1045eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen                ssids, bssids, freqs, caps, levels, mClock);
1046eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen        HashSet<String> blacklist = new HashSet<>();
1047eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen
1048eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen        mWifiNetworkSelector.selectNetwork(scanDetails, blacklist, mWifiInfo, false, true, false);
1049eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen        assertTrue(mWifiNetworkSelector.getFilteredScanDetailsForOpenUnsavedNetworks().isEmpty());
1050eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen    }
1051eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen
1052eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen    /**
1053eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen     * {@link WifiNetworkSelector#getFilteredScanDetailsForOpenUnsavedNetworks()} should return
1054eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen     * empty list when no network selection has been made.
1055eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen     *
1056eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen     * Expected behavior: return empty list
1057eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen     */
1058eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen    @Test
1059eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen    public void getfilterOpenUnsavedNetworks_returnsEmptyListWhenNoNetworkSelectionMade() {
1060eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen        assertTrue(mWifiNetworkSelector.getFilteredScanDetailsForOpenUnsavedNetworks().isEmpty());
1061eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen    }
10620e3cc5f112670c455029e89c93c1f122b897f6e2Randy Pan}
1063eb04ff08fe0985acd105a92ae397cbcd7ab91266Stephen Chen
1064