1 package org.robolectric.shadows; 2 3 import static android.net.wifi.WifiManager.SCAN_RESULTS_AVAILABLE_ACTION; 4 import static android.os.Build.VERSION_CODES.LOLLIPOP; 5 import static android.os.Build.VERSION_CODES.Q; 6 import static android.os.Build.VERSION_CODES.R; 7 import static android.os.Build.VERSION_CODES.S; 8 import static android.os.Build.VERSION_CODES.TIRAMISU; 9 import static androidx.test.core.app.ApplicationProvider.getApplicationContext; 10 import static com.google.common.truth.Truth.assertThat; 11 import static com.google.common.util.concurrent.MoreExecutors.directExecutor; 12 import static java.util.concurrent.TimeUnit.MINUTES; 13 import static org.junit.Assert.assertThrows; 14 import static org.junit.Assert.fail; 15 import static org.mockito.ArgumentMatchers.eq; 16 import static org.mockito.Mockito.mock; 17 import static org.mockito.Mockito.verify; 18 import static org.mockito.Mockito.verifyNoMoreInteractions; 19 import static org.robolectric.Shadows.shadowOf; 20 21 import android.app.Application; 22 import android.app.admin.DeviceAdminService; 23 import android.app.admin.DevicePolicyManager; 24 import android.content.ComponentName; 25 import android.content.Context; 26 import android.content.Intent; 27 import android.net.ConnectivityManager; 28 import android.net.DhcpInfo; 29 import android.net.MacAddress; 30 import android.net.NetworkInfo; 31 import android.net.wifi.ScanResult; 32 import android.net.wifi.SoftApConfiguration; 33 import android.net.wifi.WifiConfiguration; 34 import android.net.wifi.WifiInfo; 35 import android.net.wifi.WifiManager; 36 import android.net.wifi.WifiManager.AddNetworkResult; 37 import android.net.wifi.WifiManager.LocalOnlyConnectionFailureListener; 38 import android.net.wifi.WifiManager.MulticastLock; 39 import android.net.wifi.WifiManager.PnoScanResultsCallback; 40 import android.net.wifi.WifiNetworkSpecifier; 41 import android.net.wifi.WifiSsid; 42 import android.net.wifi.WifiUsabilityStatsEntry; 43 import android.os.Build; 44 import android.util.Pair; 45 import androidx.test.ext.junit.runners.AndroidJUnit4; 46 import java.util.ArrayList; 47 import java.util.List; 48 import java.util.concurrent.BlockingQueue; 49 import java.util.concurrent.ExecutorService; 50 import java.util.concurrent.Executors; 51 import java.util.concurrent.LinkedBlockingQueue; 52 import org.junit.Before; 53 import org.junit.Test; 54 import org.junit.runner.RunWith; 55 import org.mockito.ArgumentCaptor; 56 import org.robolectric.RuntimeEnvironment; 57 import org.robolectric.annotation.Config; 58 import org.robolectric.shadow.api.Shadow; 59 import org.robolectric.util.ReflectionHelpers; 60 import org.robolectric.versioning.AndroidVersions.U; 61 62 @RunWith(AndroidJUnit4.class) 63 public class ShadowWifiManagerTest { 64 private WifiManager wifiManager; 65 66 @Before setUp()67 public void setUp() throws Exception { 68 wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE); 69 } 70 71 @Test shouldReturnWifiInfo()72 public void shouldReturnWifiInfo() { 73 assertThat(wifiManager.getConnectionInfo().getClass()).isEqualTo(WifiInfo.class); 74 } 75 76 @Test setWifiInfo_shouldUpdateWifiInfo()77 public void setWifiInfo_shouldUpdateWifiInfo() { 78 WifiInfo wifiInfo = newWifiInfo(); 79 shadowOf(wifiManager).setConnectionInfo(wifiInfo); 80 assertThat(wifiManager.getConnectionInfo()).isSameInstanceAs(wifiInfo); 81 } 82 newWifiInfo()83 private static WifiInfo newWifiInfo() { 84 if (RuntimeEnvironment.getApiLevel() >= LOLLIPOP) { 85 return new WifiInfo(); 86 } else { 87 return ReflectionHelpers.callConstructor(WifiInfo.class); 88 } 89 } 90 91 @Test setWifiEnabled_shouldThrowSecurityExceptionWhenAccessWifiStatePermissionNotGranted()92 public void setWifiEnabled_shouldThrowSecurityExceptionWhenAccessWifiStatePermissionNotGranted() { 93 shadowOf(wifiManager).setAccessWifiStatePermission(false); 94 try { 95 wifiManager.setWifiEnabled(true); 96 fail("SecurityException not thrown"); 97 } catch (SecurityException e) { 98 // expected 99 } 100 } 101 102 @Test isWifiEnabled_shouldThrowSecurityExceptionWhenAccessWifiStatePermissionNotGranted()103 public void isWifiEnabled_shouldThrowSecurityExceptionWhenAccessWifiStatePermissionNotGranted() { 104 shadowOf(wifiManager).setAccessWifiStatePermission(false); 105 try { 106 wifiManager.isWifiEnabled(); 107 fail("SecurityException not thrown"); 108 } catch (SecurityException e) { 109 // expected 110 } 111 } 112 113 @Test getWifiState_shouldThrowSecurityExceptionWhenAccessWifiStatePermissionNotGranted()114 public void getWifiState_shouldThrowSecurityExceptionWhenAccessWifiStatePermissionNotGranted() { 115 shadowOf(wifiManager).setAccessWifiStatePermission(false); 116 try { 117 wifiManager.getWifiState(); 118 fail("SecurityException not thrown"); 119 } catch (SecurityException e) { 120 // expected 121 } 122 } 123 124 @Test 125 public void getConnectionInfo_shouldThrowSecurityExceptionWhenAccessWifiStatePermissionNotGranted()126 getConnectionInfo_shouldThrowSecurityExceptionWhenAccessWifiStatePermissionNotGranted() { 127 shadowOf(wifiManager).setAccessWifiStatePermission(false); 128 try { 129 wifiManager.getConnectionInfo(); 130 fail("SecurityException not thrown"); 131 } catch (SecurityException e) { 132 // expected 133 } 134 } 135 136 @Test getWifiState()137 public void getWifiState() { 138 wifiManager.setWifiEnabled(true); 139 assertThat(wifiManager.getWifiState()).isEqualTo(WifiManager.WIFI_STATE_ENABLED); 140 141 wifiManager.setWifiEnabled(false); 142 assertThat(wifiManager.getWifiState()).isEqualTo(WifiManager.WIFI_STATE_DISABLED); 143 } 144 145 @Test startScan()146 public void startScan() { 147 // By default startScan() succeeds. 148 assertThat(wifiManager.startScan()).isTrue(); 149 150 shadowOf(wifiManager).setStartScanSucceeds(true); 151 assertThat(wifiManager.startScan()).isTrue(); 152 153 shadowOf(wifiManager).setStartScanSucceeds(false); 154 assertThat(wifiManager.startScan()).isFalse(); 155 } 156 157 @Test getIsScanAlwaysAvailable()158 public void getIsScanAlwaysAvailable() { 159 shadowOf(wifiManager).setIsScanAlwaysAvailable(true); 160 assertThat(wifiManager.isScanAlwaysAvailable()).isEqualTo(true); 161 162 shadowOf(wifiManager).setIsScanAlwaysAvailable(false); 163 assertThat(wifiManager.isScanAlwaysAvailable()).isEqualTo(false); 164 } 165 166 @Test shouldEnableNetworks()167 public void shouldEnableNetworks() { 168 wifiManager.enableNetwork(666, true); 169 Pair<Integer, Boolean> lastEnabled = shadowOf(wifiManager).getLastEnabledNetwork(); 170 assertThat(lastEnabled).isEqualTo(new Pair<>(666, true)); 171 172 wifiManager.enableNetwork(777, false); 173 lastEnabled = shadowOf(wifiManager).getLastEnabledNetwork(); 174 assertThat(lastEnabled).isEqualTo(new Pair<>(777, false)); 175 176 boolean enabledNetwork = shadowOf(wifiManager).isNetworkEnabled(666); 177 assertThat(enabledNetwork).isTrue(); 178 179 enabledNetwork = shadowOf(wifiManager).isNetworkEnabled(777); 180 assertThat(enabledNetwork).isTrue(); 181 } 182 183 @Test shouldDisableNetwork()184 public void shouldDisableNetwork() { 185 wifiManager.enableNetwork(666, true); 186 boolean enabledNetwork = shadowOf(wifiManager).isNetworkEnabled(666); 187 assertThat(enabledNetwork).isTrue(); 188 189 wifiManager.disableNetwork(666); 190 enabledNetwork = shadowOf(wifiManager).isNetworkEnabled(666); 191 assertThat(enabledNetwork).isFalse(); 192 } 193 194 @Test shouldReturnSetScanResults()195 public void shouldReturnSetScanResults() { 196 List<ScanResult> scanResults = new ArrayList<>(); 197 shadowOf(wifiManager).setScanResults(scanResults); 198 assertThat(wifiManager.getScanResults()).isSameInstanceAs(scanResults); 199 } 200 201 @Test shouldReturnDhcpInfo()202 public void shouldReturnDhcpInfo() { 203 DhcpInfo dhcpInfo = new DhcpInfo(); 204 shadowOf(wifiManager).setDhcpInfo(dhcpInfo); 205 assertThat(wifiManager.getDhcpInfo()).isSameInstanceAs(dhcpInfo); 206 } 207 208 @Test shouldRecordTheLastAddedNetwork()209 public void shouldRecordTheLastAddedNetwork() { 210 WifiConfiguration wifiConfiguration = new WifiConfiguration(); 211 wifiConfiguration.networkId = -1; 212 int networkId = wifiManager.addNetwork(wifiConfiguration); 213 assertThat(networkId).isEqualTo(0); 214 assertThat(wifiManager.getConfiguredNetworks().get(0)).isNotSameInstanceAs(wifiConfiguration); 215 assertThat(wifiConfiguration.networkId).isEqualTo(-1); 216 assertThat(wifiManager.getConfiguredNetworks().get(0).networkId).isEqualTo(0); 217 assertThat(wifiManager.addNetwork(/* wifiConfiguration= */ null)).isEqualTo(-1); 218 219 WifiConfiguration anotherConfig = new WifiConfiguration(); 220 assertThat(wifiManager.addNetwork(anotherConfig)).isEqualTo(1); 221 assertThat(anotherConfig.networkId).isEqualTo(-1); 222 assertThat(wifiManager.getConfiguredNetworks().get(1).networkId).isEqualTo(1); 223 } 224 225 @Test updateNetwork_shouldReplaceNetworks()226 public void updateNetwork_shouldReplaceNetworks() { 227 WifiConfiguration wifiConfiguration = new WifiConfiguration(); 228 wifiConfiguration.networkId = -1; 229 wifiManager.addNetwork(wifiConfiguration); 230 231 WifiConfiguration anotherConfig = new WifiConfiguration(); 232 int networkId = wifiManager.addNetwork(anotherConfig); 233 234 assertThat(networkId).isEqualTo(1); 235 WifiConfiguration configuration = new WifiConfiguration(); 236 configuration.networkId = networkId; 237 configuration.priority = 44; 238 239 assertThat(wifiManager.updateNetwork(configuration)).isEqualTo(networkId); 240 List<WifiConfiguration> configuredNetworks = wifiManager.getConfiguredNetworks(); 241 assertThat(configuredNetworks.size()).isEqualTo(2); 242 assertThat(configuration.priority).isEqualTo(44); 243 assertThat(configuredNetworks.get(1).priority).isEqualTo(44); 244 } 245 246 @Test updateNetworkTests_permissions()247 public void updateNetworkTests_permissions() { 248 int networkId = 1; 249 WifiConfiguration wifiConfiguration = new WifiConfiguration(); 250 wifiConfiguration.networkId = networkId; 251 252 // By default we should have permission to update networks. 253 assertThat(wifiManager.updateNetwork(wifiConfiguration)).isEqualTo(networkId); 254 255 // If we don't have permission to update, updateNetwork will return -1. 256 shadowOf(wifiManager).setUpdateNetworkPermission(networkId, /* hasPermission= */ false); 257 assertThat(wifiManager.updateNetwork(wifiConfiguration)).isEqualTo(-1); 258 259 // Ensure updates can occur if permission is restored. 260 shadowOf(wifiManager).setUpdateNetworkPermission(networkId, /* hasPermission= */ true); 261 assertThat(wifiManager.updateNetwork(wifiConfiguration)).isEqualTo(networkId); 262 } 263 264 @Test removeNetwork()265 public void removeNetwork() { 266 WifiConfiguration wifiConfiguration = new WifiConfiguration(); 267 wifiConfiguration.networkId = 123; 268 wifiManager.addNetwork(wifiConfiguration); 269 270 List<WifiConfiguration> list = wifiManager.getConfiguredNetworks(); 271 assertThat(list.size()).isEqualTo(1); 272 273 wifiManager.removeNetwork(0); 274 275 list = wifiManager.getConfiguredNetworks(); 276 assertThat(list.size()).isEqualTo(0); 277 } 278 279 @Test 280 @Config(minSdk = S) addNetworkPrivileged_nullConfig_shouldThrowIllegalArgumentException()281 public void addNetworkPrivileged_nullConfig_shouldThrowIllegalArgumentException() { 282 assertThrows(IllegalArgumentException.class, () -> wifiManager.addNetworkPrivileged(null)); 283 } 284 285 @Test 286 @Config(minSdk = S) addNetworkPrivileged_nonNullConfig_shouldAddNetworkSuccessfully()287 public void addNetworkPrivileged_nonNullConfig_shouldAddNetworkSuccessfully() { 288 WifiConfiguration wifiConfiguration = new WifiConfiguration(); 289 290 AddNetworkResult addNetworkResult = wifiManager.addNetworkPrivileged(wifiConfiguration); 291 292 assertThat(addNetworkResult).isNotNull(); 293 assertThat(addNetworkResult.statusCode).isEqualTo(AddNetworkResult.STATUS_SUCCESS); 294 assertThat(wifiManager.getConfiguredNetworks()).hasSize(1); 295 } 296 297 @Test 298 @Config(minSdk = S) 299 public void getCallerConfiguredNetworks_noAccessWifiStatePermission_shouldThrowSecurityException()300 getCallerConfiguredNetworks_noAccessWifiStatePermission_shouldThrowSecurityException() { 301 shadowOf(wifiManager).setAccessWifiStatePermission(false); 302 303 assertThrows(SecurityException.class, () -> wifiManager.getCallerConfiguredNetworks()); 304 } 305 306 @Test 307 @Config(minSdk = S) getCallerConfiguredNetworks_noNetworksConfigured_returnsEmptyList()308 public void getCallerConfiguredNetworks_noNetworksConfigured_returnsEmptyList() { 309 assertThat(wifiManager.getCallerConfiguredNetworks()).isEmpty(); 310 } 311 312 @Test 313 @Config(minSdk = S) getCallerConfiguredNetworks_networksAddedAndRemoved_returnsConfiguredNetworks()314 public void getCallerConfiguredNetworks_networksAddedAndRemoved_returnsConfiguredNetworks() { 315 WifiConfiguration wifiConfiguration = new WifiConfiguration(); 316 wifiManager.addNetwork(wifiConfiguration); 317 318 assertThat(wifiManager.getCallerConfiguredNetworks()).hasSize(1); 319 320 wifiManager.removeNetwork(0); 321 322 assertThat(wifiManager.getCallerConfiguredNetworks()).isEmpty(); 323 } 324 325 @Test 326 @Config(minSdk = S) 327 public void removeNonCallerConfiguredNetworks_noChangeWifiStatePermission_shouldThrowSecurityException()328 removeNonCallerConfiguredNetworks_noChangeWifiStatePermission_shouldThrowSecurityException() { 329 setDeviceOwner(); 330 shadowOf(wifiManager).setChangeWifiStatePermission(false); 331 332 assertThrows(SecurityException.class, () -> wifiManager.removeNonCallerConfiguredNetworks()); 333 } 334 335 @Test 336 @Config(minSdk = S) removeNonCallerConfiguredNetworks_notDeviceOwner_shouldThrowSecurityException()337 public void removeNonCallerConfiguredNetworks_notDeviceOwner_shouldThrowSecurityException() { 338 assertThrows(SecurityException.class, () -> wifiManager.removeNonCallerConfiguredNetworks()); 339 } 340 341 @Test 342 @Config(minSdk = S) removeNonCallerConfiguredNetworks_noConfiguredNetworks_returnsFalse()343 public void removeNonCallerConfiguredNetworks_noConfiguredNetworks_returnsFalse() { 344 setDeviceOwner(); 345 346 assertThat(wifiManager.removeNonCallerConfiguredNetworks()).isFalse(); 347 } 348 349 @Test 350 @Config(minSdk = S) removeNonCallerConfiguredNetworks_hasConfiguredNetworks_removesConfiguredNetworks()351 public void removeNonCallerConfiguredNetworks_hasConfiguredNetworks_removesConfiguredNetworks() { 352 setDeviceOwner(); 353 wifiManager.addNetwork(new WifiConfiguration()); 354 wifiManager.addNetwork(new WifiConfiguration()); 355 356 assertThat(wifiManager.removeNonCallerConfiguredNetworks()).isTrue(); 357 assertThat(wifiManager.getConfiguredNetworks()).isEmpty(); 358 } 359 360 @Test 361 @Config(minSdk = Build.VERSION_CODES.LOLLIPOP) getPrivilegedConfiguredNetworks_shouldReturnConfiguredNetworks()362 public void getPrivilegedConfiguredNetworks_shouldReturnConfiguredNetworks() { 363 WifiConfiguration wifiConfiguration = new WifiConfiguration(); 364 wifiConfiguration.networkId = 123; 365 wifiManager.addNetwork(wifiConfiguration); 366 367 List<WifiConfiguration> list = wifiManager.getPrivilegedConfiguredNetworks(); 368 assertThat(list.size()).isEqualTo(1); 369 370 wifiManager.removeNetwork(0); 371 372 list = wifiManager.getPrivilegedConfiguredNetworks(); 373 assertThat(list.size()).isEqualTo(0); 374 } 375 376 @Test updateNetwork_shouldRejectNullandNewConfigs()377 public void updateNetwork_shouldRejectNullandNewConfigs() { 378 WifiConfiguration config = new WifiConfiguration(); 379 config.networkId = -1; 380 assertThat(wifiManager.updateNetwork(config)).isEqualTo(-1); 381 assertThat(wifiManager.updateNetwork(null)).isEqualTo(-1); 382 assertThat(wifiManager.getConfiguredNetworks()).isEmpty(); 383 } 384 385 @Test shouldSaveConfigurations()386 public void shouldSaveConfigurations() { 387 assertThat(wifiManager.saveConfiguration()).isTrue(); 388 assertThat(shadowOf(wifiManager).wasConfigurationSaved()).isTrue(); 389 } 390 391 @Test shouldCreateWifiLock()392 public void shouldCreateWifiLock() { 393 assertThat(wifiManager.createWifiLock("TAG")).isNotNull(); 394 assertThat(wifiManager.createWifiLock(1, "TAG")).isNotNull(); 395 } 396 397 @Test wifiLockAcquireIncreasesActiveLockCount()398 public void wifiLockAcquireIncreasesActiveLockCount() { 399 WifiManager.WifiLock lock = wifiManager.createWifiLock("TAG"); 400 assertThat(shadowOf(wifiManager).getActiveLockCount()).isEqualTo(0); 401 lock.acquire(); 402 assertThat(shadowOf(wifiManager).getActiveLockCount()).isEqualTo(1); 403 lock.release(); 404 assertThat(shadowOf(wifiManager).getActiveLockCount()).isEqualTo(0); 405 } 406 407 @Test multicastLockAcquireIncreasesActiveLockCount()408 public void multicastLockAcquireIncreasesActiveLockCount() { 409 MulticastLock lock = wifiManager.createMulticastLock("TAG"); 410 assertThat(shadowOf(wifiManager).getActiveLockCount()).isEqualTo(0); 411 lock.acquire(); 412 assertThat(shadowOf(wifiManager).getActiveLockCount()).isEqualTo(1); 413 lock.release(); 414 assertThat(shadowOf(wifiManager).getActiveLockCount()).isEqualTo(0); 415 } 416 417 @Test shouldAcquireAndReleaseWifilockRefCounted()418 public void shouldAcquireAndReleaseWifilockRefCounted() { 419 WifiManager.WifiLock lock = wifiManager.createWifiLock("TAG"); 420 lock.acquire(); 421 lock.acquire(); 422 assertThat(lock.isHeld()).isTrue(); 423 lock.release(); 424 assertThat(lock.isHeld()).isTrue(); 425 lock.release(); 426 assertThat(lock.isHeld()).isFalse(); 427 } 428 429 @Test shouldAcquireAndReleaseWifilockNonRefCounted()430 public void shouldAcquireAndReleaseWifilockNonRefCounted() { 431 WifiManager.WifiLock lock = wifiManager.createWifiLock("TAG"); 432 lock.setReferenceCounted(false); 433 lock.acquire(); 434 assertThat(lock.isHeld()).isTrue(); 435 lock.acquire(); 436 assertThat(lock.isHeld()).isTrue(); 437 lock.release(); 438 assertThat(lock.isHeld()).isFalse(); 439 } 440 441 @Test shouldThrowRuntimeExceptionIfWifiLockisUnderlocked()442 public void shouldThrowRuntimeExceptionIfWifiLockisUnderlocked() { 443 WifiManager.WifiLock lock = wifiManager.createWifiLock("TAG"); 444 try { 445 lock.release(); 446 fail("RuntimeException not thrown"); 447 } catch (RuntimeException e) { 448 // expected 449 } 450 } 451 452 @Test shouldThrowUnsupportedOperationIfWifiLockisOverlocked()453 public void shouldThrowUnsupportedOperationIfWifiLockisOverlocked() { 454 WifiManager.WifiLock lock = wifiManager.createWifiLock("TAG"); 455 try { 456 for (int i = 0; i < ShadowWifiManager.ShadowWifiLock.MAX_ACTIVE_LOCKS; i++) { 457 lock.acquire(); 458 } 459 fail("UnsupportedOperationException not thrown"); 460 } catch (UnsupportedOperationException e) { 461 // expected 462 } 463 } 464 465 @Test shouldCreateMulticastLock()466 public void shouldCreateMulticastLock() { 467 assertThat(wifiManager.createMulticastLock("TAG")).isNotNull(); 468 } 469 470 @Test shouldAcquireAndReleaseMulticastLockRefCounted()471 public void shouldAcquireAndReleaseMulticastLockRefCounted() { 472 MulticastLock lock = wifiManager.createMulticastLock("TAG"); 473 lock.acquire(); 474 lock.acquire(); 475 assertThat(lock.isHeld()).isTrue(); 476 lock.release(); 477 assertThat(lock.isHeld()).isTrue(); 478 lock.release(); 479 assertThat(lock.isHeld()).isFalse(); 480 } 481 482 @Test shouldAcquireAndReleaseMulticastLockNonRefCounted()483 public void shouldAcquireAndReleaseMulticastLockNonRefCounted() { 484 MulticastLock lock = wifiManager.createMulticastLock("TAG"); 485 lock.setReferenceCounted(false); 486 lock.acquire(); 487 assertThat(lock.isHeld()).isTrue(); 488 lock.acquire(); 489 assertThat(lock.isHeld()).isTrue(); 490 lock.release(); 491 assertThat(lock.isHeld()).isFalse(); 492 } 493 494 @Test shouldThrowRuntimeExceptionIfMulticastLockisUnderlocked()495 public void shouldThrowRuntimeExceptionIfMulticastLockisUnderlocked() { 496 MulticastLock lock = wifiManager.createMulticastLock("TAG"); 497 try { 498 lock.release(); 499 fail("Expected exception"); 500 } catch (RuntimeException expected) { 501 } 502 ; 503 } 504 505 @Test shouldThrowUnsupportedOperationIfMulticastLockisOverlocked()506 public void shouldThrowUnsupportedOperationIfMulticastLockisOverlocked() { 507 MulticastLock lock = wifiManager.createMulticastLock("TAG"); 508 try { 509 for (int i = 0; i < ShadowWifiManager.ShadowMulticastLock.MAX_ACTIVE_LOCKS; i++) { 510 lock.acquire(); 511 } 512 fail("Expected exception"); 513 } catch (UnsupportedOperationException e) { 514 // expected 515 } 516 } 517 518 @Test shouldCalculateSignalLevelSetBefore()519 public void shouldCalculateSignalLevelSetBefore() { 520 ShadowWifiManager.setSignalLevelInPercent(0.5f); 521 assertThat(WifiManager.calculateSignalLevel(0, 5)).isEqualTo(2); 522 assertThat(WifiManager.calculateSignalLevel(2, 5)).isEqualTo(2); 523 524 ShadowWifiManager.setSignalLevelInPercent(0.9f); 525 assertThat(WifiManager.calculateSignalLevel(0, 5)).isEqualTo(3); 526 assertThat(WifiManager.calculateSignalLevel(2, 5)).isEqualTo(3); 527 528 ShadowWifiManager.setSignalLevelInPercent(1f); 529 assertThat(WifiManager.calculateSignalLevel(0, 4)).isEqualTo(3); 530 assertThat(WifiManager.calculateSignalLevel(2, 4)).isEqualTo(3); 531 532 ShadowWifiManager.setSignalLevelInPercent(0); 533 assertThat(WifiManager.calculateSignalLevel(0, 5)).isEqualTo(0); 534 assertThat(WifiManager.calculateSignalLevel(2, 5)).isEqualTo(0); 535 } 536 537 @Test(expected = IllegalArgumentException.class) shouldThrowIllegalArgumentExceptionWhenSignalLevelToLow()538 public void shouldThrowIllegalArgumentExceptionWhenSignalLevelToLow() { 539 ShadowWifiManager.setSignalLevelInPercent(-0.01f); 540 } 541 542 @Test(expected = IllegalArgumentException.class) shouldThrowIllegalArgumentExceptionWhenSignalLevelToHigh()543 public void shouldThrowIllegalArgumentExceptionWhenSignalLevelToHigh() { 544 ShadowWifiManager.setSignalLevelInPercent(1.01f); 545 } 546 547 @Test startScan_shouldNotThrowException()548 public void startScan_shouldNotThrowException() { 549 assertThat(wifiManager.startScan()).isTrue(); 550 } 551 552 @Test reconnect_shouldNotThrowException()553 public void reconnect_shouldNotThrowException() { 554 assertThat(wifiManager.reconnect()).isFalse(); 555 } 556 557 @Test reconnect_setsConnectionInfo()558 public void reconnect_setsConnectionInfo() { 559 // GIVEN 560 WifiConfiguration wifiConfiguration = new WifiConfiguration(); 561 wifiConfiguration.SSID = "SSID"; 562 int netId = wifiManager.addNetwork(wifiConfiguration); 563 wifiManager.enableNetwork(netId, false); 564 565 // WHEN 566 wifiManager.reconnect(); 567 568 // THEN 569 assertThat(wifiManager.getConnectionInfo().getSSID()).contains("SSID"); 570 } 571 572 @Test reconnect_shouldEnableDhcp()573 public void reconnect_shouldEnableDhcp() { 574 // GIVEN 575 WifiConfiguration config = new WifiConfiguration(); 576 config.SSID = "SSID"; 577 int netId = wifiManager.addNetwork(config); 578 wifiManager.enableNetwork(netId, false); 579 580 // WHEN 581 wifiManager.reconnect(); 582 583 // THEN 584 assertThat(wifiManager.getDhcpInfo()).isNotNull(); 585 } 586 587 @Test reconnect_updatesConnectivityManager()588 public void reconnect_updatesConnectivityManager() { 589 // GIVEN 590 WifiConfiguration config = new WifiConfiguration(); 591 config.SSID = "SSID"; 592 int netId = wifiManager.addNetwork(config); 593 wifiManager.enableNetwork(netId, false); 594 595 // WHEN 596 wifiManager.reconnect(); 597 598 // THEN 599 NetworkInfo networkInfo = 600 ((ConnectivityManager) 601 getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE)) 602 .getActiveNetworkInfo(); 603 assertThat(networkInfo.getType()).isEqualTo(ConnectivityManager.TYPE_WIFI); 604 assertThat(networkInfo.isConnected()).isTrue(); 605 } 606 607 @Test connect_setsNetworkId_shouldHasNetworkId()608 public void connect_setsNetworkId_shouldHasNetworkId() { 609 // WHEN 610 wifiManager.connect(123, null); 611 612 // THEN 613 assertThat(wifiManager.getConnectionInfo().getNetworkId()).isEqualTo(123); 614 } 615 616 @Test connect_setsConnectionInfo()617 public void connect_setsConnectionInfo() { 618 // GIVEN 619 WifiConfiguration wifiConfiguration = new WifiConfiguration(); 620 wifiConfiguration.SSID = "foo"; 621 622 // WHEN 623 wifiManager.connect(wifiConfiguration, null); 624 625 // THEN 626 assertThat(wifiManager.getConnectionInfo().getSSID()).contains("foo"); 627 } 628 629 @Test is5GhzBandSupportedAndConfigurable()630 public void is5GhzBandSupportedAndConfigurable() { 631 assertThat(wifiManager.is5GHzBandSupported()).isFalse(); 632 shadowOf(wifiManager).setIs5GHzBandSupported(true); 633 assertThat(wifiManager.is5GHzBandSupported()).isTrue(); 634 } 635 636 @Test 637 @Config(minSdk = R) isStaApConcurrencySupportedAndConfigurable()638 public void isStaApConcurrencySupportedAndConfigurable() { 639 assertThat(wifiManager.isStaApConcurrencySupported()).isFalse(); 640 shadowOf(wifiManager).setStaApConcurrencySupported(true); 641 assertThat(wifiManager.isStaApConcurrencySupported()).isTrue(); 642 } 643 644 @Test 645 @Config(minSdk = Q) isWpa3SaeSupportedAndConfigurable()646 public void isWpa3SaeSupportedAndConfigurable() { 647 assertThat(wifiManager.isWpa3SaeSupported()).isFalse(); 648 shadowOf(wifiManager).setWpa3SaeSupported(true); 649 assertThat(wifiManager.isWpa3SaeSupported()).isTrue(); 650 } 651 652 @Test 653 @Config(minSdk = S) isWpa3SaePublicKeySupportedAndConfigurable()654 public void isWpa3SaePublicKeySupportedAndConfigurable() { 655 assertThat(wifiManager.isWpa3SaePublicKeySupported()).isFalse(); 656 shadowOf(wifiManager).setWpa3SaePublicKeySupported(true); 657 assertThat(wifiManager.isWpa3SaePublicKeySupported()).isTrue(); 658 } 659 660 @Test 661 @Config(minSdk = S) isWpa3SaeH2eSupportedAndConfigurable()662 public void isWpa3SaeH2eSupportedAndConfigurable() { 663 assertThat(wifiManager.isWpa3SaeH2eSupported()).isFalse(); 664 shadowOf(wifiManager).setWpa3SaeH2eSupported(true); 665 assertThat(wifiManager.isWpa3SaeH2eSupported()).isTrue(); 666 } 667 668 @Test 669 @Config(minSdk = Q) isWpa3SuiteBSupportedAndConfigurable()670 public void isWpa3SuiteBSupportedAndConfigurable() { 671 assertThat(wifiManager.isWpa3SuiteBSupported()).isFalse(); 672 shadowOf(wifiManager).setWpa3SuiteBSupported(true); 673 assertThat(wifiManager.isWpa3SuiteBSupported()).isTrue(); 674 } 675 676 @Test 677 @Config(minSdk = Q) testAddOnWifiUsabilityStatsListener()678 public void testAddOnWifiUsabilityStatsListener() { 679 // GIVEN 680 WifiManager.OnWifiUsabilityStatsListener mockListener = 681 mock(WifiManager.OnWifiUsabilityStatsListener.class); 682 wifiManager.addOnWifiUsabilityStatsListener(directExecutor(), mockListener); 683 684 // WHEN 685 WifiUsabilityStatsEntryBuilder builder = new WifiUsabilityStatsEntryBuilder(); 686 builder 687 .setTimeStampMillis(1234567L) 688 .setRssi(23) 689 .setLinkSpeedMbps(998) 690 .setTotalTxSuccess(1) 691 .setTotalTxRetries(2) 692 .setTotalTxBad(3) 693 .setTotalRxSuccess(4) 694 .setTotalRadioOnTimeMillis(5) 695 .setTotalRadioTxTimeMillis(6) 696 .setTotalRadioRxTimeMillis(7) 697 .setTotalScanTimeMillis(8) 698 .setTotalNanScanTimeMillis(9) 699 .setTotalBackgroundScanTimeMillis(10) 700 .setTotalRoamScanTimeMillis(11) 701 .setTotalPnoScanTimeMillis(12) 702 .setTotalHotspot2ScanTimeMillis(13) 703 .setTotalCcaBusyFreqTimeMillis(14) 704 .setTotalRadioOnFreqTimeMillis(15) 705 .setTotalBeaconRx(16) 706 .setProbeStatusSinceLastUpdate(2) 707 .setProbeElapsedTimeSinceLastUpdateMillis(18) 708 .setProbeMcsRateSinceLastUpdate(19) 709 .setRxLinkSpeedMbps(20) 710 .setCellularDataNetworkType(1) 711 .setCellularSignalStrengthDbm(2) 712 .setCellularSignalStrengthDb(3) 713 .setSameRegisteredCell(false); 714 715 if (RuntimeEnvironment.getApiLevel() >= S) { 716 builder 717 .setTimeSliceDutyCycleInPercent(10) 718 .setIsCellularDataAvailable(false) 719 .setIsThroughputSufficient(false) 720 .setIsWifiScoringEnabled(false); 721 } 722 723 shadowOf(wifiManager) 724 .postUsabilityStats(/* seqNum= */ 10, /* isSameBssidAndFreq= */ false, builder); 725 // THEN 726 727 ArgumentCaptor<WifiUsabilityStatsEntry> usabilityStats = 728 ArgumentCaptor.forClass(WifiUsabilityStatsEntry.class); 729 verify(mockListener).onWifiUsabilityStats(eq(10), eq(false), usabilityStats.capture()); 730 assertThat(usabilityStats.getValue().getTimeStampMillis()).isEqualTo(1234567L); 731 assertThat(usabilityStats.getValue().getRssi()).isEqualTo(23); 732 assertThat(usabilityStats.getValue().getLinkSpeedMbps()).isEqualTo(998); 733 assertThat(usabilityStats.getValue().getTotalTxSuccess()).isEqualTo(1); 734 assertThat(usabilityStats.getValue().getTotalTxRetries()).isEqualTo(2); 735 assertThat(usabilityStats.getValue().getTotalTxBad()).isEqualTo(3); 736 assertThat(usabilityStats.getValue().getTotalRxSuccess()).isEqualTo(4); 737 assertThat(usabilityStats.getValue().getTotalRadioOnTimeMillis()).isEqualTo(5); 738 assertThat(usabilityStats.getValue().getTotalRadioTxTimeMillis()).isEqualTo(6); 739 assertThat(usabilityStats.getValue().getTotalRadioRxTimeMillis()).isEqualTo(7); 740 assertThat(usabilityStats.getValue().getTotalScanTimeMillis()).isEqualTo(8); 741 assertThat(usabilityStats.getValue().getTotalNanScanTimeMillis()).isEqualTo(9); 742 assertThat(usabilityStats.getValue().getTotalBackgroundScanTimeMillis()).isEqualTo(10); 743 assertThat(usabilityStats.getValue().getTotalRoamScanTimeMillis()).isEqualTo(11); 744 assertThat(usabilityStats.getValue().getTotalPnoScanTimeMillis()).isEqualTo(12); 745 assertThat(usabilityStats.getValue().getTotalHotspot2ScanTimeMillis()).isEqualTo(13); 746 assertThat(usabilityStats.getValue().getTotalCcaBusyFreqTimeMillis()).isEqualTo(14); 747 assertThat(usabilityStats.getValue().getTotalRadioOnFreqTimeMillis()).isEqualTo(15); 748 assertThat(usabilityStats.getValue().getTotalBeaconRx()).isEqualTo(16); 749 assertThat(usabilityStats.getValue().getProbeStatusSinceLastUpdate()).isEqualTo(2); 750 assertThat(usabilityStats.getValue().getProbeElapsedTimeSinceLastUpdateMillis()).isEqualTo(18); 751 assertThat(usabilityStats.getValue().getProbeMcsRateSinceLastUpdate()).isEqualTo(19); 752 assertThat(usabilityStats.getValue().getRxLinkSpeedMbps()).isEqualTo(20); 753 assertThat(usabilityStats.getValue().getCellularDataNetworkType()).isEqualTo(1); 754 assertThat(usabilityStats.getValue().getCellularSignalStrengthDbm()).isEqualTo(2); 755 assertThat(usabilityStats.getValue().getCellularSignalStrengthDb()).isEqualTo(3); 756 assertThat(usabilityStats.getValue().isSameRegisteredCell()).isFalse(); 757 if (RuntimeEnvironment.getApiLevel() >= S) { 758 assertThat(usabilityStats.getValue().getTimeSliceDutyCycleInPercent()).isEqualTo(10); 759 assertThat(usabilityStats.getValue().isCellularDataAvailable()).isFalse(); 760 assertThat(usabilityStats.getValue().isThroughputSufficient()).isFalse(); 761 assertThat(usabilityStats.getValue().isWifiScoringEnabled()).isFalse(); 762 } 763 verifyNoMoreInteractions(mockListener); 764 } 765 766 @Test 767 @Config(minSdk = Q) testRemoveOnWifiUsabilityStatsListener()768 public void testRemoveOnWifiUsabilityStatsListener() { 769 // GIVEN 770 WifiManager.OnWifiUsabilityStatsListener mockListener = 771 mock(WifiManager.OnWifiUsabilityStatsListener.class); 772 wifiManager.addOnWifiUsabilityStatsListener(directExecutor(), mockListener); 773 774 WifiUsabilityStatsEntryBuilder builder = new WifiUsabilityStatsEntryBuilder(); 775 builder 776 .setTimeStampMillis(1234567L) 777 .setRssi(23) 778 .setLinkSpeedMbps(998) 779 .setTotalTxSuccess(0) 780 .setTotalTxRetries(0) 781 .setTotalTxBad(0) 782 .setTotalRxSuccess(0) 783 .setTotalRadioOnTimeMillis(0) 784 .setTotalRadioTxTimeMillis(0) 785 .setTotalRadioRxTimeMillis(0) 786 .setTotalScanTimeMillis(0) 787 .setTotalNanScanTimeMillis(0) 788 .setTotalBackgroundScanTimeMillis(0) 789 .setTotalRoamScanTimeMillis(0) 790 .setTotalPnoScanTimeMillis(0) 791 .setTotalHotspot2ScanTimeMillis(0) 792 .setTotalCcaBusyFreqTimeMillis(0) 793 .setTotalRadioOnFreqTimeMillis(0) 794 .setTotalBeaconRx(0) 795 .setProbeStatusSinceLastUpdate(0) 796 .setProbeElapsedTimeSinceLastUpdateMillis(0) 797 .setProbeMcsRateSinceLastUpdate(0) 798 .setRxLinkSpeedMbps(0) 799 .setCellularDataNetworkType(0) 800 .setCellularSignalStrengthDbm(0) 801 .setCellularSignalStrengthDb(0) 802 .setSameRegisteredCell(false); 803 804 // WHEN 805 wifiManager.removeOnWifiUsabilityStatsListener(mockListener); 806 shadowOf(wifiManager) 807 .postUsabilityStats(/* seqNum= */ 10, /* isSameBssidAndFreq= */ true, builder); 808 809 // THEN 810 verifyNoMoreInteractions(mockListener); 811 } 812 813 @Test 814 @Config(minSdk = R) testSetClearWifiConnectedNetworkScorer()815 public void testSetClearWifiConnectedNetworkScorer() { 816 // GIVEN 817 WifiManager.WifiConnectedNetworkScorer mockScorer = 818 mock(WifiManager.WifiConnectedNetworkScorer.class); 819 // WHEN 820 wifiManager.setWifiConnectedNetworkScorer(directExecutor(), mockScorer); 821 assertThat(shadowOf(wifiManager).isWifiConnectedNetworkScorerEnabled()).isTrue(); 822 wifiManager.clearWifiConnectedNetworkScorer(); 823 824 // THEN 825 assertThat(shadowOf(wifiManager).isWifiConnectedNetworkScorerEnabled()).isFalse(); 826 } 827 828 @Test 829 @Config(minSdk = Q) testGetUsabilityScores()830 public void testGetUsabilityScores() { 831 // GIVEN 832 wifiManager.updateWifiUsabilityScore( 833 /* seqNum= */ 23, /* score= */ 50, /* predictionHorizonSec= */ 16); 834 wifiManager.updateWifiUsabilityScore( 835 /* seqNum= */ 24, /* score= */ 40, /* predictionHorizonSec= */ 16); 836 837 // WHEN 838 List<ShadowWifiManager.WifiUsabilityScore> scores = shadowOf(wifiManager).getUsabilityScores(); 839 840 // THEN 841 assertThat(scores).hasSize(2); 842 assertThat(scores.get(0).seqNum).isEqualTo(23); 843 assertThat(scores.get(0).score).isEqualTo(50); 844 assertThat(scores.get(0).predictionHorizonSec).isEqualTo(16); 845 assertThat(scores.get(1).seqNum).isEqualTo(24); 846 assertThat(scores.get(1).score).isEqualTo(40); 847 assertThat(scores.get(1).predictionHorizonSec).isEqualTo(16); 848 } 849 850 @Test 851 @Config(minSdk = Q) testClearUsabilityScores()852 public void testClearUsabilityScores() { 853 // GIVEN 854 wifiManager.updateWifiUsabilityScore( 855 /* seqNum= */ 23, /* score= */ 50, /* predictionHorizonSec= */ 16); 856 wifiManager.updateWifiUsabilityScore( 857 /* seqNum= */ 24, /* score= */ 40, /* predictionHorizonSec= */ 16); 858 859 // WHEN 860 shadowOf(wifiManager).clearUsabilityScores(); 861 List<ShadowWifiManager.WifiUsabilityScore> scores = shadowOf(wifiManager).getUsabilityScores(); 862 863 // THEN 864 assertThat(scores).isEmpty(); 865 } 866 867 @Test testSetWifiState()868 public void testSetWifiState() { 869 shadowOf(wifiManager).setWifiState(WifiManager.WIFI_STATE_ENABLED); 870 assertThat(wifiManager.getWifiState()).isEqualTo(WifiManager.WIFI_STATE_ENABLED); 871 assertThat(wifiManager.isWifiEnabled()).isTrue(); 872 873 wifiManager.setWifiEnabled(false); 874 assertThat(wifiManager.getWifiState()).isEqualTo(WifiManager.WIFI_STATE_DISABLED); 875 assertThat(wifiManager.isWifiEnabled()).isFalse(); 876 877 shadowOf(wifiManager).setWifiState(WifiManager.WIFI_STATE_ENABLING); 878 assertThat(wifiManager.getWifiState()).isEqualTo(WifiManager.WIFI_STATE_ENABLING); 879 assertThat(wifiManager.isWifiEnabled()).isFalse(); 880 881 shadowOf(wifiManager).setWifiState(WifiManager.WIFI_STATE_DISABLING); 882 assertThat(wifiManager.getWifiState()).isEqualTo(WifiManager.WIFI_STATE_DISABLING); 883 assertThat(wifiManager.isWifiEnabled()).isFalse(); 884 885 shadowOf(wifiManager).setWifiState(WifiManager.WIFI_STATE_UNKNOWN); 886 assertThat(wifiManager.getWifiState()).isEqualTo(WifiManager.WIFI_STATE_UNKNOWN); 887 assertThat(wifiManager.isWifiEnabled()).isFalse(); 888 889 shadowOf(wifiManager).setWifiState(WifiManager.WIFI_STATE_DISABLED); 890 assertThat(wifiManager.getWifiState()).isEqualTo(WifiManager.WIFI_STATE_DISABLED); 891 assertThat(wifiManager.isWifiEnabled()).isFalse(); 892 } 893 894 @Test shouldRecordTheLastApConfiguration()895 public void shouldRecordTheLastApConfiguration() { 896 WifiConfiguration wifiConfiguration = new WifiConfiguration(); 897 wifiConfiguration.SSID = "foo"; 898 boolean status = shadowOf(wifiManager).setWifiApConfiguration(wifiConfiguration); 899 assertThat(status).isTrue(); 900 901 assertThat(shadowOf(wifiManager).getWifiApConfiguration().SSID).isEqualTo("foo"); 902 } 903 904 @Test 905 @Config(minSdk = R) shouldRecordTheLastSoftApConfiguration()906 public void shouldRecordTheLastSoftApConfiguration() { 907 SoftApConfiguration softApConfig = 908 new SoftApConfiguration.Builder() 909 .setSsid("foo") 910 .setPassphrase(null, SoftApConfiguration.SECURITY_TYPE_OPEN) 911 .build(); 912 913 boolean status = wifiManager.setSoftApConfiguration(softApConfig); 914 assertThat(status).isTrue(); 915 916 assertThat(shadowOf(wifiManager).getSoftApConfiguration().getSsid()).isEqualTo("foo"); 917 } 918 919 @Test 920 @Config(minSdk = TIRAMISU) setExternalPnoScanRequest_nullCallback_throwsIllegalArgumentException()921 public void setExternalPnoScanRequest_nullCallback_throwsIllegalArgumentException() { 922 assertThrows( 923 IllegalArgumentException.class, 924 () -> 925 wifiManager.setExternalPnoScanRequest( 926 List.of(WifiSsid.fromBytes(new byte[] {3, 2, 5})), 927 /* frequencies= */ null, 928 Executors.newSingleThreadExecutor(), 929 /* callback= */ null)); 930 } 931 932 @Test 933 @Config(minSdk = TIRAMISU) setExternalPnoScanRequest_nullExecutor_throwsIllegalArgumentException()934 public void setExternalPnoScanRequest_nullExecutor_throwsIllegalArgumentException() { 935 assertThrows( 936 IllegalArgumentException.class, 937 () -> 938 wifiManager.setExternalPnoScanRequest( 939 List.of(WifiSsid.fromBytes(new byte[] {3, 2, 5})), 940 /* frequencies= */ null, 941 /* executor= */ null, 942 new TestPnoScanResultsCallback())); 943 } 944 945 @Test 946 @Config(minSdk = TIRAMISU) setExternalPnoScanRequest_nullSsidList_throwsIllegalStateException()947 public void setExternalPnoScanRequest_nullSsidList_throwsIllegalStateException() { 948 assertThrows( 949 IllegalStateException.class, 950 () -> 951 wifiManager.setExternalPnoScanRequest( 952 /* ssids= */ null, 953 /* frequencies= */ null, 954 Executors.newSingleThreadExecutor(), 955 new TestPnoScanResultsCallback())); 956 } 957 958 @Test 959 @Config(minSdk = TIRAMISU) setExternalPnoScanRequest_emptySsidList_throwsIllegalStateException()960 public void setExternalPnoScanRequest_emptySsidList_throwsIllegalStateException() { 961 assertThrows( 962 IllegalStateException.class, 963 () -> 964 wifiManager.setExternalPnoScanRequest( 965 /* ssids= */ List.of(), 966 /* frequencies= */ null, 967 Executors.newSingleThreadExecutor(), 968 new TestPnoScanResultsCallback())); 969 } 970 971 @Test 972 @Config(minSdk = TIRAMISU) setExternalPnoScanRequest_moreThan2Ssids_throwsIllegalArgumentException()973 public void setExternalPnoScanRequest_moreThan2Ssids_throwsIllegalArgumentException() { 974 assertThrows( 975 IllegalArgumentException.class, 976 () -> 977 wifiManager.setExternalPnoScanRequest( 978 List.of( 979 WifiSsid.fromBytes(new byte[] {1, 2, 3}), 980 WifiSsid.fromBytes(new byte[] {9, 8, 7, 6}), 981 WifiSsid.fromBytes(new byte[] {90, 81, 72, 63, 54})), 982 /* frequencies= */ null, 983 Executors.newSingleThreadExecutor(), 984 new TestPnoScanResultsCallback())); 985 } 986 987 @Test 988 @Config(minSdk = TIRAMISU) setExternalPnoScanRequest_moreThan10Frequencies_throwsIllegalArgumentException()989 public void setExternalPnoScanRequest_moreThan10Frequencies_throwsIllegalArgumentException() { 990 assertThrows( 991 IllegalArgumentException.class, 992 () -> 993 wifiManager.setExternalPnoScanRequest( 994 List.of( 995 WifiSsid.fromBytes(new byte[] {1, 2, 3}), 996 WifiSsid.fromBytes(new byte[] {9, 8, 7, 6})), 997 new int[] {5160, 5180, 5200, 5220, 5240, 5260, 5280, 5300, 5320, 5340, 5360}, 998 Executors.newSingleThreadExecutor(), 999 new TestPnoScanResultsCallback())); 1000 } 1001 1002 @Test 1003 @Config(minSdk = TIRAMISU) setExternalPnoScanRequest_validRequest_successCallbackInvoked()1004 public void setExternalPnoScanRequest_validRequest_successCallbackInvoked() throws Exception { 1005 TestPnoScanResultsCallback callback = new TestPnoScanResultsCallback(); 1006 1007 wifiManager.setExternalPnoScanRequest( 1008 List.of(WifiSsid.fromBytes(new byte[] {1, 2, 3})), 1009 /* frequencies= */ null, 1010 Executors.newSingleThreadExecutor(), 1011 callback); 1012 1013 assertThat(callback.successfulRegistrations.take()).isNotNull(); 1014 } 1015 1016 @Test 1017 @Config(minSdk = TIRAMISU) 1018 public void setExternalPnoScanRequest_outstandingRequest_failureCallbackInvokedWithAlreadyRegisteredStatus()1019 setExternalPnoScanRequest_outstandingRequest_failureCallbackInvokedWithAlreadyRegisteredStatus() 1020 throws Exception { 1021 TestPnoScanResultsCallback callback = new TestPnoScanResultsCallback(); 1022 1023 wifiManager.setExternalPnoScanRequest( 1024 List.of(WifiSsid.fromBytes(new byte[] {1, 2, 3})), 1025 /* frequencies= */ null, 1026 Executors.newSingleThreadExecutor(), 1027 callback); 1028 1029 wifiManager.setExternalPnoScanRequest( 1030 List.of(WifiSsid.fromBytes(new byte[] {9, 2, 5})), 1031 new int[] {5280}, 1032 Executors.newSingleThreadExecutor(), 1033 callback); 1034 1035 assertThat(callback.failedRegistrations.take()) 1036 .isEqualTo(PnoScanResultsCallback.REGISTER_PNO_CALLBACK_ALREADY_REGISTERED); 1037 } 1038 1039 @Test 1040 @Config(minSdk = TIRAMISU) setExternalPnoScanRequest_differentUid_failureCallbackInvokedWithBusyStatus()1041 public void setExternalPnoScanRequest_differentUid_failureCallbackInvokedWithBusyStatus() 1042 throws Exception { 1043 TestPnoScanResultsCallback callback = new TestPnoScanResultsCallback(); 1044 1045 wifiManager.setExternalPnoScanRequest( 1046 List.of(WifiSsid.fromBytes(new byte[] {1, 2, 3})), 1047 /* frequencies= */ null, 1048 Executors.newSingleThreadExecutor(), 1049 callback); 1050 1051 int firstAppUid = ShadowProcess.myUid(); 1052 int secondAppUid; 1053 do { 1054 secondAppUid = ShadowProcess.getRandomApplicationUid(); 1055 } while (firstAppUid == secondAppUid); 1056 ShadowProcess.setUid(secondAppUid); 1057 1058 wifiManager.setExternalPnoScanRequest( 1059 List.of(WifiSsid.fromBytes(new byte[] {1, 2, 3})), 1060 /* frequencies= */ null, 1061 Executors.newSingleThreadExecutor(), 1062 callback); 1063 1064 assertThat(callback.failedRegistrations.take()) 1065 .isEqualTo(PnoScanResultsCallback.REGISTER_PNO_CALLBACK_RESOURCE_BUSY); 1066 } 1067 1068 @Test 1069 @Config(minSdk = TIRAMISU) clearExternalPnoScanRequest_outstandingRequest_callbackInvokedWithUnregisteredStatus()1070 public void clearExternalPnoScanRequest_outstandingRequest_callbackInvokedWithUnregisteredStatus() 1071 throws Exception { 1072 TestPnoScanResultsCallback callback = new TestPnoScanResultsCallback(); 1073 1074 wifiManager.setExternalPnoScanRequest( 1075 List.of(WifiSsid.fromBytes(new byte[] {1, 2, 3})), 1076 /* frequencies= */ null, 1077 Executors.newSingleThreadExecutor(), 1078 callback); 1079 wifiManager.clearExternalPnoScanRequest(); 1080 1081 assertThat(callback.removedRegistrations.take()) 1082 .isEqualTo(PnoScanResultsCallback.REMOVE_PNO_CALLBACK_UNREGISTERED); 1083 } 1084 1085 @Test 1086 @Config(minSdk = TIRAMISU) clearExternalPnoScanRequest_wrongUid_callbackNotInvoked()1087 public void clearExternalPnoScanRequest_wrongUid_callbackNotInvoked() throws Exception { 1088 TestPnoScanResultsCallback callback = new TestPnoScanResultsCallback(); 1089 ExecutorService executor = Executors.newSingleThreadExecutor(); 1090 1091 wifiManager.setExternalPnoScanRequest( 1092 List.of(WifiSsid.fromBytes(new byte[] {1, 2, 3})), 1093 /* frequencies= */ null, 1094 executor, 1095 callback); 1096 1097 int firstAppUid = ShadowProcess.myUid(); 1098 int secondAppUid; 1099 do { 1100 secondAppUid = ShadowProcess.getRandomApplicationUid(); 1101 } while (firstAppUid == secondAppUid); 1102 ShadowProcess.setUid(secondAppUid); 1103 1104 wifiManager.clearExternalPnoScanRequest(); 1105 1106 executor.shutdown(); 1107 1108 assertThat(executor.awaitTermination(5, MINUTES)).isTrue(); 1109 assertThat(callback.removedRegistrations).isEmpty(); 1110 } 1111 1112 @Test 1113 @Config(minSdk = TIRAMISU) networksFoundFromPnoScan_matchingSsid_availableCallbackInvoked()1114 public void networksFoundFromPnoScan_matchingSsid_availableCallbackInvoked() throws Exception { 1115 TestPnoScanResultsCallback callback = new TestPnoScanResultsCallback(); 1116 WifiSsid wifiSsid = WifiSsid.fromBytes(new byte[] {1, 2, 3}); 1117 ScanResult scanResult = new ScanResult(); 1118 scanResult.setWifiSsid(wifiSsid); 1119 1120 wifiManager.setExternalPnoScanRequest( 1121 List.of(wifiSsid), /* frequencies= */ null, Executors.newSingleThreadExecutor(), callback); 1122 shadowOf(wifiManager).networksFoundFromPnoScan(List.of(scanResult)); 1123 1124 assertThat(callback.incomingScanResults.take()).containsExactly(scanResult); 1125 } 1126 1127 @Test 1128 @Config(minSdk = TIRAMISU) networksFoundFromPnoScan_matchingSsid_removedCallbackInvokedWithDeliveredStatus()1129 public void networksFoundFromPnoScan_matchingSsid_removedCallbackInvokedWithDeliveredStatus() 1130 throws Exception { 1131 TestPnoScanResultsCallback callback = new TestPnoScanResultsCallback(); 1132 WifiSsid wifiSsid = WifiSsid.fromBytes(new byte[] {1, 2, 3}); 1133 ScanResult scanResult = new ScanResult(); 1134 scanResult.setWifiSsid(wifiSsid); 1135 1136 wifiManager.setExternalPnoScanRequest( 1137 List.of(wifiSsid), /* frequencies= */ null, Executors.newSingleThreadExecutor(), callback); 1138 shadowOf(wifiManager).networksFoundFromPnoScan(List.of(scanResult)); 1139 1140 assertThat(callback.removedRegistrations.take()) 1141 .isEqualTo(PnoScanResultsCallback.REMOVE_PNO_CALLBACK_RESULTS_DELIVERED); 1142 } 1143 1144 @Test 1145 @Config(minSdk = TIRAMISU) networksFoundFromPnoScan_matchingSsid_scanResultsAvailableBroadcastSent()1146 public void networksFoundFromPnoScan_matchingSsid_scanResultsAvailableBroadcastSent() { 1147 TestPnoScanResultsCallback callback = new TestPnoScanResultsCallback(); 1148 WifiSsid wifiSsid = WifiSsid.fromBytes(new byte[] {1, 2, 3}); 1149 ScanResult scanResult = new ScanResult(); 1150 scanResult.setWifiSsid(wifiSsid); 1151 1152 wifiManager.setExternalPnoScanRequest( 1153 List.of(wifiSsid), /* frequencies= */ null, Executors.newSingleThreadExecutor(), callback); 1154 shadowOf(wifiManager).networksFoundFromPnoScan(List.of(scanResult)); 1155 1156 Intent expectedIntent = new Intent(SCAN_RESULTS_AVAILABLE_ACTION); 1157 expectedIntent.putExtra(WifiManager.EXTRA_RESULTS_UPDATED, true); 1158 expectedIntent.setPackage(getApplicationContext().getPackageName()); 1159 1160 assertThat( 1161 shadowOf((Application) getApplicationContext()).getBroadcastIntents().stream() 1162 .anyMatch(expectedIntent::filterEquals)) 1163 .isTrue(); 1164 } 1165 1166 @Test 1167 @Config(minSdk = TIRAMISU) networksFoundFromPnoScan_noMatchingSsid_availableCallbackNotInvoked()1168 public void networksFoundFromPnoScan_noMatchingSsid_availableCallbackNotInvoked() 1169 throws Exception { 1170 TestPnoScanResultsCallback callback = new TestPnoScanResultsCallback(); 1171 ExecutorService executor = Executors.newSingleThreadExecutor(); 1172 WifiSsid wifiSsid = WifiSsid.fromBytes(new byte[] {1, 2, 3}); 1173 WifiSsid otherWifiSsid = WifiSsid.fromBytes(new byte[] {9, 8, 7, 6}); 1174 ScanResult scanResult = new ScanResult(); 1175 scanResult.setWifiSsid(otherWifiSsid); 1176 1177 wifiManager.setExternalPnoScanRequest( 1178 List.of(wifiSsid), /* frequencies= */ null, executor, callback); 1179 shadowOf(wifiManager).networksFoundFromPnoScan(List.of(scanResult)); 1180 1181 executor.shutdown(); 1182 1183 assertThat(executor.awaitTermination(5, MINUTES)).isTrue(); 1184 assertThat(callback.incomingScanResults).isEmpty(); 1185 } 1186 1187 @Test 1188 @Config(minSdk = U.SDK_INT) addLocalOnlyConnectionFailureListener_nullExecutor_throwsIllegalArgumentException()1189 public void addLocalOnlyConnectionFailureListener_nullExecutor_throwsIllegalArgumentException() { 1190 assertThrows( 1191 IllegalArgumentException.class, 1192 () -> 1193 wifiManager.addLocalOnlyConnectionFailureListener( 1194 /* executor= */ null, /* listener= */ (unused1, unused2) -> {})); 1195 } 1196 1197 @Test 1198 @Config(minSdk = U.SDK_INT) addLocalOnlyConnectionFailureListener_nullListener_throwsIllegalArgumentException()1199 public void addLocalOnlyConnectionFailureListener_nullListener_throwsIllegalArgumentException() { 1200 assertThrows( 1201 IllegalArgumentException.class, 1202 () -> 1203 wifiManager.addLocalOnlyConnectionFailureListener( 1204 Executors.newSingleThreadExecutor(), /* listener= */ null)); 1205 } 1206 1207 @Test 1208 @Config(minSdk = U.SDK_INT) 1209 public void removeLocalOnlyConnectionFailureListener_nullListener_throwsIllegalArgumentException()1210 removeLocalOnlyConnectionFailureListener_nullListener_throwsIllegalArgumentException() { 1211 assertThrows( 1212 IllegalArgumentException.class, 1213 () -> wifiManager.removeLocalOnlyConnectionFailureListener(/* listener= */ null)); 1214 } 1215 1216 @Test 1217 @Config(minSdk = U.SDK_INT) triggerLocalConnectionFailure_callbackTriggered()1218 public void triggerLocalConnectionFailure_callbackTriggered() throws Exception { 1219 ExecutorService executor = Executors.newSingleThreadExecutor(); 1220 TestFailureListener listener = new TestFailureListener(); 1221 WifiNetworkSpecifier wifiNetworkSpecifier = 1222 new WifiNetworkSpecifier.Builder() 1223 .setSsid("icanhazinternet") 1224 .setBssid(MacAddress.fromString("01:92:83:74:65:AB")) 1225 .setWpa3Passphrase("r3@l gud pa$$w0rd") 1226 .build(); 1227 1228 wifiManager.addLocalOnlyConnectionFailureListener(executor, listener); 1229 ((ShadowWifiManager) Shadow.extract(wifiManager)) 1230 .triggerLocalConnectionFailure( 1231 wifiNetworkSpecifier, WifiManager.STATUS_LOCAL_ONLY_CONNECTION_FAILURE_AUTHENTICATION); 1232 executor.shutdown(); 1233 1234 IncomingFailure incomingFailure = listener.incomingFailures.take(); 1235 assertThat(incomingFailure.wifiNetworkSpecifier).isEqualTo(wifiNetworkSpecifier); 1236 assertThat(incomingFailure.failureReason) 1237 .isEqualTo(WifiManager.STATUS_LOCAL_ONLY_CONNECTION_FAILURE_AUTHENTICATION); 1238 } 1239 1240 @Test 1241 @Config(minSdk = U.SDK_INT) triggerLocalConnectionFailure_multipleCallbacksRegistered_allCallbacksTriggered()1242 public void triggerLocalConnectionFailure_multipleCallbacksRegistered_allCallbacksTriggered() 1243 throws Exception { 1244 ExecutorService executor = Executors.newSingleThreadExecutor(); 1245 TestFailureListener listener1 = new TestFailureListener(); 1246 TestFailureListener listener2 = new TestFailureListener(); 1247 WifiNetworkSpecifier wifiNetworkSpecifier = 1248 new WifiNetworkSpecifier.Builder() 1249 .setSsid("icanhazinternet") 1250 .setBssid(MacAddress.fromString("01:92:83:74:65:AB")) 1251 .setWpa3Passphrase("r3@l gud pa$$w0rd") 1252 .build(); 1253 1254 wifiManager.addLocalOnlyConnectionFailureListener(executor, listener1); 1255 wifiManager.addLocalOnlyConnectionFailureListener(executor, listener2); 1256 ((ShadowWifiManager) Shadow.extract(wifiManager)) 1257 .triggerLocalConnectionFailure( 1258 wifiNetworkSpecifier, WifiManager.STATUS_LOCAL_ONLY_CONNECTION_FAILURE_AUTHENTICATION); 1259 executor.shutdown(); 1260 1261 IncomingFailure incomingFailure = listener1.incomingFailures.take(); 1262 assertThat(incomingFailure.wifiNetworkSpecifier).isEqualTo(wifiNetworkSpecifier); 1263 assertThat(incomingFailure.failureReason) 1264 .isEqualTo(WifiManager.STATUS_LOCAL_ONLY_CONNECTION_FAILURE_AUTHENTICATION); 1265 incomingFailure = listener2.incomingFailures.take(); 1266 assertThat(incomingFailure.wifiNetworkSpecifier).isEqualTo(wifiNetworkSpecifier); 1267 assertThat(incomingFailure.failureReason) 1268 .isEqualTo(WifiManager.STATUS_LOCAL_ONLY_CONNECTION_FAILURE_AUTHENTICATION); 1269 } 1270 1271 @Test 1272 @Config(minSdk = U.SDK_INT) 1273 public void triggerLocalConnectionFailure_multipleCallbacksRegisteredOnDifferentExecutors_allCallbacksTriggered()1274 triggerLocalConnectionFailure_multipleCallbacksRegisteredOnDifferentExecutors_allCallbacksTriggered() 1275 throws Exception { 1276 ExecutorService executor1 = Executors.newSingleThreadExecutor(); 1277 ExecutorService executor2 = Executors.newSingleThreadExecutor(); 1278 TestFailureListener listener1 = new TestFailureListener(); 1279 TestFailureListener listener2 = new TestFailureListener(); 1280 WifiNetworkSpecifier wifiNetworkSpecifier = 1281 new WifiNetworkSpecifier.Builder() 1282 .setSsid("icanhazinternet") 1283 .setBssid(MacAddress.fromString("01:92:83:74:65:AB")) 1284 .setWpa3Passphrase("r3@l gud pa$$w0rd") 1285 .build(); 1286 1287 wifiManager.addLocalOnlyConnectionFailureListener(executor1, listener1); 1288 wifiManager.addLocalOnlyConnectionFailureListener(executor2, listener2); 1289 ((ShadowWifiManager) Shadow.extract(wifiManager)) 1290 .triggerLocalConnectionFailure( 1291 wifiNetworkSpecifier, WifiManager.STATUS_LOCAL_ONLY_CONNECTION_FAILURE_AUTHENTICATION); 1292 executor1.shutdown(); 1293 executor2.shutdown(); 1294 1295 IncomingFailure incomingFailure = listener1.incomingFailures.take(); 1296 assertThat(incomingFailure.wifiNetworkSpecifier).isEqualTo(wifiNetworkSpecifier); 1297 assertThat(incomingFailure.failureReason) 1298 .isEqualTo(WifiManager.STATUS_LOCAL_ONLY_CONNECTION_FAILURE_AUTHENTICATION); 1299 incomingFailure = listener2.incomingFailures.take(); 1300 assertThat(incomingFailure.wifiNetworkSpecifier).isEqualTo(wifiNetworkSpecifier); 1301 assertThat(incomingFailure.failureReason) 1302 .isEqualTo(WifiManager.STATUS_LOCAL_ONLY_CONNECTION_FAILURE_AUTHENTICATION); 1303 } 1304 1305 @Test 1306 @Config(minSdk = U.SDK_INT) triggerLocalConnectionFailure_listenerRemovedBeforeTrigger_callbackNotInvoked()1307 public void triggerLocalConnectionFailure_listenerRemovedBeforeTrigger_callbackNotInvoked() { 1308 ExecutorService executor = Executors.newSingleThreadExecutor(); 1309 TestFailureListener listener = new TestFailureListener(); 1310 WifiNetworkSpecifier wifiNetworkSpecifier = 1311 new WifiNetworkSpecifier.Builder() 1312 .setSsid("icanhazinternet") 1313 .setBssid(MacAddress.fromString("01:92:83:74:65:AB")) 1314 .setWpa3Passphrase("r3@l gud pa$$w0rd") 1315 .build(); 1316 1317 wifiManager.addLocalOnlyConnectionFailureListener(executor, listener); 1318 wifiManager.removeLocalOnlyConnectionFailureListener(listener); 1319 ((ShadowWifiManager) Shadow.extract(wifiManager)) 1320 .triggerLocalConnectionFailure( 1321 wifiNetworkSpecifier, WifiManager.STATUS_LOCAL_ONLY_CONNECTION_FAILURE_AUTHENTICATION); 1322 executor.shutdown(); 1323 1324 assertThat(listener.incomingFailures).isEmpty(); 1325 } 1326 1327 private static final class IncomingFailure { 1328 private final WifiNetworkSpecifier wifiNetworkSpecifier; 1329 private final int failureReason; 1330 IncomingFailure(WifiNetworkSpecifier wifiNetworkSpecifier, int failureReason)1331 IncomingFailure(WifiNetworkSpecifier wifiNetworkSpecifier, int failureReason) { 1332 this.wifiNetworkSpecifier = wifiNetworkSpecifier; 1333 this.failureReason = failureReason; 1334 } 1335 } 1336 1337 private static final class TestFailureListener implements LocalOnlyConnectionFailureListener { 1338 private final BlockingQueue<IncomingFailure> incomingFailures = new LinkedBlockingQueue<>(); 1339 1340 @Override onConnectionFailed(WifiNetworkSpecifier wifiNetworkSpecifier, int i)1341 public void onConnectionFailed(WifiNetworkSpecifier wifiNetworkSpecifier, int i) { 1342 incomingFailures.add(new IncomingFailure(wifiNetworkSpecifier, i)); 1343 } 1344 } 1345 1346 private class TestPnoScanResultsCallback implements PnoScanResultsCallback { 1347 LinkedBlockingQueue<List<ScanResult>> incomingScanResults = new LinkedBlockingQueue<>(); 1348 LinkedBlockingQueue<Object> successfulRegistrations = new LinkedBlockingQueue<>(); 1349 LinkedBlockingQueue<Integer> failedRegistrations = new LinkedBlockingQueue<>(); 1350 LinkedBlockingQueue<Integer> removedRegistrations = new LinkedBlockingQueue<>(); 1351 1352 @Override onScanResultsAvailable(List<ScanResult> scanResults)1353 public void onScanResultsAvailable(List<ScanResult> scanResults) { 1354 incomingScanResults.add(scanResults); 1355 } 1356 1357 @Override onRegisterSuccess()1358 public void onRegisterSuccess() { 1359 successfulRegistrations.add(new Object()); 1360 } 1361 1362 @Override onRegisterFailed(int reason)1363 public void onRegisterFailed(int reason) { 1364 failedRegistrations.add(reason); 1365 } 1366 1367 @Override onRemoved(int reason)1368 public void onRemoved(int reason) { 1369 removedRegistrations.add(reason); 1370 } 1371 } 1372 setDeviceOwner()1373 private void setDeviceOwner() { 1374 shadowOf( 1375 (DevicePolicyManager) 1376 getApplicationContext().getSystemService(Context.DEVICE_POLICY_SERVICE)) 1377 .setDeviceOwner(new ComponentName(getApplicationContext(), DeviceAdminService.class)); 1378 } 1379 } 1380