AccessPointTest.java revision 6390fa836e4c345240e37e360f2b52f3d6c9a77a
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 */
16package com.android.settingslib.wifi;
17
18import static com.google.common.truth.Truth.assertThat;
19import static com.google.common.truth.Truth.assertWithMessage;
20
21import static org.mockito.Mockito.any;
22import static org.mockito.Mockito.anyInt;
23import static org.mockito.Mockito.mock;
24import static org.mockito.Mockito.never;
25import static org.mockito.Mockito.times;
26import static org.mockito.Mockito.verify;
27import static org.mockito.Mockito.when;
28
29import android.content.Context;
30import android.net.ConnectivityManager;
31import android.net.NetworkInfo;
32import android.net.NetworkKey;
33import android.net.RssiCurve;
34import android.net.ScoredNetwork;
35import android.net.WifiKey;
36import android.net.wifi.ScanResult;
37import android.net.wifi.WifiConfiguration;
38import android.net.wifi.WifiEnterpriseConfig;
39import android.net.wifi.WifiInfo;
40import android.net.wifi.WifiNetworkScoreCache;
41import android.net.wifi.WifiSsid;
42import android.net.wifi.hotspot2.PasspointConfiguration;
43import android.net.wifi.hotspot2.pps.HomeSp;
44import android.os.Bundle;
45import android.os.SystemClock;
46import android.support.test.InstrumentationRegistry;
47import android.support.test.filters.SmallTest;
48import android.support.test.runner.AndroidJUnit4;
49import android.text.SpannableString;
50import android.text.style.TtsSpan;
51
52import com.android.settingslib.R;
53
54import com.android.settingslib.wifi.AccessPoint.Speed;
55import org.junit.Before;
56import org.junit.Test;
57import org.junit.runner.RunWith;
58import org.mockito.Mock;
59import org.mockito.MockitoAnnotations;
60
61import java.util.ArrayList;
62import java.util.Collections;
63
64@SmallTest
65@RunWith(AndroidJUnit4.class)
66public class AccessPointTest {
67
68    private static final String TEST_SSID = "test_ssid";
69    private static final int NUM_SCAN_RESULTS = 5;
70
71    private static final ArrayList<ScanResult> SCAN_RESULTS = buildScanResultCache();
72
73    private Context mContext;
74    @Mock private RssiCurve mockBadgeCurve;
75    @Mock private WifiNetworkScoreCache mockWifiNetworkScoreCache;
76
77    private static ScanResult createScanResult(String ssid, String bssid, int rssi) {
78        ScanResult scanResult = new ScanResult();
79        scanResult.SSID = ssid;
80        scanResult.level = rssi;
81        scanResult.BSSID = bssid;
82        scanResult.timestamp = SystemClock.elapsedRealtime() * 1000;
83        scanResult.capabilities = "";
84        return scanResult;
85    }
86
87    @Before
88    public void setUp() {
89        MockitoAnnotations.initMocks(this);
90        mContext = InstrumentationRegistry.getTargetContext();
91        WifiTracker.sVerboseLogging = false;
92    }
93
94    @Test
95    public void testSsidIsTelephoneSpan() {
96        final Bundle bundle = new Bundle();
97        bundle.putString("key_ssid", TEST_SSID);
98        final AccessPoint ap = new AccessPoint(InstrumentationRegistry.getTargetContext(), bundle);
99        final CharSequence ssid = ap.getSsid();
100
101        assertThat(ssid instanceof SpannableString).isTrue();
102
103        TtsSpan[] spans = ((SpannableString) ssid).getSpans(0, TEST_SSID.length(), TtsSpan.class);
104
105        assertThat(spans.length).isEqualTo(1);
106        assertThat(spans[0].getType()).isEqualTo(TtsSpan.TYPE_TELEPHONE);
107    }
108
109    @Test
110    public void testCopyAccessPoint_dataShouldMatch() {
111        WifiConfiguration configuration = createWifiConfiguration();
112        configuration.meteredHint = true;
113
114        NetworkInfo networkInfo =
115                new NetworkInfo(ConnectivityManager.TYPE_WIFI, 2, "WIFI", "WIFI_SUBTYPE");
116        AccessPoint originalAccessPoint = new AccessPoint(mContext, configuration);
117        WifiInfo wifiInfo = new WifiInfo();
118        wifiInfo.setSSID(WifiSsid.createFromAsciiEncoded(configuration.SSID));
119        wifiInfo.setBSSID(configuration.BSSID);
120        originalAccessPoint.update(configuration, wifiInfo, networkInfo);
121        AccessPoint copy = new AccessPoint(mContext, originalAccessPoint);
122
123        assertThat(originalAccessPoint.getSsid().toString()).isEqualTo(copy.getSsid().toString());
124        assertThat(originalAccessPoint.getBssid()).isEqualTo(copy.getBssid());
125        assertThat(originalAccessPoint.getConfig()).isEqualTo(copy.getConfig());
126        assertThat(originalAccessPoint.getSecurity()).isEqualTo(copy.getSecurity());
127        assertThat(originalAccessPoint.isMetered()).isEqualTo(copy.isMetered());
128        assertThat(originalAccessPoint.compareTo(copy) == 0).isTrue();
129    }
130
131    @Test
132    public void testThatCopyAccessPoint_scanCacheShouldMatch() {
133        AccessPoint original = createAccessPointWithScanResultCache();
134        assertThat(original.getRssi()).isEqualTo(4);
135        AccessPoint copy = new AccessPoint(mContext, createWifiConfiguration());
136        assertThat(copy.getRssi()).isEqualTo(AccessPoint.UNREACHABLE_RSSI);
137        copy.copyFrom(original);
138        assertThat(original.getRssi()).isEqualTo(copy.getRssi());
139    }
140
141    @Test
142    public void testCompareTo_GivesActiveBeforeInactive() {
143        AccessPoint activeAp = new TestAccessPointBuilder(mContext).setActive(true).build();
144        AccessPoint inactiveAp = new TestAccessPointBuilder(mContext).setActive(false).build();
145
146        assertSortingWorks(activeAp, inactiveAp);
147    }
148
149    @Test
150    public void testCompareTo_GivesReachableBeforeUnreachable() {
151        AccessPoint nearAp = new TestAccessPointBuilder(mContext).setReachable(true).build();
152        AccessPoint farAp = new TestAccessPointBuilder(mContext).setReachable(false).build();
153
154        assertSortingWorks(nearAp, farAp);
155    }
156
157    @Test
158    public void testCompareTo_GivesSavedBeforeUnsaved() {
159        AccessPoint savedAp = new TestAccessPointBuilder(mContext).setSaved(true).build();
160        AccessPoint notSavedAp = new TestAccessPointBuilder(mContext).setSaved(false).build();
161
162        assertSortingWorks(savedAp, notSavedAp);
163    }
164
165    @Test
166    public void testCompareTo_GivesHighSpeedBeforeLowSpeed() {
167        AccessPoint fastAp = new TestAccessPointBuilder(mContext).setSpeed(Speed.FAST).build();
168        AccessPoint slowAp = new TestAccessPointBuilder(mContext).setSpeed(Speed.SLOW).build();
169
170        assertSortingWorks(fastAp, slowAp);
171    }
172
173    @Test
174    public void testCompareTo_GivesHighLevelBeforeLowLevel() {
175        final int highLevel = AccessPoint.SIGNAL_LEVELS - 1;
176        final int lowLevel = 1;
177        assertThat(highLevel).isGreaterThan(lowLevel);
178
179        AccessPoint strongAp = new TestAccessPointBuilder(mContext).setLevel(highLevel).build();
180        AccessPoint weakAp = new TestAccessPointBuilder(mContext).setLevel(lowLevel).build();
181
182        assertSortingWorks(strongAp, weakAp);
183    }
184
185    @Test
186    public void testCompareTo_GivesSsidAlphabetically() {
187
188        final String firstName = "AAAAAA";
189        final String secondName = "zzzzzz";
190
191        AccessPoint firstAp = new TestAccessPointBuilder(mContext).setSsid(firstName).build();
192        AccessPoint secondAp = new TestAccessPointBuilder(mContext).setSsid(secondName).build();
193
194        assertThat(firstAp.getSsidStr().compareToIgnoreCase(secondAp.getSsidStr()) < 0).isTrue();
195        assertSortingWorks(firstAp, secondAp);
196    }
197
198    @Test
199    public void testCompareTo_GivesSsidCasePrecendenceAfterAlphabetical() {
200
201        final String firstName = "aaAaaa";
202        final String secondName = "aaaaaa";
203        final String thirdName = "BBBBBB";
204
205        AccessPoint firstAp = new TestAccessPointBuilder(mContext).setSsid(firstName).build();
206        AccessPoint secondAp = new TestAccessPointBuilder(mContext).setSsid(secondName).build();
207        AccessPoint thirdAp = new TestAccessPointBuilder(mContext).setSsid(thirdName).build();
208
209        assertSortingWorks(firstAp, secondAp);
210        assertSortingWorks(secondAp, thirdAp);
211    }
212
213    @Test
214    public void testCompareTo_AllSortingRulesCombined() {
215
216        AccessPoint active = new TestAccessPointBuilder(mContext).setActive(true).build();
217        AccessPoint reachableAndMinLevel = new TestAccessPointBuilder(mContext)
218                .setReachable(true).build();
219        AccessPoint saved = new TestAccessPointBuilder(mContext).setSaved(true).build();
220        AccessPoint highLevelAndReachable = new TestAccessPointBuilder(mContext)
221                .setLevel(AccessPoint.SIGNAL_LEVELS - 1).build();
222        AccessPoint firstName = new TestAccessPointBuilder(mContext).setSsid("a").build();
223        AccessPoint lastname = new TestAccessPointBuilder(mContext).setSsid("z").build();
224
225        ArrayList<AccessPoint> points = new ArrayList<AccessPoint>();
226        points.add(lastname);
227        points.add(firstName);
228        points.add(highLevelAndReachable);
229        points.add(saved);
230        points.add(reachableAndMinLevel);
231        points.add(active);
232
233        Collections.sort(points);
234        assertThat(points.indexOf(active)).isLessThan(points.indexOf(reachableAndMinLevel));
235        assertThat(points.indexOf(reachableAndMinLevel)).isLessThan(points.indexOf(saved));
236        // note: the saved AP will not appear before highLevelAndReachable,
237        // because all APs with a signal level are reachable,
238        // and isReachable() takes higher sorting precedence than isSaved().
239        assertThat(points.indexOf(saved)).isLessThan(points.indexOf(firstName));
240        assertThat(points.indexOf(highLevelAndReachable)).isLessThan(points.indexOf(firstName));
241        assertThat(points.indexOf(firstName)).isLessThan(points.indexOf(lastname));
242    }
243
244    @Test
245    public void testRssiIsSetFromScanResults() {
246        AccessPoint ap = createAccessPointWithScanResultCache();
247        int originalRssi = ap.getRssi();
248        assertThat(originalRssi).isNotEqualTo(AccessPoint.UNREACHABLE_RSSI);
249    }
250
251    @Test
252    public void testGetRssiShouldReturnSetRssiValue() {
253        AccessPoint ap = createAccessPointWithScanResultCache();
254        int originalRssi = ap.getRssi();
255        int newRssi = originalRssi - 10;
256        ap.setRssi(newRssi);
257        assertThat(ap.getRssi()).isEqualTo(newRssi);
258    }
259
260    @Test
261    public void testUpdateWithScanResultShouldAverageRssi() {
262        String ssid = "ssid";
263        int originalRssi = -65;
264        int newRssi = -80;
265        int expectedRssi = (originalRssi + newRssi) / 2;
266        AccessPoint ap =
267                new TestAccessPointBuilder(mContext).setSsid(ssid).setRssi(originalRssi).build();
268
269        ScanResult scanResult = new ScanResult();
270        scanResult.SSID = ssid;
271        scanResult.level = newRssi;
272        scanResult.BSSID = "bssid";
273        scanResult.timestamp = SystemClock.elapsedRealtime() * 1000;
274        scanResult.capabilities = "";
275        assertThat(ap.update(scanResult, true /* evict old scan results */)).isTrue();
276
277        assertThat(ap.getRssi()).isEqualTo(expectedRssi);
278    }
279
280    @Test
281    public void testCreateFromPasspointConfig() {
282        PasspointConfiguration config = new PasspointConfiguration();
283        HomeSp homeSp = new HomeSp();
284        homeSp.setFqdn("test.com");
285        homeSp.setFriendlyName("Test Provider");
286        config.setHomeSp(homeSp);
287        AccessPoint ap = new AccessPoint(mContext, config);
288        assertThat(ap.isPasspointConfig()).isTrue();
289    }
290
291    @Test
292    public void testIsMetered_returnTrueWhenWifiConfigurationIsMetered() {
293        WifiConfiguration configuration = createWifiConfiguration();
294        configuration.meteredHint = true;
295
296        NetworkInfo networkInfo =
297                new NetworkInfo(ConnectivityManager.TYPE_WIFI, 2, "WIFI", "WIFI_SUBTYPE");
298        AccessPoint accessPoint = new AccessPoint(mContext, configuration);
299        WifiInfo wifiInfo = new WifiInfo();
300        wifiInfo.setSSID(WifiSsid.createFromAsciiEncoded(configuration.SSID));
301        wifiInfo.setBSSID(configuration.BSSID);
302        wifiInfo.setNetworkId(configuration.networkId);
303        accessPoint.update(configuration, wifiInfo, networkInfo);
304
305        assertThat(accessPoint.isMetered()).isTrue();
306    }
307
308    @Test
309    public void testIsMetered_returnTrueWhenWifiInfoIsMetered() {
310        WifiConfiguration configuration = createWifiConfiguration();
311
312        NetworkInfo networkInfo =
313                new NetworkInfo(ConnectivityManager.TYPE_WIFI, 2, "WIFI", "WIFI_SUBTYPE");
314        AccessPoint accessPoint = new AccessPoint(mContext, configuration);
315        WifiInfo wifiInfo = new WifiInfo();
316        wifiInfo.setSSID(WifiSsid.createFromAsciiEncoded(configuration.SSID));
317        wifiInfo.setBSSID(configuration.BSSID);
318        wifiInfo.setNetworkId(configuration.networkId);
319        wifiInfo.setMeteredHint(true);
320        accessPoint.update(configuration, wifiInfo, networkInfo);
321
322        assertThat(accessPoint.isMetered()).isTrue();
323    }
324
325    @Test
326    public void testIsMetered_returnTrueWhenScoredNetworkIsMetered() {
327        AccessPoint ap = createAccessPointWithScanResultCache();
328
329        when(mockWifiNetworkScoreCache.getScoredNetwork(any(ScanResult.class)))
330                .thenReturn(
331                        new ScoredNetwork(
332                                null /* NetworkKey */,
333                                null /* rssiCurve */,
334                                true /* metered */));
335        ap.update(mockWifiNetworkScoreCache, false /* scoringUiEnabled */);
336
337        assertThat(ap.isMetered()).isTrue();
338    }
339
340    @Test
341    public void testIsMetered_returnFalseByDefault() {
342        WifiConfiguration configuration = createWifiConfiguration();
343
344        NetworkInfo networkInfo =
345                new NetworkInfo(ConnectivityManager.TYPE_WIFI, 2, "WIFI", "WIFI_SUBTYPE");
346        AccessPoint accessPoint = new AccessPoint(mContext, configuration);
347        WifiInfo wifiInfo = new WifiInfo();
348        wifiInfo.setSSID(WifiSsid.createFromAsciiEncoded(configuration.SSID));
349        wifiInfo.setBSSID(configuration.BSSID);
350        wifiInfo.setNetworkId(configuration.networkId);
351        accessPoint.update(configuration, wifiInfo, networkInfo);
352
353        assertThat(accessPoint.isMetered()).isFalse();
354    }
355
356    @Test
357    public void testSpeedLabel_returnsVeryFast() {
358        AccessPoint ap = createAccessPointWithScanResultCache();
359
360        when(mockWifiNetworkScoreCache.getScoredNetwork(any(ScanResult.class)))
361                .thenReturn(buildScoredNetworkWithMockBadgeCurve());
362        when(mockBadgeCurve.lookupScore(anyInt())).thenReturn((byte) AccessPoint.Speed.VERY_FAST);
363
364        ap.update(mockWifiNetworkScoreCache, true /* scoringUiEnabled */);
365
366        assertThat(ap.getSpeed()).isEqualTo(AccessPoint.Speed.VERY_FAST);
367        assertThat(ap.getSpeedLabel())
368                .isEqualTo(mContext.getString(R.string.speed_label_very_fast));
369    }
370
371    @Test
372    public void testSpeedLabel_returnsFast() {
373        AccessPoint ap = createAccessPointWithScanResultCache();
374
375        when(mockWifiNetworkScoreCache.getScoredNetwork(any(ScanResult.class)))
376                .thenReturn(buildScoredNetworkWithMockBadgeCurve());
377        when(mockBadgeCurve.lookupScore(anyInt())).thenReturn((byte) AccessPoint.Speed.FAST);
378
379        ap.update(mockWifiNetworkScoreCache, true /* scoringUiEnabled */);
380
381        assertThat(ap.getSpeed()).isEqualTo(AccessPoint.Speed.FAST);
382        assertThat(ap.getSpeedLabel())
383                .isEqualTo(mContext.getString(R.string.speed_label_fast));
384    }
385
386    @Test
387    public void testSpeedLabel_returnsOkay() {
388        AccessPoint ap = createAccessPointWithScanResultCache();
389
390        when(mockWifiNetworkScoreCache.getScoredNetwork(any(ScanResult.class)))
391                .thenReturn(buildScoredNetworkWithMockBadgeCurve());
392        when(mockBadgeCurve.lookupScore(anyInt())).thenReturn((byte) AccessPoint.Speed.MODERATE);
393
394        ap.update(mockWifiNetworkScoreCache, true /* scoringUiEnabled */);
395
396        assertThat(ap.getSpeed()).isEqualTo(AccessPoint.Speed.MODERATE);
397        assertThat(ap.getSpeedLabel())
398                .isEqualTo(mContext.getString(R.string.speed_label_okay));
399    }
400
401    @Test
402    public void testSpeedLabel_returnsSlow() {
403        AccessPoint ap = createAccessPointWithScanResultCache();
404
405        when(mockWifiNetworkScoreCache.getScoredNetwork(any(ScanResult.class)))
406                .thenReturn(buildScoredNetworkWithMockBadgeCurve());
407        when(mockBadgeCurve.lookupScore(anyInt())).thenReturn((byte) AccessPoint.Speed.SLOW);
408
409        ap.update(mockWifiNetworkScoreCache, true /* scoringUiEnabled */);
410
411        assertThat(ap.getSpeed()).isEqualTo(AccessPoint.Speed.SLOW);
412        assertThat(ap.getSpeedLabel())
413                .isEqualTo(mContext.getString(R.string.speed_label_slow));
414    }
415
416    @Test
417    public void testSpeedLabel_isDerivedFromConnectedBssidWhenScoreAvailable() {
418        int rssi = -55;
419        String bssid = "00:00:00:00:00:00";
420        int networkId = 123;
421
422        WifiInfo info = new WifiInfo();
423        info.setRssi(rssi);
424        info.setSSID(WifiSsid.createFromAsciiEncoded(TEST_SSID));
425        info.setBSSID(bssid);
426        info.setNetworkId(networkId);
427
428        ArrayList<ScanResult> scanResults = new ArrayList<>();
429        ScanResult scanResultUnconnected = createScanResult(TEST_SSID, "11:11:11:11:11:11", rssi);
430        scanResults.add(scanResultUnconnected);
431
432        ScanResult scanResultConnected = createScanResult(TEST_SSID, bssid, rssi);
433        scanResults.add(scanResultConnected);
434
435        AccessPoint ap =
436                new TestAccessPointBuilder(mContext)
437                        .setActive(true)
438                        .setNetworkId(networkId)
439                        .setSsid(TEST_SSID)
440                        .setScanResultCache(scanResults)
441                        .setWifiInfo(info)
442                        .build();
443
444        when(mockWifiNetworkScoreCache.getScoredNetwork(scanResultUnconnected))
445                .thenReturn(buildScoredNetworkWithMockBadgeCurve());
446        when(mockBadgeCurve.lookupScore(anyInt())).thenReturn((byte) Speed.SLOW);
447
448        int connectedSpeed = Speed.VERY_FAST;
449        RssiCurve connectedBadgeCurve = mock(RssiCurve.class);
450        Bundle attr1 = new Bundle();
451        attr1.putParcelable(ScoredNetwork.ATTRIBUTES_KEY_BADGING_CURVE, connectedBadgeCurve);
452        ScoredNetwork connectedScore = new ScoredNetwork(
453                NetworkKey.createFromScanResult(scanResultConnected),
454                connectedBadgeCurve,
455                false /* meteredHint */,
456                attr1);
457        when(mockWifiNetworkScoreCache.getScoredNetwork(scanResultConnected))
458                .thenReturn(connectedScore);
459        when(connectedBadgeCurve.lookupScore(anyInt())).thenReturn((byte) connectedSpeed);
460
461        ap.update(mockWifiNetworkScoreCache, true /* scoringUiEnabled */);
462
463        assertThat(ap.getSpeed()).isEqualTo(connectedSpeed);
464    }
465
466    @Test
467    public void testSummaryString_showsSpeedLabel() {
468        AccessPoint ap = createAccessPointWithScanResultCache();
469
470        when(mockWifiNetworkScoreCache.getScoredNetwork(any(ScanResult.class)))
471                .thenReturn(buildScoredNetworkWithMockBadgeCurve());
472        when(mockBadgeCurve.lookupScore(anyInt())).thenReturn((byte) AccessPoint.Speed.VERY_FAST);
473
474        ap.update(mockWifiNetworkScoreCache, true /* scoringUiEnabled */);
475
476        assertThat(ap.getSummary()).isEqualTo(mContext.getString(R.string.speed_label_very_fast));
477    }
478
479    @Test
480    public void testVerboseSummaryString_showsScanResultSpeedLabel() {
481        WifiTracker.sVerboseLogging = true;
482
483        Bundle bundle = new Bundle();
484        ArrayList<ScanResult> scanResults = buildScanResultCache();
485        bundle.putParcelableArrayList(AccessPoint.KEY_SCANRESULTCACHE, scanResults);
486        AccessPoint ap = new AccessPoint(mContext, bundle);
487
488        when(mockWifiNetworkScoreCache.getScoredNetwork(any(ScanResult.class)))
489                .thenReturn(buildScoredNetworkWithMockBadgeCurve());
490        when(mockBadgeCurve.lookupScore(anyInt())).thenReturn((byte) AccessPoint.Speed.VERY_FAST);
491
492        ap.update(mockWifiNetworkScoreCache, true /* scoringUiEnabled */);
493        String summary = ap.verboseScanResultSummary(scanResults.get(0), null);
494
495        assertThat(summary.contains(mContext.getString(R.string.speed_label_very_fast))).isTrue();
496    }
497
498    @Test
499    public void testSummaryString_concatenatesSpeedLabel() {
500        AccessPoint ap = createAccessPointWithScanResultCache();
501        ap.update(new WifiConfiguration());
502
503        when(mockWifiNetworkScoreCache.getScoredNetwork(any(ScanResult.class)))
504                .thenReturn(buildScoredNetworkWithMockBadgeCurve());
505        when(mockBadgeCurve.lookupScore(anyInt())).thenReturn((byte) AccessPoint.Speed.VERY_FAST);
506
507        ap.update(mockWifiNetworkScoreCache, true /* scoringUiEnabled */);
508
509        String expectedString = mContext.getString(R.string.speed_label_very_fast) + " / "
510                + mContext.getString(R.string.wifi_remembered);
511        assertThat(ap.getSummary()).isEqualTo(expectedString);
512    }
513
514    @Test
515    public void testSummaryString_showsWrongPasswordLabel() {
516        WifiConfiguration configuration = createWifiConfiguration();
517        configuration.getNetworkSelectionStatus().setNetworkSelectionStatus(
518                WifiConfiguration.NetworkSelectionStatus.NETWORK_SELECTION_PERMANENTLY_DISABLED);
519        configuration.getNetworkSelectionStatus().setNetworkSelectionDisableReason(
520                WifiConfiguration.NetworkSelectionStatus.DISABLED_BY_WRONG_PASSWORD);
521        AccessPoint ap = new AccessPoint(mContext, configuration);
522
523        assertThat(ap.getSummary()).isEqualTo(mContext.getString(
524                R.string.wifi_check_password_try_again));
525    }
526
527    @Test
528    public void testSummaryString_showsAvaiableViaCarrier() {
529        String carrierName = "Test Carrier";
530        ScanResult result = new ScanResult();
531        result.BSSID = "00:11:22:33:44:55";
532        result.capabilities = "EAP";
533        result.isCarrierAp = true;
534        result.carrierApEapType = WifiEnterpriseConfig.Eap.SIM;
535        result.carrierName = carrierName;
536
537        AccessPoint ap = new AccessPoint(mContext, result);
538        assertThat(ap.getSummary()).isEqualTo(String.format(mContext.getString(
539                R.string.available_via_carrier), carrierName));
540        assertThat(ap.isCarrierAp()).isEqualTo(true);
541        assertThat(ap.getCarrierApEapType()).isEqualTo(WifiEnterpriseConfig.Eap.SIM);
542        assertThat(ap.getCarrierName()).isEqualTo(carrierName);
543    }
544
545    @Test
546    public void testSummaryString_showsConnectedViaCarrier() {
547        int networkId = 123;
548        int rssi = -55;
549        String carrierName = "Test Carrier";
550        WifiConfiguration config = new WifiConfiguration();
551        config.networkId = networkId;
552        WifiInfo wifiInfo = new WifiInfo();
553        wifiInfo.setNetworkId(networkId);
554        wifiInfo.setRssi(rssi);
555
556        NetworkInfo networkInfo =
557                new NetworkInfo(ConnectivityManager.TYPE_WIFI, 0 /* subtype */, "WIFI", "");
558        networkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTED, "", "");
559
560        AccessPoint ap = new TestAccessPointBuilder(mContext)
561                .setNetworkInfo(networkInfo)
562                .setNetworkId(networkId)
563                .setRssi(rssi)
564                .setWifiInfo(wifiInfo)
565                .setIsCarrierAp(true)
566                .setCarrierName(carrierName)
567                .build();
568        assertThat(ap.getSummary()).isEqualTo(String.format(mContext.getString(
569                R.string.connected_via_carrier), carrierName));
570    }
571
572    @Test
573    public void testUpdateScanResultWithCarrierInfo() {
574        String ssid = "ssid";
575        AccessPoint ap = new TestAccessPointBuilder(mContext).setSsid(ssid).build();
576        assertThat(ap.isCarrierAp()).isEqualTo(false);
577        assertThat(ap.getCarrierApEapType()).isEqualTo(WifiEnterpriseConfig.Eap.NONE);
578        assertThat(ap.getCarrierName()).isEqualTo(null);
579
580        int carrierApEapType = WifiEnterpriseConfig.Eap.SIM;
581        String carrierName = "Test Carrier";
582        ScanResult scanResult = new ScanResult();
583        scanResult.SSID = ssid;
584        scanResult.BSSID = "00:11:22:33:44:55";
585        scanResult.capabilities = "";
586        scanResult.isCarrierAp = true;
587        scanResult.carrierApEapType = carrierApEapType;
588        scanResult.carrierName = carrierName;
589        assertThat(ap.update(scanResult, true /* evictOldScanresults */)).isTrue();
590
591        assertThat(ap.isCarrierAp()).isEqualTo(true);
592        assertThat(ap.getCarrierApEapType()).isEqualTo(carrierApEapType);
593        assertThat(ap.getCarrierName()).isEqualTo(carrierName);
594    }
595
596    private ScoredNetwork buildScoredNetworkWithMockBadgeCurve() {
597        return buildScoredNetworkWithGivenBadgeCurve(mockBadgeCurve);
598
599    }
600
601    private ScoredNetwork buildScoredNetworkWithGivenBadgeCurve(RssiCurve badgeCurve) {
602        Bundle attr1 = new Bundle();
603        attr1.putParcelable(ScoredNetwork.ATTRIBUTES_KEY_BADGING_CURVE, badgeCurve);
604        return new ScoredNetwork(
605                new NetworkKey(new WifiKey("\"ssid\"", "00:00:00:00:00:00")),
606                mockBadgeCurve,
607                false /* meteredHint */,
608                attr1);
609
610    }
611
612    private AccessPoint createAccessPointWithScanResultCache() {
613        Bundle bundle = new Bundle();
614        bundle.putParcelableArrayList(AccessPoint.KEY_SCANRESULTCACHE, SCAN_RESULTS);
615        return new AccessPoint(mContext, bundle);
616    }
617
618    private static ArrayList<ScanResult> buildScanResultCache() {
619        ArrayList<ScanResult> scanResults = new ArrayList<>();
620        for (int i = 0; i < 5; i++) {
621            ScanResult scanResult = createScanResult(TEST_SSID, "bssid-" + i, i);
622            scanResults.add(scanResult);
623        }
624        return scanResults;
625    }
626
627    private WifiConfiguration createWifiConfiguration() {
628        WifiConfiguration configuration = new WifiConfiguration();
629        configuration.BSSID = "bssid";
630        configuration.SSID = "ssid";
631        configuration.networkId = 123;
632        return configuration;
633    }
634
635    /**
636    * Assert that the first AccessPoint appears before the second AccessPoint
637    * once sorting has been completed.
638    */
639    private void assertSortingWorks(AccessPoint first, AccessPoint second) {
640
641        ArrayList<AccessPoint> points = new ArrayList<AccessPoint>();
642
643        // add in reverse order so we can tell that sorting actually changed something
644        points.add(second);
645        points.add(first);
646        Collections.sort(points);
647        assertWithMessage(
648                String.format("After sorting: second AccessPoint should have higher array index "
649                    + "than the first, but found indicies second '%s' and first '%s'.",
650                    points.indexOf(second), points.indexOf(first)))
651            .that(points.indexOf(second)).isGreaterThan(points.indexOf(first));
652    }
653
654    @Test
655    public void testBuilder_setActive() {
656        AccessPoint activeAp = new TestAccessPointBuilder(mContext).setActive(true).build();
657        assertThat(activeAp.isActive()).isTrue();
658
659        AccessPoint inactiveAp = new TestAccessPointBuilder(mContext).setActive(false).build();
660        assertThat(inactiveAp.isActive()).isFalse();
661    }
662
663    @Test
664    public void testBuilder_setReachable() {
665        AccessPoint nearAp = new TestAccessPointBuilder(mContext).setReachable(true).build();
666        assertThat(nearAp.isReachable()).isTrue();
667
668        AccessPoint farAp = new TestAccessPointBuilder(mContext).setReachable(false).build();
669        assertThat(farAp.isReachable()).isFalse();
670    }
671
672    @Test
673    public void testBuilder_setSaved() {
674        AccessPoint savedAp = new TestAccessPointBuilder(mContext).setSaved(true).build();
675        assertThat(savedAp.isSaved()).isTrue();
676
677        AccessPoint newAp = new TestAccessPointBuilder(mContext).setSaved(false).build();
678        assertThat(newAp.isSaved()).isFalse();
679    }
680
681    @Test
682    public void testBuilder_setLevel() {
683        AccessPoint testAp;
684
685        for (int i = 0; i < AccessPoint.SIGNAL_LEVELS; i++) {
686            testAp = new TestAccessPointBuilder(mContext).setLevel(i).build();
687            assertThat(testAp.getLevel()).isEqualTo(i);
688        }
689
690        // numbers larger than the max level should be set to max
691        testAp = new TestAccessPointBuilder(mContext).setLevel(AccessPoint.SIGNAL_LEVELS).build();
692        assertThat(testAp.getLevel()).isEqualTo(AccessPoint.SIGNAL_LEVELS - 1);
693
694        // numbers less than 0 should give level 0
695        testAp = new TestAccessPointBuilder(mContext).setLevel(-100).build();
696        assertThat(testAp.getLevel()).isEqualTo(0);
697    }
698
699    @Test
700    public void testBuilder_settingReachableAfterLevelDoesNotAffectLevel() {
701        int level = 1;
702        assertThat(level).isLessThan(AccessPoint.SIGNAL_LEVELS - 1);
703
704        AccessPoint testAp =
705                new TestAccessPointBuilder(mContext).setLevel(level).setReachable(true).build();
706        assertThat(testAp.getLevel()).isEqualTo(level);
707    }
708
709    @Test
710    public void testBuilder_setSsid() {
711        String name = "AmazingSsid!";
712        AccessPoint namedAp = new TestAccessPointBuilder(mContext).setSsid(name).build();
713        assertThat(namedAp.getSsidStr()).isEqualTo(name);
714    }
715
716    @Test
717    public void testBuilder_passpointConfig() {
718        String fqdn = "Test.com";
719        String providerFriendlyName = "Test Provider";
720        AccessPoint ap = new TestAccessPointBuilder(mContext).setFqdn(fqdn)
721                .setProviderFriendlyName(providerFriendlyName).build();
722        assertThat(ap.isPasspointConfig()).isTrue();
723        assertThat(ap.getPasspointFqdn()).isEqualTo(fqdn);
724        assertThat(ap.getConfigName()).isEqualTo(providerFriendlyName);
725    }
726
727    @Test
728    public void testUpdateNetworkInfo_returnsTrue() {
729        int networkId = 123;
730        int rssi = -55;
731        WifiConfiguration config = new WifiConfiguration();
732        config.networkId = networkId;
733        WifiInfo wifiInfo = new WifiInfo();
734        wifiInfo.setNetworkId(networkId);
735        wifiInfo.setRssi(rssi);
736
737        NetworkInfo networkInfo =
738                new NetworkInfo(ConnectivityManager.TYPE_WIFI, 0 /* subtype */, "WIFI", "");
739        networkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTING, "", "");
740
741        AccessPoint ap = new TestAccessPointBuilder(mContext)
742                .setNetworkInfo(networkInfo)
743                .setNetworkId(networkId)
744                .setRssi(rssi)
745                .setWifiInfo(wifiInfo)
746                .build();
747
748        NetworkInfo newInfo = new NetworkInfo(networkInfo);
749        newInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTED, "", "");
750        assertThat(ap.update(config, wifiInfo, newInfo)).isTrue();
751    }
752
753    @Test
754    public void testUpdateNetworkInfoWithSameInfo_returnsFalse() {
755        int networkId = 123;
756        int rssi = -55;
757        WifiConfiguration config = new WifiConfiguration();
758        config.networkId = networkId;
759        WifiInfo wifiInfo = new WifiInfo();
760        wifiInfo.setNetworkId(networkId);
761        wifiInfo.setRssi(rssi);
762
763        NetworkInfo networkInfo =
764                new NetworkInfo(ConnectivityManager.TYPE_WIFI, 0 /* subtype */, "WIFI", "");
765        networkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTING, "", "");
766
767        AccessPoint ap = new TestAccessPointBuilder(mContext)
768                .setNetworkInfo(networkInfo)
769                .setNetworkId(networkId)
770                .setRssi(rssi)
771                .setWifiInfo(wifiInfo)
772                .build();
773
774        NetworkInfo newInfo = new NetworkInfo(networkInfo); // same values
775        assertThat(ap.update(config, wifiInfo, newInfo)).isFalse();
776    }
777
778    @Test
779    public void testUpdateWithDifferentRssi_returnsTrue() {
780        int networkId = 123;
781        int rssi = -55;
782        WifiConfiguration config = new WifiConfiguration();
783        config.networkId = networkId;
784        WifiInfo wifiInfo = new WifiInfo();
785        wifiInfo.setNetworkId(networkId);
786        wifiInfo.setRssi(rssi);
787
788        NetworkInfo networkInfo =
789                new NetworkInfo(ConnectivityManager.TYPE_WIFI, 0 /* subtype */, "WIFI", "");
790        networkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTING, "", "");
791
792        AccessPoint ap = new TestAccessPointBuilder(mContext)
793                .setNetworkInfo(networkInfo)
794                .setNetworkId(networkId)
795                .setRssi(rssi)
796                .setWifiInfo(wifiInfo)
797                .build();
798
799        NetworkInfo newInfo = new NetworkInfo(networkInfo); // same values
800        wifiInfo.setRssi(rssi + 1);
801        assertThat(ap.update(config, wifiInfo, newInfo)).isTrue();
802    }
803
804    @Test
805    public void testUpdateWithInvalidRssi_returnsFalse() {
806        int networkId = 123;
807        int rssi = -55;
808        WifiConfiguration config = new WifiConfiguration();
809        config.networkId = networkId;
810        WifiInfo wifiInfo = new WifiInfo();
811        wifiInfo.setNetworkId(networkId);
812        wifiInfo.setRssi(rssi);
813
814        NetworkInfo networkInfo =
815                new NetworkInfo(ConnectivityManager.TYPE_WIFI, 0 /* subtype */, "WIFI", "");
816        networkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTING, "", "");
817
818        AccessPoint ap = new TestAccessPointBuilder(mContext)
819                .setNetworkInfo(networkInfo)
820                .setNetworkId(networkId)
821                .setRssi(rssi)
822                .setWifiInfo(wifiInfo)
823                .build();
824
825        NetworkInfo newInfo = new NetworkInfo(networkInfo); // same values
826        wifiInfo.setRssi(WifiInfo.INVALID_RSSI);
827        assertThat(ap.update(config, wifiInfo, newInfo)).isFalse();
828    }
829    @Test
830    public void testUpdateWithConfigChangeOnly_returnsFalseButInvokesListener() {
831        int networkId = 123;
832        int rssi = -55;
833        WifiConfiguration config = new WifiConfiguration();
834        config.networkId = networkId;
835        config.numNoInternetAccessReports = 1;
836
837        WifiInfo wifiInfo = new WifiInfo();
838        wifiInfo.setNetworkId(networkId);
839        wifiInfo.setRssi(rssi);
840
841        NetworkInfo networkInfo =
842                new NetworkInfo(ConnectivityManager.TYPE_WIFI, 0 /* subtype */, "WIFI", "");
843        networkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTED, "", "");
844
845        AccessPoint ap = new TestAccessPointBuilder(mContext)
846                .setNetworkInfo(networkInfo)
847                .setNetworkId(networkId)
848                .setRssi(rssi)
849                .setWifiInfo(wifiInfo)
850                .build();
851
852        AccessPoint.AccessPointListener mockListener = mock(AccessPoint.AccessPointListener.class);
853        ap.setListener(mockListener);
854        WifiConfiguration newConfig = new WifiConfiguration(config);
855        config.validatedInternetAccess = true;
856
857        assertThat(ap.update(newConfig, wifiInfo, networkInfo)).isFalse();
858        verify(mockListener).onAccessPointChanged(ap);
859    }
860
861    @Test
862    public void testUpdateWithNullWifiConfiguration_doesNotThrowNPE() {
863        int networkId = 123;
864        int rssi = -55;
865        WifiConfiguration config = new WifiConfiguration();
866        config.networkId = networkId;
867        WifiInfo wifiInfo = new WifiInfo();
868        wifiInfo.setNetworkId(networkId);
869        wifiInfo.setRssi(rssi);
870
871        NetworkInfo networkInfo =
872                new NetworkInfo(ConnectivityManager.TYPE_WIFI, 0 /* subtype */, "WIFI", "");
873        networkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTING, "", "");
874
875        AccessPoint ap = new TestAccessPointBuilder(mContext)
876                .setNetworkInfo(networkInfo)
877                .setNetworkId(networkId)
878                .setRssi(rssi)
879                .setWifiInfo(wifiInfo)
880                .build();
881
882        ap.update(null, wifiInfo, networkInfo);
883    }
884
885    @Test
886    public void testSpeedLabelAveragesAllBssidScores() {
887        AccessPoint ap = createAccessPointWithScanResultCache();
888
889        int speed1 = Speed.MODERATE;
890        RssiCurve badgeCurve1 = mock(RssiCurve.class);
891        when(badgeCurve1.lookupScore(anyInt())).thenReturn((byte) speed1);
892        when(mockWifiNetworkScoreCache.getScoredNetwork(SCAN_RESULTS.get(0)))
893                .thenReturn(buildScoredNetworkWithGivenBadgeCurve(badgeCurve1));
894        int speed2 = Speed.VERY_FAST;
895        RssiCurve badgeCurve2 = mock(RssiCurve.class);
896        when(badgeCurve2.lookupScore(anyInt())).thenReturn((byte) speed2);
897        when(mockWifiNetworkScoreCache.getScoredNetwork(SCAN_RESULTS.get(1)))
898                .thenReturn(buildScoredNetworkWithGivenBadgeCurve(badgeCurve2));
899
900        int expectedSpeed = (speed1 + speed2) / 2;
901
902        ap.update(mockWifiNetworkScoreCache, true /* scoringUiEnabled */);
903
904        assertThat(ap.getSpeed()).isEqualTo(expectedSpeed);
905    }
906
907    @Test
908    public void testSpeedLabelAverageIgnoresNoSpeedScores() {
909        AccessPoint ap = createAccessPointWithScanResultCache();
910
911        int speed1 = Speed.VERY_FAST;
912        RssiCurve badgeCurve1 = mock(RssiCurve.class);
913        when(badgeCurve1.lookupScore(anyInt())).thenReturn((byte) speed1);
914        when(mockWifiNetworkScoreCache.getScoredNetwork(SCAN_RESULTS.get(0)))
915                .thenReturn(buildScoredNetworkWithGivenBadgeCurve(badgeCurve1));
916        int speed2 = Speed.NONE;
917        RssiCurve badgeCurve2 = mock(RssiCurve.class);
918        when(badgeCurve2.lookupScore(anyInt())).thenReturn((byte) speed2);
919        when(mockWifiNetworkScoreCache.getScoredNetwork(SCAN_RESULTS.get(1)))
920                .thenReturn(buildScoredNetworkWithGivenBadgeCurve(badgeCurve2));
921
922        ap.update(mockWifiNetworkScoreCache, true /* scoringUiEnabled */);
923
924        assertThat(ap.getSpeed()).isEqualTo(speed1);
925    }
926
927    @Test
928    public void testSpeedLabelUsesFallbackScoreWhenConnectedAccessPointScoreUnavailable() {
929        int rssi = -55;
930        String bssid = "00:00:00:00:00:00";
931        int networkId = 123;
932
933        WifiInfo info = new WifiInfo();
934        info.setRssi(rssi);
935        info.setSSID(WifiSsid.createFromAsciiEncoded(TEST_SSID));
936        info.setBSSID(bssid);
937        info.setNetworkId(networkId);
938
939        ArrayList<ScanResult> scanResults = new ArrayList<>();
940        ScanResult scanResultUnconnected = createScanResult(TEST_SSID, "11:11:11:11:11:11", rssi);
941        scanResults.add(scanResultUnconnected);
942
943        ScanResult scanResultConnected = createScanResult(TEST_SSID, bssid, rssi);
944        scanResults.add(scanResultConnected);
945
946        AccessPoint ap =
947                new TestAccessPointBuilder(mContext)
948                        .setActive(true)
949                        .setNetworkId(networkId)
950                        .setSsid(TEST_SSID)
951                        .setScanResultCache(scanResults)
952                        .setWifiInfo(info)
953                        .build();
954
955        int fallbackSpeed = Speed.SLOW;
956        when(mockWifiNetworkScoreCache.getScoredNetwork(scanResultUnconnected))
957                .thenReturn(buildScoredNetworkWithMockBadgeCurve());
958        when(mockBadgeCurve.lookupScore(anyInt())).thenReturn((byte) fallbackSpeed);
959
960        when(mockWifiNetworkScoreCache.getScoredNetwork(scanResultConnected))
961                .thenReturn(null);
962
963        ap.update(mockWifiNetworkScoreCache, true /* scoringUiEnabled */);
964
965        assertThat(ap.getSpeed()).isEqualTo(fallbackSpeed);
966    }
967}
968