1 /* 2 * Copyright (C) 2019 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 android.net.wifi.ScanResult.InformationElement.EID_VSA; 20 21 import static com.google.common.truth.Truth.assertThat; 22 23 import static org.junit.Assert.assertArrayEquals; 24 import static org.junit.Assert.assertEquals; 25 import static org.junit.Assert.assertNotNull; 26 import static org.junit.Assert.assertNull; 27 import static org.junit.Assert.assertThrows; 28 import static org.junit.Assert.assertTrue; 29 import static org.junit.Assert.fail; 30 import static org.junit.Assume.assumeFalse; 31 import static org.junit.Assume.assumeTrue; 32 import static org.mockito.Mockito.mock; 33 34 import android.net.MacAddress; 35 import android.os.Parcel; 36 import android.os.PersistableBundle; 37 import android.util.SparseIntArray; 38 39 import androidx.test.filters.SmallTest; 40 41 import com.android.modules.utils.build.SdkLevel; 42 43 import org.junit.Test; 44 45 import java.util.ArrayList; 46 import java.util.Arrays; 47 import java.util.List; 48 import java.util.Random; 49 50 @SmallTest 51 public class SoftApConfigurationTest { 52 private static final String TEST_CHAR_SET_AS_STRING = "abcdefghijklmnopqrstuvwxyz0123456789"; 53 private static final String TEST_BSSID = "aa:22:33:aa:bb:cc"; 54 private static final List<ScanResult.InformationElement> TEST_TWO_VENDOR_ELEMENTS = 55 new ArrayList<>(Arrays.asList( 56 new ScanResult.InformationElement(EID_VSA, 0, new byte[]{ 1, 2, 3, 4 }), 57 new ScanResult.InformationElement( 58 EID_VSA, 59 0, 60 new byte[]{ (byte) 170, (byte) 187, (byte) 204, (byte) 221 }) 61 )); 62 private static final List<ScanResult.InformationElement> TEST_TWO_VENDOR_ELEMENTS_INVALID = 63 new ArrayList<>(Arrays.asList( 64 new ScanResult.InformationElement(EID_VSA, 0, new byte[]{ 1, 2, 3, 4 }), 65 new ScanResult.InformationElement( 66 (byte) 222, 67 0, 68 new byte[]{ (byte) 170, (byte) 187, (byte) 204, (byte) 221 }) 69 )); 70 parcelUnparcel(SoftApConfiguration configIn)71 private SoftApConfiguration parcelUnparcel(SoftApConfiguration configIn) { 72 Parcel parcel = Parcel.obtain(); 73 parcel.writeParcelable(configIn, 0); 74 parcel.setDataPosition(0); 75 SoftApConfiguration configOut = 76 parcel.readParcelable(SoftApConfiguration.class.getClassLoader()); 77 parcel.recycle(); 78 return configOut; 79 } 80 81 /** 82 * Helper method to generate random string. 83 * 84 * Note: this method has limited use as a random string generator. 85 * The characters used in this method do no not cover all valid inputs. 86 * @param length number of characters to generate for the string 87 * @return String generated string of random characters 88 */ generateRandomString(int length)89 private String generateRandomString(int length) { 90 Random random = new Random(); 91 StringBuilder stringBuilder = new StringBuilder(length); 92 int index = -1; 93 while (stringBuilder.length() < length) { 94 index = random.nextInt(TEST_CHAR_SET_AS_STRING.length()); 95 stringBuilder.append(TEST_CHAR_SET_AS_STRING.charAt(index)); 96 } 97 return stringBuilder.toString(); 98 } 99 100 @Test testBasicSettings()101 public void testBasicSettings() { 102 MacAddress testBssid = MacAddress.fromString(TEST_BSSID); 103 String utf8Ssid = "ssid"; 104 SoftApConfiguration original = new SoftApConfiguration.Builder() 105 .setSsid(utf8Ssid) 106 .build(); 107 assertThat(original.getSsid()).isEqualTo(utf8Ssid); 108 assertThat(original.getWifiSsid()).isEqualTo(WifiSsid.fromUtf8Text(utf8Ssid)); 109 assertThat(original.getPassphrase()).isNull(); 110 assertThat(original.getSecurityType()).isEqualTo(SoftApConfiguration.SECURITY_TYPE_OPEN); 111 assertThat(original.getBand()).isEqualTo(SoftApConfiguration.BAND_2GHZ); 112 assertThat(original.getChannel()).isEqualTo(0); 113 assertThat(original.isHiddenSsid()).isEqualTo(false); 114 assertThat(original.getMaxNumberOfClients()).isEqualTo(0); 115 assertThat(original.getPersistentRandomizedMacAddress()).isNull(); 116 if (SdkLevel.isAtLeastS()) { 117 assertThat(original.isBridgedModeOpportunisticShutdownEnabled()) 118 .isEqualTo(true); 119 assertThat(original.isIeee80211axEnabled()) 120 .isEqualTo(true); 121 assertThat(original.isUserConfiguration()) 122 .isEqualTo(true); 123 if (SdkLevel.isAtLeastT()) { 124 assertThat(original.getBridgedModeOpportunisticShutdownTimeoutMillis()) 125 .isEqualTo(SoftApConfiguration.DEFAULT_TIMEOUT); 126 assertThat(original.getMacRandomizationSetting()) 127 .isEqualTo(SoftApConfiguration.RANDOMIZATION_NON_PERSISTENT); 128 assertThat(original.getVendorElements().size()).isEqualTo(0); 129 } else { 130 assertThat(original.getMacRandomizationSetting()) 131 .isEqualTo(SoftApConfiguration.RANDOMIZATION_PERSISTENT); 132 } 133 } 134 135 SoftApConfiguration unparceled = parcelUnparcel(original); 136 assertThat(unparceled).isNotSameInstanceAs(original); 137 assertThat(unparceled).isEqualTo(original); 138 assertThat(unparceled.hashCode()).isEqualTo(original.hashCode()); 139 140 SoftApConfiguration copy = new SoftApConfiguration.Builder(original).build(); 141 assertThat(copy).isNotSameInstanceAs(original); 142 assertThat(copy).isEqualTo(original); 143 assertThat(copy.hashCode()).isEqualTo(original.hashCode()); 144 } 145 146 @Test testSetWifiSsid()147 public void testSetWifiSsid() { 148 assumeTrue(SdkLevel.isAtLeastT()); 149 150 // UTF-8 151 WifiSsid wifiSsidUtf8 = WifiSsid.fromUtf8Text("ssid"); 152 SoftApConfiguration utf8Config = new SoftApConfiguration.Builder() 153 .setWifiSsid(wifiSsidUtf8) 154 .build(); 155 assertThat(utf8Config.getWifiSsid()).isEqualTo(wifiSsidUtf8); 156 assertThat(utf8Config.getSsid()).isEqualTo("ssid"); 157 158 SoftApConfiguration unparceled = parcelUnparcel(utf8Config); 159 assertThat(unparceled).isNotSameInstanceAs(utf8Config); 160 assertThat(unparceled).isEqualTo(utf8Config); 161 assertThat(unparceled.hashCode()).isEqualTo(utf8Config.hashCode()); 162 163 // Non-UTF-8 164 byte[] nonUtf8Bytes = 165 new byte[]{(byte) 0x01, (byte) 0x23, (byte) 0x45, (byte) 0x67, (byte) 0x89}; 166 WifiSsid wifiSsidNonUtf8 = WifiSsid.fromBytes(nonUtf8Bytes); 167 SoftApConfiguration nonUtf8Config = new SoftApConfiguration.Builder() 168 .setWifiSsid(wifiSsidNonUtf8) 169 .build(); 170 assertThat(nonUtf8Config.getWifiSsid()).isEqualTo(wifiSsidNonUtf8); 171 assertThat(nonUtf8Config.getSsid()).isEqualTo(WifiManager.UNKNOWN_SSID); 172 173 unparceled = parcelUnparcel(nonUtf8Config); 174 assertThat(unparceled).isNotSameInstanceAs(nonUtf8Config); 175 assertThat(unparceled).isEqualTo(nonUtf8Config); 176 assertThat(unparceled.hashCode()).isEqualTo(nonUtf8Config.hashCode()); 177 } 178 179 @Test testWpa2()180 public void testWpa2() { 181 SoftApConfiguration original = new SoftApConfiguration.Builder() 182 .setPassphrase("secretsecret", SoftApConfiguration.SECURITY_TYPE_WPA2_PSK) 183 .build(); 184 assertThat(original.getPassphrase()).isEqualTo("secretsecret"); 185 assertThat(original.getSecurityType()).isEqualTo( 186 SoftApConfiguration.SECURITY_TYPE_WPA2_PSK); 187 assertThat(original.getBand()).isEqualTo(SoftApConfiguration.BAND_2GHZ); 188 assertThat(original.getChannel()).isEqualTo(0); 189 assertThat(original.isHiddenSsid()).isEqualTo(false); 190 assertThat(original.getMaxNumberOfClients()).isEqualTo(0); 191 192 SoftApConfiguration unparceled = parcelUnparcel(original); 193 assertThat(unparceled).isNotSameInstanceAs(original); 194 assertThat(unparceled).isEqualTo(original); 195 assertThat(unparceled.hashCode()).isEqualTo(original.hashCode()); 196 197 SoftApConfiguration copy = new SoftApConfiguration.Builder(original).build(); 198 assertThat(copy).isNotSameInstanceAs(original); 199 assertThat(copy).isEqualTo(original); 200 assertThat(copy.hashCode()).isEqualTo(original.hashCode()); 201 } 202 203 @Test testWpa2WithAllFieldCustomized()204 public void testWpa2WithAllFieldCustomized() { 205 MacAddress testRandomizedMacAddress = MacAddress.fromString(TEST_BSSID); 206 List<MacAddress> testBlockedClientList = new ArrayList<>(); 207 List<MacAddress> testAllowedClientList = new ArrayList<>(); 208 testBlockedClientList.add(MacAddress.fromString("11:22:33:44:55:66")); 209 testAllowedClientList.add(MacAddress.fromString("aa:bb:cc:dd:ee:ff")); 210 SoftApConfiguration.Builder originalBuilder = new SoftApConfiguration.Builder() 211 .setPassphrase("secretsecret", SoftApConfiguration.SECURITY_TYPE_WPA2_PSK) 212 .setChannel(149, SoftApConfiguration.BAND_5GHZ) 213 .setHiddenSsid(true) 214 .setMaxNumberOfClients(10) 215 .setAutoShutdownEnabled(true) 216 .setShutdownTimeoutMillis(500000) 217 .setClientControlByUserEnabled(true) 218 .setBlockedClientList(testBlockedClientList) 219 .setAllowedClientList(testAllowedClientList) 220 .setRandomizedMacAddress(testRandomizedMacAddress); 221 if (SdkLevel.isAtLeastS()) { 222 originalBuilder.setMacRandomizationSetting(SoftApConfiguration.RANDOMIZATION_NONE); 223 originalBuilder.setBridgedModeOpportunisticShutdownEnabled(false); 224 originalBuilder.setIeee80211axEnabled(false); 225 originalBuilder.setUserConfiguration(false); 226 } 227 228 if (SdkLevel.isAtLeastT()) { 229 originalBuilder.setBridgedModeOpportunisticShutdownTimeoutMillis(300_000); 230 originalBuilder.setVendorElements(TEST_TWO_VENDOR_ELEMENTS); 231 } 232 233 SoftApConfiguration original = originalBuilder.build(); 234 assertThat(original.getPassphrase()).isEqualTo("secretsecret"); 235 assertThat(original.getSecurityType()).isEqualTo( 236 SoftApConfiguration.SECURITY_TYPE_WPA2_PSK); 237 assertThat(original.getBand()).isEqualTo(SoftApConfiguration.BAND_5GHZ); 238 assertThat(original.getChannel()).isEqualTo(149); 239 assertThat(original.isHiddenSsid()).isEqualTo(true); 240 assertThat(original.getMaxNumberOfClients()).isEqualTo(10); 241 assertThat(original.isAutoShutdownEnabled()).isEqualTo(true); 242 assertThat(original.getShutdownTimeoutMillis()).isEqualTo(500000); 243 assertThat(original.isClientControlByUserEnabled()).isEqualTo(true); 244 assertThat(original.getBlockedClientList()).isEqualTo(testBlockedClientList); 245 assertThat(original.getAllowedClientList()).isEqualTo(testAllowedClientList); 246 assertThat(original.getPersistentRandomizedMacAddress()) 247 .isEqualTo(testRandomizedMacAddress); 248 if (SdkLevel.isAtLeastS()) { 249 assertThat(original.getMacRandomizationSetting()) 250 .isEqualTo(SoftApConfiguration.RANDOMIZATION_NONE); 251 assertThat(original.isBridgedModeOpportunisticShutdownEnabled()) 252 .isEqualTo(false); 253 assertThat(original.isIeee80211axEnabled()) 254 .isEqualTo(false); 255 assertThat(original.isUserConfiguration()) 256 .isEqualTo(false); 257 } 258 if (SdkLevel.isAtLeastT()) { 259 assertThat(original.getBridgedModeOpportunisticShutdownTimeoutMillis()) 260 .isEqualTo(300_000); 261 assertThat(original.getVendorElements()) 262 .isEqualTo(TEST_TWO_VENDOR_ELEMENTS); 263 } 264 265 SoftApConfiguration unparceled = parcelUnparcel(original); 266 assertThat(unparceled).isNotSameInstanceAs(original); 267 assertThat(unparceled).isEqualTo(original); 268 assertThat(unparceled.hashCode()).isEqualTo(original.hashCode()); 269 270 SoftApConfiguration copy = new SoftApConfiguration.Builder(original).build(); 271 assertThat(copy).isNotSameInstanceAs(original); 272 assertThat(copy).isEqualTo(original); 273 assertThat(copy.hashCode()).isEqualTo(original.hashCode()); 274 } 275 276 @Test testWpa3Sae()277 public void testWpa3Sae() { 278 SoftApConfiguration original = new SoftApConfiguration.Builder() 279 .setPassphrase("secretsecret", SoftApConfiguration.SECURITY_TYPE_WPA3_SAE) 280 .setChannel(149, SoftApConfiguration.BAND_5GHZ) 281 .setHiddenSsid(true) 282 .build(); 283 assertThat(original.getPassphrase()).isEqualTo("secretsecret"); 284 assertThat(original.getSecurityType()).isEqualTo( 285 SoftApConfiguration.SECURITY_TYPE_WPA3_SAE); 286 assertThat(original.getBand()).isEqualTo(SoftApConfiguration.BAND_5GHZ); 287 assertThat(original.getChannel()).isEqualTo(149); 288 assertThat(original.isHiddenSsid()).isEqualTo(true); 289 290 291 SoftApConfiguration unparceled = parcelUnparcel(original); 292 assertThat(unparceled).isNotSameInstanceAs(original); 293 assertThat(unparceled).isEqualTo(original); 294 assertThat(unparceled.hashCode()).isEqualTo(original.hashCode()); 295 296 SoftApConfiguration copy = new SoftApConfiguration.Builder(original).build(); 297 assertThat(copy).isNotSameInstanceAs(original); 298 assertThat(copy).isEqualTo(original); 299 assertThat(copy.hashCode()).isEqualTo(original.hashCode()); 300 } 301 302 @Test testWpa3SaeTransition()303 public void testWpa3SaeTransition() { 304 SoftApConfiguration original = new SoftApConfiguration.Builder() 305 .setPassphrase("secretsecret", 306 SoftApConfiguration.SECURITY_TYPE_WPA3_SAE_TRANSITION) 307 .setChannel(149, SoftApConfiguration.BAND_5GHZ) 308 .setHiddenSsid(true) 309 .build(); 310 assertThat(original.getSecurityType()).isEqualTo( 311 SoftApConfiguration.SECURITY_TYPE_WPA3_SAE_TRANSITION); 312 assertThat(original.getPassphrase()).isEqualTo("secretsecret"); 313 assertThat(original.getBand()).isEqualTo(SoftApConfiguration.BAND_5GHZ); 314 assertThat(original.getChannel()).isEqualTo(149); 315 assertThat(original.isHiddenSsid()).isEqualTo(true); 316 317 318 SoftApConfiguration unparceled = parcelUnparcel(original); 319 assertThat(unparceled).isNotSameInstanceAs(original); 320 assertThat(unparceled).isEqualTo(original); 321 assertThat(unparceled.hashCode()).isEqualTo(original.hashCode()); 322 323 SoftApConfiguration copy = new SoftApConfiguration.Builder(original).build(); 324 assertThat(copy).isNotSameInstanceAs(original); 325 assertThat(copy).isEqualTo(original); 326 assertThat(copy.hashCode()).isEqualTo(original.hashCode()); 327 } 328 329 @Test testWpa3OweTransition()330 public void testWpa3OweTransition() { 331 assumeTrue(SdkLevel.isAtLeastT()); 332 SoftApConfiguration original = new SoftApConfiguration.Builder() 333 .setPassphrase(null, 334 SoftApConfiguration.SECURITY_TYPE_WPA3_OWE_TRANSITION) 335 .setChannel(149, SoftApConfiguration.BAND_5GHZ) 336 .setHiddenSsid(false) 337 .build(); 338 assertThat(original.getSecurityType()).isEqualTo( 339 SoftApConfiguration.SECURITY_TYPE_WPA3_OWE_TRANSITION); 340 assertThat(original.getPassphrase()).isEqualTo(null); 341 assertThat(original.getBand()).isEqualTo(SoftApConfiguration.BAND_5GHZ); 342 assertThat(original.getChannel()).isEqualTo(149); 343 assertThat(original.isHiddenSsid()).isEqualTo(false); 344 345 SoftApConfiguration unparceled = parcelUnparcel(original); 346 assertThat(unparceled).isNotSameInstanceAs(original); 347 assertThat(unparceled).isEqualTo(original); 348 assertThat(unparceled.hashCode()).isEqualTo(original.hashCode()); 349 350 SoftApConfiguration copy = new SoftApConfiguration.Builder(original).build(); 351 assertThat(copy).isNotSameInstanceAs(original); 352 assertThat(copy).isEqualTo(original); 353 assertThat(copy.hashCode()).isEqualTo(original.hashCode()); 354 355 assertThrows(IllegalArgumentException.class, 356 () -> new SoftApConfiguration.Builder().setPassphrase( 357 "something or other", 358 SoftApConfiguration.SECURITY_TYPE_WPA3_OWE_TRANSITION)); 359 } 360 361 @Test testWpa3Owe()362 public void testWpa3Owe() { 363 assumeTrue(SdkLevel.isAtLeastT()); 364 SoftApConfiguration original = new SoftApConfiguration.Builder() 365 .setPassphrase(null, 366 SoftApConfiguration.SECURITY_TYPE_WPA3_OWE) 367 .setChannel(149, SoftApConfiguration.BAND_5GHZ) 368 .setHiddenSsid(false) 369 .build(); 370 assertThat(original.getSecurityType()).isEqualTo( 371 SoftApConfiguration.SECURITY_TYPE_WPA3_OWE); 372 assertThat(original.getPassphrase()).isEqualTo(null); 373 assertThat(original.getBand()).isEqualTo(SoftApConfiguration.BAND_5GHZ); 374 assertThat(original.getChannel()).isEqualTo(149); 375 assertThat(original.isHiddenSsid()).isEqualTo(false); 376 377 SoftApConfiguration unparceled = parcelUnparcel(original); 378 assertThat(unparceled).isNotSameInstanceAs(original); 379 assertThat(unparceled).isEqualTo(original); 380 assertThat(unparceled.hashCode()).isEqualTo(original.hashCode()); 381 382 SoftApConfiguration copy = new SoftApConfiguration.Builder(original).build(); 383 assertThat(copy).isNotSameInstanceAs(original); 384 assertThat(copy).isEqualTo(original); 385 assertThat(copy.hashCode()).isEqualTo(original.hashCode()); 386 387 assertThrows(IllegalArgumentException.class, 388 () -> new SoftApConfiguration.Builder().setPassphrase( 389 "something or other", 390 SoftApConfiguration.SECURITY_TYPE_WPA3_OWE)); 391 } 392 393 @Test(expected = IllegalArgumentException.class) testInvalidBroadcastBssid()394 public void testInvalidBroadcastBssid() { 395 SoftApConfiguration original = new SoftApConfiguration.Builder() 396 .setBssid(MacAddress.BROADCAST_ADDRESS) 397 .build(); 398 } 399 400 @Test(expected = IllegalArgumentException.class) testInvalidMulticastBssid()401 public void testInvalidMulticastBssid() { 402 SoftApConfiguration original = new SoftApConfiguration.Builder() 403 .setBssid(MacAddress.fromString("01:aa:bb:cc:dd:ee")) 404 .build(); 405 } 406 407 @Test testValidWpa2PasswordLength()408 public void testValidWpa2PasswordLength() { 409 // ASCII 410 new SoftApConfiguration.Builder().setPassphrase( 411 "password", 412 SoftApConfiguration.SECURITY_TYPE_WPA2_PSK); 413 // Pass without IllegalArgumentException 414 415 // UTF-8 416 new SoftApConfiguration.Builder().setPassphrase( 417 "パスワード", 418 SoftApConfiguration.SECURITY_TYPE_WPA2_PSK); 419 // Pass without IllegalArgumentException 420 } 421 422 @Test testValidWpa3SaeTransitionPasswordLength()423 public void testValidWpa3SaeTransitionPasswordLength() { 424 // ASCII 425 new SoftApConfiguration.Builder().setPassphrase( 426 "password", 427 SoftApConfiguration.SECURITY_TYPE_WPA3_SAE_TRANSITION); 428 // Pass without IllegalArgumentException 429 430 // UTF-8 431 new SoftApConfiguration.Builder().setPassphrase( 432 "パスワード", 433 SoftApConfiguration.SECURITY_TYPE_WPA3_SAE_TRANSITION); 434 // Pass without IllegalArgumentException 435 } 436 437 @Test testInvalidWpa2PasswordLength()438 public void testInvalidWpa2PasswordLength() { 439 assumeFalse(SdkLevel.isAtLeastT()); 440 // Too short ASCII 441 try { 442 new SoftApConfiguration.Builder().setPassphrase( 443 "Short!", 444 SoftApConfiguration.SECURITY_TYPE_WPA2_PSK); 445 fail("Short ASCII password did not throw exception!"); 446 } catch (IllegalArgumentException e) { 447 // Success 448 } 449 450 // Too long ASCII 451 try { 452 new SoftApConfiguration.Builder().setPassphrase( 453 "This ASCII passphrase is definitely much too long to be valid...", 454 SoftApConfiguration.SECURITY_TYPE_WPA2_PSK); 455 fail("Long ASCII password did not throw exception!"); 456 } catch (IllegalArgumentException e) { 457 // Success 458 } 459 460 // Too short UTF-8 461 try { 462 new SoftApConfiguration.Builder().setPassphrase( 463 "短い", 464 SoftApConfiguration.SECURITY_TYPE_WPA2_PSK); 465 fail("Short UTF-8 password did not throw exception!"); 466 } catch (IllegalArgumentException e) { 467 // Success 468 } 469 470 // Too long UTF-8 471 try { 472 new SoftApConfiguration.Builder().setPassphrase( 473 "このパスワードはちょっと長すぎて使えられません。", 474 SoftApConfiguration.SECURITY_TYPE_WPA2_PSK); 475 fail("Long UTF-8 password did not throw exception!"); 476 } catch (IllegalArgumentException e) { 477 // Success 478 } 479 } 480 481 @Test testInvalidWpa3SaeTransitionPasswordLength()482 public void testInvalidWpa3SaeTransitionPasswordLength() { 483 assumeFalse(SdkLevel.isAtLeastT()); 484 // Too short ASCII 485 try { 486 new SoftApConfiguration.Builder().setPassphrase( 487 "Short!", 488 SoftApConfiguration.SECURITY_TYPE_WPA3_SAE_TRANSITION); 489 fail("Short ASCII password did not throw exception!"); 490 } catch (IllegalArgumentException e) { 491 // Success 492 } 493 494 // Too long ASCII 495 try { 496 new SoftApConfiguration.Builder().setPassphrase( 497 "This ASCII passphrase is definitely much too long to be valid...", 498 SoftApConfiguration.SECURITY_TYPE_WPA3_SAE_TRANSITION); 499 fail("Long ASCII password did not throw exception!"); 500 } catch (IllegalArgumentException e) { 501 // Success 502 } 503 504 // Too short UTF-8 505 try { 506 new SoftApConfiguration.Builder().setPassphrase( 507 "短い", 508 SoftApConfiguration.SECURITY_TYPE_WPA3_SAE_TRANSITION); 509 fail("Short UTF-8 password did not throw exception!"); 510 } catch (IllegalArgumentException e) { 511 // Success 512 } 513 514 // Too long UTF-8 515 try { 516 new SoftApConfiguration.Builder().setPassphrase( 517 "このパスワードはちょっと長すぎて使えられません。", 518 SoftApConfiguration.SECURITY_TYPE_WPA3_SAE_TRANSITION); 519 fail("Long UTF-8 password did not throw exception!"); 520 } catch (IllegalArgumentException e) { 521 // Success 522 } 523 } 524 525 @Test(expected = IllegalArgumentException.class) testInvalieShutdownTimeoutMillis()526 public void testInvalieShutdownTimeoutMillis() { 527 SoftApConfiguration original = new SoftApConfiguration.Builder() 528 .setShutdownTimeoutMillis(-2) 529 .build(); 530 } 531 532 @Test(expected = IllegalArgumentException.class) testZeroIsInvalidBridgedModeOpportunisticShutdownTimeoutMillis()533 public void testZeroIsInvalidBridgedModeOpportunisticShutdownTimeoutMillis() { 534 assumeTrue(SdkLevel.isAtLeastT()); 535 SoftApConfiguration original = new SoftApConfiguration.Builder() 536 .setBridgedModeOpportunisticShutdownTimeoutMillis(0) 537 .build(); 538 } 539 540 @Test(expected = IllegalArgumentException.class) testInvalidBridgedModeOpportunisticShutdownTimeoutMillis()541 public void testInvalidBridgedModeOpportunisticShutdownTimeoutMillis() { 542 assumeTrue(SdkLevel.isAtLeastT()); 543 SoftApConfiguration original = new SoftApConfiguration.Builder() 544 .setBridgedModeOpportunisticShutdownTimeoutMillis(-2) 545 .build(); 546 } 547 548 @Test(expected = IllegalArgumentException.class) testSetClientListExceptionWhenExistMacAddressInBothList()549 public void testSetClientListExceptionWhenExistMacAddressInBothList() { 550 final MacAddress testMacAddress_1 = MacAddress.fromString("22:33:44:55:66:77"); 551 final MacAddress testMacAddress_2 = MacAddress.fromString("aa:bb:cc:dd:ee:ff"); 552 ArrayList<MacAddress> testAllowedClientList = new ArrayList<>(); 553 testAllowedClientList.add(testMacAddress_1); 554 testAllowedClientList.add(testMacAddress_2); 555 ArrayList<MacAddress> testBlockedClientList = new ArrayList<>(); 556 testBlockedClientList.add(testMacAddress_1); 557 SoftApConfiguration.Builder configBuilder = new SoftApConfiguration.Builder(); 558 configBuilder.setBlockedClientList(testBlockedClientList) 559 .setAllowedClientList(testAllowedClientList) 560 .build(); 561 } 562 563 @Test testToWifiConfigurationWithUnsupportedParameter()564 public void testToWifiConfigurationWithUnsupportedParameter() { 565 SoftApConfiguration sae_config = new SoftApConfiguration.Builder() 566 .setPassphrase("secretsecret", SoftApConfiguration.SECURITY_TYPE_WPA3_SAE) 567 .build(); 568 569 assertNull(sae_config.toWifiConfiguration()); 570 SoftApConfiguration band_6g_config = new SoftApConfiguration.Builder() 571 .setBand(SoftApConfiguration.BAND_6GHZ) 572 .build(); 573 574 assertNull(band_6g_config.toWifiConfiguration()); 575 } 576 577 @Test testToWifiConfigurationWithSupportedParameter()578 public void testToWifiConfigurationWithSupportedParameter() { 579 SoftApConfiguration softApConfig_2g = new SoftApConfiguration.Builder() 580 .setPassphrase("secretsecret", 581 SoftApConfiguration.SECURITY_TYPE_WPA2_PSK) 582 .setChannel(11, SoftApConfiguration.BAND_2GHZ) 583 .setHiddenSsid(true) 584 .build(); 585 WifiConfiguration wifiConfig_2g = softApConfig_2g.toWifiConfiguration(); 586 assertThat(wifiConfig_2g.getAuthType()).isEqualTo(WifiConfiguration.KeyMgmt.WPA2_PSK); 587 assertThat(wifiConfig_2g.preSharedKey).isEqualTo("secretsecret"); 588 assertThat(wifiConfig_2g.apBand).isEqualTo(WifiConfiguration.AP_BAND_2GHZ); 589 assertThat(wifiConfig_2g.apChannel).isEqualTo(11); 590 assertThat(wifiConfig_2g.hiddenSSID).isEqualTo(true); 591 592 SoftApConfiguration softApConfig_5g = new SoftApConfiguration.Builder() 593 .setPassphrase("secretsecret", 594 SoftApConfiguration.SECURITY_TYPE_WPA2_PSK) 595 .setChannel(149, SoftApConfiguration.BAND_5GHZ) 596 .setHiddenSsid(true) 597 .build(); 598 WifiConfiguration wifiConfig_5g = softApConfig_5g.toWifiConfiguration(); 599 assertThat(wifiConfig_5g.getAuthType()).isEqualTo(WifiConfiguration.KeyMgmt.WPA2_PSK); 600 assertThat(wifiConfig_5g.preSharedKey).isEqualTo("secretsecret"); 601 assertThat(wifiConfig_5g.apBand).isEqualTo(WifiConfiguration.AP_BAND_5GHZ); 602 assertThat(wifiConfig_5g.apChannel).isEqualTo(149); 603 assertThat(wifiConfig_5g.hiddenSSID).isEqualTo(true); 604 605 SoftApConfiguration softApConfig_2g5g = new SoftApConfiguration.Builder() 606 .setPassphrase("secretsecret", 607 SoftApConfiguration.SECURITY_TYPE_WPA2_PSK) 608 .setBand(SoftApConfiguration.BAND_2GHZ | SoftApConfiguration.BAND_5GHZ) 609 .setHiddenSsid(true) 610 .build(); 611 WifiConfiguration wifiConfig_2g5g = softApConfig_2g5g.toWifiConfiguration(); 612 assertThat(wifiConfig_2g5g.getAuthType()).isEqualTo(WifiConfiguration.KeyMgmt.WPA2_PSK); 613 assertThat(wifiConfig_2g5g.preSharedKey).isEqualTo("secretsecret"); 614 assertThat(wifiConfig_2g5g.apBand).isEqualTo(WifiConfiguration.AP_BAND_ANY); 615 assertThat(wifiConfig_2g5g.apChannel).isEqualTo(0); 616 assertThat(wifiConfig_2g5g.hiddenSSID).isEqualTo(true); 617 618 SoftApConfiguration softApConfig_sae_transition = new SoftApConfiguration.Builder() 619 .setPassphrase("secretsecret", 620 SoftApConfiguration.SECURITY_TYPE_WPA3_SAE_TRANSITION) 621 .build(); 622 623 WifiConfiguration wifiConfig_sae_transition = 624 softApConfig_sae_transition.toWifiConfiguration(); 625 assertThat(wifiConfig_sae_transition.getAuthType()) 626 .isEqualTo(WifiConfiguration.KeyMgmt.WPA2_PSK); 627 assertThat(wifiConfig_sae_transition.preSharedKey).isEqualTo("secretsecret"); 628 } 629 630 @Test testDualBands()631 public void testDualBands() { 632 assumeTrue(SdkLevel.isAtLeastS()); 633 int[] dual_bands = new int[2]; 634 dual_bands[0] = SoftApConfiguration.BAND_2GHZ; 635 dual_bands[1] = SoftApConfiguration.BAND_5GHZ; 636 SoftApConfiguration dual_bands_config = new SoftApConfiguration.Builder() 637 .setSsid("ssid") 638 .setBands(dual_bands) 639 .build(); 640 assertTrue(Arrays.equals(dual_bands, dual_bands_config.getBands())); 641 assertThat(dual_bands_config.getBand()).isEqualTo(SoftApConfiguration.BAND_2GHZ); 642 } 643 644 @Test testDualChannels()645 public void testDualChannels() { 646 assumeTrue(SdkLevel.isAtLeastS()); 647 int[] expected_dual_bands = new int[2]; 648 expected_dual_bands[0] = SoftApConfiguration.BAND_2GHZ; 649 expected_dual_bands[1] = SoftApConfiguration.BAND_5GHZ; 650 SparseIntArray dual_channels = new SparseIntArray(2); 651 dual_channels.put(SoftApConfiguration.BAND_5GHZ, 149); 652 dual_channels.put(SoftApConfiguration.BAND_2GHZ, 2); 653 SoftApConfiguration dual_channels_config = new SoftApConfiguration.Builder() 654 .setSsid("ssid") 655 .setChannels(dual_channels) 656 .build(); 657 assertTrue(Arrays.equals(expected_dual_bands, dual_channels_config.getBands())); 658 assertThat(dual_channels_config.getBand()).isEqualTo(SoftApConfiguration.BAND_2GHZ); 659 assertTrue(dual_channels.toString().equals(dual_channels_config.getChannels().toString())); 660 assertThat(dual_channels_config.getChannel()).isEqualTo(2); 661 662 // Test different parameters. 663 dual_channels.clear(); 664 dual_channels.put(SoftApConfiguration.BAND_5GHZ, 149); 665 dual_channels.put(SoftApConfiguration.BAND_2GHZ | SoftApConfiguration.BAND_5GHZ, 0); 666 expected_dual_bands[0] = SoftApConfiguration.BAND_5GHZ; 667 expected_dual_bands[1] = SoftApConfiguration.BAND_2GHZ | SoftApConfiguration.BAND_5GHZ; 668 dual_channels_config = new SoftApConfiguration.Builder() 669 .setSsid("ssid") 670 .setChannels(dual_channels) 671 .build(); 672 assertTrue(Arrays.equals(expected_dual_bands, dual_channels_config.getBands())); 673 assertThat(dual_channels_config.getBand()).isEqualTo(SoftApConfiguration.BAND_5GHZ); 674 assertTrue(dual_channels.toString().equals(dual_channels_config.getChannels().toString())); 675 assertThat(dual_channels_config.getChannel()).isEqualTo(149); 676 } 677 678 @Test testInvalidBandWhenSetBands()679 public void testInvalidBandWhenSetBands() { 680 assumeTrue(SdkLevel.isAtLeastS()); 681 boolean isIllegalArgumentExceptionHappened = false; 682 int[] dual_bands = new int[2]; 683 dual_bands[0] = SoftApConfiguration.BAND_2GHZ; 684 dual_bands[1] = -1; 685 try { 686 SoftApConfiguration dual_channels_config = new SoftApConfiguration.Builder() 687 .setSsid("ssid") 688 .setBands(dual_bands) 689 .build(); 690 isIllegalArgumentExceptionHappened = false; 691 } catch (IllegalArgumentException iae) { 692 isIllegalArgumentExceptionHappened = true; 693 } 694 assertTrue(isIllegalArgumentExceptionHappened); 695 696 try { 697 SoftApConfiguration dual_channels_config = new SoftApConfiguration.Builder() 698 .setSsid("ssid") 699 .setBands(new int[0]) 700 .build(); 701 isIllegalArgumentExceptionHappened = false; 702 } catch (IllegalArgumentException iae) { 703 isIllegalArgumentExceptionHappened = true; 704 } 705 assertTrue(isIllegalArgumentExceptionHappened); 706 707 try { 708 SoftApConfiguration dual_channels_config = new SoftApConfiguration.Builder() 709 .setSsid("ssid") 710 .setBands(new int[3]) 711 .build(); 712 isIllegalArgumentExceptionHappened = false; 713 } catch (IllegalArgumentException iae) { 714 isIllegalArgumentExceptionHappened = true; 715 } 716 assertTrue(isIllegalArgumentExceptionHappened); 717 } 718 719 @Test testInvalidConfigWhenSetChannels()720 public void testInvalidConfigWhenSetChannels() { 721 assumeTrue(SdkLevel.isAtLeastS()); 722 boolean isIllegalArgumentExceptionHappened = false; 723 SparseIntArray invalid_channels = new SparseIntArray(); 724 try { 725 SoftApConfiguration zero_channels_config = new SoftApConfiguration.Builder() 726 .setSsid("ssid") 727 .setChannels(invalid_channels) 728 .build(); 729 isIllegalArgumentExceptionHappened = false; 730 } catch (IllegalArgumentException iae) { 731 isIllegalArgumentExceptionHappened = true; 732 } 733 assertTrue(isIllegalArgumentExceptionHappened); 734 735 try { 736 invalid_channels.clear(); 737 invalid_channels.put(SoftApConfiguration.BAND_2GHZ, 2); 738 invalid_channels.put(SoftApConfiguration.BAND_5GHZ, 11); 739 SoftApConfiguration invalid_band_channels_config = new SoftApConfiguration.Builder() 740 .setSsid("ssid") 741 .setChannels(invalid_channels) 742 .build(); 743 isIllegalArgumentExceptionHappened = false; 744 } catch (IllegalArgumentException iae) { 745 isIllegalArgumentExceptionHappened = true; 746 } 747 assertTrue(isIllegalArgumentExceptionHappened); 748 749 try { 750 invalid_channels.clear(); 751 invalid_channels.put(SoftApConfiguration.BAND_2GHZ, 2); 752 invalid_channels.put(SoftApConfiguration.BAND_2GHZ | SoftApConfiguration.BAND_5GHZ, 753 149); 754 SoftApConfiguration invalid_dual_channels_config = new SoftApConfiguration.Builder() 755 .setSsid("ssid") 756 .setChannels(invalid_channels) 757 .build(); 758 isIllegalArgumentExceptionHappened = false; 759 } catch (IllegalArgumentException iae) { 760 isIllegalArgumentExceptionHappened = true; 761 } 762 assertTrue(isIllegalArgumentExceptionHappened); 763 764 try { 765 invalid_channels.clear(); 766 invalid_channels.put(SoftApConfiguration.BAND_2GHZ, 2); 767 invalid_channels.put(SoftApConfiguration.BAND_5GHZ, 149); 768 invalid_channels.put(SoftApConfiguration.BAND_6GHZ, 2); 769 SoftApConfiguration three_channels_config = new SoftApConfiguration.Builder() 770 .setSsid("ssid") 771 .setChannels(invalid_channels) 772 .build(); 773 isIllegalArgumentExceptionHappened = false; 774 } catch (IllegalArgumentException iae) { 775 isIllegalArgumentExceptionHappened = true; 776 } 777 assertTrue(isIllegalArgumentExceptionHappened); 778 } 779 780 @Test(expected = IllegalArgumentException.class) testInvalidConfigWhenSet60GhzChannels()781 public void testInvalidConfigWhenSet60GhzChannels() throws Exception { 782 assumeTrue(SdkLevel.isAtLeastS()); 783 SparseIntArray invalid_channels = new SparseIntArray(); 784 invalid_channels.put(SoftApConfiguration.BAND_60GHZ, 99); 785 SoftApConfiguration config = new SoftApConfiguration.Builder() 786 .setSsid("ssid") 787 .setChannels(invalid_channels) 788 .build(); 789 } 790 791 @Test(expected = IllegalArgumentException.class) testInvalidVendorElementsID()792 public void testInvalidVendorElementsID() { 793 assumeTrue(SdkLevel.isAtLeastT()); 794 SoftApConfiguration original = new SoftApConfiguration.Builder() 795 .setVendorElements(TEST_TWO_VENDOR_ELEMENTS_INVALID) 796 .build(); 797 } 798 799 @Test(expected = IllegalArgumentException.class) testInvalidVendorElementsDuplicate()800 public void testInvalidVendorElementsDuplicate() { 801 assumeTrue(SdkLevel.isAtLeastT()); 802 List<ScanResult.InformationElement> dupElements = new ArrayList<>(TEST_TWO_VENDOR_ELEMENTS); 803 dupElements.addAll(TEST_TWO_VENDOR_ELEMENTS); 804 SoftApConfiguration original = new SoftApConfiguration.Builder() 805 .setVendorElements(dupElements) 806 .build(); 807 } 808 809 @Test(expected = IllegalArgumentException.class) testThrowsExceptionWhenBssidSetButMacRandomizationSettingIsPersistent()810 public void testThrowsExceptionWhenBssidSetButMacRandomizationSettingIsPersistent() { 811 assumeTrue(SdkLevel.isAtLeastS()); 812 MacAddress testBssid = MacAddress.fromString(TEST_BSSID); 813 SoftApConfiguration config_setBssidAfterSetMacRandomizationSettingToPersistent = 814 new SoftApConfiguration.Builder() 815 .setMacRandomizationSetting(SoftApConfiguration.RANDOMIZATION_PERSISTENT) 816 .setBssid(testBssid) 817 .build(); 818 } 819 820 @Test(expected = IllegalArgumentException.class) testThrowsExceptionWhenBssidSetButMacRandomizationSettingIsNonPersistent()821 public void testThrowsExceptionWhenBssidSetButMacRandomizationSettingIsNonPersistent() { 822 assumeTrue(SdkLevel.isAtLeastS()); 823 MacAddress testBssid = MacAddress.fromString(TEST_BSSID); 824 SoftApConfiguration config_setBssidAfterSetMacRandomizationSettingToNonPersistent = 825 new SoftApConfiguration.Builder() 826 .setMacRandomizationSetting(SoftApConfiguration.RANDOMIZATION_NON_PERSISTENT) 827 .setBssid(testBssid) 828 .build(); 829 } 830 831 @Test testSetBssidSucceededWWithDisableMacRandomizationSetting()832 public void testSetBssidSucceededWWithDisableMacRandomizationSetting() { 833 assumeTrue(SdkLevel.isAtLeastS()); 834 MacAddress testBssid = MacAddress.fromString(TEST_BSSID); 835 SoftApConfiguration config_setBssidAfterSetMacRandomizationSettingToNone = 836 new SoftApConfiguration.Builder() 837 .setMacRandomizationSetting(SoftApConfiguration.RANDOMIZATION_NONE) 838 .setBssid(testBssid) 839 .build(); 840 assertEquals(config_setBssidAfterSetMacRandomizationSettingToNone.getBssid(), 841 testBssid); 842 } 843 844 @Test testSetAllowedAcsChannels()845 public void testSetAllowedAcsChannels() throws Exception { 846 assumeTrue(SdkLevel.isAtLeastT()); 847 848 SoftApConfiguration config = new SoftApConfiguration.Builder() 849 .build(); 850 assertEquals(0, config.getAllowedAcsChannels(SoftApConfiguration.BAND_2GHZ).length); 851 assertEquals(0, config.getAllowedAcsChannels(SoftApConfiguration.BAND_5GHZ).length); 852 assertEquals(0, config.getAllowedAcsChannels(SoftApConfiguration.BAND_6GHZ).length); 853 854 int[] channels2g = {1, 6, 11}; 855 int[] channels5g = {36, 149, 136}; 856 int[] channels6g = {1, 2, 3}; 857 858 config = new SoftApConfiguration.Builder() 859 .setAllowedAcsChannels(SoftApConfiguration.BAND_2GHZ, channels2g) 860 .setAllowedAcsChannels(SoftApConfiguration.BAND_5GHZ, channels5g) 861 .setAllowedAcsChannels(SoftApConfiguration.BAND_6GHZ, channels6g) 862 .build(); 863 assertArrayEquals(channels2g, config.getAllowedAcsChannels(SoftApConfiguration.BAND_2GHZ)); 864 assertArrayEquals(channels5g, config.getAllowedAcsChannels(SoftApConfiguration.BAND_5GHZ)); 865 assertArrayEquals(channels6g, config.getAllowedAcsChannels(SoftApConfiguration.BAND_6GHZ)); 866 } 867 868 @Test testSetAllowedAcsChannelsInvalidValues()869 public void testSetAllowedAcsChannelsInvalidValues() throws Exception { 870 assumeTrue(SdkLevel.isAtLeastT()); 871 872 int[] channels2g = {1, 6, 11, 50}; 873 int[] channels5g = {36, 7, 149, 800}; 874 int[] channels6g = {1, 2, -1, 3}; 875 876 assertThrows(IllegalArgumentException.class, 877 () -> new SoftApConfiguration.Builder() 878 .setAllowedAcsChannels(SoftApConfiguration.BAND_2GHZ, channels2g)); 879 assertThrows(IllegalArgumentException.class, 880 () -> new SoftApConfiguration.Builder() 881 .setAllowedAcsChannels(SoftApConfiguration.BAND_5GHZ, channels5g)); 882 assertThrows(IllegalArgumentException.class, 883 () -> new SoftApConfiguration.Builder() 884 .setAllowedAcsChannels(SoftApConfiguration.BAND_6GHZ, channels6g)); 885 } 886 887 @Test testMaxChannelBandwidth()888 public void testMaxChannelBandwidth() throws Exception { 889 assumeTrue(SdkLevel.isAtLeastT()); 890 891 SoftApConfiguration config = new SoftApConfiguration.Builder() 892 .build(); 893 assertEquals(SoftApInfo.CHANNEL_WIDTH_AUTO, config.getMaxChannelBandwidth()); 894 895 config = new SoftApConfiguration.Builder() 896 .setMaxChannelBandwidth(SoftApInfo.CHANNEL_WIDTH_20MHZ) 897 .build(); 898 assertEquals(SoftApInfo.CHANNEL_WIDTH_20MHZ, config.getMaxChannelBandwidth()); 899 900 config = new SoftApConfiguration.Builder() 901 .setMaxChannelBandwidth(SoftApInfo.CHANNEL_WIDTH_AUTO) 902 .build(); 903 assertEquals(SoftApInfo.CHANNEL_WIDTH_AUTO, config.getMaxChannelBandwidth()); 904 905 // Invalid value 906 assertThrows(IllegalArgumentException.class, 907 () -> new SoftApConfiguration.Builder() 908 .setMaxChannelBandwidth(SoftApInfo.CHANNEL_WIDTH_80MHZ_PLUS_MHZ)); 909 } 910 911 @Test testVendorDataValid()912 public void testVendorDataValid() throws Exception { 913 assumeTrue(SdkLevel.isAtLeastV()); 914 915 // Default value should be an empty list. 916 SoftApConfiguration config = new SoftApConfiguration.Builder().build(); 917 List<OuiKeyedData> retrievedVendorData = config.getVendorData(); 918 assertNotNull(retrievedVendorData); 919 assertEquals(0, retrievedVendorData.size()); 920 921 List<OuiKeyedData> mockVendorData = Arrays.asList(mock(OuiKeyedData.class)); 922 config = new SoftApConfiguration.Builder().setVendorData(mockVendorData).build(); 923 assertTrue(mockVendorData.equals(config.getVendorData())); 924 } 925 926 @Test testVendorDataInvalid()927 public void testVendorDataInvalid() { 928 assumeTrue(SdkLevel.isAtLeastV()); 929 SoftApConfiguration.Builder builder = new SoftApConfiguration.Builder(); 930 // Vendor data must be non-null, if provided. 931 assertThrows(IllegalArgumentException.class, () -> builder.setVendorData(null)); 932 } 933 934 @Test testVendorDataParcelUnparcel()935 public void testVendorDataParcelUnparcel() { 936 assumeTrue(SdkLevel.isAtLeastV()); 937 938 int oui = 0x00112233; 939 String fieldKey = "fieldKey"; 940 PersistableBundle bundle = new PersistableBundle(); 941 bundle.putInt(fieldKey, 12345); 942 943 OuiKeyedData ouiKeyedData = new OuiKeyedData.Builder(oui, bundle).build(); 944 List<OuiKeyedData> vendorData = Arrays.asList(ouiKeyedData); 945 SoftApConfiguration config = 946 new SoftApConfiguration.Builder().setVendorData(vendorData).build(); 947 948 SoftApConfiguration unparceled = parcelUnparcel(config); 949 assertThat(unparceled).isNotSameInstanceAs(config); 950 assertThat(unparceled).isEqualTo(config); 951 assertThat(unparceled.hashCode()).isEqualTo(config.hashCode()); 952 OuiKeyedData unparceledOuiKeyedData = unparceled.getVendorData().get(0); 953 assertEquals(bundle.getInt(fieldKey), unparceledOuiKeyedData.getData().getInt(fieldKey)); 954 } 955 } 956