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 package com.android.settingslib.wifi; 17 18 import static com.google.common.truth.Truth.assertThat; 19 import static com.google.common.truth.Truth.assertWithMessage; 20 21 import static org.junit.Assert.fail; 22 import static org.mockito.ArgumentMatchers.eq; 23 import static org.mockito.Mockito.any; 24 import static org.mockito.Mockito.anyInt; 25 import static org.mockito.Mockito.mock; 26 import static org.mockito.Mockito.spy; 27 import static org.mockito.Mockito.verify; 28 import static org.mockito.Mockito.when; 29 30 import android.content.Context; 31 import android.content.ContextWrapper; 32 import android.content.pm.ApplicationInfo; 33 import android.content.pm.PackageManager; 34 import android.content.res.Resources; 35 import android.net.ConnectivityManager; 36 import android.net.NetworkInfo; 37 import android.net.NetworkKey; 38 import android.net.RssiCurve; 39 import android.net.ScoredNetwork; 40 import android.net.WifiKey; 41 import android.net.wifi.ScanResult; 42 import android.net.wifi.WifiConfiguration; 43 import android.net.wifi.WifiConfiguration.KeyMgmt; 44 import android.net.wifi.WifiInfo; 45 import android.net.wifi.WifiManager; 46 import android.net.wifi.WifiNetworkScoreCache; 47 import android.net.wifi.WifiSsid; 48 import android.net.wifi.hotspot2.OsuProvider; 49 import android.net.wifi.hotspot2.PasspointConfiguration; 50 import android.net.wifi.hotspot2.ProvisioningCallback; 51 import android.net.wifi.hotspot2.pps.HomeSp; 52 import android.os.Bundle; 53 import android.os.Parcelable; 54 import android.os.SystemClock; 55 import android.text.SpannableString; 56 import android.text.format.DateUtils; 57 import android.util.ArraySet; 58 import android.util.Pair; 59 60 import androidx.test.InstrumentationRegistry; 61 import androidx.test.filters.SmallTest; 62 import androidx.test.runner.AndroidJUnit4; 63 64 import com.android.settingslib.R; 65 import com.android.settingslib.utils.ThreadUtils; 66 import com.android.settingslib.wifi.AccessPoint.Speed; 67 68 import org.junit.Before; 69 import org.junit.Test; 70 import org.junit.runner.RunWith; 71 import org.mockito.Mock; 72 import org.mockito.MockitoAnnotations; 73 74 import java.util.ArrayList; 75 import java.util.Arrays; 76 import java.util.Collections; 77 import java.util.HashMap; 78 import java.util.List; 79 import java.util.Map; 80 import java.util.Set; 81 import java.util.concurrent.CountDownLatch; 82 83 @SmallTest 84 @RunWith(AndroidJUnit4.class) 85 public class AccessPointTest { 86 private static final String TEST_SSID = "\"test_ssid\""; 87 private static final String ROAMING_SSID = "\"roaming_ssid\""; 88 private static final String OSU_FRIENDLY_NAME = "osu_friendly_name"; 89 90 private ArrayList<ScanResult> mScanResults; 91 private ArrayList<ScanResult> mRoamingScans; 92 93 private static final RssiCurve FAST_BADGE_CURVE = 94 new RssiCurve(-150, 10, new byte[]{Speed.FAST}); 95 public static final String TEST_BSSID = "00:00:00:00:00:00"; 96 private static final long MAX_SCORE_CACHE_AGE_MILLIS = 97 20 * DateUtils.MINUTE_IN_MILLIS; 98 99 private Context mContext; 100 private int mMaxSignalLevel; 101 private WifiInfo mWifiInfo; 102 @Mock private Context mMockContext; 103 @Mock private WifiManager mMockWifiManager; 104 @Mock private RssiCurve mockBadgeCurve; 105 @Mock private WifiNetworkScoreCache mockWifiNetworkScoreCache; 106 @Mock private AccessPoint.AccessPointListener mMockAccessPointListener; 107 @Mock private WifiManager.ActionListener mMockConnectListener; 108 private static final int NETWORK_ID = 123; 109 private static final int DEFAULT_RSSI = -55; 110 createScanResult(String ssid, String bssid, int rssi)111 private ScanResult createScanResult(String ssid, String bssid, int rssi) { 112 ScanResult scanResult = new ScanResult(); 113 scanResult.SSID = ssid; 114 scanResult.level = rssi; 115 scanResult.BSSID = bssid; 116 scanResult.timestamp = SystemClock.elapsedRealtime() * 1000; 117 scanResult.capabilities = ""; 118 return scanResult; 119 } 120 createOsuProvider()121 private OsuProvider createOsuProvider() { 122 Map<String, String> friendlyNames = new HashMap<>(); 123 friendlyNames.put("en", OSU_FRIENDLY_NAME); 124 return new OsuProvider((WifiSsid) null, friendlyNames, null, null, null, null); 125 } 126 127 @Before setUp()128 public void setUp() { 129 MockitoAnnotations.initMocks(this); 130 mContext = InstrumentationRegistry.getTargetContext(); 131 mMaxSignalLevel = mContext.getSystemService(WifiManager.class).getMaxSignalLevel(); 132 mWifiInfo = new WifiInfo(); 133 mWifiInfo.setSSID(WifiSsid.createFromAsciiEncoded(TEST_SSID)); 134 mWifiInfo.setBSSID(TEST_BSSID); 135 mScanResults = buildScanResultCache(TEST_SSID); 136 mRoamingScans = buildScanResultCache(ROAMING_SSID); 137 WifiTracker.sVerboseLogging = false; 138 } 139 140 @Test testSsidIsSpannableString_returnFalse()141 public void testSsidIsSpannableString_returnFalse() { 142 final Bundle bundle = new Bundle(); 143 bundle.putString("key_ssid", TEST_SSID); 144 final AccessPoint ap = new AccessPoint(InstrumentationRegistry.getTargetContext(), bundle); 145 final CharSequence ssid = ap.getSsid(); 146 147 assertThat(ssid instanceof SpannableString).isFalse(); 148 } 149 150 @Test testCompareTo_GivesNull()151 public void testCompareTo_GivesNull() { 152 WifiConfiguration spyConfig = spy(new WifiConfiguration()); 153 154 when(spyConfig.isPasspoint()).thenReturn(true); 155 spyConfig.providerFriendlyName = null; 156 AccessPoint passpointAp = new AccessPoint(mContext, spyConfig); 157 158 assertThat(passpointAp.getTitle()).isEqualTo(""); 159 } 160 161 @Test testCompareTo_GivesActiveBeforeInactive()162 public void testCompareTo_GivesActiveBeforeInactive() { 163 AccessPoint activeAp = new TestAccessPointBuilder(mContext).setActive(true).build(); 164 AccessPoint inactiveAp = new TestAccessPointBuilder(mContext).setActive(false).build(); 165 166 assertSortingWorks(activeAp, inactiveAp); 167 } 168 169 @Test testCompareTo_GivesReachableBeforeUnreachable()170 public void testCompareTo_GivesReachableBeforeUnreachable() { 171 AccessPoint nearAp = new TestAccessPointBuilder(mContext).setReachable(true).build(); 172 AccessPoint farAp = new TestAccessPointBuilder(mContext).setReachable(false).build(); 173 174 assertSortingWorks(nearAp, farAp); 175 } 176 177 @Test testCompareTo_GivesSavedBeforeUnsaved()178 public void testCompareTo_GivesSavedBeforeUnsaved() { 179 AccessPoint savedAp = new TestAccessPointBuilder(mContext).setSaved(true).build(); 180 AccessPoint notSavedAp = new TestAccessPointBuilder(mContext).setSaved(false).build(); 181 182 assertSortingWorks(savedAp, notSavedAp); 183 } 184 185 @Test testCompareTo_GivesHighSpeedBeforeLowSpeed()186 public void testCompareTo_GivesHighSpeedBeforeLowSpeed() { 187 AccessPoint fastAp = new TestAccessPointBuilder(mContext).setSpeed(Speed.FAST).build(); 188 AccessPoint slowAp = new TestAccessPointBuilder(mContext).setSpeed(Speed.SLOW).build(); 189 190 assertSortingWorks(fastAp, slowAp); 191 } 192 193 @Test testCompareTo_GivesHighLevelBeforeLowLevel()194 public void testCompareTo_GivesHighLevelBeforeLowLevel() { 195 final int highLevel = mMaxSignalLevel; 196 final int lowLevel = 1; 197 assertThat(highLevel).isGreaterThan(lowLevel); 198 199 AccessPoint strongAp = new TestAccessPointBuilder(mContext).setLevel(highLevel).build(); 200 AccessPoint weakAp = new TestAccessPointBuilder(mContext).setLevel(lowLevel).build(); 201 202 assertSortingWorks(strongAp, weakAp); 203 } 204 205 @Test testCompareTo_GivesSsidAlphabetically()206 public void testCompareTo_GivesSsidAlphabetically() { 207 208 final String firstName = "AAAAAA"; 209 final String secondName = "zzzzzz"; 210 211 AccessPoint firstAp = new TestAccessPointBuilder(mContext).setSsid(firstName).build(); 212 AccessPoint secondAp = new TestAccessPointBuilder(mContext).setSsid(secondName).build(); 213 214 assertThat(firstAp.getSsidStr().compareToIgnoreCase(secondAp.getSsidStr()) < 0).isTrue(); 215 assertSortingWorks(firstAp, secondAp); 216 } 217 218 @Test 219 public void testCompareTo_GivesSsidCasePrecendenceAfterAlphabetical() { 220 221 final String firstName = "aaAaaa"; 222 final String secondName = "aaaaaa"; 223 final String thirdName = "BBBBBB"; 224 225 AccessPoint firstAp = new TestAccessPointBuilder(mContext).setSsid(firstName).build(); 226 AccessPoint secondAp = new TestAccessPointBuilder(mContext).setSsid(secondName).build(); 227 AccessPoint thirdAp = new TestAccessPointBuilder(mContext).setSsid(thirdName).build(); 228 229 assertSortingWorks(firstAp, secondAp); 230 assertSortingWorks(secondAp, thirdAp); 231 } 232 233 @Test 234 public void testCompareTo_AllSortingRulesCombined() { 235 236 AccessPoint active = new TestAccessPointBuilder(mContext).setActive(true).build(); 237 AccessPoint reachableAndMinLevel = new TestAccessPointBuilder(mContext) 238 .setReachable(true).build(); 239 AccessPoint saved = new TestAccessPointBuilder(mContext).setSaved(true).build(); 240 AccessPoint highLevelAndReachable = new TestAccessPointBuilder(mContext) 241 .setLevel(mMaxSignalLevel).build(); 242 AccessPoint firstName = new TestAccessPointBuilder(mContext).setSsid("a").build(); 243 AccessPoint lastname = new TestAccessPointBuilder(mContext).setSsid("z").build(); 244 245 ArrayList<AccessPoint> points = new ArrayList<AccessPoint>(); 246 points.add(lastname); 247 points.add(firstName); 248 points.add(highLevelAndReachable); 249 points.add(saved); 250 points.add(reachableAndMinLevel); 251 points.add(active); 252 253 Collections.sort(points); 254 assertThat(points.indexOf(active)).isLessThan(points.indexOf(reachableAndMinLevel)); 255 assertThat(points.indexOf(reachableAndMinLevel)).isLessThan(points.indexOf(saved)); 256 // note: the saved AP will not appear before highLevelAndReachable, 257 // because all APs with a signal level are reachable, 258 // and isReachable() takes higher sorting precedence than isSaved(). 259 assertThat(points.indexOf(saved)).isLessThan(points.indexOf(firstName)); 260 assertThat(points.indexOf(highLevelAndReachable)).isLessThan(points.indexOf(firstName)); 261 assertThat(points.indexOf(firstName)).isLessThan(points.indexOf(lastname)); 262 } 263 264 @Test 265 public void testRssiIsSetFromScanResults() { 266 AccessPoint ap = createAccessPointWithScanResultCache(); 267 int originalRssi = ap.getRssi(); 268 assertThat(originalRssi).isNotEqualTo(AccessPoint.UNREACHABLE_RSSI); 269 } 270 271 @Test 272 public void testGetRssiShouldReturnSetRssiValue() { 273 AccessPoint ap = createAccessPointWithScanResultCache(); 274 int originalRssi = ap.getRssi(); 275 int newRssi = originalRssi - 10; 276 ap.setRssi(newRssi); 277 assertThat(ap.getRssi()).isEqualTo(newRssi); 278 } 279 280 @Test 281 public void testUpdateWithScanResultShouldAverageRssi() { 282 String ssid = "ssid"; 283 int originalRssi = -65; 284 int newRssi = -80; 285 int expectedRssi = (originalRssi + newRssi) / 2; 286 AccessPoint ap = 287 new TestAccessPointBuilder(mContext).setSsid(ssid).setRssi(originalRssi).build(); 288 289 ScanResult scanResult = new ScanResult(); 290 scanResult.SSID = ssid; 291 scanResult.level = newRssi; 292 scanResult.BSSID = "bssid"; 293 scanResult.timestamp = SystemClock.elapsedRealtime() * 1000; 294 scanResult.capabilities = ""; 295 296 ap.setScanResults(Collections.singletonList(scanResult)); 297 298 assertThat(ap.getRssi()).isEqualTo(expectedRssi); 299 } 300 301 @Test 302 public void testCreateFromPasspointConfig() { 303 PasspointConfiguration config = new PasspointConfiguration(); 304 HomeSp homeSp = new HomeSp(); 305 homeSp.setFqdn("test.com"); 306 homeSp.setFriendlyName("Test Provider"); 307 config.setHomeSp(homeSp); 308 AccessPoint ap = new AccessPoint(mContext, config); 309 assertThat(ap.isPasspointConfig()).isTrue(); 310 } 311 312 @Test 313 public void testIsMetered_returnTrueWhenWifiConfigurationIsMetered() { 314 WifiConfiguration configuration = createWifiConfiguration(); 315 configuration.meteredHint = true; 316 317 NetworkInfo networkInfo = 318 new NetworkInfo(ConnectivityManager.TYPE_WIFI, 2, "WIFI", "WIFI_SUBTYPE"); 319 AccessPoint accessPoint = new AccessPoint(mContext, configuration); 320 WifiInfo wifiInfo = new WifiInfo(); 321 wifiInfo.setSSID(WifiSsid.createFromAsciiEncoded(configuration.SSID)); 322 wifiInfo.setBSSID(configuration.BSSID); 323 wifiInfo.setNetworkId(configuration.networkId); 324 accessPoint.update(configuration, wifiInfo, networkInfo); 325 326 assertThat(accessPoint.isMetered()).isTrue(); 327 } 328 329 @Test 330 public void testIsMetered_returnTrueWhenWifiInfoIsMetered() { 331 WifiConfiguration configuration = createWifiConfiguration(); 332 333 NetworkInfo networkInfo = 334 new NetworkInfo(ConnectivityManager.TYPE_WIFI, 2, "WIFI", "WIFI_SUBTYPE"); 335 AccessPoint accessPoint = new AccessPoint(mContext, configuration); 336 WifiInfo wifiInfo = new WifiInfo(); 337 wifiInfo.setSSID(WifiSsid.createFromAsciiEncoded(configuration.SSID)); 338 wifiInfo.setBSSID(configuration.BSSID); 339 wifiInfo.setNetworkId(configuration.networkId); 340 wifiInfo.setMeteredHint(true); 341 accessPoint.update(configuration, wifiInfo, networkInfo); 342 343 assertThat(accessPoint.isMetered()).isTrue(); 344 } 345 346 @Test 347 public void testIsMetered_returnTrueWhenScoredNetworkIsMetered() { 348 AccessPoint ap = createAccessPointWithScanResultCache(); 349 350 when(mockWifiNetworkScoreCache.getScoredNetwork(any(ScanResult.class))) 351 .thenReturn( 352 new ScoredNetwork( 353 null /* NetworkKey */, 354 null /* rssiCurve */, 355 true /* metered */)); 356 ap.update(mockWifiNetworkScoreCache, false /* scoringUiEnabled */, 357 MAX_SCORE_CACHE_AGE_MILLIS); 358 359 assertThat(ap.isMetered()).isTrue(); 360 } 361 362 @Test 363 public void testIsMetered_returnFalseByDefault() { 364 WifiConfiguration configuration = createWifiConfiguration(); 365 366 NetworkInfo networkInfo = 367 new NetworkInfo(ConnectivityManager.TYPE_WIFI, 2, "WIFI", "WIFI_SUBTYPE"); 368 AccessPoint accessPoint = new AccessPoint(mContext, configuration); 369 WifiInfo wifiInfo = new WifiInfo(); 370 wifiInfo.setSSID(WifiSsid.createFromAsciiEncoded(configuration.SSID)); 371 wifiInfo.setBSSID(configuration.BSSID); 372 wifiInfo.setNetworkId(configuration.networkId); 373 accessPoint.update(configuration, wifiInfo, networkInfo); 374 375 assertThat(accessPoint.isMetered()).isFalse(); 376 } 377 378 @Test 379 public void testSpeedLabel_returnsVeryFast() { 380 AccessPoint ap = createAccessPointWithScanResultCache(); 381 382 when(mockWifiNetworkScoreCache.getScoredNetwork(any(ScanResult.class))) 383 .thenReturn(buildScoredNetworkWithMockBadgeCurve()); 384 when(mockBadgeCurve.lookupScore(anyInt())).thenReturn((byte) AccessPoint.Speed.VERY_FAST); 385 386 ap.update(mockWifiNetworkScoreCache, true /* scoringUiEnabled */, 387 MAX_SCORE_CACHE_AGE_MILLIS); 388 389 assertThat(ap.getSpeed()).isEqualTo(AccessPoint.Speed.VERY_FAST); 390 assertThat(ap.getSpeedLabel()) 391 .isEqualTo(mContext.getString(R.string.speed_label_very_fast)); 392 } 393 394 @Test 395 public void testSpeedLabel_returnsFast() { 396 AccessPoint ap = createAccessPointWithScanResultCache(); 397 398 when(mockWifiNetworkScoreCache.getScoredNetwork(any(ScanResult.class))) 399 .thenReturn(buildScoredNetworkWithMockBadgeCurve()); 400 when(mockBadgeCurve.lookupScore(anyInt())).thenReturn((byte) AccessPoint.Speed.FAST); 401 402 ap.update(mockWifiNetworkScoreCache, true /* scoringUiEnabled */, 403 MAX_SCORE_CACHE_AGE_MILLIS); 404 405 assertThat(ap.getSpeed()).isEqualTo(AccessPoint.Speed.FAST); 406 assertThat(ap.getSpeedLabel()) 407 .isEqualTo(mContext.getString(R.string.speed_label_fast)); 408 } 409 410 @Test 411 public void testSpeedLabel_returnsOkay() { 412 AccessPoint ap = createAccessPointWithScanResultCache(); 413 414 when(mockWifiNetworkScoreCache.getScoredNetwork(any(ScanResult.class))) 415 .thenReturn(buildScoredNetworkWithMockBadgeCurve()); 416 when(mockBadgeCurve.lookupScore(anyInt())).thenReturn((byte) AccessPoint.Speed.MODERATE); 417 418 ap.update(mockWifiNetworkScoreCache, true /* scoringUiEnabled */, 419 MAX_SCORE_CACHE_AGE_MILLIS); 420 421 assertThat(ap.getSpeed()).isEqualTo(AccessPoint.Speed.MODERATE); 422 assertThat(ap.getSpeedLabel()) 423 .isEqualTo(mContext.getString(R.string.speed_label_okay)); 424 } 425 426 @Test 427 public void testSpeedLabel_returnsSlow() { 428 AccessPoint ap = createAccessPointWithScanResultCache(); 429 430 when(mockWifiNetworkScoreCache.getScoredNetwork(any(ScanResult.class))) 431 .thenReturn(buildScoredNetworkWithMockBadgeCurve()); 432 when(mockBadgeCurve.lookupScore(anyInt())).thenReturn((byte) AccessPoint.Speed.SLOW); 433 434 ap.update(mockWifiNetworkScoreCache, true /* scoringUiEnabled */, 435 MAX_SCORE_CACHE_AGE_MILLIS); 436 437 assertThat(ap.getSpeed()).isEqualTo(AccessPoint.Speed.SLOW); 438 assertThat(ap.getSpeedLabel()) 439 .isEqualTo(mContext.getString(R.string.speed_label_slow)); 440 } 441 442 @Test 443 public void testSummaryString_showsSpeedLabel() { 444 AccessPoint ap = createAccessPointWithScanResultCache(); 445 446 when(mockWifiNetworkScoreCache.getScoredNetwork(any(ScanResult.class))) 447 .thenReturn(buildScoredNetworkWithMockBadgeCurve()); 448 when(mockBadgeCurve.lookupScore(anyInt())).thenReturn((byte) AccessPoint.Speed.VERY_FAST); 449 450 ap.update(mockWifiNetworkScoreCache, true /* scoringUiEnabled */, 451 MAX_SCORE_CACHE_AGE_MILLIS); 452 453 assertThat(ap.getSummary()).isEqualTo(mContext.getString(R.string.speed_label_very_fast)); 454 } 455 456 @Test 457 public void testSummaryString_concatenatesSpeedLabel() { 458 AccessPoint ap = createAccessPointWithScanResultCache(); 459 ap.update(new WifiConfiguration()); 460 461 when(mockWifiNetworkScoreCache.getScoredNetwork(any(ScanResult.class))) 462 .thenReturn(buildScoredNetworkWithMockBadgeCurve()); 463 when(mockBadgeCurve.lookupScore(anyInt())).thenReturn((byte) AccessPoint.Speed.VERY_FAST); 464 465 ap.update(mockWifiNetworkScoreCache, true /* scoringUiEnabled */, 466 MAX_SCORE_CACHE_AGE_MILLIS); 467 468 String expectedString = mContext.getString(R.string.speed_label_very_fast) + " / " 469 + mContext.getString(R.string.wifi_remembered); 470 assertThat(ap.getSummary()).isEqualTo(expectedString); 471 } 472 473 @Test 474 public void testSummaryString_showsWrongPasswordLabel() { 475 WifiConfiguration configuration = spy(createWifiConfiguration()); 476 WifiConfiguration.NetworkSelectionStatus status = 477 mock(WifiConfiguration.NetworkSelectionStatus.class); 478 when(configuration.getNetworkSelectionStatus()).thenReturn(status); 479 when(status.getNetworkSelectionStatus()).thenReturn( 480 WifiConfiguration.NetworkSelectionStatus.NETWORK_SELECTION_TEMPORARY_DISABLED); 481 when(status.getNetworkSelectionDisableReason()).thenReturn( 482 WifiConfiguration.NetworkSelectionStatus.DISABLED_BY_WRONG_PASSWORD); 483 AccessPoint ap = new AccessPoint(mContext, configuration); 484 485 assertThat(ap.getSummary()).isEqualTo(mContext.getString( 486 R.string.wifi_check_password_try_again)); 487 } 488 489 @Test 490 public void testSummaryString_showsDisconnected() { 491 AccessPoint ap = createAccessPointWithScanResultCache(); 492 ap.update(new WifiConfiguration()); 493 494 assertThat(ap.getSettingsSummary(true /*convertSavedAsDisconnected*/)) 495 .isEqualTo(mContext.getString(R.string.wifi_disconnected)); 496 } 497 498 @Test 499 public void testSummaryString_concatenatedMeteredAndDisconnected() { 500 AccessPoint ap = createAccessPointWithScanResultCache(); 501 WifiConfiguration config = new WifiConfiguration(); 502 config.meteredHint = true; 503 ap.update(config); 504 505 String expectedString = 506 mContext.getResources().getString(R.string.preference_summary_default_combination, 507 mContext.getString(R.string.wifi_metered_label), 508 mContext.getString(R.string.wifi_disconnected)); 509 assertThat(ap.getSettingsSummary(true /*convertSavedAsDisconnected*/)) 510 .isEqualTo(expectedString); 511 } 512 513 @Test 514 public void testSummaryString_showsConnectedViaSuggestionOrSpecifierApp() throws Exception { 515 final int rssi = -55; 516 final String appPackageName = "com.test.app"; 517 final CharSequence appLabel = "Test App"; 518 final String connectedViaAppResourceString = "Connected via "; 519 520 WifiInfo wifiInfo = new WifiInfo(); 521 wifiInfo.setSSID(WifiSsid.createFromAsciiEncoded(TEST_SSID)); 522 wifiInfo.setEphemeral(true); 523 wifiInfo.setRequestingPackageName(appPackageName); 524 wifiInfo.setRssi(rssi); 525 526 Context context = mock(Context.class); 527 Resources resources = mock(Resources.class); 528 PackageManager packageManager = mock(PackageManager.class); 529 ApplicationInfo applicationInfo = mock(ApplicationInfo.class); 530 when(context.getPackageManager()).thenReturn(packageManager); 531 when(context.getResources()).thenReturn(resources); 532 when(resources.getString(R.string.connected_via_app, appLabel)) 533 .thenReturn(connectedViaAppResourceString + appLabel.toString()); 534 when(packageManager.getApplicationInfoAsUser(eq(appPackageName), anyInt(), anyInt())) 535 .thenReturn(applicationInfo); 536 when(applicationInfo.loadLabel(packageManager)).thenReturn(appLabel); 537 when(context.getSystemService(Context.WIFI_SERVICE)).thenReturn(mMockWifiManager); 538 when(mMockWifiManager.calculateSignalLevel(rssi)).thenReturn(4); 539 540 NetworkInfo networkInfo = 541 new NetworkInfo(ConnectivityManager.TYPE_WIFI, 0 /* subtype */, "WIFI", ""); 542 networkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTED, "", ""); 543 544 AccessPoint ap = new TestAccessPointBuilder(context) 545 .setSsid(TEST_SSID) 546 .setNetworkInfo(networkInfo) 547 .setRssi(rssi) 548 .setSecurity(AccessPoint.SECURITY_NONE) 549 .setWifiInfo(wifiInfo) 550 .build(); 551 assertThat(ap.getSummary()).isEqualTo("Connected via Test App"); 552 } 553 554 private ScoredNetwork buildScoredNetworkWithMockBadgeCurve() { 555 return buildScoredNetworkWithGivenBadgeCurve(mockBadgeCurve); 556 } 557 558 private ScoredNetwork buildScoredNetworkWithGivenBadgeCurve(RssiCurve badgeCurve) { 559 Bundle attr1 = new Bundle(); 560 attr1.putParcelable(ScoredNetwork.ATTRIBUTES_KEY_BADGING_CURVE, badgeCurve); 561 return new ScoredNetwork( 562 new NetworkKey(new WifiKey(TEST_SSID, TEST_BSSID)), 563 badgeCurve, 564 false /* meteredHint */, 565 attr1); 566 } 567 568 private AccessPoint createAccessPointWithScanResultCache() { 569 Bundle bundle = new Bundle(); 570 bundle.putParcelableArray( 571 AccessPoint.KEY_SCANRESULTS, 572 mScanResults.toArray(new Parcelable[mScanResults.size()])); 573 return new AccessPoint(mContext, bundle); 574 } 575 576 private ArrayList<ScanResult> buildScanResultCache(String ssid) { 577 ArrayList<ScanResult> scanResults = new ArrayList<>(); 578 for (int i = 0; i < 5; i++) { 579 ScanResult scanResult = createScanResult(ssid, "bssid-" + i, i); 580 scanResults.add(scanResult); 581 } 582 return scanResults; 583 } 584 585 private WifiConfiguration createWifiConfiguration() { 586 WifiConfiguration configuration = new WifiConfiguration(); 587 configuration.BSSID = "bssid"; 588 configuration.SSID = "ssid"; 589 configuration.networkId = 123; 590 return configuration; 591 } 592 593 private AccessPoint createApWithFastTimestampedScoredNetworkCache( 594 long elapsedTimeMillis) { 595 TimestampedScoredNetwork recentScore = new TimestampedScoredNetwork( 596 buildScoredNetworkWithGivenBadgeCurve(FAST_BADGE_CURVE), 597 elapsedTimeMillis); 598 return new TestAccessPointBuilder(mContext) 599 .setSsid(TEST_SSID) 600 .setScoredNetworkCache( 601 new ArrayList<>(Arrays.asList(recentScore))) 602 .build(); 603 } 604 605 /** 606 * Assert that the first AccessPoint appears before the second AccessPoint 607 * once sorting has been completed. 608 */ 609 private void assertSortingWorks(AccessPoint first, AccessPoint second) { 610 611 ArrayList<AccessPoint> points = new ArrayList<AccessPoint>(); 612 613 // add in reverse order so we can tell that sorting actually changed something 614 points.add(second); 615 points.add(first); 616 Collections.sort(points); 617 assertWithMessage( 618 String.format("After sorting: second AccessPoint should have higher array index " 619 + "than the first, but found indicies second '%s' and first '%s'.", 620 points.indexOf(second), points.indexOf(first))) 621 .that(points.indexOf(second)).isGreaterThan(points.indexOf(first)); 622 } 623 624 @Test 625 public void testBuilder_setActive() { 626 AccessPoint activeAp = new TestAccessPointBuilder(mContext).setActive(true).build(); 627 assertThat(activeAp.isActive()).isTrue(); 628 629 AccessPoint inactiveAp = new TestAccessPointBuilder(mContext).setActive(false).build(); 630 assertThat(inactiveAp.isActive()).isFalse(); 631 } 632 633 @Test 634 public void testBuilder_setReachable() { 635 AccessPoint nearAp = new TestAccessPointBuilder(mContext).setReachable(true).build(); 636 assertThat(nearAp.isReachable()).isTrue(); 637 638 AccessPoint farAp = new TestAccessPointBuilder(mContext).setReachable(false).build(); 639 assertThat(farAp.isReachable()).isFalse(); 640 } 641 642 @Test 643 public void testBuilder_setSaved() { 644 AccessPoint savedAp = new TestAccessPointBuilder(mContext).setSaved(true).build(); 645 assertThat(savedAp.isSaved()).isTrue(); 646 647 AccessPoint newAp = new TestAccessPointBuilder(mContext).setSaved(false).build(); 648 assertThat(newAp.isSaved()).isFalse(); 649 } 650 651 @Test 652 public void testBuilder_setLevel() { 653 AccessPoint testAp; 654 655 for (int i = 0; i <= mMaxSignalLevel; i++) { 656 testAp = new TestAccessPointBuilder(mContext).setLevel(i).build(); 657 assertThat(testAp.getLevel()).isEqualTo(i); 658 } 659 660 // numbers larger than the max level should be set to max 661 testAp = new TestAccessPointBuilder(mContext).setLevel(mMaxSignalLevel + 1).build(); 662 assertThat(testAp.getLevel()).isEqualTo(mMaxSignalLevel); 663 664 // numbers less than 0 should give level 0 665 testAp = new TestAccessPointBuilder(mContext).setLevel(-100).build(); 666 assertThat(testAp.getLevel()).isEqualTo(0); 667 } 668 669 @Test 670 public void testBuilder_settingReachableAfterLevelDoesNotAffectLevel() { 671 int level = 1; 672 assertThat(level).isLessThan(mMaxSignalLevel); 673 674 AccessPoint testAp = 675 new TestAccessPointBuilder(mContext).setLevel(level).setReachable(true).build(); 676 assertThat(testAp.getLevel()).isEqualTo(level); 677 } 678 679 @Test 680 public void testBuilder_setSsid() { 681 String name = "AmazingSsid!"; 682 AccessPoint namedAp = new TestAccessPointBuilder(mContext).setSsid(name).build(); 683 assertThat(namedAp.getSsidStr()).isEqualTo(name); 684 } 685 686 @Test 687 public void testBuilder_passpointConfig() { 688 String fqdn = "Test.com"; 689 String providerFriendlyName = "Test Provider"; 690 AccessPoint ap = new TestAccessPointBuilder(mContext).setFqdn(fqdn) 691 .setProviderFriendlyName(providerFriendlyName).build(); 692 assertThat(ap.isPasspointConfig()).isTrue(); 693 assertThat(ap.getPasspointFqdn()).isEqualTo(fqdn); 694 assertThat(ap.getTitle()).isEqualTo(providerFriendlyName); 695 } 696 697 // This method doesn't copy mIsFailover, mIsAvailable and mIsRoaming because NetworkInfo 698 // doesn't expose those three set methods. But that's fine since the tests don't use those three 699 // variables. 700 private NetworkInfo copyNetworkInfo(NetworkInfo ni) { 701 final NetworkInfo copy = new NetworkInfo(ni.getType(), ni.getSubtype(), ni.getTypeName(), 702 ni.getSubtypeName()); 703 copy.setDetailedState(ni.getDetailedState(), ni.getReason(), ni.getExtraInfo()); 704 return copy; 705 } 706 707 @Test 708 public void testUpdateNetworkInfo_returnsTrue() { 709 int networkId = 123; 710 int rssi = -55; 711 WifiConfiguration config = new WifiConfiguration(); 712 config.networkId = networkId; 713 WifiInfo wifiInfo = new WifiInfo(); 714 wifiInfo.setNetworkId(networkId); 715 wifiInfo.setRssi(rssi); 716 717 NetworkInfo networkInfo = 718 new NetworkInfo(ConnectivityManager.TYPE_WIFI, 0 /* subtype */, "WIFI", ""); 719 networkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTING, "", ""); 720 721 AccessPoint ap = new TestAccessPointBuilder(mContext) 722 .setNetworkInfo(networkInfo) 723 .setNetworkId(networkId) 724 .setRssi(rssi) 725 .setWifiInfo(wifiInfo) 726 .build(); 727 728 NetworkInfo newInfo = copyNetworkInfo(networkInfo); 729 newInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTED, "", ""); 730 assertThat(ap.update(config, wifiInfo, newInfo)).isTrue(); 731 } 732 733 @Test 734 public void testUpdateNetworkInfoWithSameInfo_returnsFalse() { 735 int networkId = 123; 736 int rssi = -55; 737 WifiConfiguration config = new WifiConfiguration(); 738 config.networkId = networkId; 739 WifiInfo wifiInfo = new WifiInfo(); 740 wifiInfo.setNetworkId(networkId); 741 wifiInfo.setRssi(rssi); 742 743 NetworkInfo networkInfo = 744 new NetworkInfo(ConnectivityManager.TYPE_WIFI, 0 /* subtype */, "WIFI", ""); 745 networkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTING, "", ""); 746 747 AccessPoint ap = new TestAccessPointBuilder(mContext) 748 .setNetworkInfo(networkInfo) 749 .setNetworkId(networkId) 750 .setRssi(rssi) 751 .setWifiInfo(wifiInfo) 752 .build(); 753 754 NetworkInfo newInfo = copyNetworkInfo(networkInfo); // same values 755 assertThat(ap.update(config, wifiInfo, newInfo)).isFalse(); 756 } 757 758 @Test 759 public void testUpdateWithDifferentRssi_returnsTrue() { 760 int networkId = 123; 761 int rssi = -55; 762 WifiConfiguration config = new WifiConfiguration(); 763 config.networkId = networkId; 764 WifiInfo wifiInfo = new WifiInfo(); 765 wifiInfo.setNetworkId(networkId); 766 wifiInfo.setRssi(rssi); 767 768 NetworkInfo networkInfo = 769 new NetworkInfo(ConnectivityManager.TYPE_WIFI, 0 /* subtype */, "WIFI", ""); 770 networkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTING, "", ""); 771 772 AccessPoint ap = new TestAccessPointBuilder(mContext) 773 .setNetworkInfo(networkInfo) 774 .setNetworkId(networkId) 775 .setRssi(rssi) 776 .setWifiInfo(wifiInfo) 777 .build(); 778 779 NetworkInfo newInfo = copyNetworkInfo(networkInfo); // same values 780 wifiInfo.setRssi(rssi + 1); 781 assertThat(ap.update(config, wifiInfo, newInfo)).isTrue(); 782 } 783 784 @Test 785 public void testUpdateWithInvalidRssi_returnsFalse() { 786 int networkId = 123; 787 int rssi = -55; 788 WifiConfiguration config = new WifiConfiguration(); 789 config.networkId = networkId; 790 WifiInfo wifiInfo = new WifiInfo(); 791 wifiInfo.setNetworkId(networkId); 792 wifiInfo.setRssi(rssi); 793 794 NetworkInfo networkInfo = 795 new NetworkInfo(ConnectivityManager.TYPE_WIFI, 0 /* subtype */, "WIFI", ""); 796 networkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTING, "", ""); 797 798 AccessPoint ap = new TestAccessPointBuilder(mContext) 799 .setNetworkInfo(networkInfo) 800 .setNetworkId(networkId) 801 .setRssi(rssi) 802 .setWifiInfo(wifiInfo) 803 .build(); 804 805 NetworkInfo newInfo = copyNetworkInfo(networkInfo); // same values 806 wifiInfo.setRssi(WifiInfo.INVALID_RSSI); 807 assertThat(ap.update(config, wifiInfo, newInfo)).isFalse(); 808 } 809 @Test 810 public void testUpdateWithConfigChangeOnly_returnsFalseButInvokesListener() 811 throws InterruptedException { 812 WifiConfiguration config = new WifiConfiguration(); 813 config.networkId = NETWORK_ID; 814 config.numNoInternetAccessReports = 1; 815 816 WifiInfo wifiInfo = new WifiInfo(); 817 wifiInfo.setNetworkId(NETWORK_ID); 818 wifiInfo.setRssi(DEFAULT_RSSI); 819 820 NetworkInfo networkInfo = 821 new NetworkInfo(ConnectivityManager.TYPE_WIFI, 0 /* subtype */, "WIFI", ""); 822 networkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTED, "", ""); 823 824 AccessPoint ap = new TestAccessPointBuilder(mContext) 825 .setNetworkInfo(networkInfo) 826 .setNetworkId(NETWORK_ID) 827 .setRssi(DEFAULT_RSSI) 828 .setWifiInfo(wifiInfo) 829 .build(); 830 831 AccessPoint.AccessPointListener mockListener = mock(AccessPoint.AccessPointListener.class); 832 ap.setListener(mockListener); 833 WifiConfiguration newConfig = new WifiConfiguration(config); 834 config.validatedInternetAccess = true; 835 836 assertThat(ap.update(newConfig, wifiInfo, networkInfo)).isFalse(); 837 838 // Wait for MainHandler to process callback 839 CountDownLatch latch = new CountDownLatch(1); 840 ThreadUtils.postOnMainThread(latch::countDown); 841 842 latch.await(); 843 verify(mockListener).onAccessPointChanged(ap); 844 } 845 846 @Test 847 public void testConnectionInfo_doesNotThrowNPE_ifListenerIsNulledWhileAwaitingExecution() 848 throws InterruptedException { 849 WifiConfiguration config = new WifiConfiguration(); 850 config.networkId = NETWORK_ID; 851 config.numNoInternetAccessReports = 1; 852 853 WifiInfo wifiInfo = new WifiInfo(); 854 wifiInfo.setNetworkId(NETWORK_ID); 855 wifiInfo.setRssi(DEFAULT_RSSI); 856 857 NetworkInfo networkInfo = 858 new NetworkInfo(ConnectivityManager.TYPE_WIFI, 0 /* subtype */, "WIFI", ""); 859 networkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTED, "", ""); 860 861 AccessPoint ap = new TestAccessPointBuilder(mContext) 862 .setNetworkInfo(networkInfo) 863 .setNetworkId(NETWORK_ID) 864 .setRssi(DEFAULT_RSSI) 865 .setWifiInfo(wifiInfo) 866 .build(); 867 868 WifiConfiguration newConfig = new WifiConfiguration(config); 869 config.validatedInternetAccess = true; 870 871 performGivenUpdateAndThenNullListenerBeforeResumingMainHandlerExecution( 872 ap, () -> assertThat(ap.update(newConfig, wifiInfo, networkInfo)).isFalse()); 873 874 } 875 876 private void performGivenUpdateAndThenNullListenerBeforeResumingMainHandlerExecution( 877 AccessPoint ap, Runnable r) { 878 AccessPoint.AccessPointListener mockListener = mock(AccessPoint.AccessPointListener.class); 879 ap.setListener(mockListener); 880 881 // Put a latch on the MainHandler to prevent the callback from being invoked instantly 882 CountDownLatch latch1 = new CountDownLatch(1); 883 ThreadUtils.postOnMainThread(() -> { 884 try{ 885 latch1.await(); 886 } catch (InterruptedException e) { 887 fail("Interruped Exception thrown while awaiting latch countdown"); 888 } 889 }); 890 891 r.run(); 892 893 ap.setListener(null); 894 latch1.countDown(); 895 896 // The second latch ensures the previously posted listener invocation has processed on the 897 // main thread. 898 CountDownLatch latch2 = new CountDownLatch(1); 899 ThreadUtils.postOnMainThread(latch2::countDown); 900 901 try{ 902 latch2.await(); 903 } catch (InterruptedException e) { 904 fail("Interruped Exception thrown while awaiting latch countdown"); 905 } 906 } 907 908 @Test 909 public void testUpdateScanResults_doesNotThrowNPE_ifListenerIsNulledWhileAwaitingExecution() 910 throws InterruptedException { 911 String ssid = "ssid"; 912 int newRssi = -80; 913 AccessPoint ap = new TestAccessPointBuilder(mContext).setSsid(ssid).build(); 914 915 ScanResult scanResult = new ScanResult(); 916 scanResult.SSID = ssid; 917 scanResult.level = newRssi; 918 scanResult.BSSID = "bssid"; 919 scanResult.timestamp = SystemClock.elapsedRealtime() * 1000; 920 scanResult.capabilities = ""; 921 922 performGivenUpdateAndThenNullListenerBeforeResumingMainHandlerExecution( 923 ap, () -> ap.setScanResults(Collections.singletonList(scanResult))); 924 } 925 926 @Test testUpdateConfig_doesNotThrowNPE_ifListenerIsNulledWhileAwaitingExecution()927 public void testUpdateConfig_doesNotThrowNPE_ifListenerIsNulledWhileAwaitingExecution() 928 throws InterruptedException { 929 WifiConfiguration config = new WifiConfiguration(); 930 config.networkId = NETWORK_ID; 931 config.numNoInternetAccessReports = 1; 932 933 WifiInfo wifiInfo = new WifiInfo(); 934 wifiInfo.setNetworkId(NETWORK_ID); 935 wifiInfo.setRssi(DEFAULT_RSSI); 936 937 NetworkInfo networkInfo = 938 new NetworkInfo(ConnectivityManager.TYPE_WIFI, 0 /* subtype */, "WIFI", ""); 939 networkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTED, "", ""); 940 941 AccessPoint ap = new TestAccessPointBuilder(mContext) 942 .setNetworkInfo(networkInfo) 943 .setNetworkId(NETWORK_ID) 944 .setRssi(DEFAULT_RSSI) 945 .setWifiInfo(wifiInfo) 946 .build(); 947 948 WifiConfiguration newConfig = new WifiConfiguration(config); 949 config.validatedInternetAccess = true; 950 951 performGivenUpdateAndThenNullListenerBeforeResumingMainHandlerExecution( 952 ap, () -> ap.update(newConfig)); 953 } 954 955 @Test testUpdateWithNullWifiConfiguration_doesNotThrowNPE()956 public void testUpdateWithNullWifiConfiguration_doesNotThrowNPE() { 957 WifiConfiguration config = new WifiConfiguration(); 958 config.networkId = NETWORK_ID; 959 WifiInfo wifiInfo = new WifiInfo(); 960 wifiInfo.setNetworkId(NETWORK_ID); 961 wifiInfo.setRssi(DEFAULT_RSSI); 962 963 NetworkInfo networkInfo = 964 new NetworkInfo(ConnectivityManager.TYPE_WIFI, 0 /* subtype */, "WIFI", ""); 965 networkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTING, "", ""); 966 967 AccessPoint ap = new TestAccessPointBuilder(mContext) 968 .setNetworkInfo(networkInfo) 969 .setNetworkId(NETWORK_ID) 970 .setRssi(DEFAULT_RSSI) 971 .setWifiInfo(wifiInfo) 972 .build(); 973 974 ap.update(null, wifiInfo, networkInfo); 975 } 976 977 @Test testSpeedLabelAveragesAllBssidScores()978 public void testSpeedLabelAveragesAllBssidScores() { 979 AccessPoint ap = createAccessPointWithScanResultCache(); 980 981 int speed1 = Speed.MODERATE; 982 RssiCurve badgeCurve1 = mock(RssiCurve.class); 983 when(badgeCurve1.lookupScore(anyInt())).thenReturn((byte) speed1); 984 when(mockWifiNetworkScoreCache.getScoredNetwork(mScanResults.get(0))) 985 .thenReturn(buildScoredNetworkWithGivenBadgeCurve(badgeCurve1)); 986 int speed2 = Speed.VERY_FAST; 987 RssiCurve badgeCurve2 = mock(RssiCurve.class); 988 when(badgeCurve2.lookupScore(anyInt())).thenReturn((byte) speed2); 989 when(mockWifiNetworkScoreCache.getScoredNetwork(mScanResults.get(1))) 990 .thenReturn(buildScoredNetworkWithGivenBadgeCurve(badgeCurve2)); 991 992 int expectedSpeed = (speed1 + speed2) / 2; 993 994 ap.update(mockWifiNetworkScoreCache, true /* scoringUiEnabled */, 995 MAX_SCORE_CACHE_AGE_MILLIS); 996 997 assertThat(ap.getSpeed()).isEqualTo(expectedSpeed); 998 } 999 1000 @Test testSpeedLabelAverageIgnoresNoSpeedScores()1001 public void testSpeedLabelAverageIgnoresNoSpeedScores() { 1002 AccessPoint ap = createAccessPointWithScanResultCache(); 1003 1004 int speed1 = Speed.VERY_FAST; 1005 RssiCurve badgeCurve1 = mock(RssiCurve.class); 1006 when(badgeCurve1.lookupScore(anyInt())).thenReturn((byte) speed1); 1007 when(mockWifiNetworkScoreCache.getScoredNetwork(mScanResults.get(0))) 1008 .thenReturn(buildScoredNetworkWithGivenBadgeCurve(badgeCurve1)); 1009 int speed2 = Speed.NONE; 1010 RssiCurve badgeCurve2 = mock(RssiCurve.class); 1011 when(badgeCurve2.lookupScore(anyInt())).thenReturn((byte) speed2); 1012 when(mockWifiNetworkScoreCache.getScoredNetwork(mScanResults.get(1))) 1013 .thenReturn(buildScoredNetworkWithGivenBadgeCurve(badgeCurve2)); 1014 1015 ap.update( 1016 mockWifiNetworkScoreCache, true /* scoringUiEnabled */, MAX_SCORE_CACHE_AGE_MILLIS); 1017 1018 assertThat(ap.getSpeed()).isEqualTo(speed1); 1019 } 1020 1021 @Test testSpeedLabelFallbackScoreIgnoresNullCurves()1022 public void testSpeedLabelFallbackScoreIgnoresNullCurves() { 1023 String bssid = "00:00:00:00:00:00"; 1024 1025 WifiInfo info = new WifiInfo(); 1026 info.setRssi(DEFAULT_RSSI); 1027 info.setSSID(WifiSsid.createFromAsciiEncoded(TEST_SSID)); 1028 info.setBSSID(bssid); 1029 info.setNetworkId(NETWORK_ID); 1030 1031 ArrayList<ScanResult> scanResults = new ArrayList<>(); 1032 ScanResult scanResultUnconnected = 1033 createScanResult(TEST_SSID, "11:11:11:11:11:11", DEFAULT_RSSI); 1034 scanResults.add(scanResultUnconnected); 1035 1036 ScanResult scanResultConnected = 1037 createScanResult(TEST_SSID, bssid, DEFAULT_RSSI); 1038 scanResults.add(scanResultConnected); 1039 1040 AccessPoint ap = 1041 new TestAccessPointBuilder(mContext) 1042 .setActive(true) 1043 .setNetworkId(NETWORK_ID) 1044 .setSsid(TEST_SSID) 1045 .setScanResults(scanResults) 1046 .setWifiInfo(info) 1047 .build(); 1048 1049 int fallbackSpeed = Speed.SLOW; 1050 when(mockWifiNetworkScoreCache.getScoredNetwork(scanResultUnconnected)) 1051 .thenReturn(buildScoredNetworkWithMockBadgeCurve()); 1052 when(mockBadgeCurve.lookupScore(anyInt())).thenReturn((byte) fallbackSpeed); 1053 1054 when(mockWifiNetworkScoreCache.getScoredNetwork(scanResultConnected)) 1055 .thenReturn(null); 1056 1057 ap.update(mockWifiNetworkScoreCache, true /* scoringUiEnabled */, 1058 MAX_SCORE_CACHE_AGE_MILLIS); 1059 1060 assertThat(ap.getSpeed()).isEqualTo(fallbackSpeed); 1061 } 1062 1063 @Test testScoredNetworkCacheBundling()1064 public void testScoredNetworkCacheBundling() { 1065 long timeMillis = SystemClock.elapsedRealtime(); 1066 AccessPoint ap = createApWithFastTimestampedScoredNetworkCache(timeMillis); 1067 Bundle bundle = new Bundle(); 1068 ap.saveWifiState(bundle); 1069 1070 ArrayList<TimestampedScoredNetwork> list = 1071 bundle.getParcelableArrayList(AccessPoint.KEY_SCOREDNETWORKCACHE); 1072 assertThat(list).hasSize(1); 1073 assertThat(list.get(0).getUpdatedTimestampMillis()).isEqualTo(timeMillis); 1074 1075 RssiCurve curve = list.get(0).getScore().attributes.getParcelable( 1076 ScoredNetwork.ATTRIBUTES_KEY_BADGING_CURVE); 1077 assertThat(curve).isEqualTo(FAST_BADGE_CURVE); 1078 } 1079 1080 @Test testRecentNetworkScoresAreUsedForSpeedLabelGeneration()1081 public void testRecentNetworkScoresAreUsedForSpeedLabelGeneration() { 1082 AccessPoint ap = 1083 createApWithFastTimestampedScoredNetworkCache(SystemClock.elapsedRealtime()); 1084 1085 ap.update(mockWifiNetworkScoreCache, true /* scoringUiEnabled */, 1086 MAX_SCORE_CACHE_AGE_MILLIS); 1087 1088 assertThat(ap.getSpeed()).isEqualTo(Speed.FAST); 1089 } 1090 1091 @Test testNetworkScoresAreUsedForSpeedLabelGenerationWhenWithinAgeRange()1092 public void testNetworkScoresAreUsedForSpeedLabelGenerationWhenWithinAgeRange() { 1093 long withinRangeTimeMillis = 1094 SystemClock.elapsedRealtime() - (MAX_SCORE_CACHE_AGE_MILLIS - 10000); 1095 AccessPoint ap = 1096 createApWithFastTimestampedScoredNetworkCache(withinRangeTimeMillis); 1097 1098 ap.update(mockWifiNetworkScoreCache, true /* scoringUiEnabled */, 1099 MAX_SCORE_CACHE_AGE_MILLIS); 1100 1101 assertThat(ap.getSpeed()).isEqualTo(Speed.FAST); 1102 } 1103 1104 @Test testOldNetworkScoresAreNotUsedForSpeedLabelGeneration()1105 public void testOldNetworkScoresAreNotUsedForSpeedLabelGeneration() { 1106 long tooOldTimeMillis = 1107 SystemClock.elapsedRealtime() - (MAX_SCORE_CACHE_AGE_MILLIS + 1); 1108 AccessPoint ap = 1109 createApWithFastTimestampedScoredNetworkCache(tooOldTimeMillis); 1110 1111 ap.update(mockWifiNetworkScoreCache, true /* scoringUiEnabled */, 1112 MAX_SCORE_CACHE_AGE_MILLIS); 1113 1114 assertThat(ap.getSpeed()).isEqualTo(Speed.NONE); 1115 } 1116 1117 @Test testUpdateScoresRefreshesScoredNetworkCacheTimestamps()1118 public void testUpdateScoresRefreshesScoredNetworkCacheTimestamps () { 1119 long tooOldTimeMillis = 1120 SystemClock.elapsedRealtime() - (MAX_SCORE_CACHE_AGE_MILLIS + 1); 1121 1122 ScoredNetwork scoredNetwork = buildScoredNetworkWithGivenBadgeCurve(FAST_BADGE_CURVE); 1123 TimestampedScoredNetwork recentScore = new TimestampedScoredNetwork( 1124 scoredNetwork, 1125 tooOldTimeMillis); 1126 AccessPoint ap = new TestAccessPointBuilder(mContext) 1127 .setSsid(TEST_SSID) 1128 .setBssid(TEST_BSSID) 1129 .setActive(true) 1130 .setScoredNetworkCache( 1131 new ArrayList(Arrays.asList(recentScore))) 1132 .setScanResults(mScanResults) 1133 .build(); 1134 1135 when(mockWifiNetworkScoreCache.getScoredNetwork(any(ScanResult.class))) 1136 .thenReturn(scoredNetwork); 1137 1138 ap.update(mockWifiNetworkScoreCache, true /* scoringUiEnabled */, 1139 MAX_SCORE_CACHE_AGE_MILLIS); 1140 1141 // Fast should still be returned since cache was updated with recent time 1142 assertThat(ap.getSpeed()).isEqualTo(Speed.FAST); 1143 } 1144 1145 @Test testUpdateScoresRefreshesScoredNetworkCacheWithNewSpeed()1146 public void testUpdateScoresRefreshesScoredNetworkCacheWithNewSpeed () { 1147 long tooOldTimeMillis = 1148 SystemClock.elapsedRealtime() - (MAX_SCORE_CACHE_AGE_MILLIS + 1); 1149 1150 ScoredNetwork scoredNetwork = buildScoredNetworkWithGivenBadgeCurve(FAST_BADGE_CURVE); 1151 TimestampedScoredNetwork recentScore = new TimestampedScoredNetwork( 1152 scoredNetwork, 1153 tooOldTimeMillis); 1154 AccessPoint ap = new TestAccessPointBuilder(mContext) 1155 .setSsid(TEST_SSID) 1156 .setBssid(TEST_BSSID) 1157 .setActive(true) 1158 .setScoredNetworkCache( 1159 new ArrayList(Arrays.asList(recentScore))) 1160 .setScanResults(mScanResults) 1161 .build(); 1162 1163 int newSpeed = Speed.MODERATE; 1164 when(mockWifiNetworkScoreCache.getScoredNetwork(any(ScanResult.class))) 1165 .thenReturn(buildScoredNetworkWithMockBadgeCurve()); 1166 when(mockBadgeCurve.lookupScore(anyInt())).thenReturn((byte) newSpeed); 1167 1168 ap.update(mockWifiNetworkScoreCache, true /* scoringUiEnabled */, 1169 MAX_SCORE_CACHE_AGE_MILLIS); 1170 1171 // Fast should still be returned since cache was updated with recent time 1172 assertThat(ap.getSpeed()).isEqualTo(newSpeed); 1173 } 1174 1175 /** 1176 * Verifies that a Passpoint WifiInfo updates the matching Passpoint AP 1177 */ 1178 @Test testUpdate_passpointWifiInfo_updatesPasspointAccessPoint()1179 public void testUpdate_passpointWifiInfo_updatesPasspointAccessPoint() { 1180 mWifiInfo.setFQDN("fqdn"); 1181 mWifiInfo.setProviderFriendlyName("providerFriendlyName"); 1182 1183 WifiConfiguration spyConfig = spy(new WifiConfiguration()); 1184 when(spyConfig.isPasspoint()).thenReturn(true); 1185 spyConfig.SSID = TEST_SSID; 1186 spyConfig.BSSID = TEST_BSSID; 1187 spyConfig.FQDN = "fqdn"; 1188 spyConfig.providerFriendlyName = "providerFriendlyName"; 1189 AccessPoint passpointAp = new AccessPoint(mContext, spyConfig); 1190 1191 assertThat(passpointAp.update(null, mWifiInfo, null)).isTrue(); 1192 } 1193 1194 /** 1195 * Verifies that a Passpoint WifiInfo does not update a non-Passpoint AP with the same SSID. 1196 */ 1197 @Test testUpdate_passpointWifiInfo_doesNotUpdateNonPasspointAccessPoint()1198 public void testUpdate_passpointWifiInfo_doesNotUpdateNonPasspointAccessPoint() { 1199 mWifiInfo.setFQDN("fqdn"); 1200 mWifiInfo.setProviderFriendlyName("providerFriendlyName"); 1201 1202 AccessPoint ap = new TestAccessPointBuilder(mContext) 1203 .setSsid(TEST_SSID) 1204 .setBssid(TEST_BSSID) 1205 .setScanResults(mScanResults) 1206 .build(); 1207 1208 assertThat(ap.update(null, mWifiInfo, null)).isFalse(); 1209 } 1210 1211 /** 1212 * Verifies that a non-Passpoint WifiInfo does not update a Passpoint AP with the same SSID. 1213 */ 1214 @Test testUpdate_nonPasspointWifiInfo_doesNotUpdatePasspointAccessPoint()1215 public void testUpdate_nonPasspointWifiInfo_doesNotUpdatePasspointAccessPoint() { 1216 WifiConfiguration spyConfig = spy(new WifiConfiguration()); 1217 when(spyConfig.isPasspoint()).thenReturn(true); 1218 spyConfig.SSID = TEST_SSID; 1219 spyConfig.BSSID = TEST_BSSID; 1220 spyConfig.FQDN = "fqdn"; 1221 spyConfig.providerFriendlyName = "providerFriendlyName"; 1222 AccessPoint passpointAp = new AccessPoint(mContext, spyConfig); 1223 1224 assertThat(passpointAp.update(null, mWifiInfo, null)).isFalse(); 1225 } 1226 1227 /** 1228 * Verifies that an AccessPoint's getKey() is consistent with the overloaded static getKey(). 1229 */ 1230 @Test testGetKey_matchesKeysCorrectly()1231 public void testGetKey_matchesKeysCorrectly() { 1232 AccessPoint ap = new AccessPoint(mContext, mScanResults); 1233 assertThat(ap.getKey()).isEqualTo(AccessPoint.getKey(mContext, mScanResults.get(0))); 1234 1235 WifiConfiguration spyConfig = spy(new WifiConfiguration()); 1236 when(spyConfig.isPasspoint()).thenReturn(true); 1237 spyConfig.FQDN = "fqdn"; 1238 AccessPoint passpointAp = new AccessPoint(mContext, spyConfig, mScanResults, null); 1239 assertThat(passpointAp.getKey()).isEqualTo(AccessPoint.getKey(spyConfig)); 1240 1241 PasspointConfiguration passpointConfig = new PasspointConfiguration(); 1242 HomeSp homeSp = new HomeSp(); 1243 homeSp.setFqdn("fqdn"); 1244 homeSp.setFriendlyName("Test Provider"); 1245 passpointConfig.setHomeSp(homeSp); 1246 AccessPoint passpointConfigAp = new AccessPoint(mContext, passpointConfig); 1247 assertThat(passpointConfigAp.getKey()).isEqualTo(AccessPoint.getKey("fqdn")); 1248 1249 OsuProvider provider = createOsuProvider(); 1250 AccessPoint osuAp = new AccessPoint(mContext, provider, mScanResults); 1251 assertThat(osuAp.getKey()).isEqualTo(AccessPoint.getKey(provider)); 1252 } 1253 1254 /** 1255 * Test that getKey returns a key of SAE type for a PSK/SAE transition mode ScanResult. 1256 */ 1257 @Test testGetKey_supportSaeTransitionMode_shouldGetSaeKey()1258 public void testGetKey_supportSaeTransitionMode_shouldGetSaeKey() { 1259 ScanResult scanResult = createScanResult(TEST_SSID, TEST_BSSID, DEFAULT_RSSI); 1260 scanResult.capabilities = 1261 "[WPA2-FT/PSK-CCMP][RSN-FT/PSK+PSK-SHA256+SAE+FT/SAE-CCMP][ESS][WPS]"; 1262 when(mMockWifiManager.isWpa3SaeSupported()).thenReturn(true); 1263 when(mMockContext.getSystemService(Context.WIFI_SERVICE)).thenReturn(mMockWifiManager); 1264 StringBuilder key = new StringBuilder(); 1265 key.append(AccessPoint.KEY_PREFIX_AP); 1266 key.append(TEST_SSID); 1267 key.append(','); 1268 key.append(AccessPoint.SECURITY_SAE); 1269 1270 assertThat(AccessPoint.getKey(mMockContext, scanResult)).isEqualTo(key.toString()); 1271 } 1272 1273 /** 1274 * Test that getKey returns a key of PSK type for a PSK/SAE transition mode ScanResult. 1275 */ 1276 @Test testGetKey_notSupportSaeTransitionMode_shouldGetPskKey()1277 public void testGetKey_notSupportSaeTransitionMode_shouldGetPskKey() { 1278 ScanResult scanResult = createScanResult(TEST_SSID, TEST_BSSID, DEFAULT_RSSI); 1279 scanResult.capabilities = 1280 "[WPA2-FT/PSK-CCMP][RSN-FT/PSK+PSK-SHA256+SAE+FT/SAE-CCMP][ESS][WPS]"; 1281 when(mMockWifiManager.isWpa3SaeSupported()).thenReturn(false); 1282 when(mMockContext.getSystemService(Context.WIFI_SERVICE)).thenReturn(mMockWifiManager); 1283 StringBuilder key = new StringBuilder(); 1284 key.append(AccessPoint.KEY_PREFIX_AP); 1285 key.append(TEST_SSID); 1286 key.append(','); 1287 key.append(AccessPoint.SECURITY_PSK); 1288 1289 assertThat(AccessPoint.getKey(mMockContext, scanResult)).isEqualTo(key.toString()); 1290 } 1291 1292 /** 1293 * Verifies that the Passpoint AccessPoint constructor creates AccessPoints whose isPasspoint() 1294 * returns true. 1295 */ 1296 @Test testPasspointAccessPointConstructor_createdAccessPointIsPasspoint()1297 public void testPasspointAccessPointConstructor_createdAccessPointIsPasspoint() { 1298 WifiConfiguration spyConfig = spy(new WifiConfiguration()); 1299 when(spyConfig.isPasspoint()).thenReturn(true); 1300 AccessPoint passpointAccessPoint = new AccessPoint(mContext, spyConfig, 1301 mScanResults, mRoamingScans); 1302 1303 assertThat(passpointAccessPoint.isPasspoint()).isTrue(); 1304 } 1305 1306 /** 1307 * Verifies that Passpoint AccessPoints set their config's SSID to the home scans', and to the 1308 * roaming scans' if no home scans are available. 1309 */ 1310 @Test testSetScanResultsPasspoint_differentiatesHomeAndRoaming()1311 public void testSetScanResultsPasspoint_differentiatesHomeAndRoaming() { 1312 WifiConfiguration spyConfig = spy(new WifiConfiguration()); 1313 when(spyConfig.isPasspoint()).thenReturn(true); 1314 AccessPoint passpointAccessPoint = new AccessPoint(mContext, spyConfig, 1315 mScanResults, mRoamingScans); 1316 assertThat(AccessPoint.removeDoubleQuotes(spyConfig.SSID)).isEqualTo(TEST_SSID); 1317 1318 passpointAccessPoint.setScanResultsPasspoint(null, mRoamingScans); 1319 assertThat(AccessPoint.removeDoubleQuotes(spyConfig.SSID)).isEqualTo(ROAMING_SSID); 1320 1321 passpointAccessPoint.setScanResultsPasspoint(mScanResults, null); 1322 assertThat(AccessPoint.removeDoubleQuotes(spyConfig.SSID)).isEqualTo(TEST_SSID); 1323 } 1324 1325 /** 1326 * Verifies that getScanResults returns both home and roaming scans. 1327 */ 1328 @Test testGetScanResults_showsHomeAndRoamingScans()1329 public void testGetScanResults_showsHomeAndRoamingScans() { 1330 WifiConfiguration spyConfig = spy(new WifiConfiguration()); 1331 when(spyConfig.isPasspoint()).thenReturn(true); 1332 AccessPoint passpointAccessPoint = new AccessPoint(mContext, spyConfig, 1333 mScanResults, mRoamingScans); 1334 Set<ScanResult> fullSet = new ArraySet<>(); 1335 fullSet.addAll(mScanResults); 1336 fullSet.addAll(mRoamingScans); 1337 assertThat(passpointAccessPoint.getScanResults()).isEqualTo(fullSet); 1338 } 1339 1340 /** 1341 * Verifies that the Passpoint AccessPoint takes the ssid of the strongest scan result. 1342 */ 1343 @Test testPasspointAccessPoint_setsBestSsid()1344 public void testPasspointAccessPoint_setsBestSsid() { 1345 WifiConfiguration spyConfig = spy(new WifiConfiguration()); 1346 when(spyConfig.isPasspoint()).thenReturn(true); 1347 1348 String badSsid = "badSsid"; 1349 String goodSsid = "goodSsid"; 1350 String bestSsid = "bestSsid"; 1351 ScanResult badScanResult = createScanResult(badSsid, TEST_BSSID, -100); 1352 ScanResult goodScanResult = createScanResult(goodSsid, TEST_BSSID, -10); 1353 ScanResult bestScanResult = createScanResult(bestSsid, TEST_BSSID, -1); 1354 1355 AccessPoint passpointAccessPoint = new AccessPoint(mContext, spyConfig, 1356 Arrays.asList(badScanResult, goodScanResult), null); 1357 assertThat(passpointAccessPoint.getConfig().SSID) 1358 .isEqualTo(AccessPoint.convertToQuotedString(goodSsid)); 1359 passpointAccessPoint.setScanResultsPasspoint( 1360 Arrays.asList(badScanResult, goodScanResult, bestScanResult), null); 1361 assertThat(passpointAccessPoint.getConfig().SSID) 1362 .isEqualTo(AccessPoint.convertToQuotedString(bestSsid)); 1363 } 1364 1365 /** 1366 * Verifies that the OSU AccessPoint constructor creates AccessPoints whose isOsuProvider() 1367 * returns true. 1368 */ 1369 @Test testOsuAccessPointConstructor_createdAccessPointIsOsuProvider()1370 public void testOsuAccessPointConstructor_createdAccessPointIsOsuProvider() { 1371 AccessPoint osuAccessPoint = new AccessPoint(mContext, createOsuProvider(), 1372 mScanResults); 1373 1374 assertThat(osuAccessPoint.isOsuProvider()).isTrue(); 1375 } 1376 1377 /** 1378 * Verifies that the summary of an OSU entry only shows the tap_to_sign_up string. 1379 */ 1380 @Test testOsuAccessPointSummary_showsTapToSignUp()1381 public void testOsuAccessPointSummary_showsTapToSignUp() { 1382 AccessPoint osuAccessPoint = new AccessPoint(mContext, createOsuProvider(), 1383 mScanResults); 1384 1385 assertThat(osuAccessPoint.getSummary()) 1386 .isEqualTo(mContext.getString(R.string.tap_to_sign_up)); 1387 } 1388 1389 /** 1390 * Verifies that the summary of an OSU entry updates based on provisioning status. 1391 */ 1392 @Test testOsuAccessPointSummary_showsProvisioningUpdates()1393 public void testOsuAccessPointSummary_showsProvisioningUpdates() { 1394 OsuProvider provider = createOsuProvider(); 1395 Context spyContext = spy(new ContextWrapper(mContext)); 1396 when(spyContext.getSystemService(Context.WIFI_SERVICE)).thenReturn(mMockWifiManager); 1397 Map<OsuProvider, PasspointConfiguration> osuProviderConfigMap = new HashMap<>(); 1398 osuProviderConfigMap.put(provider, null); 1399 when(mMockWifiManager.getMatchingPasspointConfigsForOsuProviders( 1400 Collections.singleton(provider))).thenReturn(osuProviderConfigMap); 1401 AccessPoint osuAccessPoint = new AccessPoint(spyContext, provider, 1402 mScanResults); 1403 1404 osuAccessPoint.setListener(mMockAccessPointListener); 1405 1406 AccessPoint.AccessPointProvisioningCallback provisioningCallback = 1407 osuAccessPoint.new AccessPointProvisioningCallback(); 1408 1409 int[] openingProviderStatuses = { 1410 ProvisioningCallback.OSU_STATUS_AP_CONNECTING, 1411 ProvisioningCallback.OSU_STATUS_AP_CONNECTED, 1412 ProvisioningCallback.OSU_STATUS_SERVER_CONNECTING, 1413 ProvisioningCallback.OSU_STATUS_SERVER_VALIDATED, 1414 ProvisioningCallback.OSU_STATUS_SERVER_CONNECTED, 1415 ProvisioningCallback.OSU_STATUS_INIT_SOAP_EXCHANGE, 1416 ProvisioningCallback.OSU_STATUS_WAITING_FOR_REDIRECT_RESPONSE 1417 }; 1418 int[] completingSignUpStatuses = { 1419 ProvisioningCallback.OSU_STATUS_REDIRECT_RESPONSE_RECEIVED, 1420 ProvisioningCallback.OSU_STATUS_SECOND_SOAP_EXCHANGE, 1421 ProvisioningCallback.OSU_STATUS_THIRD_SOAP_EXCHANGE, 1422 ProvisioningCallback.OSU_STATUS_RETRIEVING_TRUST_ROOT_CERTS, 1423 }; 1424 1425 for (int status : openingProviderStatuses) { 1426 provisioningCallback.onProvisioningStatus(status); 1427 assertThat(osuAccessPoint.getSummary()) 1428 .isEqualTo(String.format(mContext.getString(R.string.osu_opening_provider), 1429 OSU_FRIENDLY_NAME)); 1430 } 1431 1432 provisioningCallback.onProvisioningFailure(0); 1433 assertThat(osuAccessPoint.getSummary()) 1434 .isEqualTo(mContext.getString(R.string.osu_connect_failed)); 1435 1436 for (int status : completingSignUpStatuses) { 1437 provisioningCallback.onProvisioningStatus(status); 1438 assertThat(osuAccessPoint.getSummary()) 1439 .isEqualTo(mContext.getString(R.string.osu_completing_sign_up)); 1440 } 1441 1442 provisioningCallback.onProvisioningFailure(0); 1443 assertThat(osuAccessPoint.getSummary()) 1444 .isEqualTo(mContext.getString(R.string.osu_sign_up_failed)); 1445 1446 provisioningCallback.onProvisioningComplete(); 1447 assertThat(osuAccessPoint.getSummary()) 1448 .isEqualTo(mContext.getString(R.string.osu_sign_up_complete)); 1449 } 1450 1451 /** 1452 * Verifies that after provisioning through an OSU provider, we connect to the freshly 1453 * provisioned network. 1454 */ 1455 @Test testOsuAccessPoint_connectsAfterProvisioning()1456 public void testOsuAccessPoint_connectsAfterProvisioning() { 1457 // Set up mock for WifiManager.getAllMatchingWifiConfigs 1458 WifiConfiguration config = new WifiConfiguration(); 1459 config.FQDN = "fqdn"; 1460 Map<Integer, List<ScanResult>> scanMapping = new HashMap<>(); 1461 scanMapping.put(WifiManager.PASSPOINT_HOME_NETWORK, mScanResults); 1462 Pair<WifiConfiguration, Map<Integer, List<ScanResult>>> configMapPair = 1463 new Pair<>(config, scanMapping); 1464 List<Pair<WifiConfiguration, Map<Integer, List<ScanResult>>>> matchingWifiConfig = 1465 new ArrayList<>(); 1466 matchingWifiConfig.add(configMapPair); 1467 when(mMockWifiManager.getAllMatchingWifiConfigs(any())).thenReturn(matchingWifiConfig); 1468 1469 // Set up mock for WifiManager.getMatchingPasspointConfigsForOsuProviders 1470 OsuProvider provider = createOsuProvider(); 1471 PasspointConfiguration passpointConfig = new PasspointConfiguration(); 1472 HomeSp homeSp = new HomeSp(); 1473 homeSp.setFqdn("fqdn"); 1474 homeSp.setFriendlyName("Test Provider"); 1475 passpointConfig.setHomeSp(homeSp); 1476 Map<OsuProvider, PasspointConfiguration> osuProviderConfigMap = new HashMap<>(); 1477 osuProviderConfigMap.put(provider, passpointConfig); 1478 when(mMockWifiManager 1479 .getMatchingPasspointConfigsForOsuProviders(Collections.singleton(provider))) 1480 .thenReturn(osuProviderConfigMap); 1481 1482 when(mMockContext.getSystemService(Context.WIFI_SERVICE)).thenReturn(mMockWifiManager); 1483 1484 AccessPoint osuAccessPoint = new AccessPoint(mMockContext, provider, mScanResults); 1485 osuAccessPoint.setListener(mMockAccessPointListener); 1486 1487 AccessPoint.AccessPointProvisioningCallback provisioningCallback = 1488 osuAccessPoint.new AccessPointProvisioningCallback(); 1489 provisioningCallback.onProvisioningComplete(); 1490 1491 verify(mMockWifiManager).connect(any(), any()); 1492 } 1493 1494 /** 1495 * Verifies that after provisioning through an OSU provider, we call the connect listener's 1496 * onFailure() method if we cannot find the network we just provisioned. 1497 */ 1498 @Test testOsuAccessPoint_noMatchingConfigsAfterProvisioning_callsOnFailure()1499 public void testOsuAccessPoint_noMatchingConfigsAfterProvisioning_callsOnFailure() { 1500 // Set up mock for WifiManager.getAllMatchingWifiConfigs 1501 when(mMockWifiManager.getAllMatchingWifiConfigs(any())).thenReturn(new ArrayList<>()); 1502 1503 // Set up mock for WifiManager.getMatchingPasspointConfigsForOsuProviders 1504 OsuProvider provider = createOsuProvider(); 1505 PasspointConfiguration passpointConfig = new PasspointConfiguration(); 1506 HomeSp homeSp = new HomeSp(); 1507 homeSp.setFqdn("fqdn"); 1508 homeSp.setFriendlyName("Test Provider"); 1509 passpointConfig.setHomeSp(homeSp); 1510 Map<OsuProvider, PasspointConfiguration> osuProviderConfigMap = new HashMap<>(); 1511 osuProviderConfigMap.put(provider, passpointConfig); 1512 when(mMockWifiManager 1513 .getMatchingPasspointConfigsForOsuProviders(Collections.singleton(provider))) 1514 .thenReturn(osuProviderConfigMap); 1515 1516 when(mMockContext.getSystemService(Context.WIFI_SERVICE)).thenReturn(mMockWifiManager); 1517 1518 AccessPoint osuAccessPoint = new AccessPoint(mMockContext, provider, mScanResults); 1519 osuAccessPoint.setListener(mMockAccessPointListener); 1520 osuAccessPoint.startOsuProvisioning(mMockConnectListener); 1521 1522 AccessPoint.AccessPointProvisioningCallback provisioningCallback = 1523 osuAccessPoint.new AccessPointProvisioningCallback(); 1524 provisioningCallback.onProvisioningComplete(); 1525 1526 verify(mMockConnectListener).onFailure(anyInt()); 1527 } 1528 1529 /** 1530 * Verifies that isOpenNetwork returns true for SECURITY_NONE, SECURITY_OWE, and 1531 * SECURITY_OWE_TRANSITION. 1532 */ 1533 @Test testIsOpenNetwork_returnValidResult()1534 public void testIsOpenNetwork_returnValidResult() { 1535 final Bundle bundle = new Bundle(); 1536 AccessPoint ap; 1537 1538 for (int i = 0; i < AccessPoint.SECURITY_MAX_VAL; i++) { 1539 bundle.putInt("key_security", i); 1540 ap = new AccessPoint(InstrumentationRegistry.getTargetContext(), bundle); 1541 1542 if (i == AccessPoint.SECURITY_NONE || i == AccessPoint.SECURITY_OWE) { 1543 assertThat(ap.isOpenNetwork()).isTrue(); 1544 } else { 1545 assertThat(ap.isOpenNetwork()).isFalse(); 1546 } 1547 } 1548 } 1549 1550 /** 1551 * Verifies that matches(AccessPoint other) matches a PSK/SAE transition mode AP to a PSK or a 1552 * SAE AP. 1553 */ 1554 @Test testMatches1_transitionModeApMatchesNotTransitionModeAp_shouldMatchCorrectly()1555 public void testMatches1_transitionModeApMatchesNotTransitionModeAp_shouldMatchCorrectly() { 1556 when(mMockContext.getSystemService(Context.WIFI_SERVICE)).thenReturn(mMockWifiManager); 1557 when(mMockWifiManager.isWpa3SaeSupported()).thenReturn(true); 1558 AccessPoint pskSaeTransitionModeAp = getPskSaeTransitionModeAp(); 1559 1560 // Transition mode AP matches a SAE AP. 1561 AccessPoint saeAccessPoint = new TestAccessPointBuilder(mContext) 1562 .setSsid(AccessPoint.removeDoubleQuotes(TEST_SSID)) 1563 .setSecurity(AccessPoint.SECURITY_SAE) 1564 .build(); 1565 assertThat(pskSaeTransitionModeAp.matches(saeAccessPoint)).isTrue(); 1566 1567 // Transition mode AP matches a PSK AP. 1568 AccessPoint pskAccessPoint = new TestAccessPointBuilder(mContext) 1569 .setSsid(AccessPoint.removeDoubleQuotes(TEST_SSID)) 1570 .setSecurity(AccessPoint.SECURITY_PSK) 1571 .build(); 1572 1573 assertThat(pskSaeTransitionModeAp.matches(pskAccessPoint)).isTrue(); 1574 1575 // Transition mode AP does not match a SAE AP if the device does not support SAE. 1576 when(mMockWifiManager.isWpa3SaeSupported()).thenReturn(false); 1577 pskSaeTransitionModeAp = getPskSaeTransitionModeAp(); 1578 saeAccessPoint = new TestAccessPointBuilder(mContext) 1579 .setSsid(AccessPoint.removeDoubleQuotes(TEST_SSID)) 1580 .setSecurity(AccessPoint.SECURITY_SAE) 1581 .build(); 1582 1583 assertThat(pskSaeTransitionModeAp.matches(saeAccessPoint)).isFalse(); 1584 } 1585 1586 /** 1587 * Verifies that matches(WifiConfiguration config) matches a PSK/SAE transition mode AP to a PSK 1588 * or a SAE WifiConfiguration. 1589 */ 1590 @Test testMatches2_transitionModeApMatchesNotTransitionModeAp_shouldMatchCorrectly()1591 public void testMatches2_transitionModeApMatchesNotTransitionModeAp_shouldMatchCorrectly() { 1592 when(mMockContext.getSystemService(Context.WIFI_SERVICE)).thenReturn(mMockWifiManager); 1593 when(mMockWifiManager.isWpa3SaeSupported()).thenReturn(true); 1594 AccessPoint pskSaeTransitionModeAp = getPskSaeTransitionModeAp(); 1595 1596 // Transition mode AP matches a SAE WifiConfiguration. 1597 WifiConfiguration saeConfig = new WifiConfiguration(); 1598 saeConfig.SSID = TEST_SSID; 1599 saeConfig.allowedKeyManagement.set(KeyMgmt.SAE); 1600 1601 assertThat(pskSaeTransitionModeAp.matches(saeConfig)).isTrue(); 1602 1603 // Transition mode AP matches a PSK WifiConfiguration. 1604 WifiConfiguration pskConfig = new WifiConfiguration(); 1605 pskConfig.SSID = TEST_SSID; 1606 pskConfig.allowedKeyManagement.set(KeyMgmt.WPA_PSK); 1607 1608 assertThat(pskSaeTransitionModeAp.matches(pskConfig)).isTrue(); 1609 1610 // Transition mode AP does not matches a SAE WifiConfiguration if the device does not 1611 // support SAE. 1612 when(mMockWifiManager.isWpa3SaeSupported()).thenReturn(false); 1613 pskSaeTransitionModeAp = getPskSaeTransitionModeAp(); 1614 1615 assertThat(pskSaeTransitionModeAp.matches(saeConfig)).isFalse(); 1616 } 1617 1618 /** 1619 * Verifies that matches(ScanResult scanResult) matches a PSK/SAE transition mode AP to a PSK 1620 * or a SAE ScanResult. 1621 */ 1622 @Test testMatches3_transitionModeApMatchesNotTransitionModeAp_shouldMatchCorrectly()1623 public void testMatches3_transitionModeApMatchesNotTransitionModeAp_shouldMatchCorrectly() { 1624 when(mMockContext.getSystemService(Context.WIFI_SERVICE)).thenReturn(mMockWifiManager); 1625 when(mMockWifiManager.isWpa3SaeSupported()).thenReturn(true); 1626 AccessPoint pskSaeTransitionModeAp = getPskSaeTransitionModeAp(); 1627 1628 // Transition mode AP matches a SAE ScanResult. 1629 ScanResult saeScanResult = createScanResult(AccessPoint.removeDoubleQuotes(TEST_SSID), 1630 TEST_BSSID, DEFAULT_RSSI); 1631 saeScanResult.capabilities = "[SAE-CCMP][ESS][WPS]"; 1632 1633 assertThat(pskSaeTransitionModeAp.matches(saeScanResult)).isTrue(); 1634 1635 // Transition mode AP matches a PSK ScanResult. 1636 ScanResult pskScanResult = createScanResult(AccessPoint.removeDoubleQuotes(TEST_SSID), 1637 TEST_BSSID, DEFAULT_RSSI); 1638 pskScanResult.capabilities = "[RSN-PSK-CCMP][ESS][WPS]"; 1639 1640 assertThat(pskSaeTransitionModeAp.matches(pskScanResult)).isTrue(); 1641 1642 // Transition mode AP does not matches a SAE ScanResult if the device does not support SAE. 1643 when(mMockWifiManager.isWpa3SaeSupported()).thenReturn(false); 1644 pskSaeTransitionModeAp = getPskSaeTransitionModeAp(); 1645 1646 assertThat(pskSaeTransitionModeAp.matches(saeScanResult)).isFalse(); 1647 } 1648 1649 @Test testGetSecurityString_oweTransitionMode_shouldReturnCorrectly()1650 public void testGetSecurityString_oweTransitionMode_shouldReturnCorrectly() { 1651 when(mMockContext.getSystemService(Context.WIFI_SERVICE)).thenReturn(mMockWifiManager); 1652 when(mMockWifiManager.isEnhancedOpenSupported()).thenReturn(true); 1653 AccessPoint oweTransitionModeAp = getOweTransitionModeAp(); 1654 1655 assertThat(oweTransitionModeAp.getSecurityString(true /* concise */)) 1656 .isEqualTo(mContext.getString(R.string.wifi_security_short_none_owe)); 1657 assertThat(oweTransitionModeAp.getSecurityString(false /* concise */)) 1658 .isEqualTo(mContext.getString(R.string.wifi_security_none_owe)); 1659 } 1660 getPskSaeTransitionModeAp()1661 private AccessPoint getPskSaeTransitionModeAp() { 1662 ScanResult scanResult = createScanResult(AccessPoint.removeDoubleQuotes(TEST_SSID), 1663 TEST_BSSID, DEFAULT_RSSI); 1664 scanResult.capabilities = 1665 "[WPA2-FT/PSK-CCMP][RSN-FT/PSK+PSK-SHA256+SAE+FT/SAE-CCMP][ESS][WPS]"; 1666 return new TestAccessPointBuilder(mMockContext) 1667 .setScanResults(new ArrayList<ScanResult>(Arrays.asList(scanResult))) 1668 .build(); 1669 } 1670 getOweTransitionModeAp()1671 private AccessPoint getOweTransitionModeAp() { 1672 ScanResult scanResult = createScanResult(AccessPoint.removeDoubleQuotes(TEST_SSID), 1673 TEST_BSSID, DEFAULT_RSSI); 1674 scanResult.capabilities = "[OWE_TRANSITION]"; 1675 return new TestAccessPointBuilder(mContext) 1676 .setScanResults(new ArrayList<ScanResult>(Arrays.asList(scanResult))) 1677 .build(); 1678 } 1679 1680 @Test testGenerateOpenNetworkConfig_oweNotSupported_shouldGetCorrectSecurity()1681 public void testGenerateOpenNetworkConfig_oweNotSupported_shouldGetCorrectSecurity() { 1682 when(mMockContext.getSystemService(Context.WIFI_SERVICE)).thenReturn(mMockWifiManager); 1683 AccessPoint oweAccessPoint = new TestAccessPointBuilder(mMockContext) 1684 .setSecurity(AccessPoint.SECURITY_OWE).build(); 1685 AccessPoint noneAccessPoint = new TestAccessPointBuilder(mMockContext) 1686 .setSecurity(AccessPoint.SECURITY_NONE).build(); 1687 1688 oweAccessPoint.generateOpenNetworkConfig(); 1689 noneAccessPoint.generateOpenNetworkConfig(); 1690 1691 assertThat(oweAccessPoint.getConfig().allowedKeyManagement.get(KeyMgmt.NONE)).isFalse(); 1692 assertThat(oweAccessPoint.getConfig().allowedKeyManagement.get(KeyMgmt.OWE)).isTrue(); 1693 assertThat(noneAccessPoint.getConfig().allowedKeyManagement.get(KeyMgmt.NONE)).isTrue(); 1694 assertThat(noneAccessPoint.getConfig().allowedKeyManagement.get(KeyMgmt.OWE)).isFalse(); 1695 } 1696 } 1697