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