AccessPointTest.java revision 96a53579088a21590cb02e5befc88ef965520d3e
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.junit.Assert.assertTrue;
22import static org.mockito.Mockito.any;
23import static org.mockito.Mockito.when;
24
25import android.content.Context;
26import android.net.ConnectivityManager;
27import android.net.NetworkInfo;
28import android.net.ScoredNetwork;
29import android.net.wifi.ScanResult;
30import android.net.wifi.WifiConfiguration;
31import android.net.wifi.WifiInfo;
32import android.net.wifi.WifiNetworkScoreCache;
33import android.net.wifi.WifiSsid;
34import android.net.wifi.hotspot2.PasspointConfiguration;
35import android.net.wifi.hotspot2.pps.HomeSp;
36import android.os.Bundle;
37import android.os.SystemClock;
38import android.support.test.InstrumentationRegistry;
39import android.support.test.filters.SmallTest;
40import android.support.test.runner.AndroidJUnit4;
41import android.text.SpannableString;
42import android.text.style.TtsSpan;
43
44import org.junit.Before;
45import org.junit.Test;
46import org.junit.runner.RunWith;
47import org.mockito.Mock;
48import org.mockito.MockitoAnnotations;
49
50import java.util.ArrayList;
51import java.util.Collections;
52
53@SmallTest
54@RunWith(AndroidJUnit4.class)
55public class AccessPointTest {
56
57    private static final String TEST_SSID = "test_ssid";
58    private Context mContext;
59    @Mock private WifiNetworkScoreCache mWifiNetworkScoreCache;
60
61    @Before
62    public void setUp() {
63        MockitoAnnotations.initMocks(this);
64        mContext = InstrumentationRegistry.getTargetContext();
65    }
66
67    @Test
68    public void testSsidIsTelephoneSpan() {
69        final Bundle bundle = new Bundle();
70        bundle.putString("key_ssid", TEST_SSID);
71        final AccessPoint ap = new AccessPoint(InstrumentationRegistry.getTargetContext(), bundle);
72        final CharSequence ssid = ap.getSsid();
73
74        assertThat(ssid instanceof SpannableString).isTrue();
75
76        TtsSpan[] spans = ((SpannableString) ssid).getSpans(0, TEST_SSID.length(), TtsSpan.class);
77
78        assertThat(spans.length).isEqualTo(1);
79        assertThat(spans[0].getType()).isEqualTo(TtsSpan.TYPE_TELEPHONE);
80    }
81
82    @Test
83    public void testCopyAccessPoint_dataShouldMatch() {
84        WifiConfiguration configuration = createWifiConfiguration();
85        configuration.meteredHint = true;
86
87        NetworkInfo networkInfo =
88                new NetworkInfo(ConnectivityManager.TYPE_WIFI, 2, "WIFI", "WIFI_SUBTYPE");
89        AccessPoint originalAccessPoint = new AccessPoint(mContext, configuration);
90        WifiInfo wifiInfo = new WifiInfo();
91        wifiInfo.setSSID(WifiSsid.createFromAsciiEncoded(configuration.SSID));
92        wifiInfo.setBSSID(configuration.BSSID);
93        originalAccessPoint.update(configuration, wifiInfo, networkInfo);
94        AccessPoint copy = new AccessPoint(mContext, originalAccessPoint);
95
96        assertThat(originalAccessPoint.getSsid().toString()).isEqualTo(copy.getSsid().toString());
97        assertThat(originalAccessPoint.getBssid()).isEqualTo(copy.getBssid());
98        assertThat(originalAccessPoint.getConfig()).isEqualTo(copy.getConfig());
99        assertThat(originalAccessPoint.getSecurity()).isEqualTo(copy.getSecurity());
100        assertThat(originalAccessPoint.isMetered()).isEqualTo(copy.isMetered());
101        assertThat(originalAccessPoint.compareTo(copy) == 0).isTrue();
102    }
103
104    @Test
105    public void testThatCopyAccessPoint_scanCacheShouldMatch() {
106        AccessPoint original = createAccessPointWithScanResultCache();
107        assertThat(original.getRssi()).isEqualTo(4);
108        AccessPoint copy = new AccessPoint(mContext, createWifiConfiguration());
109        assertThat(copy.getRssi()).isEqualTo(AccessPoint.UNREACHABLE_RSSI);
110        copy.copyFrom(original);
111        assertThat(original.getRssi()).isEqualTo(copy.getRssi());
112    }
113
114    @Test
115    public void testCompareTo_GivesActiveBeforeInactive() {
116        AccessPoint activeAp = new TestAccessPointBuilder(mContext).setActive(true).build();
117        AccessPoint inactiveAp = new TestAccessPointBuilder(mContext).setActive(false).build();
118
119        assertSortingWorks(activeAp, inactiveAp);
120    }
121
122    @Test
123    public void testCompareTo_GivesReachableBeforeUnreachable() {
124        AccessPoint nearAp = new TestAccessPointBuilder(mContext).setReachable(true).build();
125        AccessPoint farAp = new TestAccessPointBuilder(mContext).setReachable(false).build();
126
127        assertSortingWorks(nearAp, farAp);
128    }
129
130    @Test
131    public void testCompareTo_GivesSavedBeforeUnsaved() {
132        AccessPoint savedAp = new TestAccessPointBuilder(mContext).setSaved(true).build();
133        AccessPoint notSavedAp = new TestAccessPointBuilder(mContext).setSaved(false).build();
134
135        assertSortingWorks(savedAp, notSavedAp);
136    }
137
138    //TODO: add tests for mRankingScore sort order if ranking is exposed
139
140    @Test
141    public void testCompareTo_GivesHighLevelBeforeLowLevel() {
142        final int highLevel = AccessPoint.SIGNAL_LEVELS - 1;
143        final int lowLevel = 1;
144        assertThat(highLevel).isGreaterThan(lowLevel);
145
146        AccessPoint strongAp = new TestAccessPointBuilder(mContext).setLevel(highLevel).build();
147        AccessPoint weakAp = new TestAccessPointBuilder(mContext).setLevel(lowLevel).build();
148
149        assertSortingWorks(strongAp, weakAp);
150    }
151
152    @Test
153    public void testCompareTo_GivesSsidAlphabetically() {
154
155        final String firstName = "AAAAAA";
156        final String secondName = "zzzzzz";
157
158        AccessPoint firstAp = new TestAccessPointBuilder(mContext).setSsid(firstName).build();
159        AccessPoint secondAp = new TestAccessPointBuilder(mContext).setSsid(secondName).build();
160
161        assertThat(firstAp.getSsidStr().compareToIgnoreCase(secondAp.getSsidStr()) < 0).isTrue();
162        assertSortingWorks(firstAp, secondAp);
163    }
164
165    @Test
166    public void testCompareTo_AllSortingRulesCombined() {
167
168        AccessPoint active = new TestAccessPointBuilder(mContext).setActive(true).build();
169        AccessPoint reachableAndMinLevel = new TestAccessPointBuilder(mContext)
170                .setReachable(true).build();
171        AccessPoint saved = new TestAccessPointBuilder(mContext).setSaved(true).build();
172        AccessPoint highLevelAndReachable = new TestAccessPointBuilder(mContext)
173                .setLevel(AccessPoint.SIGNAL_LEVELS - 1).build();
174        AccessPoint firstName = new TestAccessPointBuilder(mContext).setSsid("a").build();
175        AccessPoint lastname = new TestAccessPointBuilder(mContext).setSsid("z").build();
176
177        ArrayList<AccessPoint> points = new ArrayList<AccessPoint>();
178        points.add(lastname);
179        points.add(firstName);
180        points.add(highLevelAndReachable);
181        points.add(saved);
182        points.add(reachableAndMinLevel);
183        points.add(active);
184
185        Collections.sort(points);
186        assertThat(points.indexOf(active)).isLessThan(points.indexOf(reachableAndMinLevel));
187        assertThat(points.indexOf(reachableAndMinLevel)).isLessThan(points.indexOf(saved));
188        // note: the saved AP will not appear before highLevelAndReachable,
189        // because all APs with a signal level are reachable,
190        // and isReachable() takes higher sorting precedence than isSaved().
191        assertThat(points.indexOf(saved)).isLessThan(points.indexOf(firstName));
192        assertThat(points.indexOf(highLevelAndReachable)).isLessThan(points.indexOf(firstName));
193        assertThat(points.indexOf(firstName)).isLessThan(points.indexOf(lastname));
194    }
195
196    @Test
197    public void testRssiIsSetFromScanResults() {
198        AccessPoint ap = createAccessPointWithScanResultCache();
199        int originalRssi = ap.getRssi();
200        assertThat(originalRssi).isNotEqualTo(AccessPoint.UNREACHABLE_RSSI);
201    }
202
203    @Test
204    public void testGetRssiShouldReturnSetRssiValue() {
205        AccessPoint ap = createAccessPointWithScanResultCache();
206        int originalRssi = ap.getRssi();
207        int newRssi = originalRssi - 10;
208        ap.setRssi(newRssi);
209        assertThat(ap.getRssi()).isEqualTo(newRssi);
210    }
211
212    @Test
213    public void testUpdateWithScanResultShouldAverageRssi() {
214        String ssid = "ssid";
215        int originalRssi = -65;
216        int newRssi = -80;
217        int expectedRssi = (originalRssi + newRssi) / 2;
218        AccessPoint ap =
219                new TestAccessPointBuilder(mContext).setSsid(ssid).setRssi(originalRssi).build();
220
221        ScanResult scanResult = new ScanResult();
222        scanResult.SSID = ssid;
223        scanResult.level = newRssi;
224        scanResult.BSSID = "bssid";
225        scanResult.timestamp = SystemClock.elapsedRealtime() * 1000;
226        scanResult.capabilities = "";
227        assertThat(ap.update(scanResult)).isTrue();
228
229        assertThat(ap.getRssi()).isEqualTo(expectedRssi);
230    }
231
232    @Test
233    public void testCreateFromPasspointConfig() {
234        PasspointConfiguration config = new PasspointConfiguration();
235        HomeSp homeSp = new HomeSp();
236        homeSp.setFqdn("test.com");
237        homeSp.setFriendlyName("Test Provider");
238        config.setHomeSp(homeSp);
239        AccessPoint ap = new AccessPoint(mContext, config);
240        assertTrue(ap.isPasspointConfig());
241    }
242
243    @Test
244    public void testIsMetered_returnTrueWhenWifiConfigurationIsMetered() {
245        WifiConfiguration configuration = createWifiConfiguration();
246        configuration.meteredHint = true;
247
248        NetworkInfo networkInfo =
249                new NetworkInfo(ConnectivityManager.TYPE_WIFI, 2, "WIFI", "WIFI_SUBTYPE");
250        AccessPoint accessPoint = new AccessPoint(mContext, configuration);
251        WifiInfo wifiInfo = new WifiInfo();
252        wifiInfo.setSSID(WifiSsid.createFromAsciiEncoded(configuration.SSID));
253        wifiInfo.setBSSID(configuration.BSSID);
254        wifiInfo.setNetworkId(configuration.networkId);
255        accessPoint.update(configuration, wifiInfo, networkInfo);
256
257        assertTrue(accessPoint.isMetered());
258    };
259
260    @Test
261    public void testIsMetered_returnTrueWhenWifiInfoIsMetered() {
262        WifiConfiguration configuration = createWifiConfiguration();
263
264        NetworkInfo networkInfo =
265                new NetworkInfo(ConnectivityManager.TYPE_WIFI, 2, "WIFI", "WIFI_SUBTYPE");
266        AccessPoint accessPoint = new AccessPoint(mContext, configuration);
267        WifiInfo wifiInfo = new WifiInfo();
268        wifiInfo.setSSID(WifiSsid.createFromAsciiEncoded(configuration.SSID));
269        wifiInfo.setBSSID(configuration.BSSID);
270        wifiInfo.setNetworkId(configuration.networkId);
271        wifiInfo.setMeteredHint(true);
272        accessPoint.update(configuration, wifiInfo, networkInfo);
273
274        assertTrue(accessPoint.isMetered());
275    };
276
277    @Test
278    public void testIsMetered_returnTrueWhenScoredNetworkIsMetered() {
279        AccessPoint ap = createAccessPointWithScanResultCache();
280
281        when(mWifiNetworkScoreCache.getScoredNetwork(any(ScanResult.class)))
282                .thenReturn(
283                        new ScoredNetwork(
284                                null /* NetworkKey */,
285                                null /* rssiCurve */,
286                                true /* metered */));
287        ap.update(mWifiNetworkScoreCache, false /* scoringUiEnabled */);
288
289        assertTrue(ap.isMetered());
290    };
291
292    private AccessPoint createAccessPointWithScanResultCache() {
293        Bundle bundle = new Bundle();
294        ArrayList<ScanResult> scanResults = new ArrayList<>();
295        for (int i = 0; i < 5; i++) {
296            ScanResult scanResult = new ScanResult();
297            scanResult.level = i;
298            scanResult.BSSID = "bssid-" + i;
299            scanResult.timestamp = SystemClock.elapsedRealtime() * 1000;
300            scanResult.capabilities = "";
301            scanResults.add(scanResult);
302        }
303
304        bundle.putParcelableArrayList("key_scanresultcache", scanResults);
305        return new AccessPoint(mContext, bundle);
306    }
307
308    private WifiConfiguration createWifiConfiguration() {
309        WifiConfiguration configuration = new WifiConfiguration();
310        configuration.BSSID = "bssid";
311        configuration.SSID = "ssid";
312        configuration.networkId = 123;
313        return configuration;
314    }
315
316    /**
317    * Assert that the first AccessPoint appears after the second AccessPoint
318    * once sorting has been completed.
319    */
320    private void assertSortingWorks(AccessPoint first, AccessPoint second) {
321
322        ArrayList<AccessPoint> points = new ArrayList<AccessPoint>();
323
324        // add in reverse order so we can tell that sorting actually changed something
325        points.add(second);
326        points.add(first);
327        Collections.sort(points);
328        assertWithMessage(
329                String.format("After sorting: second AccessPoint should have higher array index "
330                    + "than the first, but found indicies second '%s' and first '%s'.",
331                    points.indexOf(second), points.indexOf(first)))
332            .that(points.indexOf(second)).isGreaterThan(points.indexOf(first));
333    }
334
335    @Test
336    public void testBuilder_setActive() {
337        AccessPoint activeAp = new TestAccessPointBuilder(mContext).setActive(true).build();
338        assertThat(activeAp.isActive()).isTrue();
339
340        AccessPoint inactiveAp = new TestAccessPointBuilder(mContext).setActive(false).build();
341        assertThat(inactiveAp.isActive()).isFalse();
342    }
343
344    @Test
345    public void testBuilder_setReachable() {
346        AccessPoint nearAp = new TestAccessPointBuilder(mContext).setReachable(true).build();
347        assertThat(nearAp.isReachable()).isTrue();
348
349        AccessPoint farAp = new TestAccessPointBuilder(mContext).setReachable(false).build();
350        assertThat(farAp.isReachable()).isFalse();
351    }
352
353    @Test
354    public void testBuilder_setSaved() {
355        AccessPoint savedAp = new TestAccessPointBuilder(mContext).setSaved(true).build();
356        assertThat(savedAp.isSaved()).isTrue();
357
358        AccessPoint newAp = new TestAccessPointBuilder(mContext).setSaved(false).build();
359        assertThat(newAp.isSaved()).isFalse();
360    }
361
362    @Test
363    public void testBuilder_setLevel() {
364        AccessPoint testAp;
365
366        for (int i = 0; i < AccessPoint.SIGNAL_LEVELS; i++) {
367            testAp = new TestAccessPointBuilder(mContext).setLevel(i).build();
368            assertThat(testAp.getLevel()).isEqualTo(i);
369        }
370
371        // numbers larger than the max level should be set to max
372        testAp = new TestAccessPointBuilder(mContext).setLevel(AccessPoint.SIGNAL_LEVELS).build();
373        assertThat(testAp.getLevel()).isEqualTo(AccessPoint.SIGNAL_LEVELS - 1);
374
375        // numbers less than 0 should give level 0
376        testAp = new TestAccessPointBuilder(mContext).setLevel(-100).build();
377        assertThat(testAp.getLevel()).isEqualTo(0);
378    }
379
380    @Test
381    public void testBuilder_settingReachableAfterLevelDoesNotAffectLevel() {
382        int level = 1;
383        assertThat(level).isLessThan(AccessPoint.SIGNAL_LEVELS - 1);
384
385        AccessPoint testAp =
386                new TestAccessPointBuilder(mContext).setLevel(level).setReachable(true).build();
387        assertThat(testAp.getLevel()).isEqualTo(level);
388    }
389
390    @Test
391    public void testBuilder_setSsid() {
392        String name = "AmazingSsid!";
393        AccessPoint namedAp = new TestAccessPointBuilder(mContext).setSsid(name).build();
394        assertThat(namedAp.getSsidStr()).isEqualTo(name);
395    }
396
397    @Test
398    public void testBuilder_passpointConfig() {
399        String fqdn = "Test.com";
400        String providerFriendlyName = "Test Provider";
401        AccessPoint ap = new TestAccessPointBuilder(mContext).setFqdn(fqdn)
402                .setProviderFriendlyName(providerFriendlyName).build();
403        assertTrue(ap.isPasspointConfig());
404        assertThat(ap.getPasspointFqdn()).isEqualTo(fqdn);
405        assertThat(ap.getConfigName()).isEqualTo(providerFriendlyName);
406    }
407
408    @Test
409    public void testUpdateNetworkInfo_returnsTrue() {
410        int networkId = 123;
411        int rssi = -55;
412        WifiConfiguration config = new WifiConfiguration();
413        config.networkId = networkId;
414        WifiInfo wifiInfo = new WifiInfo();
415        wifiInfo.setNetworkId(networkId);
416        wifiInfo.setRssi(rssi);
417
418        NetworkInfo networkInfo =
419                new NetworkInfo(ConnectivityManager.TYPE_WIFI, 0 /* subtype */, "WIFI", "");
420        networkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTING, "", "");
421
422        AccessPoint ap = new TestAccessPointBuilder(mContext)
423                .setNetworkInfo(networkInfo)
424                .setNetworkId(networkId)
425                .setRssi(rssi)
426                .setWifiInfo(wifiInfo)
427                .build();
428
429        NetworkInfo newInfo = new NetworkInfo(networkInfo);
430        newInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTED, "", "");
431        assertThat(ap.update(config, wifiInfo, newInfo)).isTrue();
432    }
433
434    @Test
435    public void testUpdateNetworkInfoWithSameInfo_returnsFalse() {
436        int networkId = 123;
437        int rssi = -55;
438        WifiConfiguration config = new WifiConfiguration();
439        config.networkId = networkId;
440        WifiInfo wifiInfo = new WifiInfo();
441        wifiInfo.setNetworkId(networkId);
442        wifiInfo.setRssi(rssi);
443
444        NetworkInfo networkInfo =
445                new NetworkInfo(ConnectivityManager.TYPE_WIFI, 0 /* subtype */, "WIFI", "");
446        networkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTING, "", "");
447
448        AccessPoint ap = new TestAccessPointBuilder(mContext)
449                .setNetworkInfo(networkInfo)
450                .setNetworkId(networkId)
451                .setRssi(rssi)
452                .setWifiInfo(wifiInfo)
453                .build();
454
455        NetworkInfo newInfo = new NetworkInfo(networkInfo); // same values
456        assertThat(ap.update(config, wifiInfo, newInfo)).isFalse();
457    }
458}
459