1 /* 2 * Copyright (C) 2018 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 17 package android.net.wifi; 18 19 import static org.junit.Assert.assertArrayEquals; 20 import static org.junit.Assert.assertEquals; 21 import static org.junit.Assert.assertFalse; 22 import static org.junit.Assert.assertNotEquals; 23 import static org.junit.Assert.assertNotNull; 24 import static org.junit.Assert.assertNotSame; 25 import static org.junit.Assert.assertNull; 26 import static org.junit.Assert.assertThrows; 27 import static org.junit.Assert.assertTrue; 28 import static org.junit.Assert.fail; 29 import static org.junit.Assume.assumeTrue; 30 31 import android.net.MacAddress; 32 import android.net.NetworkCapabilities; 33 import android.net.wifi.util.HexEncoding; 34 import android.os.Parcel; 35 import android.telephony.SubscriptionManager; 36 37 import androidx.test.filters.SmallTest; 38 39 import com.android.modules.utils.build.SdkLevel; 40 41 import org.junit.Test; 42 43 import java.nio.charset.Charset; 44 import java.nio.charset.StandardCharsets; 45 import java.util.ArrayList; 46 import java.util.List; 47 48 /** 49 * Unit tests for {@link android.net.wifi.WifiInfo}. 50 */ 51 @SmallTest 52 public class WifiInfoTest { 53 private static final long TEST_TX_SUCCESS = 1; 54 private static final long TEST_TX_RETRIES = 2; 55 private static final long TEST_TX_BAD = 3; 56 private static final long TEST_RX_SUCCESS = 4; 57 private static final String TEST_PACKAGE_NAME = "com.test.example"; 58 private static final String TEST_FQDN = "test.com"; 59 private static final String TEST_PROVIDER_NAME = "test"; 60 private static final int TEST_WIFI_STANDARD = ScanResult.WIFI_STANDARD_11AC; 61 private static final int TEST_MAX_SUPPORTED_TX_LINK_SPEED_MBPS = 866; 62 private static final int TEST_MAX_SUPPORTED_RX_LINK_SPEED_MBPS = 1200; 63 private static final String TEST_SSID = "Test123"; 64 private static final String TEST_BSSID = "12:12:12:12:12:12"; 65 private static final int TEST_RSSI = -60; 66 private static final int TEST_NETWORK_ID = 5; 67 private static final int TEST_NETWORK_ID2 = 6; 68 private static final int TEST_SUB_ID = 1; 69 private static final String TEST_NETWORK_KEY = "TestNetworkKey"; 70 private static final String AP_MLD_MAC_ADDRESS = "22:33:44:55:66:77"; 71 private static final String MLO_LINK_STA_MAC_ADDRESS = "12:34:56:78:9a:bc"; 72 private static final String MLO_LINK_AP_MAC_ADDRESS = "bc:9a:78:56:34:12"; 73 private static final int TEST_MLO_LINK_ID = 3; 74 private static final int TEST_CHANNEL = 36; 75 private static final int TEST_LINK_SPEED = 300; 76 private static final List<OuiKeyedData> TEST_VENDOR_DATA = 77 OuiKeyedDataUtil.createTestOuiKeyedDataList(5); 78 addMloInfo(WifiInfo info)79 private void addMloInfo(WifiInfo info) { 80 info.setApMldMacAddress(MacAddress.fromString(AP_MLD_MAC_ADDRESS)); 81 info.enableApTidToLinkMappingNegotiationSupport(true); 82 List<MloLink> links = new ArrayList<>(); 83 MloLink link = new MloLink(); 84 link.setStaMacAddress(MacAddress.fromString(MLO_LINK_STA_MAC_ADDRESS)); 85 link.setApMacAddress(MacAddress.fromString(MLO_LINK_AP_MAC_ADDRESS)); 86 links.add(link); 87 info.setAffiliatedMloLinks(links); 88 link.setRssi(TEST_RSSI); 89 link.setLinkId(TEST_MLO_LINK_ID); 90 link.setBand(WifiScanner.WIFI_BAND_5_GHZ); 91 link.setChannel(TEST_CHANNEL); 92 link.setRxLinkSpeedMbps(TEST_LINK_SPEED); 93 link.setTxLinkSpeedMbps(TEST_LINK_SPEED); 94 link.setState(MloLink.MLO_LINK_STATE_UNASSOCIATED); 95 } 96 assertMloNoRedaction(WifiInfo info)97 private void assertMloNoRedaction(WifiInfo info) { 98 assertTrue(info.isApTidToLinkMappingNegotiationSupported()); 99 assertNotNull(info.getApMldMacAddress()); 100 assertEquals(AP_MLD_MAC_ADDRESS, info.getApMldMacAddress().toString()); 101 List<MloLink> links = info.getAffiliatedMloLinks(); 102 assertEquals(1, links.size()); 103 for (MloLink link : links) { 104 assertNotNull(link.getApMacAddress()); 105 assertEquals(MLO_LINK_AP_MAC_ADDRESS, link.getApMacAddress().toString()); 106 assertNotNull(link.getStaMacAddress()); 107 assertEquals(MLO_LINK_STA_MAC_ADDRESS, link.getStaMacAddress().toString()); 108 assertEquals(TEST_RSSI, link.getRssi()); 109 assertEquals(TEST_CHANNEL, link.getChannel()); 110 assertEquals(TEST_LINK_SPEED, link.getRxLinkSpeedMbps()); 111 assertEquals(TEST_LINK_SPEED, link.getTxLinkSpeedMbps()); 112 assertEquals(TEST_MLO_LINK_ID, link.getLinkId()); 113 assertEquals(WifiScanner.WIFI_BAND_5_GHZ, link.getBand()); 114 assertEquals(MloLink.MLO_LINK_STATE_UNASSOCIATED, link.getState()); 115 } 116 } 117 assertMloLocalMacRedaction(WifiInfo info)118 private void assertMloLocalMacRedaction(WifiInfo info) { 119 assertNotNull(info.getApMldMacAddress()); 120 assertEquals(AP_MLD_MAC_ADDRESS, info.getApMldMacAddress().toString()); 121 List<MloLink> links = info.getAffiliatedMloLinks(); 122 assertEquals(1, links.size()); 123 for (MloLink link : links) { 124 assertNotNull(link.getApMacAddress()); 125 assertEquals(MLO_LINK_AP_MAC_ADDRESS, link.getApMacAddress().toString()); 126 assertNull(link.getStaMacAddress()); 127 } 128 } 129 assertMloSensitiveLocationRedaction(WifiInfo info)130 private void assertMloSensitiveLocationRedaction(WifiInfo info) { 131 assertNull(info.getApMldMacAddress()); 132 List<MloLink> links = info.getAffiliatedMloLinks(); 133 assertEquals(1, links.size()); 134 for (MloLink link : links) { 135 assertNull(link.getApMacAddress()); 136 assertNotNull(link.getStaMacAddress()); 137 assertEquals(MLO_LINK_STA_MAC_ADDRESS, link.getStaMacAddress().toString()); 138 } 139 } 140 makeWifiInfoForRedactionTest( List<ScanResult.InformationElement> informationElements)141 private WifiInfo makeWifiInfoForRedactionTest( 142 List<ScanResult.InformationElement> informationElements) { 143 WifiInfo info = new WifiInfo(); 144 info.txSuccess = TEST_TX_SUCCESS; 145 info.txRetries = TEST_TX_RETRIES; 146 info.txBad = TEST_TX_BAD; 147 info.rxSuccess = TEST_RX_SUCCESS; 148 info.setSSID(WifiSsid.fromUtf8Text(TEST_SSID)); 149 info.setBSSID(TEST_BSSID); 150 info.setNetworkId(TEST_NETWORK_ID); 151 info.setTrusted(true); 152 info.setOemPaid(true); 153 info.setOemPrivate(true); 154 info.setCarrierMerged(true); 155 info.setOsuAp(true); 156 info.setFQDN(TEST_FQDN); 157 info.setProviderFriendlyName(TEST_PROVIDER_NAME); 158 info.setRequestingPackageName(TEST_PACKAGE_NAME); 159 info.setWifiStandard(TEST_WIFI_STANDARD); 160 info.setMaxSupportedTxLinkSpeedMbps(TEST_MAX_SUPPORTED_TX_LINK_SPEED_MBPS); 161 info.setMaxSupportedRxLinkSpeedMbps(TEST_MAX_SUPPORTED_RX_LINK_SPEED_MBPS); 162 info.setSubscriptionId(TEST_SUB_ID); 163 info.setInformationElements(informationElements); 164 info.setIsPrimary(true); 165 info.setMacAddress(TEST_BSSID); 166 if (SdkLevel.isAtLeastT()) { 167 addMloInfo(info); 168 } 169 if (SdkLevel.isAtLeastV()) { 170 info.setVendorData(TEST_VENDOR_DATA); 171 } 172 173 return info; 174 } 175 assertNoRedaction(WifiInfo info, List<ScanResult.InformationElement> informationElements)176 private void assertNoRedaction(WifiInfo info, 177 List<ScanResult.InformationElement> informationElements) { 178 assertEquals(TEST_TX_SUCCESS, info.txSuccess); 179 assertEquals(TEST_TX_RETRIES, info.txRetries); 180 assertEquals(TEST_TX_BAD, info.txBad); 181 assertEquals(TEST_RX_SUCCESS, info.rxSuccess); 182 assertEquals("\"" + TEST_SSID + "\"", info.getSSID()); 183 assertEquals(TEST_BSSID, info.getBSSID()); 184 assertEquals(TEST_NETWORK_ID, info.getNetworkId()); 185 assertTrue(info.isTrusted()); 186 assertFalse((info.isRestricted())); 187 assertTrue(info.isOsuAp()); 188 assertTrue(info.isPasspointAp()); 189 assertEquals(TEST_PACKAGE_NAME, info.getRequestingPackageName()); 190 assertEquals(TEST_FQDN, info.getPasspointFqdn()); 191 assertEquals(TEST_PROVIDER_NAME, info.getPasspointProviderFriendlyName()); 192 assertEquals(TEST_WIFI_STANDARD, info.getWifiStandard()); 193 assertEquals(TEST_MAX_SUPPORTED_TX_LINK_SPEED_MBPS, info.getMaxSupportedTxLinkSpeedMbps()); 194 assertEquals(TEST_MAX_SUPPORTED_RX_LINK_SPEED_MBPS, info.getMaxSupportedRxLinkSpeedMbps()); 195 assertEquals(TEST_BSSID, info.getMacAddress()); 196 assertEquals(2, info.getInformationElements().size()); 197 assertEquals(informationElements.get(0).id, 198 info.getInformationElements().get(0).id); 199 assertEquals(informationElements.get(0).idExt, 200 info.getInformationElements().get(0).idExt); 201 assertArrayEquals(informationElements.get(0).bytes, 202 info.getInformationElements().get(0).bytes); 203 assertEquals(informationElements.get(1).id, 204 info.getInformationElements().get(1).id); 205 assertEquals(informationElements.get(1).idExt, 206 info.getInformationElements().get(1).idExt); 207 assertArrayEquals(informationElements.get(1).bytes, 208 info.getInformationElements().get(1).bytes); 209 if (SdkLevel.isAtLeastS()) { 210 assertTrue(info.isOemPaid()); 211 assertTrue(info.isOemPrivate()); 212 assertTrue(info.isCarrierMerged()); 213 assertEquals(TEST_SUB_ID, info.getSubscriptionId()); 214 assertTrue(info.isPrimary()); 215 } 216 if (SdkLevel.isAtLeastT()) { 217 assertMloNoRedaction(info); 218 } 219 if (SdkLevel.isAtLeastV()) { 220 assertTrue(TEST_VENDOR_DATA.equals(info.getVendorData())); 221 } 222 } 223 224 /** 225 * Verify redaction of WifiInfo with REDACT_NONE. 226 */ 227 @Test testWifiInfoRedactNoRedactions()228 public void testWifiInfoRedactNoRedactions() throws Exception { 229 List<ScanResult.InformationElement> informationElements = generateIes(); 230 WifiInfo writeWifiInfo = makeWifiInfoForRedactionTest(informationElements); 231 232 // Make a copy which allows parcelling of location sensitive data. 233 WifiInfo redactedWifiInfo = writeWifiInfo.makeCopy(NetworkCapabilities.REDACT_NONE); 234 235 Parcel parcel = Parcel.obtain(); 236 redactedWifiInfo.writeToParcel(parcel, 0); 237 // Rewind the pointer to the head of the parcel. 238 parcel.setDataPosition(0); 239 WifiInfo readWifiInfo = WifiInfo.CREATOR.createFromParcel(parcel); 240 241 // Verify that redaction did not affect the original WifiInfo 242 assertNoRedaction(writeWifiInfo, informationElements); 243 244 assertNoRedaction(redactedWifiInfo, informationElements); 245 assertNoRedaction(readWifiInfo, informationElements); 246 247 if (SdkLevel.isAtLeastS()) { 248 // equals() was only introduced in S. 249 assertEquals(readWifiInfo, redactedWifiInfo); 250 } 251 } 252 assertLocationSensitiveRedaction(WifiInfo info)253 private void assertLocationSensitiveRedaction(WifiInfo info) { 254 assertNotNull(info); 255 assertEquals(TEST_TX_SUCCESS, info.txSuccess); 256 assertEquals(TEST_TX_RETRIES, info.txRetries); 257 assertEquals(TEST_TX_BAD, info.txBad); 258 assertEquals(TEST_RX_SUCCESS, info.rxSuccess); 259 assertEquals(WifiManager.UNKNOWN_SSID, info.getSSID()); 260 assertEquals(WifiInfo.DEFAULT_MAC_ADDRESS, info.getBSSID()); 261 assertEquals(WifiConfiguration.INVALID_NETWORK_ID, info.getNetworkId()); 262 assertTrue(info.isTrusted()); 263 assertFalse(info.isRestricted()); 264 assertTrue(info.isOsuAp()); 265 assertFalse(info.isPasspointAp()); // fqdn & friendly name is masked. 266 assertEquals(TEST_PACKAGE_NAME, info.getRequestingPackageName()); 267 assertNull(info.getPasspointFqdn()); 268 assertNull(info.getPasspointProviderFriendlyName()); 269 assertEquals(TEST_WIFI_STANDARD, info.getWifiStandard()); 270 assertEquals(TEST_MAX_SUPPORTED_TX_LINK_SPEED_MBPS, info.getMaxSupportedTxLinkSpeedMbps()); 271 assertEquals(TEST_MAX_SUPPORTED_RX_LINK_SPEED_MBPS, info.getMaxSupportedRxLinkSpeedMbps()); 272 assertEquals(WifiInfo.DEFAULT_MAC_ADDRESS, info.getMacAddress()); 273 assertNull(info.getInformationElements()); 274 if (SdkLevel.isAtLeastS()) { 275 assertTrue(info.isOemPaid()); 276 assertTrue(info.isOemPrivate()); 277 assertTrue(info.isCarrierMerged()); 278 assertEquals(TEST_SUB_ID, info.getSubscriptionId()); 279 assertTrue(info.isPrimary()); 280 } 281 assertEquals(null, info.getNetworkKey()); 282 if (SdkLevel.isAtLeastT()) { 283 assertMloSensitiveLocationRedaction(info); 284 } 285 } 286 287 /** 288 * Verify redaction of WifiInfo with REDACT_FOR_ACCESS_FINE_LOCATION. 289 */ 290 @Test testWifiInfoRedactLocationSensitiveInfo()291 public void testWifiInfoRedactLocationSensitiveInfo() throws Exception { 292 List<ScanResult.InformationElement> informationElements = generateIes(); 293 WifiInfo writeWifiInfo = makeWifiInfoForRedactionTest(informationElements); 294 295 WifiInfo redactedWifiInfo = 296 writeWifiInfo.makeCopy(NetworkCapabilities.REDACT_FOR_ACCESS_FINE_LOCATION); 297 298 Parcel parcel = Parcel.obtain(); 299 redactedWifiInfo.writeToParcel(parcel, 0); 300 // Rewind the pointer to the head of the parcel. 301 parcel.setDataPosition(0); 302 WifiInfo readWifiInfo = WifiInfo.CREATOR.createFromParcel(parcel); 303 304 // Verify that redaction did not affect the original WifiInfo 305 assertNoRedaction(writeWifiInfo, informationElements); 306 307 assertLocationSensitiveRedaction(redactedWifiInfo); 308 assertLocationSensitiveRedaction(readWifiInfo); 309 310 if (SdkLevel.isAtLeastS()) { 311 // equals() was only introduced in S. 312 assertEquals(redactedWifiInfo, readWifiInfo); 313 } 314 } 315 assertLocalMacAddressInfoRedaction(WifiInfo info)316 private void assertLocalMacAddressInfoRedaction(WifiInfo info) { 317 assertNotNull(info); 318 assertEquals(TEST_TX_SUCCESS, info.txSuccess); 319 assertEquals(TEST_TX_RETRIES, info.txRetries); 320 assertEquals(TEST_TX_BAD, info.txBad); 321 assertEquals(TEST_RX_SUCCESS, info.rxSuccess); 322 assertEquals("\"" + TEST_SSID + "\"", info.getSSID()); 323 assertEquals(TEST_BSSID, info.getBSSID()); 324 assertEquals(TEST_NETWORK_ID, info.getNetworkId()); 325 assertTrue(info.isTrusted()); 326 assertFalse(info.isRestricted()); 327 assertTrue(info.isOsuAp()); 328 assertTrue(info.isPasspointAp()); 329 assertEquals(TEST_PACKAGE_NAME, info.getRequestingPackageName()); 330 331 assertEquals(TEST_FQDN, info.getPasspointFqdn()); 332 assertEquals(TEST_PROVIDER_NAME, info.getPasspointProviderFriendlyName()); 333 assertEquals(TEST_WIFI_STANDARD, info.getWifiStandard()); 334 assertEquals(TEST_MAX_SUPPORTED_TX_LINK_SPEED_MBPS, info.getMaxSupportedTxLinkSpeedMbps()); 335 assertEquals(TEST_MAX_SUPPORTED_RX_LINK_SPEED_MBPS, info.getMaxSupportedRxLinkSpeedMbps()); 336 assertEquals(WifiInfo.DEFAULT_MAC_ADDRESS, info.getMacAddress()); 337 if (SdkLevel.isAtLeastS()) { 338 assertTrue(info.isOemPaid()); 339 assertTrue(info.isOemPrivate()); 340 assertTrue(info.isCarrierMerged()); 341 assertEquals(TEST_SUB_ID, info.getSubscriptionId()); 342 assertTrue(info.isPrimary()); 343 } 344 assertEquals(null, info.getNetworkKey()); 345 if (SdkLevel.isAtLeastT()) { 346 assertMloLocalMacRedaction(info); 347 } 348 } 349 350 /** 351 * Verify redaction of WifiInfo with REDACT_FOR_LOCAL_MAC_ADDRESS. 352 */ 353 @Test testWifiInfoRedactLocalMacAddressInfo()354 public void testWifiInfoRedactLocalMacAddressInfo() throws Exception { 355 List<ScanResult.InformationElement> informationElements = generateIes(); 356 WifiInfo writeWifiInfo = makeWifiInfoForRedactionTest(informationElements); 357 358 WifiInfo redactedWifiInfo = 359 writeWifiInfo.makeCopy(NetworkCapabilities.REDACT_FOR_LOCAL_MAC_ADDRESS); 360 361 Parcel parcel = Parcel.obtain(); 362 redactedWifiInfo.writeToParcel(parcel, 0); 363 // Rewind the pointer to the head of the parcel. 364 parcel.setDataPosition(0); 365 WifiInfo readWifiInfo = WifiInfo.CREATOR.createFromParcel(parcel); 366 367 // Verify that redaction did not affect the original WifiInfo 368 assertNoRedaction(writeWifiInfo, informationElements); 369 370 assertLocalMacAddressInfoRedaction(redactedWifiInfo); 371 assertLocalMacAddressInfoRedaction(readWifiInfo); 372 if (SdkLevel.isAtLeastS()) { 373 // equals() was only introduced in S. 374 assertEquals(redactedWifiInfo, readWifiInfo); 375 } 376 } 377 assertIsPrimaryThrowsSecurityException(WifiInfo info)378 private void assertIsPrimaryThrowsSecurityException(WifiInfo info) { 379 try { 380 // Should generate a security exception if caller does not have network settings 381 // permission. 382 info.isPrimary(); 383 fail(); 384 } catch (SecurityException e) { /* pass */ } 385 } 386 387 /** 388 * Verify redaction of WifiInfo with REDACT_FOR_NETWORK_SETTINGS. 389 */ 390 @Test testWifiInfoRedactNetworkSettingsInfo()391 public void testWifiInfoRedactNetworkSettingsInfo() throws Exception { 392 assumeTrue(SdkLevel.isAtLeastS()); 393 394 WifiInfo writeWifiInfo = new WifiInfo(); 395 writeWifiInfo.setIsPrimary(true); 396 writeWifiInfo.setRequestingPackageName(TEST_PACKAGE_NAME); 397 writeWifiInfo.setIsPrimary(true); 398 assertTrue(writeWifiInfo.isPrimary()); 399 400 WifiInfo redactedWifiInfo = 401 writeWifiInfo.makeCopy(NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS); 402 assertNull(redactedWifiInfo.getRequestingPackageName()); 403 assertThrows(SecurityException.class, () -> redactedWifiInfo.isPrimary()); 404 405 Parcel parcel = Parcel.obtain(); 406 redactedWifiInfo.writeToParcel(parcel, 0); 407 // Rewind the pointer to the head of the parcel. 408 parcel.setDataPosition(0); 409 WifiInfo readWifiInfo = WifiInfo.CREATOR.createFromParcel(parcel); 410 411 assertNotNull(redactedWifiInfo); 412 assertIsPrimaryThrowsSecurityException(redactedWifiInfo); 413 assertNotNull(readWifiInfo); 414 assertIsPrimaryThrowsSecurityException(readWifiInfo); 415 416 if (SdkLevel.isAtLeastS()) { 417 // equals() was only introduced in S. 418 assertEquals(redactedWifiInfo, readWifiInfo); 419 } 420 } 421 422 @Test testWifiInfoGetApplicableRedactions()423 public void testWifiInfoGetApplicableRedactions() throws Exception { 424 long redactions = new WifiInfo().getApplicableRedactions(); 425 assertEquals(NetworkCapabilities.REDACT_FOR_ACCESS_FINE_LOCATION 426 | NetworkCapabilities.REDACT_FOR_LOCAL_MAC_ADDRESS 427 | NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS, redactions); 428 } 429 assertLocationSensitiveAndLocalMacAddressRedaction(WifiInfo info)430 private void assertLocationSensitiveAndLocalMacAddressRedaction(WifiInfo info) { 431 assertNotNull(info); 432 assertEquals(WifiManager.UNKNOWN_SSID, info.getSSID()); 433 assertEquals(WifiInfo.DEFAULT_MAC_ADDRESS, info.getBSSID()); 434 assertEquals(WifiConfiguration.INVALID_NETWORK_ID, info.getNetworkId()); 435 assertNull(info.getPasspointFqdn()); 436 assertNull(info.getPasspointProviderFriendlyName()); 437 assertEquals(WifiInfo.DEFAULT_MAC_ADDRESS, info.getMacAddress()); 438 assertNull(info.getInformationElements()); 439 assertNull(info.getNetworkKey()); 440 } 441 442 @Test testWifiInfoRedactLocationAndLocalMacAddressSensitiveInfo()443 public void testWifiInfoRedactLocationAndLocalMacAddressSensitiveInfo() 444 throws Exception { 445 assumeTrue(SdkLevel.isAtLeastS()); 446 List<ScanResult.InformationElement> informationElements = generateIes(); 447 WifiInfo writeWifiInfo = makeWifiInfoForRedactionTest(informationElements); 448 449 WifiInfo redactedWifiInfo = 450 writeWifiInfo.makeCopy(NetworkCapabilities.REDACT_FOR_ACCESS_FINE_LOCATION 451 | NetworkCapabilities.REDACT_FOR_LOCAL_MAC_ADDRESS); 452 453 Parcel parcel = Parcel.obtain(); 454 redactedWifiInfo.writeToParcel(parcel, 0); 455 // Rewind the pointer to the head of the parcel. 456 parcel.setDataPosition(0); 457 WifiInfo readWifiInfo = WifiInfo.CREATOR.createFromParcel(parcel); 458 459 assertLocationSensitiveAndLocalMacAddressRedaction(redactedWifiInfo); 460 assertLocationSensitiveAndLocalMacAddressRedaction(readWifiInfo); 461 462 if (SdkLevel.isAtLeastS()) { 463 // equals() was only introduced in S. 464 assertEquals(redactedWifiInfo, readWifiInfo); 465 } 466 } 467 468 /** 469 * Verify parcel write/read with null information elements. 470 */ 471 @Test testWifiInfoParcelWriteReadWithNullInfoElements()472 public void testWifiInfoParcelWriteReadWithNullInfoElements() throws Exception { 473 assumeTrue(SdkLevel.isAtLeastS()); 474 475 WifiInfo writeWifiInfo = new WifiInfo(); 476 writeWifiInfo.setInformationElements(null); 477 478 // Make a copy which allows parcelling of location sensitive data. 479 WifiInfo writeWifiInfoCopy = writeWifiInfo.makeCopy(NetworkCapabilities.REDACT_NONE); 480 481 Parcel parcel = Parcel.obtain(); 482 writeWifiInfoCopy.writeToParcel(parcel, 0); 483 // Rewind the pointer to the head of the parcel. 484 parcel.setDataPosition(0); 485 WifiInfo readWifiInfo = WifiInfo.CREATOR.createFromParcel(parcel); 486 assertNull(readWifiInfo.getInformationElements()); 487 } 488 489 /** 490 * Verify parcel write/read with empty information elements. 491 */ 492 @Test testWifiInfoParcelWriteReadWithEmptyInfoElements()493 public void testWifiInfoParcelWriteReadWithEmptyInfoElements() throws Exception { 494 assumeTrue(SdkLevel.isAtLeastS()); 495 496 WifiInfo writeWifiInfo = new WifiInfo(); 497 writeWifiInfo.setInformationElements(new ArrayList<>()); 498 499 // Make a copy which allows parcelling of location sensitive data. 500 WifiInfo writeWifiInfoCopy = writeWifiInfo.makeCopy(NetworkCapabilities.REDACT_NONE); 501 502 Parcel parcel = Parcel.obtain(); 503 writeWifiInfoCopy.writeToParcel(parcel, 0); 504 // Rewind the pointer to the head of the parcel. 505 parcel.setDataPosition(0); 506 WifiInfo readWifiInfo = WifiInfo.CREATOR.createFromParcel(parcel); 507 assertTrue(readWifiInfo.getInformationElements().isEmpty()); 508 } 509 510 @Test testWifiInfoCopyConstructor()511 public void testWifiInfoCopyConstructor() throws Exception { 512 WifiInfo writeWifiInfo = new WifiInfo(); 513 writeWifiInfo.txSuccess = TEST_TX_SUCCESS; 514 writeWifiInfo.txRetries = TEST_TX_RETRIES; 515 writeWifiInfo.txBad = TEST_TX_BAD; 516 writeWifiInfo.rxSuccess = TEST_RX_SUCCESS; 517 writeWifiInfo.setTrusted(true); 518 writeWifiInfo.setOemPaid(true); 519 writeWifiInfo.setOemPrivate(true); 520 writeWifiInfo.setCarrierMerged(true); 521 writeWifiInfo.setOsuAp(true); 522 writeWifiInfo.setFQDN(TEST_FQDN); 523 writeWifiInfo.setProviderFriendlyName(TEST_PROVIDER_NAME); 524 writeWifiInfo.setRequestingPackageName(TEST_PACKAGE_NAME); 525 writeWifiInfo.setWifiStandard(TEST_WIFI_STANDARD); 526 writeWifiInfo.setMaxSupportedTxLinkSpeedMbps(TEST_MAX_SUPPORTED_TX_LINK_SPEED_MBPS); 527 writeWifiInfo.setMaxSupportedRxLinkSpeedMbps(TEST_MAX_SUPPORTED_RX_LINK_SPEED_MBPS); 528 writeWifiInfo.setSubscriptionId(TEST_SUB_ID); 529 writeWifiInfo.setIsPrimary(true); 530 writeWifiInfo.setRestricted(true); 531 writeWifiInfo.enableApTidToLinkMappingNegotiationSupport(true); 532 if (SdkLevel.isAtLeastV()) { 533 writeWifiInfo.setVendorData(TEST_VENDOR_DATA); 534 } 535 536 WifiInfo readWifiInfo = new WifiInfo(writeWifiInfo); 537 538 assertEquals(TEST_TX_SUCCESS, readWifiInfo.txSuccess); 539 assertEquals(TEST_TX_RETRIES, readWifiInfo.txRetries); 540 assertEquals(TEST_TX_BAD, readWifiInfo.txBad); 541 assertEquals(TEST_RX_SUCCESS, readWifiInfo.rxSuccess); 542 assertTrue(readWifiInfo.isTrusted()); 543 assertTrue(readWifiInfo.isOsuAp()); 544 assertTrue(readWifiInfo.isPasspointAp()); 545 assertEquals(TEST_PACKAGE_NAME, readWifiInfo.getRequestingPackageName()); 546 assertEquals(TEST_FQDN, readWifiInfo.getPasspointFqdn()); 547 assertEquals(TEST_PROVIDER_NAME, readWifiInfo.getPasspointProviderFriendlyName()); 548 assertEquals(TEST_WIFI_STANDARD, readWifiInfo.getWifiStandard()); 549 assertEquals(TEST_MAX_SUPPORTED_TX_LINK_SPEED_MBPS, 550 readWifiInfo.getMaxSupportedTxLinkSpeedMbps()); 551 assertEquals(TEST_MAX_SUPPORTED_RX_LINK_SPEED_MBPS, 552 readWifiInfo.getMaxSupportedRxLinkSpeedMbps()); 553 assertTrue(readWifiInfo.isRestricted()); 554 if (SdkLevel.isAtLeastS()) { 555 assertTrue(readWifiInfo.isOemPaid()); 556 assertTrue(readWifiInfo.isOemPrivate()); 557 assertTrue(readWifiInfo.isCarrierMerged()); 558 assertEquals(TEST_SUB_ID, readWifiInfo.getSubscriptionId()); 559 assertTrue(readWifiInfo.isPrimary()); 560 } 561 assertTrue(readWifiInfo.isApTidToLinkMappingNegotiationSupported()); 562 if (SdkLevel.isAtLeastV()) { 563 assertTrue(TEST_VENDOR_DATA.equals(readWifiInfo.getVendorData())); 564 } 565 } 566 567 /** 568 * Verify values after reset() 569 */ 570 @Test testWifiInfoResetValue()571 public void testWifiInfoResetValue() throws Exception { 572 WifiInfo wifiInfo = new WifiInfo(); 573 wifiInfo.reset(); 574 assertEquals(WifiInfo.LINK_SPEED_UNKNOWN, wifiInfo.getMaxSupportedTxLinkSpeedMbps()); 575 assertEquals(WifiInfo.LINK_SPEED_UNKNOWN, wifiInfo.getMaxSupportedRxLinkSpeedMbps()); 576 assertEquals(WifiInfo.LINK_SPEED_UNKNOWN, wifiInfo.getTxLinkSpeedMbps()); 577 assertEquals(WifiInfo.LINK_SPEED_UNKNOWN, wifiInfo.getRxLinkSpeedMbps()); 578 assertEquals(WifiInfo.INVALID_RSSI, wifiInfo.getRssi()); 579 assertEquals(WifiManager.UNKNOWN_SSID, wifiInfo.getSSID()); 580 assertNull(wifiInfo.getBSSID()); 581 assertEquals(-1, wifiInfo.getNetworkId()); 582 if (SdkLevel.isAtLeastS()) { 583 assertFalse(wifiInfo.isOemPaid()); 584 assertFalse(wifiInfo.isOemPrivate()); 585 assertFalse(wifiInfo.isCarrierMerged()); 586 assertEquals(SubscriptionManager.INVALID_SUBSCRIPTION_ID, wifiInfo.getSubscriptionId()); 587 assertFalse(wifiInfo.isPrimary()); 588 } 589 assertNull(wifiInfo.getNetworkKey()); 590 assertEquals(MloLink.INVALID_MLO_LINK_ID, wifiInfo.getApMloLinkId()); 591 assertNull(wifiInfo.getApMldMacAddress()); 592 assertEquals(0, wifiInfo.getAffiliatedMloLinks().size()); 593 assertFalse(wifiInfo.isApTidToLinkMappingNegotiationSupported()); 594 if (SdkLevel.isAtLeastV()) { 595 assertNotNull(wifiInfo.getVendorData()); 596 assertTrue(wifiInfo.getVendorData().isEmpty()); 597 } 598 } 599 600 /** 601 * Test that the WifiInfo Builder returns the same values that was set, and that 602 * calling build multiple times returns different instances. 603 */ 604 @Test testWifiInfoBuilder()605 public void testWifiInfoBuilder() throws Exception { 606 WifiInfo.Builder builder = new WifiInfo.Builder() 607 .setSsid(TEST_SSID.getBytes(StandardCharsets.UTF_8)) 608 .setBssid(TEST_BSSID) 609 .setRssi(TEST_RSSI) 610 .setNetworkId(TEST_NETWORK_ID); 611 612 WifiInfo info1 = builder.build(); 613 614 assertEquals("\"" + TEST_SSID + "\"", info1.getSSID()); 615 assertEquals(TEST_BSSID, info1.getBSSID()); 616 assertEquals(TEST_RSSI, info1.getRssi()); 617 assertEquals(TEST_NETWORK_ID, info1.getNetworkId()); 618 619 WifiInfo info2 = builder 620 .setNetworkId(TEST_NETWORK_ID2) 621 .build(); 622 623 // different instances 624 assertNotSame(info1, info2); 625 626 // assert that info1 didn't change 627 assertEquals("\"" + TEST_SSID + "\"", info1.getSSID()); 628 assertEquals(TEST_BSSID, info1.getBSSID()); 629 assertEquals(TEST_RSSI, info1.getRssi()); 630 assertEquals(TEST_NETWORK_ID, info1.getNetworkId()); 631 632 // assert that info2 changed 633 assertEquals("\"" + TEST_SSID + "\"", info2.getSSID()); 634 assertEquals(TEST_BSSID, info2.getBSSID()); 635 assertEquals(TEST_RSSI, info2.getRssi()); 636 assertEquals(TEST_NETWORK_ID2, info2.getNetworkId()); 637 } 638 639 @Test testSetSsid()640 public void testSetSsid() throws Exception { 641 WifiInfo.Builder builder = new WifiInfo.Builder(); 642 643 // Null 644 assertEquals(WifiManager.UNKNOWN_SSID, builder.build().getSSID()); 645 646 // Empty 647 builder.setSsid(new byte[0]); 648 assertEquals(WifiManager.UNKNOWN_SSID, builder.build().getSSID()); 649 650 // UTF-8 651 builder.setSsid(TEST_SSID.getBytes(StandardCharsets.UTF_8)); 652 assertEquals("\"" + TEST_SSID + "\"", builder.build().getSSID()); 653 654 // Non-UTF-8 655 byte[] gbkBytes = "服務集識別碼".getBytes(Charset.forName("GBK")); 656 builder.setSsid(gbkBytes); 657 assertEquals(HexEncoding.encodeToString(gbkBytes, false), builder.build().getSSID()); 658 } 659 660 @Test testWifiInfoEquals()661 public void testWifiInfoEquals() throws Exception { 662 WifiInfo.Builder builder = new WifiInfo.Builder() 663 .setSsid(TEST_SSID.getBytes(StandardCharsets.UTF_8)) 664 .setBssid(TEST_BSSID) 665 .setRssi(TEST_RSSI) 666 .setNetworkId(TEST_NETWORK_ID); 667 668 WifiInfo info1 = builder.build(); 669 WifiInfo info2 = builder.build(); 670 if (SdkLevel.isAtLeastS()) { 671 assertEquals(info1, info2); 672 } else { 673 // On R devices, reference equality. 674 assertNotEquals(info1, info2); 675 } 676 677 info1.setSubscriptionId(TEST_SUB_ID); 678 assertNotEquals(info1, info2); 679 680 info2.setSubscriptionId(TEST_SUB_ID); 681 if (SdkLevel.isAtLeastS()) { 682 assertEquals(info1, info2); 683 } else { 684 // On R devices, reference equality. 685 assertNotEquals(info1, info2); 686 } 687 688 info1.setSSID(WifiSsid.fromBytes(null)); 689 assertNotEquals(info1, info2); 690 691 info2.setSSID(WifiSsid.fromBytes(null)); 692 if (SdkLevel.isAtLeastS()) { 693 assertEquals(info1, info2); 694 } else { 695 // On R devices, reference equality. 696 assertNotEquals(info1, info2); 697 } 698 } 699 700 @Test testWifiInfoEqualsWithInfoElements()701 public void testWifiInfoEqualsWithInfoElements() throws Exception { 702 WifiInfo.Builder builder = new WifiInfo.Builder() 703 .setSsid(TEST_SSID.getBytes(StandardCharsets.UTF_8)) 704 .setBssid(TEST_BSSID) 705 .setRssi(TEST_RSSI) 706 .setNetworkId(TEST_NETWORK_ID); 707 708 WifiInfo info1 = builder.build(); 709 WifiInfo info2 = builder.build(); 710 if (SdkLevel.isAtLeastS()) { 711 assertEquals(info1, info2); 712 } else { 713 // On R devices, reference equality. 714 assertNotEquals(info1, info2); 715 } 716 717 info1.setInformationElements(generateIes()); 718 info2.setInformationElements(generateIes()); 719 720 if (SdkLevel.isAtLeastS()) { 721 assertEquals(info1, info2); 722 } else { 723 // On R devices, reference equality. 724 assertNotEquals(info1, info2); 725 } 726 } 727 728 @Test testWifiInfoHashcode()729 public void testWifiInfoHashcode() throws Exception { 730 WifiInfo.Builder builder = new WifiInfo.Builder() 731 .setSsid(TEST_SSID.getBytes(StandardCharsets.UTF_8)) 732 .setBssid(TEST_BSSID) 733 .setRssi(TEST_RSSI) 734 .setNetworkId(TEST_NETWORK_ID); 735 736 WifiInfo info1 = builder.build(); 737 WifiInfo info2 = builder.build(); 738 if (SdkLevel.isAtLeastS()) { 739 assertEquals(info1.hashCode(), info2.hashCode()); 740 } else { 741 // On R devices, system generated hashcode. 742 assertNotEquals(info1.hashCode(), info2.hashCode()); 743 } 744 745 info1.setSubscriptionId(TEST_SUB_ID); 746 assertNotEquals(info1.hashCode(), info2.hashCode()); 747 748 info2.setSubscriptionId(TEST_SUB_ID); 749 if (SdkLevel.isAtLeastS()) { 750 assertEquals(info1.hashCode(), info2.hashCode()); 751 } else { 752 // On R devices, system generated hashcode. 753 assertNotEquals(info1.hashCode(), info2.hashCode()); 754 } 755 756 info1.setSSID(WifiSsid.fromBytes(null)); 757 assertNotEquals(info1.hashCode(), info2.hashCode()); 758 759 info2.setSSID(WifiSsid.fromBytes(null)); 760 if (SdkLevel.isAtLeastS()) { 761 assertEquals(info1.hashCode(), info2.hashCode()); 762 } else { 763 // On R devices, system generated hashcode. 764 assertNotEquals(info1.hashCode(), info2.hashCode()); 765 } 766 } 767 768 @Test testWifiInfoCurrentSecurityType()769 public void testWifiInfoCurrentSecurityType() throws Exception { 770 WifiInfo.Builder builder = new WifiInfo.Builder() 771 .setSsid(TEST_SSID.getBytes(StandardCharsets.UTF_8)) 772 .setBssid(TEST_BSSID) 773 .setRssi(TEST_RSSI) 774 .setNetworkId(TEST_NETWORK_ID) 775 .setCurrentSecurityType(WifiConfiguration.SECURITY_TYPE_SAE); 776 777 WifiInfo info = new WifiInfo(); 778 assertEquals(WifiInfo.SECURITY_TYPE_UNKNOWN, info.getCurrentSecurityType()); 779 780 info = builder.build(); 781 assertEquals(WifiInfo.SECURITY_TYPE_SAE, info.getCurrentSecurityType()); 782 783 info = builder.setCurrentSecurityType(WifiConfiguration.SECURITY_TYPE_OPEN).build(); 784 assertEquals(WifiInfo.SECURITY_TYPE_OPEN, info.getCurrentSecurityType()); 785 786 info = builder.setCurrentSecurityType(WifiConfiguration.SECURITY_TYPE_WEP).build(); 787 assertEquals(WifiInfo.SECURITY_TYPE_WEP, info.getCurrentSecurityType()); 788 789 info = builder.setCurrentSecurityType(WifiConfiguration.SECURITY_TYPE_PSK).build(); 790 assertEquals(WifiInfo.SECURITY_TYPE_PSK, info.getCurrentSecurityType()); 791 792 info = builder.setCurrentSecurityType(WifiConfiguration.SECURITY_TYPE_EAP).build(); 793 assertEquals(WifiInfo.SECURITY_TYPE_EAP, info.getCurrentSecurityType()); 794 795 info = builder.setCurrentSecurityType(WifiConfiguration.SECURITY_TYPE_OWE).build(); 796 assertEquals(WifiInfo.SECURITY_TYPE_OWE, info.getCurrentSecurityType()); 797 798 info = builder.setCurrentSecurityType(WifiConfiguration.SECURITY_TYPE_WAPI_PSK).build(); 799 assertEquals(WifiInfo.SECURITY_TYPE_WAPI_PSK, info.getCurrentSecurityType()); 800 801 info = builder.setCurrentSecurityType(WifiConfiguration.SECURITY_TYPE_WAPI_CERT).build(); 802 assertEquals(WifiInfo.SECURITY_TYPE_WAPI_CERT, info.getCurrentSecurityType()); 803 804 info = builder.setCurrentSecurityType( 805 WifiConfiguration.SECURITY_TYPE_EAP_WPA3_ENTERPRISE).build(); 806 assertEquals(WifiInfo.SECURITY_TYPE_EAP_WPA3_ENTERPRISE, info.getCurrentSecurityType()); 807 808 info = builder.setCurrentSecurityType( 809 WifiConfiguration.SECURITY_TYPE_EAP_WPA3_ENTERPRISE_192_BIT).build(); 810 assertEquals(WifiInfo.SECURITY_TYPE_EAP_WPA3_ENTERPRISE_192_BIT, 811 info.getCurrentSecurityType()); 812 813 info = builder.setCurrentSecurityType( 814 WifiConfiguration.SECURITY_TYPE_PASSPOINT_R1_R2).build(); 815 assertEquals(WifiInfo.SECURITY_TYPE_PASSPOINT_R1_R2, info.getCurrentSecurityType()); 816 817 info = builder.setCurrentSecurityType(WifiConfiguration.SECURITY_TYPE_PASSPOINT_R3).build(); 818 assertEquals(WifiInfo.SECURITY_TYPE_PASSPOINT_R3, info.getCurrentSecurityType()); 819 820 info.clearCurrentSecurityType(); 821 assertEquals(WifiInfo.SECURITY_TYPE_UNKNOWN, info.getCurrentSecurityType()); 822 } 823 generateIes()824 private static List<ScanResult.InformationElement> generateIes() { 825 List<ScanResult.InformationElement> informationElements = new ArrayList<>(); 826 ScanResult.InformationElement informationElement = new ScanResult.InformationElement(); 827 informationElement.id = ScanResult.InformationElement.EID_HT_OPERATION; 828 informationElement.idExt = 0; 829 informationElement.bytes = new byte[]{0x11, 0x22, 0x33}; 830 informationElements.add(informationElement); 831 832 informationElement = new ScanResult.InformationElement(); 833 informationElement.id = ScanResult.InformationElement.EID_EXTENSION_PRESENT; 834 informationElement.idExt = ScanResult.InformationElement.EID_EXT_HE_OPERATION; 835 informationElement.bytes = new byte[]{0x44, 0x55, 0x66}; 836 informationElements.add(informationElement); 837 838 return informationElements; 839 } 840 841 @Test testMloLink()842 public void testMloLink() throws Exception { 843 // Create an MLO link and set parameters. 844 MloLink link1 = new MloLink(); 845 link1.setStaMacAddress(MacAddress.fromString(MLO_LINK_STA_MAC_ADDRESS)); 846 link1.setApMacAddress(MacAddress.fromString(MLO_LINK_AP_MAC_ADDRESS)); 847 link1.setRssi(TEST_RSSI); 848 link1.setLinkId(TEST_MLO_LINK_ID); 849 link1.setBand(WifiScanner.WIFI_BAND_5_GHZ); 850 link1.setChannel(TEST_CHANNEL); 851 link1.setRxLinkSpeedMbps(TEST_LINK_SPEED); 852 link1.setTxLinkSpeedMbps(TEST_LINK_SPEED); 853 link1.setState(MloLink.MLO_LINK_STATE_UNASSOCIATED); 854 link1.setLostTxPacketsPerSecond(10); 855 link1.setRetriedTxPacketsRate(20); 856 link1.setSuccessfulTxPacketsPerSecond(30); 857 link1.setSuccessfulRxPacketsPerSecond(40); 858 859 // Make sure all parameters are set. 860 assertNotNull(link1.getApMacAddress()); 861 assertEquals(MLO_LINK_AP_MAC_ADDRESS, link1.getApMacAddress().toString()); 862 assertNotNull(link1.getStaMacAddress()); 863 assertEquals(MLO_LINK_STA_MAC_ADDRESS, link1.getStaMacAddress().toString()); 864 assertEquals(TEST_RSSI, link1.getRssi()); 865 assertEquals(TEST_CHANNEL, link1.getChannel()); 866 assertEquals(TEST_LINK_SPEED, link1.getRxLinkSpeedMbps()); 867 assertEquals(TEST_LINK_SPEED, link1.getTxLinkSpeedMbps()); 868 assertEquals(TEST_MLO_LINK_ID, link1.getLinkId()); 869 assertEquals(WifiScanner.WIFI_BAND_5_GHZ, link1.getBand()); 870 assertEquals(MloLink.MLO_LINK_STATE_UNASSOCIATED, link1.getState()); 871 assertEquals(10, link1.getLostTxPacketsPerSecond(), 0); 872 assertEquals(20, link1.getRetriedTxPacketsPerSecond(), 0); 873 assertEquals(30, link1.getSuccessfulTxPacketsPerSecond(), 0); 874 assertEquals(40, link1.getSuccessfulRxPacketsPerSecond(), 0); 875 // Check default values 876 assertEquals(0, link1.txBad); 877 assertEquals(0, link1.txRetries); 878 assertEquals(0, link1.txSuccess); 879 assertEquals(0, link1.rxSuccess); 880 881 // Test RSSI range. 882 link1.setRssi(WifiInfo.INVALID_RSSI - 1); 883 assertEquals(WifiInfo.INVALID_RSSI, link1.getRssi()); 884 link1.setRssi(WifiInfo.MAX_RSSI + 1); 885 assertEquals(WifiInfo.MAX_RSSI, link1.getRssi()); 886 887 // Copy link 888 MloLink link2 = new MloLink(link1, 0); 889 890 // Check links are equal. 891 assertTrue(link1.equals(link2)); 892 assertEquals(link2.hashCode(), link1.hashCode()); 893 assertEquals(link2.toString(), link1.toString()); 894 895 // Change one parameter and check the links are not equal. 896 link1.setState(MloLink.MLO_LINK_STATE_INVALID); 897 assertFalse(link1.equals(link2)); 898 assertNotEquals(link2.hashCode(), link1.hashCode()); 899 assertNotEquals(link2.toString(), link1.toString()); 900 901 // Validate states. 902 assertTrue(MloLink.isValidState(MloLink.MLO_LINK_STATE_INVALID)); 903 assertTrue(MloLink.isValidState(MloLink.MLO_LINK_STATE_UNASSOCIATED)); 904 assertTrue(MloLink.isValidState(MloLink.MLO_LINK_STATE_ACTIVE)); 905 assertTrue(MloLink.isValidState(MloLink.MLO_LINK_STATE_IDLE)); 906 assertFalse(MloLink.isValidState(MloLink.MLO_LINK_STATE_INVALID - 1)); 907 } 908 } 909