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
19
20import static com.android.server.wifi.WifiConfigurationTestUtil.SECURITY_NONE;
21import static com.android.server.wifi.WifiConfigurationTestUtil.SECURITY_PSK;
22
23import static org.junit.Assert.*;
24import static org.mockito.Mockito.*;
25
26import android.content.Context;
27import android.database.ContentObserver;
28import android.net.NetworkKey;
29import android.net.NetworkScoreManager;
30import android.net.Uri;
31import android.net.wifi.ScanResult;
32import android.net.wifi.WifiConfiguration;
33import android.net.wifi.WifiNetworkScoreCache;
34import android.os.Looper;
35import android.os.SystemClock;
36import android.provider.Settings;
37import android.test.suitebuilder.annotation.SmallTest;
38import android.util.LocalLog;
39
40import com.android.server.wifi.WifiNetworkSelectorTestUtil.ScanDetailsAndWifiConfigs;
41
42import org.junit.After;
43import org.junit.Before;
44import org.junit.Test;
45import org.mockito.ArgumentCaptor;
46import org.mockito.Captor;
47import org.mockito.Mock;
48import org.mockito.MockitoAnnotations;
49
50import java.util.ArrayList;
51import java.util.List;
52
53/**
54 * Unit tests for {@link ScoredNetworkEvaluator}.
55 */
56@SmallTest
57public class ScoredNetworkEvaluatorTest {
58    private ContentObserver mContentObserver;
59    private int mThresholdQualifiedRssi2G;
60    private int mThresholdQualifiedRssi5G;
61
62    @Mock private Context mContext;
63    @Mock private Clock mClock;
64    @Mock private FrameworkFacade mFrameworkFacade;
65    @Mock private NetworkScoreManager mNetworkScoreManager;
66    @Mock private WifiConfigManager mWifiConfigManager;
67
68    @Captor private ArgumentCaptor<NetworkKey[]> mNetworkKeyArrayCaptor;
69
70    private WifiNetworkScoreCache mScoreCache;
71    private ScoredNetworkEvaluator mScoredNetworkEvaluator;
72
73    @Before
74    public void setUp() throws Exception {
75        mThresholdQualifiedRssi2G = -73;
76        mThresholdQualifiedRssi5G = -70;
77
78        MockitoAnnotations.initMocks(this);
79
80        when(mFrameworkFacade.getIntegerSetting(mContext,
81                Settings.Global.NETWORK_RECOMMENDATIONS_ENABLED, 0))
82                .thenReturn(1);
83
84        ArgumentCaptor<ContentObserver> observerCaptor =
85                ArgumentCaptor.forClass(ContentObserver.class);
86        mScoreCache = new WifiNetworkScoreCache(mContext);
87        mScoredNetworkEvaluator = new ScoredNetworkEvaluator(mContext,
88                Looper.getMainLooper(), mFrameworkFacade, mNetworkScoreManager,
89                mWifiConfigManager, new LocalLog(0), mScoreCache);
90        verify(mFrameworkFacade).registerContentObserver(eq(mContext), any(Uri.class), eq(false),
91                observerCaptor.capture());
92        mContentObserver = observerCaptor.getValue();
93
94        reset(mNetworkScoreManager);
95
96        when(mClock.getElapsedSinceBootMillis()).thenReturn(SystemClock.elapsedRealtime());
97    }
98
99    @After
100    public void tearDown() {
101        validateMockitoUsage();
102    }
103
104    @Test
105    public void testUpdate_recommendationsDisabled() {
106        String[] ssids = {"\"test1\""};
107        String[] bssids = {"6c:f3:7f:ae:8c:f3"};
108        int[] freqs = {2470};
109        String[] caps = {"[WPA2-EAP-CCMP][ESS]"};
110        int[] levels = {mThresholdQualifiedRssi2G + 8};
111        int[] securities = {SECURITY_PSK};
112
113        ScanDetailsAndWifiConfigs scanDetailsAndConfigs = WifiNetworkSelectorTestUtil
114                .setupScanDetailsAndConfigStore(
115                ssids, bssids, freqs, caps, levels, securities, mWifiConfigManager, mClock);
116
117        when(mFrameworkFacade.getIntegerSetting(mContext,
118                Settings.Global.NETWORK_RECOMMENDATIONS_ENABLED, 0))
119                .thenReturn(0);
120
121        mContentObserver.onChange(false /* unused */);
122
123        mScoredNetworkEvaluator.update(scanDetailsAndConfigs.getScanDetails());
124
125        verifyZeroInteractions(mNetworkScoreManager);
126    }
127
128    @Test
129    public void testUpdate_emptyScanList() {
130        String[] ssids = {"\"test1\""};
131        String[] bssids = {"6c:f3:7f:ae:8c:f3"};
132        int[] freqs = {2470};
133        String[] caps = {"[WPA2-EAP-CCMP][ESS]"};
134        int[] levels = {mThresholdQualifiedRssi2G + 8};
135        int[] securities = {SECURITY_PSK};
136
137        ScanDetailsAndWifiConfigs scanDetailsAndConfigs = WifiNetworkSelectorTestUtil
138                .setupScanDetailsAndConfigStore(
139                        ssids, bssids, freqs, caps, levels, securities, mWifiConfigManager, mClock);
140
141        mScoredNetworkEvaluator.update(new ArrayList<ScanDetail>());
142
143        verifyZeroInteractions(mNetworkScoreManager);
144    }
145
146    @Test
147    public void testUpdate_allNetworksUnscored() {
148        String[] ssids = {"\"test1\"", "\"test2\""};
149        String[] bssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4"};
150        int[] freqs = {2470, 2437};
151        String[] caps = {"[WPA2-EAP-CCMP][ESS]", "[ESS]"};
152        int[] securities = {SECURITY_PSK, SECURITY_NONE};
153        int[] levels = {mThresholdQualifiedRssi2G + 8, mThresholdQualifiedRssi2G + 10};
154
155        ScanDetailsAndWifiConfigs scanDetailsAndConfigs = WifiNetworkSelectorTestUtil
156                .setupScanDetailsAndConfigStore(
157                        ssids, bssids, freqs, caps, levels, securities, mWifiConfigManager, mClock);
158
159        mScoredNetworkEvaluator.update(scanDetailsAndConfigs.getScanDetails());
160
161        verify(mNetworkScoreManager).requestScores(mNetworkKeyArrayCaptor.capture());
162        assertEquals(2, mNetworkKeyArrayCaptor.getValue().length);
163        NetworkKey expectedNetworkKey = NetworkKey.createFromScanResult(
164                scanDetailsAndConfigs.getScanDetails().get(0).getScanResult());
165        assertEquals(expectedNetworkKey, mNetworkKeyArrayCaptor.getValue()[0]);
166        expectedNetworkKey = NetworkKey.createFromScanResult(
167                scanDetailsAndConfigs.getScanDetails().get(1).getScanResult());
168        assertEquals(expectedNetworkKey, mNetworkKeyArrayCaptor.getValue()[1]);
169    }
170
171    @Test
172    public void testUpdate_oneScored_oneUnscored() {
173        String[] ssids = {"\"test1\"", "\"test2\""};
174        String[] bssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4"};
175        int[] freqs = {2470, 2437};
176        String[] caps = {"[WPA2-EAP-CCMP][ESS]", "[ESS]"};
177        int[] securities = {SECURITY_PSK, SECURITY_NONE};
178        int[] levels = {mThresholdQualifiedRssi2G + 8, mThresholdQualifiedRssi2G + 10};
179
180        ScanDetailsAndWifiConfigs scanDetailsAndConfigs = WifiNetworkSelectorTestUtil
181                .setupScanDetailsAndConfigStore(
182                        ssids, bssids, freqs, caps, levels, securities, mWifiConfigManager, mClock);
183
184        List<ScanDetail> scoredScanDetails = scanDetailsAndConfigs.getScanDetails().subList(0, 1);
185        Integer[] scores = {120};
186        boolean[] meteredHints = {true};
187        WifiNetworkSelectorTestUtil.configureScoreCache(
188                mScoreCache, scoredScanDetails, scores, meteredHints);
189
190        mScoredNetworkEvaluator.update(scanDetailsAndConfigs.getScanDetails());
191
192        verify(mNetworkScoreManager).requestScores(mNetworkKeyArrayCaptor.capture());
193
194        NetworkKey[] requestedScores = mNetworkKeyArrayCaptor.getValue();
195        assertEquals(1, requestedScores.length);
196        NetworkKey expectedNetworkKey = NetworkKey.createFromScanResult(
197                scanDetailsAndConfigs.getScanDetails().get(1).getScanResult());
198        assertEquals(expectedNetworkKey, requestedScores[0]);
199    }
200
201    @Test
202    public void testEvaluateNetworks_recommendationsDisabled() {
203        when(mFrameworkFacade.getIntegerSetting(mContext,
204                Settings.Global.NETWORK_RECOMMENDATIONS_ENABLED, 0))
205                .thenReturn(0);
206
207        mContentObserver.onChange(false /* unused */);
208
209        mScoredNetworkEvaluator.evaluateNetworks(null, null, null, false, false, null);
210
211        verifyZeroInteractions(mWifiConfigManager, mNetworkScoreManager);
212    }
213
214    /**
215     * When no saved networks available, choose the available ephemeral networks
216     * if untrusted networks are allowed.
217     */
218    @Test
219    public void testEvaluateNetworks_chooseEphemeralNetworkBecauseOfNoSavedNetwork() {
220        String[] ssids = {"\"test1\"", "\"test2\""};
221        String[] bssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4"};
222        int[] freqs = {2470, 2437};
223        String[] caps = {"[WPA2-EAP-CCMP][ESS]", "[ESS]"};
224        int[] levels = {mThresholdQualifiedRssi2G + 8, mThresholdQualifiedRssi2G + 10};
225        Integer[] scores = {null, 120};
226        boolean[] meteredHints = {false, true};
227
228        List<ScanDetail> scanDetails = WifiNetworkSelectorTestUtil.buildScanDetails(
229                ssids, bssids, freqs, caps, levels, mClock);
230        WifiNetworkSelectorTestUtil.configureScoreCache(mScoreCache,
231                scanDetails, scores, meteredHints);
232
233        // No saved networks.
234        when(mWifiConfigManager.getSavedNetworkForScanDetailAndCache(any(ScanDetail.class)))
235                .thenReturn(null);
236
237        ScanResult scanResult = scanDetails.get(1).getScanResult();
238        WifiConfiguration ephemeralNetworkConfig = WifiNetworkSelectorTestUtil
239                .setupEphemeralNetwork(mWifiConfigManager, 1, scanDetails.get(1), meteredHints[1]);
240
241        // Untrusted networks allowed.
242        WifiConfiguration candidate = mScoredNetworkEvaluator.evaluateNetworks(scanDetails,
243                null, null, false, true, null);
244
245        WifiConfigurationTestUtil.assertConfigurationEqual(ephemeralNetworkConfig, candidate);
246        WifiNetworkSelectorTestUtil.verifySelectedScanResult(mWifiConfigManager,
247                scanResult, candidate);
248        assertEquals(meteredHints[1], candidate.meteredHint);
249    }
250
251    /**
252     * When no saved networks available, choose the highest scored ephemeral networks
253     * if untrusted networks are allowed.
254     */
255    @Test
256    public void testEvaluateNetworks_chooseHigherScoredEphemeralNetwork() {
257        String[] ssids = {"\"test1\"", "\"test2\""};
258        String[] bssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4"};
259        int[] freqs = {2470, 2437};
260        String[] caps = {"[ESS]", "[ESS]"};
261        int[] levels = {mThresholdQualifiedRssi2G + 8, mThresholdQualifiedRssi2G + 8};
262        Integer[] scores = {100, 120};
263        boolean[] meteredHints = {true, true};
264        ScanResult[] scanResults = new ScanResult[2];
265        WifiConfiguration[] ephemeralNetworkConfigs = new WifiConfiguration[2];
266
267        List<ScanDetail> scanDetails = WifiNetworkSelectorTestUtil.buildScanDetails(
268                ssids, bssids, freqs, caps, levels, mClock);
269        WifiNetworkSelectorTestUtil.configureScoreCache(mScoreCache,
270                scanDetails, scores, meteredHints);
271
272        // No saved networks.
273        when(mWifiConfigManager.getSavedNetworkForScanDetailAndCache(any(ScanDetail.class)))
274                .thenReturn(null);
275
276        for (int i = 0; i < 2; i++) {
277            scanResults[i] = scanDetails.get(i).getScanResult();
278            ephemeralNetworkConfigs[i] = WifiNetworkSelectorTestUtil.setupEphemeralNetwork(
279                    mWifiConfigManager, i, scanDetails.get(i), meteredHints[i]);
280        }
281
282        WifiConfiguration candidate = mScoredNetworkEvaluator.evaluateNetworks(scanDetails,
283                null, null, false, true, null);
284
285        WifiConfigurationTestUtil.assertConfigurationEqual(ephemeralNetworkConfigs[1], candidate);
286        WifiNetworkSelectorTestUtil.verifySelectedScanResult(mWifiConfigManager,
287                scanResults[1], candidate);
288        assertEquals(meteredHints[1], candidate.meteredHint);
289    }
290
291    /**
292     * Don't choose available ephemeral networks if no saved networks and untrusted networks
293     * are not allowed.
294     */
295    @Test
296    public void testEvaluateNetworks_noEphemeralNetworkWhenUntrustedNetworksNotAllowed() {
297        String[] ssids = {"\"test1\"", "\"test2\""};
298        String[] bssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4"};
299        int[] freqs = {2470, 2437};
300        String[] caps = {"[WPA2-EAP-CCMP][ESS]", "[ESS]"};
301        int[] levels = {mThresholdQualifiedRssi2G + 8, mThresholdQualifiedRssi2G + 10};
302        Integer[] scores = {null, 120};
303        boolean[] meteredHints = {false, true};
304
305        List<ScanDetail> scanDetails = WifiNetworkSelectorTestUtil.buildScanDetails(
306                ssids, bssids, freqs, caps, levels, mClock);
307        WifiNetworkSelectorTestUtil.configureScoreCache(mScoreCache,
308                scanDetails, scores, meteredHints);
309
310        // No saved networks.
311        when(mWifiConfigManager.getSavedNetworkForScanDetailAndCache(any(ScanDetail.class)))
312                .thenReturn(null);
313
314        WifiNetworkSelectorTestUtil.setupEphemeralNetwork(
315                mWifiConfigManager, 1, scanDetails.get(1), meteredHints[1]);
316
317        // Untrusted networks not allowed.
318        WifiConfiguration candidate = mScoredNetworkEvaluator.evaluateNetworks(scanDetails,
319                null, null, false, false, null);
320
321        assertEquals("Expect null configuration", null, candidate);
322    }
323
324    /**
325     * Choose externally scored saved network.
326     */
327    @Test
328    public void testEvaluateNetworks_chooseSavedNetworkWithExternalScore() {
329        String[] ssids = {"\"test1\""};
330        String[] bssids = {"6c:f3:7f:ae:8c:f3"};
331        int[] freqs = {5200};
332        String[] caps = {"[WPA2-EAP-CCMP][ESS]"};
333        int[] securities = {SECURITY_PSK};
334        int[] levels = {mThresholdQualifiedRssi5G + 8};
335        Integer[] scores = {120};
336        boolean[] meteredHints = {false};
337
338        WifiNetworkSelectorTestUtil.ScanDetailsAndWifiConfigs scanDetailsAndConfigs =
339                WifiNetworkSelectorTestUtil.setupScanDetailsAndConfigStore(ssids, bssids,
340                        freqs, caps, levels, securities, mWifiConfigManager, mClock);
341        List<ScanDetail> scanDetails = scanDetailsAndConfigs.getScanDetails();
342        WifiConfiguration[] savedConfigs = scanDetailsAndConfigs.getWifiConfigs();
343        savedConfigs[0].useExternalScores = true;
344
345        WifiNetworkSelectorTestUtil.configureScoreCache(mScoreCache,
346                scanDetails, scores, meteredHints);
347
348        WifiConfiguration candidate = mScoredNetworkEvaluator.evaluateNetworks(scanDetails,
349                null, null, false, true, null);
350
351        WifiConfigurationTestUtil.assertConfigurationEqual(savedConfigs[0], candidate);
352        WifiNetworkSelectorTestUtil.verifySelectedScanResult(mWifiConfigManager,
353                scanDetails.get(0).getScanResult(), candidate);
354    }
355
356    /**
357     * Choose externally scored saved network with higher score.
358     */
359    @Test
360    public void testEvaluateNetworks_chooseSavedNetworkWithHigherExternalScore() {
361        String[] ssids = {"\"test1\"", "\"test2\""};
362        String[] bssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4"};
363        int[] freqs = {2470, 2437};
364        String[] caps = {"[WPA2-EAP-CCMP][ESS]", "[WPA2-EAP-CCMP][ESS]"};
365        int[] securities = {SECURITY_PSK, SECURITY_PSK};
366        int[] levels = {mThresholdQualifiedRssi2G + 8, mThresholdQualifiedRssi2G + 8};
367        Integer[] scores = {100, 120};
368        boolean[] meteredHints = {false, false};
369
370        WifiNetworkSelectorTestUtil.ScanDetailsAndWifiConfigs scanDetailsAndConfigs =
371                WifiNetworkSelectorTestUtil.setupScanDetailsAndConfigStore(ssids, bssids,
372                        freqs, caps, levels, securities, mWifiConfigManager, mClock);
373        List<ScanDetail> scanDetails = scanDetailsAndConfigs.getScanDetails();
374        WifiConfiguration[] savedConfigs = scanDetailsAndConfigs.getWifiConfigs();
375        savedConfigs[0].useExternalScores = savedConfigs[1].useExternalScores = true;
376
377        WifiNetworkSelectorTestUtil.configureScoreCache(mScoreCache,
378                scanDetails, scores, meteredHints);
379
380        WifiConfiguration candidate = mScoredNetworkEvaluator.evaluateNetworks(scanDetails,
381                null, null, false, true, null);
382
383        WifiConfigurationTestUtil.assertConfigurationEqual(savedConfigs[1], candidate);
384        WifiNetworkSelectorTestUtil.verifySelectedScanResult(mWifiConfigManager,
385                scanDetails.get(1).getScanResult(), candidate);
386    }
387
388    /**
389     * Prefer externally scored saved network over untrusted network when they have
390     * the same score.
391     */
392    @Test
393    public void testEvaluateNetworks_chooseExternallyScoredOverUntrustedNetworksWithSameScore() {
394        String[] ssids = {"\"test1\"", "\"test2\""};
395        String[] bssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4"};
396        int[] freqs = {2470, 2437};
397        String[] caps = {"[WPA2-EAP-CCMP][ESS]", "[ESS]"};
398        int[] securities = {SECURITY_PSK, SECURITY_NONE};
399        int[] levels = {mThresholdQualifiedRssi2G + 8, mThresholdQualifiedRssi2G + 8};
400        Integer[] scores = {120, 120};
401        boolean[] meteredHints = {false, true};
402
403        WifiNetworkSelectorTestUtil.ScanDetailsAndWifiConfigs scanDetailsAndConfigs =
404                WifiNetworkSelectorTestUtil.setupScanDetailsAndConfigStore(ssids, bssids,
405                        freqs, caps, levels, securities, mWifiConfigManager, mClock);
406        List<ScanDetail> scanDetails = scanDetailsAndConfigs.getScanDetails();
407        WifiConfiguration[] savedConfigs = scanDetailsAndConfigs.getWifiConfigs();
408        savedConfigs[0].useExternalScores = true;
409
410        WifiNetworkSelectorTestUtil.configureScoreCache(mScoreCache,
411                scanDetails, scores, meteredHints);
412
413        WifiConfiguration candidate = mScoredNetworkEvaluator.evaluateNetworks(scanDetails,
414                null, null, false, true, null);
415
416        WifiConfigurationTestUtil.assertConfigurationEqual(savedConfigs[0], candidate);
417        WifiNetworkSelectorTestUtil.verifySelectedScanResult(mWifiConfigManager,
418                scanDetails.get(0).getScanResult(), candidate);
419    }
420
421    /**
422     * Choose untrusted network when it has higher score than the externally scored
423     * saved network.
424     */
425    @Test
426    public void testEvaluateNetworks_chooseUntrustedWithHigherScoreThanExternallyScoredNetwork() {
427        // Saved network.
428        String[] savedSsids = {"\"test1\""};
429        String[] savedBssids = {"6c:f3:7f:ae:8c:f3"};
430        int[] savedFreqs = {2470};
431        String[] savedCaps = {"[WPA2-EAP-CCMP][ESS]"};
432        int[] savedSecurities = {SECURITY_PSK};
433        int[] savedLevels = {mThresholdQualifiedRssi2G + 8};
434        // Ephemeral network.
435        String[] ephemeralSsids = {"\"test2\""};
436        String[] ephemeralBssids = {"6c:f3:7f:ae:8c:f4"};
437        int[] ephemeralFreqs = {2437};
438        String[] ephemeralCaps = {"[ESS]"};
439        int[] ephemeralLevels = {mThresholdQualifiedRssi2G + 8};
440        // Ephemeral network has higher score than the saved network.
441        Integer[] scores = {100, 120};
442        boolean[] meteredHints = {false, true};
443
444        // Set up the saved network.
445        WifiNetworkSelectorTestUtil.ScanDetailsAndWifiConfigs scanDetailsAndConfigs =
446                WifiNetworkSelectorTestUtil.setupScanDetailsAndConfigStore(savedSsids,
447                        savedBssids, savedFreqs, savedCaps, savedLevels, savedSecurities,
448                        mWifiConfigManager, mClock);
449        List<ScanDetail> scanDetails = scanDetailsAndConfigs.getScanDetails();
450        WifiConfiguration[] savedConfigs = scanDetailsAndConfigs.getWifiConfigs();
451        savedConfigs[0].useExternalScores = true;
452
453        // Set up the ephemeral network.
454        scanDetails.addAll(WifiNetworkSelectorTestUtil.buildScanDetails(
455                ephemeralSsids, ephemeralBssids, ephemeralFreqs,
456                ephemeralCaps, ephemeralLevels, mClock));
457        ScanResult ephemeralScanResult = scanDetails.get(1).getScanResult();
458        WifiConfiguration ephemeralNetworkConfig = WifiNetworkSelectorTestUtil
459                .setupEphemeralNetwork(mWifiConfigManager, 1, scanDetails.get(1),
460                        meteredHints[1]);
461
462        // Set up score cache for both the saved network and the ephemeral network.
463        WifiNetworkSelectorTestUtil.configureScoreCache(mScoreCache,
464                scanDetails, scores, meteredHints);
465
466        WifiConfiguration candidate = mScoredNetworkEvaluator.evaluateNetworks(scanDetails,
467                null, null, false, true, null);
468
469        WifiConfigurationTestUtil.assertConfigurationEqual(ephemeralNetworkConfig, candidate);
470        WifiNetworkSelectorTestUtil.verifySelectedScanResult(mWifiConfigManager,
471                ephemeralScanResult, candidate);
472    }
473
474    /**
475     * Prefer externally scored saved network over untrusted network when they have
476     * the same score.
477     */
478    @Test
479    public void testEvaluateNetworks_nullScoredNetworks() {
480        String[] ssids = {"\"test1\"", "\"test2\""};
481        String[] bssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4"};
482        int[] freqs = {2470, 2437};
483        String[] caps = {"[WPA2-EAP-CCMP][ESS]", "[ESS]"};
484        int[] securities = {SECURITY_PSK, SECURITY_NONE};
485        int[] levels = {mThresholdQualifiedRssi2G + 8, mThresholdQualifiedRssi2G + 8};
486        Integer[] scores = {null, null};
487        boolean[] meteredHints = {false, true};
488
489        WifiNetworkSelectorTestUtil.ScanDetailsAndWifiConfigs scanDetailsAndConfigs =
490                WifiNetworkSelectorTestUtil.setupScanDetailsAndConfigStore(ssids, bssids,
491                        freqs, caps, levels, securities, mWifiConfigManager, mClock);
492        List<ScanDetail> scanDetails = scanDetailsAndConfigs.getScanDetails();
493        WifiConfiguration[] savedConfigs = scanDetailsAndConfigs.getWifiConfigs();
494        savedConfigs[0].useExternalScores = true;
495
496        WifiNetworkSelectorTestUtil.configureScoreCache(mScoreCache,
497                scanDetails, scores, meteredHints);
498
499        WifiConfiguration candidate = mScoredNetworkEvaluator.evaluateNetworks(scanDetails,
500                null, null, false, true, null);
501
502        assertEquals("Expect null configuration", null, candidate);
503    }
504
505    /**
506     * Between two ephemeral networks with the same RSSI, choose
507     * the currently connected one.
508     */
509    @Test
510    public void testEvaluateNetworks_chooseActiveEphemeralNetwork() {
511        String[] ssids = {"\"test1\"", "\"test2\""};
512        String[] bssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4"};
513        int[] freqs = {2470, 2437};
514        String[] caps = {"[ESS]", "[ESS]"};
515        int[] levels = {mThresholdQualifiedRssi2G + 28, mThresholdQualifiedRssi2G + 28};
516        boolean[] meteredHints = {true, true};
517        ScanResult[] scanResults = new ScanResult[2];
518        WifiConfiguration[] ephemeralNetworkConfigs = new WifiConfiguration[2];
519
520        List<ScanDetail> scanDetails = WifiNetworkSelectorTestUtil
521                .buildScanDetails(ssids, bssids, freqs, caps, levels, mClock);
522
523        WifiNetworkSelectorTestUtil.configureScoreCache(
524                mScoreCache, scanDetails, null, meteredHints);
525
526        // No saved networks.
527        when(mWifiConfigManager.getSavedNetworkForScanDetailAndCache(any(ScanDetail.class)))
528                .thenReturn(null);
529
530        for (int i = 0; i < 2; i++) {
531            scanResults[i] = scanDetails.get(i).getScanResult();
532            ephemeralNetworkConfigs[i] = WifiNetworkSelectorTestUtil.setupEphemeralNetwork(
533                    mWifiConfigManager, i, scanDetails.get(i), meteredHints[i]);
534        }
535
536        WifiConfiguration candidate = mScoredNetworkEvaluator.evaluateNetworks(
537                scanDetails, ephemeralNetworkConfigs[1],
538                bssids[1], true, true, null);
539
540        WifiConfigurationTestUtil.assertConfigurationEqual(ephemeralNetworkConfigs[1], candidate);
541        WifiNetworkSelectorTestUtil.verifySelectedScanResult(mWifiConfigManager,
542                scanResults[1], candidate);
543        assertEquals(meteredHints[1], candidate.meteredHint);
544    }
545
546    /**
547     *  Between two externally scored saved networks with the same RSSI, choose
548     *  the currently connected one.
549     */
550    @Test
551    public void testEvaluateNetworks_chooseActiveSavedNetwork() {
552        String[] ssids = {"\"test1\"", "\"test2\""};
553        String[] bssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4"};
554        int[] freqs = {2470, 2437};
555        String[] caps = {"[WPA2-EAP-CCMP][ESS]", "[WPA2-EAP-CCMP][ESS]"};
556        int[] securities = {SECURITY_PSK, SECURITY_PSK};
557        int[] levels = {mThresholdQualifiedRssi2G + 28, mThresholdQualifiedRssi2G + 28};
558        boolean[] meteredHints = {false, false};
559
560        WifiNetworkSelectorTestUtil.ScanDetailsAndWifiConfigs scanDetailsAndConfigs =
561                WifiNetworkSelectorTestUtil.setupScanDetailsAndConfigStore(ssids, bssids,
562                        freqs, caps, levels, securities, mWifiConfigManager, mClock);
563        List<ScanDetail> scanDetails = scanDetailsAndConfigs.getScanDetails();
564        WifiConfiguration[] savedConfigs = scanDetailsAndConfigs.getWifiConfigs();
565        savedConfigs[0].useExternalScores = savedConfigs[1].useExternalScores = true;
566
567        WifiNetworkSelectorTestUtil.configureScoreCache(mScoreCache,
568                scanDetails, null, meteredHints);
569
570        WifiConfiguration candidate = mScoredNetworkEvaluator.evaluateNetworks(scanDetails,
571                savedConfigs[1], bssids[1], true, true, null);
572
573        WifiConfigurationTestUtil.assertConfigurationEqual(savedConfigs[1], candidate);
574        WifiNetworkSelectorTestUtil.verifySelectedScanResult(mWifiConfigManager,
575                scanDetails.get(1).getScanResult(), candidate);
576    }
577}
578