SavedNetworkEvaluatorTest.java revision d0258ee4816148ff4ab9ac6b854fc5c51ea53be3
1/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.wifi;
18
19import static com.android.server.wifi.WifiConfigurationTestUtil.SECURITY_NONE;
20import static com.android.server.wifi.WifiConfigurationTestUtil.SECURITY_PSK;
21
22import static org.junit.Assert.*;
23import static org.mockito.Mockito.*;
24
25import android.content.Context;
26import android.content.res.Resources;
27import android.net.wifi.ScanResult;
28import android.net.wifi.WifiConfiguration;
29import android.os.SystemClock;
30import android.test.suitebuilder.annotation.SmallTest;
31
32import com.android.internal.R;
33import com.android.server.wifi.WifiNetworkSelectorTestUtil.ScanDetailsAndWifiConfigs;
34
35import org.junit.After;
36import org.junit.Before;
37import org.junit.Test;
38
39import java.util.List;
40
41/**
42 * Unit tests for {@link com.android.server.wifi.SavedNetworkEvaluator}.
43 */
44@SmallTest
45public class SavedNetworkEvaluatorTest {
46
47    /** Sets up test. */
48    @Before
49    public void setUp() throws Exception {
50        mResource = getResource();
51        mContext = getContext();
52        mWifiConfigManager = getWifiConfigManager();
53
54        when(mClock.getElapsedSinceBootMillis()).thenReturn(SystemClock.elapsedRealtime());
55
56        mThresholdMinimumRssi2G = mResource.getInteger(
57                R.integer.config_wifi_framework_wifi_score_bad_rssi_threshold_24GHz);
58        mThresholdMinimumRssi5G = mResource.getInteger(
59                R.integer.config_wifi_framework_wifi_score_bad_rssi_threshold_5GHz);
60        mThresholdQualifiedRssi2G = mResource.getInteger(
61                R.integer.config_wifi_framework_wifi_score_low_rssi_threshold_24GHz);
62        mThresholdQualifiedRssi5G = mResource.getInteger(
63                R.integer.config_wifi_framework_wifi_score_low_rssi_threshold_5GHz);
64        mThresholdSaturatedRssi2G = mResource.getInteger(
65                R.integer.config_wifi_framework_wifi_score_good_rssi_threshold_24GHz);
66        mThresholdSaturatedRssi5G = mResource.getInteger(
67                R.integer.config_wifi_framework_wifi_score_good_rssi_threshold_5GHz);
68
69        mSavedNetworkEvaluator = new SavedNetworkEvaluator(mContext, mWifiConfigManager,
70                mClock, null);
71    }
72
73    /** Cleans up test. */
74    @After
75    public void cleanup() {
76        validateMockitoUsage();
77    }
78
79    private SavedNetworkEvaluator mSavedNetworkEvaluator;
80    private WifiConfigManager mWifiConfigManager;
81    private Context mContext;
82    private Resources mResource;
83    private Clock mClock = mock(Clock.class);
84    private int mThresholdMinimumRssi2G;
85    private int mThresholdMinimumRssi5G;
86    private int mThresholdQualifiedRssi2G;
87    private int mThresholdQualifiedRssi5G;
88    private int mThresholdSaturatedRssi2G;
89    private int mThresholdSaturatedRssi5G;
90    private static final String TAG = "Saved Network Evaluator Unit Test";
91
92    Context getContext() {
93        Context context = mock(Context.class);
94        Resources resource = mock(Resources.class);
95
96        when(context.getResources()).thenReturn(mResource);
97        return context;
98    }
99
100    Resources getResource() {
101        Resources resource = mock(Resources.class);
102
103        when(resource.getInteger(
104                R.integer.config_wifi_framework_wifi_score_good_rssi_threshold_5GHz))
105                .thenReturn(-70);
106        when(resource.getInteger(
107                R.integer.config_wifi_framework_wifi_score_good_rssi_threshold_24GHz))
108                .thenReturn(-73);
109        when(resource.getInteger(
110                R.integer.config_wifi_framework_wifi_score_low_rssi_threshold_5GHz))
111                .thenReturn(-70);
112        when(resource.getInteger(
113                R.integer.config_wifi_framework_wifi_score_low_rssi_threshold_24GHz))
114                .thenReturn(-73);
115        when(resource.getInteger(
116                R.integer.config_wifi_framework_wifi_score_bad_rssi_threshold_5GHz))
117                .thenReturn(-82);
118        when(resource.getInteger(
119                R.integer.config_wifi_framework_wifi_score_bad_rssi_threshold_24GHz))
120                .thenReturn(-85);
121        when(resource.getInteger(
122                R.integer.config_wifi_framework_RSSI_SCORE_SLOPE))
123                .thenReturn(4);
124        when(resource.getInteger(
125                R.integer.config_wifi_framework_RSSI_SCORE_OFFSET))
126                .thenReturn(85);
127        when(resource.getInteger(
128                R.integer.config_wifi_framework_SAME_BSSID_AWARD))
129                .thenReturn(24);
130        when(resource.getInteger(
131                R.integer.config_wifi_framework_SECURITY_AWARD))
132                .thenReturn(80);
133        when(resource.getInteger(
134                R.integer.config_wifi_framework_5GHz_preference_boost_factor))
135                .thenReturn(16);
136        when(resource.getInteger(
137                R.integer.config_wifi_framework_current_network_boost))
138                .thenReturn(16);
139
140        return resource;
141    }
142
143    WifiConfigManager getWifiConfigManager() {
144        WifiConfigManager wifiConfigManager = mock(WifiConfigManager.class);
145        when(wifiConfigManager.getLastSelectedNetwork())
146                .thenReturn(WifiConfiguration.INVALID_NETWORK_ID);
147        return wifiConfigManager;
148    }
149
150    /**
151     * Do not evaluate networks that {@link WifiConfiguration#useExternalScores}.
152     */
153    @Test
154    public void ignoreNetworksIfUseExternalScores() {
155        String[] ssids = {"\"test1\"", "\"test2\""};
156        String[] bssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4"};
157        int[] freqs = {2470, 2437};
158        String[] caps = {"[WPA2-EAP-CCMP][ESS]", "[WPA2-EAP-CCMP][ESS]"};
159        int[] levels = {mThresholdQualifiedRssi2G + 8, mThresholdQualifiedRssi2G + 10};
160        int[] securities = {SECURITY_PSK, SECURITY_PSK};
161
162        ScanDetailsAndWifiConfigs scanDetailsAndConfigs =
163                WifiNetworkSelectorTestUtil.setupScanDetailsAndConfigStore(ssids, bssids,
164                        freqs, caps, levels, securities, mWifiConfigManager, mClock);
165        List<ScanDetail> scanDetails = scanDetailsAndConfigs.getScanDetails();
166        WifiConfiguration[] savedConfigs = scanDetailsAndConfigs.getWifiConfigs();
167        for (WifiConfiguration wifiConfiguration : savedConfigs) {
168            wifiConfiguration.useExternalScores = true;
169        }
170
171        WifiConfiguration candidate = mSavedNetworkEvaluator.evaluateNetworks(scanDetails,
172                null, null, true, false, null);
173
174        assertNull(candidate);
175    }
176
177    /**
178     * Between two 2G networks, choose the one with stronger RSSI value if other conditions
179     * are the same and the RSSI values are not satuarted.
180     */
181    @Test
182    public void chooseStrongerRssi2GNetwork() {
183        String[] ssids = {"\"test1\"", "\"test2\""};
184        String[] bssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4"};
185        int[] freqs = {2470, 2437};
186        String[] caps = {"[WPA2-EAP-CCMP][ESS]", "[WPA2-EAP-CCMP][ESS]"};
187        int[] levels = {mThresholdQualifiedRssi2G + 8, mThresholdQualifiedRssi2G + 10};
188        int[] securities = {SECURITY_PSK, SECURITY_PSK};
189
190        ScanDetailsAndWifiConfigs scanDetailsAndConfigs =
191                WifiNetworkSelectorTestUtil.setupScanDetailsAndConfigStore(ssids, bssids,
192                    freqs, caps, levels, securities, mWifiConfigManager, mClock);
193        List<ScanDetail> scanDetails = scanDetailsAndConfigs.getScanDetails();
194        WifiConfiguration[] savedConfigs = scanDetailsAndConfigs.getWifiConfigs();
195
196        WifiConfiguration candidate = mSavedNetworkEvaluator.evaluateNetworks(scanDetails,
197                null, null, true, false, null);
198
199        ScanResult chosenScanResult = scanDetails.get(1).getScanResult();
200        WifiConfigurationTestUtil.assertConfigurationEqual(savedConfigs[1], candidate);
201        WifiNetworkSelectorTestUtil.verifySelectedScanResult(mWifiConfigManager,
202                chosenScanResult, candidate);
203    }
204
205    /**
206     * Between two 5G networks, choose the one with stronger RSSI value if other conditions
207     * are the same and the RSSI values are not satuarted.
208     */
209    @Test
210    public void chooseStrongerRssi5GNetwork() {
211        String[] ssids = {"\"test1\"", "\"test2\""};
212        String[] bssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4"};
213        int[] freqs = {5200, 5240};
214        String[] caps = {"[WPA2-EAP-CCMP][ESS]", "[WPA2-EAP-CCMP][ESS]"};
215        int[] levels = {mThresholdQualifiedRssi5G + 8, mThresholdQualifiedRssi5G + 10};
216        int[] securities = {SECURITY_PSK, SECURITY_PSK};
217
218        ScanDetailsAndWifiConfigs scanDetailsAndConfigs =
219                WifiNetworkSelectorTestUtil.setupScanDetailsAndConfigStore(ssids, bssids,
220                    freqs, caps, levels, securities, mWifiConfigManager, mClock);
221        List<ScanDetail> scanDetails = scanDetailsAndConfigs.getScanDetails();
222        WifiConfiguration[] savedConfigs = scanDetailsAndConfigs.getWifiConfigs();
223
224        WifiConfiguration candidate = mSavedNetworkEvaluator.evaluateNetworks(scanDetails,
225                null, null, true, false, null);
226
227        ScanResult chosenScanResult = scanDetails.get(1).getScanResult();
228        WifiConfigurationTestUtil.assertConfigurationEqual(savedConfigs[1], candidate);
229        WifiNetworkSelectorTestUtil.verifySelectedScanResult(mWifiConfigManager,
230                chosenScanResult, candidate);
231    }
232
233    /**
234     * Choose secure network over open network if other conditions are the same.
235     */
236    @Test
237    public void chooseSecureNetworkOverOpenNetwork() {
238        String[] ssids = {"\"test1\"", "\"test2\""};
239        String[] bssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4"};
240        int[] freqs = {5200, 5240};
241        String[] caps = {"[ESS]", "[WPA2-EAP-CCMP][ESS]"};
242        int[] levels = {mThresholdQualifiedRssi5G, mThresholdQualifiedRssi5G};
243        int[] securities = {SECURITY_NONE, SECURITY_PSK};
244
245        ScanDetailsAndWifiConfigs scanDetailsAndConfigs =
246                WifiNetworkSelectorTestUtil.setupScanDetailsAndConfigStore(ssids, bssids,
247                    freqs, caps, levels, securities, mWifiConfigManager, mClock);
248        List<ScanDetail> scanDetails = scanDetailsAndConfigs.getScanDetails();
249        WifiConfiguration[] savedConfigs = scanDetailsAndConfigs.getWifiConfigs();
250
251        WifiConfiguration candidate = mSavedNetworkEvaluator.evaluateNetworks(scanDetails,
252                null, null, true, false, null);
253
254        ScanResult chosenScanResult = scanDetails.get(1).getScanResult();
255        WifiConfigurationTestUtil.assertConfigurationEqual(savedConfigs[1], candidate);
256        WifiNetworkSelectorTestUtil.verifySelectedScanResult(mWifiConfigManager,
257                chosenScanResult, candidate);
258    }
259
260    /**
261     * Choose 5G network over 2G network if other conditions are the same.
262     */
263    @Test
264    public void choose5GNetworkOver2GNetwork() {
265        String[] ssids = {"\"test1\"", "\"test2\""};
266        String[] bssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4"};
267        int[] freqs = {2437, 5240};
268        String[] caps = {"[WPA2-EAP-CCMP][ESS]", "[WPA2-EAP-CCMP][ESS]"};
269        int[] levels = {mThresholdQualifiedRssi2G, mThresholdQualifiedRssi5G};
270        int[] securities = {SECURITY_PSK, SECURITY_PSK};
271
272        ScanDetailsAndWifiConfigs scanDetailsAndConfigs =
273                WifiNetworkSelectorTestUtil.setupScanDetailsAndConfigStore(ssids, bssids,
274                    freqs, caps, levels, securities, mWifiConfigManager, mClock);
275        List<ScanDetail> scanDetails = scanDetailsAndConfigs.getScanDetails();
276        WifiConfiguration[] savedConfigs = scanDetailsAndConfigs.getWifiConfigs();
277
278        WifiConfiguration candidate = mSavedNetworkEvaluator.evaluateNetworks(scanDetails,
279                null, null, true, false, null);
280
281        ScanResult chosenScanResult = scanDetails.get(1).getScanResult();
282        WifiConfigurationTestUtil.assertConfigurationEqual(savedConfigs[1], candidate);
283        WifiNetworkSelectorTestUtil.verifySelectedScanResult(mWifiConfigManager,
284                chosenScanResult, candidate);
285    }
286
287    /**
288     * Verify that we stick to the currently connected network if the other one is
289     * just slightly better scored.
290     */
291    @Test
292    public void stickToCurrentNetwork() {
293        String[] ssids = {"\"test1\"", "\"test2\""};
294        String[] bssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4"};
295        int[] freqs = {5200, 5240};
296        String[] caps = {"[WPA2-EAP-CCMP][ESS]", "[WPA2-EAP-CCMP][ESS]"};
297        // test2 has slightly stronger RSSI value than test1
298        int[] levels = {mThresholdMinimumRssi5G + 2, mThresholdMinimumRssi5G + 4};
299        int[] securities = {SECURITY_PSK, SECURITY_PSK};
300
301        ScanDetailsAndWifiConfigs scanDetailsAndConfigs =
302                WifiNetworkSelectorTestUtil.setupScanDetailsAndConfigStore(ssids, bssids,
303                    freqs, caps, levels, securities, mWifiConfigManager, mClock);
304        List<ScanDetail> scanDetails = scanDetailsAndConfigs.getScanDetails();
305        WifiConfiguration[] savedConfigs = scanDetailsAndConfigs.getWifiConfigs();
306
307        // Simuluate we are connected to SSID test1 already.
308        WifiConfiguration candidate = mSavedNetworkEvaluator.evaluateNetworks(scanDetails,
309                savedConfigs[0], null, true, false, null);
310
311        // Even though test2 has higher RSSI value, test1 is chosen because of the
312        // currently connected network bonus.
313        ScanResult chosenScanResult = scanDetails.get(0).getScanResult();
314        WifiConfigurationTestUtil.assertConfigurationEqual(savedConfigs[0], candidate);
315        WifiNetworkSelectorTestUtil.verifySelectedScanResult(mWifiConfigManager,
316                chosenScanResult, candidate);
317    }
318
319    /**
320     * Verify that we stick to the currently connected BSSID if the other one is
321     * just slightly better scored.
322     */
323    @Test
324    public void stickToCurrentBSSID() {
325        // Same SSID
326        String[] ssids = {"\"test1\"", "\"test1\""};
327        String[] bssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4"};
328        int[] freqs = {5200, 5240};
329        String[] caps = {"[WPA2-EAP-CCMP][ESS]", "[WPA2-EAP-CCMP][ESS]"};
330        // test2 has slightly stronger RSSI value than test1
331        int[] levels = {mThresholdMinimumRssi5G + 2, mThresholdMinimumRssi5G + 6};
332        int[] securities = {SECURITY_PSK, SECURITY_PSK};
333
334        ScanDetailsAndWifiConfigs scanDetailsAndConfigs =
335                WifiNetworkSelectorTestUtil.setupScanDetailsAndConfigStore(ssids, bssids,
336                    freqs, caps, levels, securities, mWifiConfigManager, mClock);
337        List<ScanDetail> scanDetails = scanDetailsAndConfigs.getScanDetails();
338        WifiConfiguration[] savedConfigs = scanDetailsAndConfigs.getWifiConfigs();
339
340        // Simuluate we are connected to BSSID "6c:f3:7f:ae:8c:f3" already
341        WifiConfiguration candidate = mSavedNetworkEvaluator.evaluateNetworks(scanDetails,
342                null, bssids[0], true, false, null);
343
344        // Even though test2 has higher RSSI value, test1 is chosen because of the
345        // currently connected BSSID bonus.
346        ScanResult chosenScanResult = scanDetails.get(0).getScanResult();
347        WifiConfigurationTestUtil.assertConfigurationEqual(savedConfigs[0], candidate);
348    }
349}
350