1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License 15 */ 16 17 package com.android.server.wifi; 18 19 import static org.hamcrest.CoreMatchers.not; 20 import static org.junit.Assert.*; 21 import static org.mockito.Mockito.*; 22 23 import android.content.Context; 24 import android.content.pm.UserInfo; 25 import android.net.wifi.FakeKeys; 26 import android.net.wifi.WifiConfiguration; 27 import android.net.wifi.WifiConfiguration.AuthAlgorithm; 28 import android.net.wifi.WifiConfiguration.GroupCipher; 29 import android.net.wifi.WifiConfiguration.KeyMgmt; 30 import android.net.wifi.WifiConfiguration.PairwiseCipher; 31 import android.net.wifi.WifiConfiguration.Protocol; 32 import android.net.wifi.WifiEnterpriseConfig; 33 import android.net.wifi.WifiEnterpriseConfig.Eap; 34 import android.net.wifi.WifiEnterpriseConfig.Phase2; 35 import android.net.wifi.WifiScanner; 36 import android.os.Process; 37 import android.os.UserHandle; 38 import android.os.UserManager; 39 import android.security.Credentials; 40 import android.security.KeyStore; 41 import android.support.test.InstrumentationRegistry; 42 import android.test.suitebuilder.annotation.SmallTest; 43 import android.text.TextUtils; 44 import android.util.Log; 45 import android.util.SparseArray; 46 47 import com.android.server.net.DelayedDiskWrite; 48 import com.android.server.wifi.MockAnswerUtil.AnswerWithArguments; 49 import com.android.server.wifi.hotspot2.omadm.PasspointManagementObjectManager; 50 import com.android.server.wifi.hotspot2.pps.Credential; 51 import com.android.server.wifi.hotspot2.pps.HomeSP; 52 53 import org.junit.Before; 54 import org.junit.Test; 55 import org.mockito.Mock; 56 import org.mockito.MockitoAnnotations; 57 58 import java.io.ByteArrayInputStream; 59 import java.io.ByteArrayOutputStream; 60 import java.io.DataInputStream; 61 import java.io.DataOutputStream; 62 import java.io.EOFException; 63 import java.io.File; 64 import java.io.FileOutputStream; 65 import java.io.IOException; 66 import java.lang.reflect.Field; 67 import java.math.BigInteger; 68 import java.security.cert.CertificateEncodingException; 69 import java.security.cert.X509Certificate; 70 import java.util.ArrayDeque; 71 import java.util.ArrayList; 72 import java.util.Arrays; 73 import java.util.BitSet; 74 import java.util.Collection; 75 import java.util.Collections; 76 import java.util.HashMap; 77 import java.util.HashSet; 78 import java.util.List; 79 import java.util.Map; 80 import java.util.Random; 81 import java.util.Set; 82 import java.util.TreeMap; 83 84 /** 85 * Unit tests for {@link com.android.server.wifi.WifiConfigManager}. 86 */ 87 @SmallTest 88 public class WifiConfigManagerTest { 89 private static final List<WifiConfiguration> CONFIGS = Arrays.asList( 90 WifiConfigurationTestUtil.generateWifiConfig( 91 0, 1000000, "\"red\"", true, true, null, null), 92 WifiConfigurationTestUtil.generateWifiConfig( 93 1, 1000001, "\"green\"", true, true, "example.com", "Green"), 94 WifiConfigurationTestUtil.generateWifiConfig( 95 2, 1100000, "\"blue\"", false, true, "example.org", "Blue"), 96 WifiConfigurationTestUtil.generateWifiConfig( 97 3, 1200000, "\"cyan\"", false, true, null, null)); 98 99 private static final int[] USER_IDS = {0, 10, 11}; 100 private static final int MANAGED_PROFILE_USER_ID = 12; 101 private static final int MANAGED_PROFILE_PARENT_USER_ID = 0; 102 private static final SparseArray<List<UserInfo>> USER_PROFILES = new SparseArray<>(); 103 static { 104 USER_PROFILES.put(0, Arrays.asList(new UserInfo(0, "Owner", 0), 105 new UserInfo(12, "Managed Profile", 0))); 106 USER_PROFILES.put(10, Arrays.asList(new UserInfo(10, "Alice", 0))); 107 USER_PROFILES.put(11, Arrays.asList(new UserInfo(11, "Bob", 0))); 108 } 109 110 private static final Map<Integer, List<WifiConfiguration>> VISIBLE_CONFIGS = new HashMap<>(); 111 static { 112 for (int userId : USER_IDS) { 113 List<WifiConfiguration> configs = new ArrayList<>(); 114 for (int i = 0; i < CONFIGS.size(); ++i) { 115 if (WifiConfigurationUtil.isVisibleToAnyProfile(CONFIGS.get(i), 116 USER_PROFILES.get(userId))) { CONFIGS.get(i)117 configs.add(CONFIGS.get(i)); 118 } 119 } VISIBLE_CONFIGS.put(userId, configs)120 VISIBLE_CONFIGS.put(userId, configs); 121 } 122 } 123 124 /** 125 * Set of WifiConfigs for HasEverConnected tests. 126 */ 127 private static final int HAS_EVER_CONNECTED_USER = 20; 128 private static final WifiConfiguration BASE_HAS_EVER_CONNECTED_CONFIG = 129 WifiConfigurationTestUtil.generateWifiConfig( 130 0, HAS_EVER_CONNECTED_USER, "testHasEverConnected", false, true, null, null, 0); 131 132 public static final String TAG = "WifiConfigManagerTest"; 133 @Mock private Context mContext; 134 @Mock private WifiNative mWifiNative; 135 @Mock private FrameworkFacade mFrameworkFacade; 136 @Mock private UserManager mUserManager; 137 @Mock private DelayedDiskWrite mWriter; 138 @Mock private PasspointManagementObjectManager mMOManager; 139 @Mock private Clock mClock; 140 private WifiConfigManager mWifiConfigManager; 141 private ConfigurationMap mConfiguredNetworks; 142 public byte[] mNetworkHistoryBytes; 143 private MockKeyStore mMockKeyStore; 144 private KeyStore mKeyStore; 145 146 /** 147 * Called before each test 148 */ 149 @Before setUp()150 public void setUp() throws Exception { 151 MockitoAnnotations.initMocks(this); 152 153 final Context realContext = InstrumentationRegistry.getContext(); 154 when(mContext.getPackageName()).thenReturn(realContext.getPackageName()); 155 when(mContext.getResources()).thenReturn(realContext.getResources()); 156 when(mContext.getPackageManager()).thenReturn(realContext.getPackageManager()); 157 158 when(mUserManager.getProfiles(UserHandle.USER_SYSTEM)) 159 .thenReturn(USER_PROFILES.get(UserHandle.USER_SYSTEM)); 160 161 for (int userId : USER_IDS) { 162 when(mUserManager.getProfiles(userId)).thenReturn(USER_PROFILES.get(userId)); 163 } 164 165 mMockKeyStore = new MockKeyStore(); 166 167 mWifiConfigManager = new WifiConfigManager(mContext, mWifiNative, mFrameworkFacade, mClock, 168 mUserManager, mMockKeyStore.createMock()); 169 170 final Field configuredNetworksField = 171 WifiConfigManager.class.getDeclaredField("mConfiguredNetworks"); 172 configuredNetworksField.setAccessible(true); 173 mConfiguredNetworks = (ConfigurationMap) configuredNetworksField.get(mWifiConfigManager); 174 175 // Intercept writes to networkHistory.txt. 176 doAnswer(new AnswerWithArguments() { 177 public void answer(String filePath, DelayedDiskWrite.Writer writer) throws Exception { 178 final ByteArrayOutputStream buffer = new ByteArrayOutputStream(); 179 final DataOutputStream stream = new DataOutputStream(buffer); 180 writer.onWriteCalled(stream); 181 stream.close(); 182 mNetworkHistoryBytes = buffer.toByteArray(); 183 }}).when(mWriter).write(anyString(), (DelayedDiskWrite.Writer) anyObject()); 184 final Field writerField = WifiConfigManager.class.getDeclaredField("mWriter"); 185 writerField.setAccessible(true); 186 writerField.set(mWifiConfigManager, mWriter); 187 final Field networkHistoryField = 188 WifiConfigManager.class.getDeclaredField("mWifiNetworkHistory"); 189 networkHistoryField.setAccessible(true); 190 WifiNetworkHistory wifiNetworkHistory = 191 (WifiNetworkHistory) networkHistoryField.get(mWifiConfigManager); 192 final Field networkHistoryWriterField = 193 WifiNetworkHistory.class.getDeclaredField("mWriter"); 194 networkHistoryWriterField.setAccessible(true); 195 networkHistoryWriterField.set(wifiNetworkHistory, mWriter); 196 197 when(mMOManager.isEnabled()).thenReturn(true); 198 final Field moManagerField = WifiConfigManager.class.getDeclaredField("mMOManager"); 199 moManagerField.setAccessible(true); 200 moManagerField.set(mWifiConfigManager, mMOManager); 201 } 202 switchUser(int newUserId)203 private void switchUser(int newUserId) { 204 when(mUserManager.getProfiles(newUserId)) 205 .thenReturn(USER_PROFILES.get(newUserId)); 206 mWifiConfigManager.handleUserSwitch(newUserId); 207 } 208 switchUserToCreatorOrParentOf(WifiConfiguration config)209 private void switchUserToCreatorOrParentOf(WifiConfiguration config) { 210 final int creatorUserId = UserHandle.getUserId(config.creatorUid); 211 if (creatorUserId == MANAGED_PROFILE_USER_ID) { 212 switchUser(MANAGED_PROFILE_PARENT_USER_ID); 213 } else { 214 switchUser(creatorUserId); 215 } 216 } 217 addNetworks()218 private void addNetworks() throws Exception { 219 for (int i = 0; i < CONFIGS.size(); ++i) { 220 assertEquals(i, CONFIGS.get(i).networkId); 221 addNetwork(CONFIGS.get(i)); 222 } 223 } 224 addNetwork(WifiConfiguration config)225 private void addNetwork(WifiConfiguration config) throws Exception { 226 final int originalUserId = mWifiConfigManager.getCurrentUserId(); 227 228 when(mWifiNative.setNetworkVariable(anyInt(), anyString(), anyString())).thenReturn(true); 229 when(mWifiNative.setNetworkExtra(anyInt(), anyString(), (Map<String, String>) anyObject())) 230 .thenReturn(true); 231 232 switchUserToCreatorOrParentOf(config); 233 final WifiConfiguration configCopy = new WifiConfiguration(config); 234 int networkId = config.networkId; 235 config.networkId = -1; 236 when(mWifiNative.addNetwork()).thenReturn(networkId); 237 when(mWifiNative.getNetworkVariable(networkId, WifiConfiguration.ssidVarName)) 238 .thenReturn(encodeConfigSSID(config)); 239 mWifiConfigManager.saveNetwork(config, configCopy.creatorUid); 240 241 switchUser(originalUserId); 242 } 243 encodeConfigSSID(WifiConfiguration config)244 private String encodeConfigSSID(WifiConfiguration config) throws Exception { 245 return new BigInteger(1, config.SSID.substring(1, config.SSID.length() - 1) 246 .getBytes("UTF-8")).toString(16); 247 } 248 249 /** 250 * Verifies that getConfiguredNetworksSize() returns the number of network configurations 251 * visible to the current user. 252 */ 253 @Test testGetConfiguredNetworksSize()254 public void testGetConfiguredNetworksSize() throws Exception { 255 addNetworks(); 256 for (Map.Entry<Integer, List<WifiConfiguration>> entry : VISIBLE_CONFIGS.entrySet()) { 257 switchUser(entry.getKey()); 258 assertEquals(entry.getValue().size(), mWifiConfigManager.getConfiguredNetworksSize()); 259 } 260 } 261 verifyNetworkConfig(WifiConfiguration expectedConfig, WifiConfiguration actualConfig)262 private void verifyNetworkConfig(WifiConfiguration expectedConfig, 263 WifiConfiguration actualConfig) { 264 assertNotNull(actualConfig); 265 assertEquals(expectedConfig.SSID, actualConfig.SSID); 266 assertEquals(expectedConfig.FQDN, actualConfig.FQDN); 267 assertEquals(expectedConfig.providerFriendlyName, 268 actualConfig.providerFriendlyName); 269 assertEquals(expectedConfig.configKey(), actualConfig.configKey(false)); 270 } 271 verifyNetworkConfigs(Collection<WifiConfiguration> expectedConfigs, Collection<WifiConfiguration> actualConfigs)272 private void verifyNetworkConfigs(Collection<WifiConfiguration> expectedConfigs, 273 Collection<WifiConfiguration> actualConfigs) { 274 assertEquals(expectedConfigs.size(), actualConfigs.size()); 275 for (WifiConfiguration expectedConfig : expectedConfigs) { 276 WifiConfiguration actualConfig = null; 277 // Find the network configuration to test (assume that |actualConfigs| contains them in 278 // undefined order). 279 for (final WifiConfiguration candidate : actualConfigs) { 280 if (candidate.networkId == expectedConfig.networkId) { 281 actualConfig = candidate; 282 break; 283 } 284 } 285 verifyNetworkConfig(expectedConfig, actualConfig); 286 } 287 } 288 289 /** 290 * Verifies that getConfiguredNetworksSize() returns the network configurations visible to the 291 * current user. 292 */ 293 @Test testGetConfiguredNetworks()294 public void testGetConfiguredNetworks() throws Exception { 295 addNetworks(); 296 for (Map.Entry<Integer, List<WifiConfiguration>> entry : VISIBLE_CONFIGS.entrySet()) { 297 switchUser(entry.getKey()); 298 verifyNetworkConfigs(entry.getValue(), mWifiConfigManager.getSavedNetworks()); 299 } 300 } 301 302 /** 303 * Verifies that getPrivilegedConfiguredNetworks() returns the network configurations visible to 304 * the current user. 305 */ 306 @Test testGetPrivilegedConfiguredNetworks()307 public void testGetPrivilegedConfiguredNetworks() throws Exception { 308 addNetworks(); 309 for (Map.Entry<Integer, List<WifiConfiguration>> entry : VISIBLE_CONFIGS.entrySet()) { 310 switchUser(entry.getKey()); 311 verifyNetworkConfigs(entry.getValue(), 312 mWifiConfigManager.getPrivilegedSavedNetworks()); 313 } 314 } 315 316 /** 317 * Verifies that getWifiConfiguration(int netId) can be used to access network configurations 318 * visible to the current user only. 319 */ 320 @Test testGetWifiConfigurationByNetworkId()321 public void testGetWifiConfigurationByNetworkId() throws Exception { 322 addNetworks(); 323 for (int userId : USER_IDS) { 324 switchUser(userId); 325 for (WifiConfiguration expectedConfig: CONFIGS) { 326 final WifiConfiguration actualConfig = 327 mWifiConfigManager.getWifiConfiguration(expectedConfig.networkId); 328 if (WifiConfigurationUtil.isVisibleToAnyProfile(expectedConfig, 329 USER_PROFILES.get(userId))) { 330 verifyNetworkConfig(expectedConfig, actualConfig); 331 } else { 332 assertNull(actualConfig); 333 } 334 } 335 } 336 } 337 338 /** 339 * Verifies that getWifiConfiguration(String key) can be used to access network configurations 340 * visible to the current user only. 341 */ 342 @Test testGetWifiConfigurationByConfigKey()343 public void testGetWifiConfigurationByConfigKey() throws Exception { 344 addNetworks(); 345 for (int userId : USER_IDS) { 346 switchUser(userId); 347 for (WifiConfiguration expectedConfig: CONFIGS) { 348 final WifiConfiguration actualConfig = 349 mWifiConfigManager.getWifiConfiguration(expectedConfig.configKey()); 350 if (WifiConfigurationUtil.isVisibleToAnyProfile(expectedConfig, 351 USER_PROFILES.get(userId))) { 352 verifyNetworkConfig(expectedConfig, actualConfig); 353 } else { 354 assertNull(actualConfig); 355 } 356 } 357 } 358 } 359 360 /** 361 * Verifies that enableAllNetworks() enables all temporarily disabled network configurations 362 * visible to the current user. 363 */ 364 @Test testEnableAllNetworks()365 public void testEnableAllNetworks() throws Exception { 366 addNetworks(); 367 for (int userId : USER_IDS) { 368 switchUser(userId); 369 370 for (WifiConfiguration config : mConfiguredNetworks.valuesForAllUsers()) { 371 final WifiConfiguration.NetworkSelectionStatus status = 372 config.getNetworkSelectionStatus(); 373 status.setNetworkSelectionStatus(WifiConfiguration.NetworkSelectionStatus 374 .NETWORK_SELECTION_TEMPORARY_DISABLED); 375 status.setNetworkSelectionDisableReason( 376 WifiConfiguration.NetworkSelectionStatus.DISABLED_AUTHENTICATION_FAILURE); 377 status.setDisableTime(System.currentTimeMillis() - 60 * 60 * 1000); 378 } 379 380 mWifiConfigManager.enableAllNetworks(); 381 382 for (WifiConfiguration config : mConfiguredNetworks.valuesForAllUsers()) { 383 assertEquals(WifiConfigurationUtil.isVisibleToAnyProfile(config, 384 USER_PROFILES.get(userId)), 385 config.getNetworkSelectionStatus().isNetworkEnabled()); 386 } 387 } 388 } 389 390 /** 391 * Verifies that selectNetwork() disables all network configurations visible to the current user 392 * except the selected one. 393 */ 394 @Test testSelectNetwork()395 public void testSelectNetwork() throws Exception { 396 addNetworks(); 397 398 for (int userId : USER_IDS) { 399 switchUser(userId); 400 401 for (WifiConfiguration config : mConfiguredNetworks.valuesForAllUsers()) { 402 // Enable all network configurations. 403 for (WifiConfiguration config2 : mConfiguredNetworks.valuesForAllUsers()) { 404 config2.status = WifiConfiguration.Status.ENABLED; 405 } 406 407 // Try to select a network configuration. 408 reset(mWifiNative); 409 when(mWifiNative.selectNetwork(config.networkId)).thenReturn(true); 410 final boolean success = 411 mWifiConfigManager.selectNetwork(config, false, config.creatorUid); 412 if (!WifiConfigurationUtil.isVisibleToAnyProfile(config, 413 USER_PROFILES.get(userId))) { 414 // If the network configuration is not visible to the current user, verify that 415 // nothing changed. 416 assertFalse(success); 417 verify(mWifiNative, never()).selectNetwork(anyInt()); 418 verify(mWifiNative, never()).enableNetwork(anyInt()); 419 for (WifiConfiguration config2 : mConfiguredNetworks.valuesForAllUsers()) { 420 assertEquals(WifiConfiguration.Status.ENABLED, config2.status); 421 } 422 } else { 423 // If the network configuration is visible to the current user, verify that it 424 // was enabled and all other network configurations visible to the user were 425 // disabled. 426 assertTrue(success); 427 verify(mWifiNative).selectNetwork(config.networkId); 428 verify(mWifiNative, never()).selectNetwork(intThat(not(config.networkId))); 429 verify(mWifiNative, never()).enableNetwork(config.networkId); 430 verify(mWifiNative, never()).enableNetwork(intThat(not(config.networkId))); 431 for (WifiConfiguration config2 : mConfiguredNetworks.valuesForAllUsers()) { 432 if (WifiConfigurationUtil.isVisibleToAnyProfile(config2, 433 USER_PROFILES.get(userId)) 434 && config2.networkId != config.networkId) { 435 assertEquals(WifiConfiguration.Status.DISABLED, config2.status); 436 } else { 437 assertEquals(WifiConfiguration.Status.ENABLED, config2.status); 438 } 439 } 440 } 441 } 442 } 443 } 444 445 /** 446 * Verifies that saveNetwork() correctly stores a network configuration in wpa_supplicant 447 * variables and the networkHistory.txt file. 448 * TODO: Test all variables. Currently, only the following variables are tested: 449 * - In the wpa_supplicant: "ssid", "id_str" 450 * - In networkHistory.txt: "CONFIG", "CREATOR_UID_KEY", "SHARED" 451 */ verifySaveNetwork(int network)452 private void verifySaveNetwork(int network) throws Exception { 453 // Switch to the correct user. 454 switchUserToCreatorOrParentOf(CONFIGS.get(network)); 455 456 // Set up wpa_supplicant. 457 when(mWifiNative.addNetwork()).thenReturn(0); 458 when(mWifiNative.setNetworkVariable(eq(network), anyString(), anyString())) 459 .thenReturn(true); 460 when(mWifiNative.setNetworkExtra(eq(network), anyString(), 461 (Map<String, String>) anyObject())).thenReturn(true); 462 when(mWifiNative.getNetworkVariable(network, WifiConfiguration.ssidVarName)) 463 .thenReturn(encodeConfigSSID(CONFIGS.get(network))); 464 when(mWifiNative.getNetworkVariable(network, WifiConfiguration.pmfVarName)) 465 .thenReturn(""); 466 467 // Store a network configuration. 468 mWifiConfigManager.saveNetwork(CONFIGS.get(network), CONFIGS.get(network).creatorUid); 469 470 // Verify that wpa_supplicant variables were written correctly for the network 471 // configuration. 472 final Map<String, String> metadata = new HashMap<String, String>(); 473 if (CONFIGS.get(network).FQDN != null) { 474 metadata.put(WifiConfigStore.ID_STRING_KEY_FQDN, CONFIGS.get(network).FQDN); 475 } 476 metadata.put(WifiConfigStore.ID_STRING_KEY_CONFIG_KEY, CONFIGS.get(network).configKey()); 477 metadata.put(WifiConfigStore.ID_STRING_KEY_CREATOR_UID, 478 Integer.toString(CONFIGS.get(network).creatorUid)); 479 verify(mWifiNative).setNetworkExtra(network, WifiConfigStore.ID_STRING_VAR_NAME, 480 metadata); 481 482 // Verify that an attempt to read back the requirePMF variable was made. 483 verify(mWifiNative).getNetworkVariable(network, WifiConfiguration.pmfVarName); 484 485 // Verify that no wpa_supplicant variables were read or written for any other network 486 // configurations. 487 verify(mWifiNative, never()).setNetworkExtra(intThat(not(network)), anyString(), 488 (Map<String, String>) anyObject()); 489 verify(mWifiNative, never()).setNetworkVariable(intThat(not(network)), anyString(), 490 anyString()); 491 verify(mWifiNative, never()).getNetworkVariable(intThat(not(network)), anyString()); 492 493 // Parse networkHistory.txt. 494 assertNotNull(mNetworkHistoryBytes); 495 final DataInputStream stream = 496 new DataInputStream(new ByteArrayInputStream(mNetworkHistoryBytes)); 497 List<String> keys = new ArrayList<>(); 498 List<String> values = new ArrayList<>(); 499 try { 500 while (true) { 501 final String[] tokens = stream.readUTF().split(":", 2); 502 if (tokens.length == 2) { 503 keys.add(tokens[0].trim()); 504 values.add(tokens[1].trim()); 505 } 506 } 507 } catch (EOFException e) { 508 // Ignore. This is expected. 509 } 510 511 // Verify that a networkHistory.txt entry was written correctly for the network 512 // configuration. 513 assertTrue(keys.size() >= 3); 514 assertEquals(WifiNetworkHistory.CONFIG_KEY, keys.get(0)); 515 assertEquals(CONFIGS.get(network).configKey(), values.get(0)); 516 final int creatorUidIndex = keys.indexOf(WifiNetworkHistory.CREATOR_UID_KEY); 517 assertTrue(creatorUidIndex != -1); 518 assertEquals(Integer.toString(CONFIGS.get(network).creatorUid), 519 values.get(creatorUidIndex)); 520 final int sharedIndex = keys.indexOf(WifiNetworkHistory.SHARED_KEY); 521 assertTrue(sharedIndex != -1); 522 assertEquals(Boolean.toString(CONFIGS.get(network).shared), values.get(sharedIndex)); 523 524 // Verify that no networkHistory.txt entries were written for any other network 525 // configurations. 526 final int lastConfigIndex = keys.lastIndexOf(WifiNetworkHistory.CONFIG_KEY); 527 assertEquals(0, lastConfigIndex); 528 } 529 530 /** 531 * Verifies that saveNetwork() correctly stores a regular network configuration. 532 */ 533 @Test testSaveNetworkRegular()534 public void testSaveNetworkRegular() throws Exception { 535 verifySaveNetwork(0); 536 } 537 538 /** 539 * Verifies that saveNetwork() correctly stores a HotSpot 2.0 network configuration. 540 */ 541 @Test testSaveNetworkHotspot20()542 public void testSaveNetworkHotspot20() throws Exception { 543 verifySaveNetwork(1); 544 } 545 546 /** 547 * Verifies that saveNetwork() correctly stores a private network configuration. 548 */ 549 @Test testSaveNetworkPrivate()550 public void testSaveNetworkPrivate() throws Exception { 551 verifySaveNetwork(2); 552 } 553 554 /** 555 * Verifies that loadConfiguredNetworks() correctly reads data from the wpa_supplicant, the 556 * networkHistory.txt file and the MOManager, correlating the three sources based on the 557 * configKey and the FQDN for HotSpot 2.0 networks. 558 * TODO: Test all variables. Currently, only the following variables are tested: 559 * - In the wpa_supplicant: "ssid", "id_str" 560 * - In networkHistory.txt: "CONFIG", "CREATOR_UID_KEY", "SHARED" 561 */ 562 @Test testLoadConfiguredNetworks()563 public void testLoadConfiguredNetworks() throws Exception { 564 // Set up list of network configurations returned by wpa_supplicant. 565 final String header = "network id / ssid / bssid / flags"; 566 String networks = header; 567 for (WifiConfiguration config : CONFIGS) { 568 networks += "\n" + Integer.toString(config.networkId) + "\t" + config.SSID + "\tany"; 569 } 570 when(mWifiNative.listNetworks(anyInt())).thenReturn(header); 571 when(mWifiNative.listNetworks(-1)).thenReturn(networks); 572 573 // Set up variables returned by wpa_supplicant for the individual network configurations. 574 for (int i = 0; i < CONFIGS.size(); ++i) { 575 when(mWifiNative.getNetworkVariable(i, WifiConfiguration.ssidVarName)) 576 .thenReturn(encodeConfigSSID(CONFIGS.get(i))); 577 } 578 // Legacy regular network configuration: No "id_str". 579 when(mWifiNative.getNetworkExtra(0, WifiConfigStore.ID_STRING_VAR_NAME)) 580 .thenReturn(null); 581 // Legacy Hotspot 2.0 network configuration: Quoted FQDN in "id_str". 582 when(mWifiNative.getNetworkExtra(1, WifiConfigStore.ID_STRING_VAR_NAME)) 583 .thenReturn(null); 584 when(mWifiNative.getNetworkVariable(1, WifiConfigStore.ID_STRING_VAR_NAME)) 585 .thenReturn('"' + CONFIGS.get(1).FQDN + '"'); 586 // Up-to-date Hotspot 2.0 network configuration: Metadata in "id_str". 587 Map<String, String> metadata = new HashMap<String, String>(); 588 metadata.put(WifiConfigStore.ID_STRING_KEY_CONFIG_KEY, CONFIGS.get(2).configKey()); 589 metadata.put(WifiConfigStore.ID_STRING_KEY_CREATOR_UID, 590 Integer.toString(CONFIGS.get(2).creatorUid)); 591 metadata.put(WifiConfigStore.ID_STRING_KEY_FQDN, CONFIGS.get(2).FQDN); 592 when(mWifiNative.getNetworkExtra(2, WifiConfigStore.ID_STRING_VAR_NAME)) 593 .thenReturn(metadata); 594 // Up-to-date regular network configuration: Metadata in "id_str". 595 metadata = new HashMap<String, String>(); 596 metadata.put(WifiConfigStore.ID_STRING_KEY_CONFIG_KEY, CONFIGS.get(3).configKey()); 597 metadata.put(WifiConfigStore.ID_STRING_KEY_CREATOR_UID, 598 Integer.toString(CONFIGS.get(3).creatorUid)); 599 when(mWifiNative.getNetworkExtra(3, WifiConfigStore.ID_STRING_VAR_NAME)) 600 .thenReturn(metadata); 601 602 // Set up networkHistory.txt file. 603 final File file = File.createTempFile("networkHistory.txt", null); 604 file.deleteOnExit(); 605 606 Field wifiNetworkHistoryConfigFile = 607 WifiNetworkHistory.class.getDeclaredField("NETWORK_HISTORY_CONFIG_FILE"); 608 wifiNetworkHistoryConfigFile.setAccessible(true); 609 wifiNetworkHistoryConfigFile.set(null, file.getAbsolutePath()); 610 611 final DataOutputStream stream = new DataOutputStream(new FileOutputStream(file)); 612 for (WifiConfiguration config : CONFIGS) { 613 stream.writeUTF(WifiNetworkHistory.CONFIG_KEY + ": " + config.configKey() + '\n'); 614 stream.writeUTF(WifiNetworkHistory.CREATOR_UID_KEY + ": " 615 + Integer.toString(config.creatorUid) + '\n'); 616 stream.writeUTF(WifiNetworkHistory.SHARED_KEY + ": " 617 + Boolean.toString(config.shared) + '\n'); 618 } 619 stream.close(); 620 621 // Set up list of home service providers returned by MOManager. 622 final List<HomeSP> homeSPs = new ArrayList<HomeSP>(); 623 for (WifiConfiguration config : CONFIGS) { 624 if (config.FQDN != null) { 625 homeSPs.add(new HomeSP(null, config.FQDN, new HashSet<Long>(), 626 new HashSet<String>(), 627 new HashSet<Long>(), new ArrayList<Long>(), 628 config.providerFriendlyName, null, 629 new Credential(0, 0, null, false, null, null), 630 null, 0, null, null, null, 0)); 631 } 632 } 633 when(mMOManager.loadAllSPs()).thenReturn(homeSPs); 634 635 // Load network configurations. 636 mWifiConfigManager.loadConfiguredNetworks(); 637 638 // Verify that network configurations were loaded and correlated correctly across the three 639 // sources. 640 verifyNetworkConfigs(CONFIGS, mConfiguredNetworks.valuesForAllUsers()); 641 } 642 643 /** 644 * Verifies that loadConfiguredNetworks() correctly handles duplicates when reading network 645 * configurations from the wpa_supplicant: The second configuration overwrites the first. 646 */ 647 @Test testLoadConfiguredNetworksEliminatesDuplicates()648 public void testLoadConfiguredNetworksEliminatesDuplicates() throws Exception { 649 final WifiConfiguration config = new WifiConfiguration(CONFIGS.get(0)); 650 config.networkId = 1; 651 652 // Set up list of network configurations returned by wpa_supplicant. The two configurations 653 // are identical except for their network IDs. 654 final String header = "network id / ssid / bssid / flags"; 655 final String networks = 656 header + "\n0\t" + config.SSID + "\tany\n1\t" + config.SSID + "\tany"; 657 when(mWifiNative.listNetworks(anyInt())).thenReturn(header); 658 when(mWifiNative.listNetworks(-1)).thenReturn(networks); 659 660 // Set up variables returned by wpa_supplicant. 661 when(mWifiNative.getNetworkVariable(anyInt(), eq(WifiConfiguration.ssidVarName))) 662 .thenReturn(encodeConfigSSID(config)); 663 final Map<String, String> metadata = new HashMap<String, String>(); 664 metadata.put(WifiConfigStore.ID_STRING_KEY_CONFIG_KEY, config.configKey()); 665 metadata.put(WifiConfigStore.ID_STRING_KEY_CREATOR_UID, 666 Integer.toString(config.creatorUid)); 667 when(mWifiNative.getNetworkExtra(anyInt(), eq(WifiConfigStore.ID_STRING_VAR_NAME))) 668 .thenReturn(metadata); 669 670 // Load network configurations. 671 mWifiConfigManager.loadConfiguredNetworks(); 672 673 // Verify that the second network configuration (network ID 1) overwrote the first (network 674 // ID 0). 675 verifyNetworkConfigs(Arrays.asList(config), mConfiguredNetworks.valuesForAllUsers()); 676 } 677 678 /** 679 * Verifies that handleUserSwitch() removes ephemeral network configurations, disables network 680 * configurations that should no longer be visible and enables network configurations that 681 * should become visible. 682 */ verifyHandleUserSwitch(int oldUserId, int newUserId, boolean makeOneConfigEphemeral)683 private void verifyHandleUserSwitch(int oldUserId, int newUserId, 684 boolean makeOneConfigEphemeral) throws Exception { 685 addNetworks(); 686 switchUser(oldUserId); 687 688 reset(mWifiNative); 689 final Field lastSelectedConfigurationField = 690 WifiConfigManager.class.getDeclaredField("mLastSelectedConfiguration"); 691 lastSelectedConfigurationField.setAccessible(true); 692 WifiConfiguration removedEphemeralConfig = null; 693 final Set<WifiConfiguration> oldUserOnlyConfigs = new HashSet<>(); 694 final Set<WifiConfiguration> newUserOnlyConfigs = new HashSet<>(); 695 final Set<WifiConfiguration> neitherUserConfigs = new HashSet<>(); 696 final Collection<WifiConfiguration> oldConfigs = mConfiguredNetworks.valuesForAllUsers(); 697 int expectedNumberOfConfigs = oldConfigs.size(); 698 for (WifiConfiguration config : oldConfigs) { 699 if (WifiConfigurationUtil.isVisibleToAnyProfile(config, USER_PROFILES.get(oldUserId))) { 700 config.status = WifiConfiguration.Status.ENABLED; 701 if (WifiConfigurationUtil.isVisibleToAnyProfile(config, 702 USER_PROFILES.get(newUserId))) { 703 if (makeOneConfigEphemeral && removedEphemeralConfig == null) { 704 config.ephemeral = true; 705 lastSelectedConfigurationField.set(mWifiConfigManager, config.configKey()); 706 removedEphemeralConfig = config; 707 } 708 } else { 709 oldUserOnlyConfigs.add(config); 710 } 711 } else { 712 config.status = WifiConfiguration.Status.DISABLED; 713 if (WifiConfigurationUtil.isVisibleToAnyProfile(config, 714 USER_PROFILES.get(newUserId))) { 715 newUserOnlyConfigs.add(config); 716 } else { 717 neitherUserConfigs.add(config); 718 } 719 } 720 } 721 722 when(mWifiNative.disableNetwork(anyInt())).thenReturn(true); 723 when(mWifiNative.removeNetwork(anyInt())).thenReturn(true); 724 725 switchUser(newUserId); 726 if (makeOneConfigEphemeral) { 727 // Verify that the ephemeral network configuration was removed. 728 assertNotNull(removedEphemeralConfig); 729 assertNull(mConfiguredNetworks.getForAllUsers(removedEphemeralConfig.networkId)); 730 assertNull(lastSelectedConfigurationField.get(mWifiConfigManager)); 731 verify(mWifiNative).removeNetwork(removedEphemeralConfig.networkId); 732 --expectedNumberOfConfigs; 733 } else { 734 assertNull(removedEphemeralConfig); 735 } 736 737 // Verify that the other network configurations were revealed/hidden and enabled/disabled as 738 // appropriate. 739 final Collection<WifiConfiguration> newConfigs = mConfiguredNetworks.valuesForAllUsers(); 740 assertEquals(expectedNumberOfConfigs, newConfigs.size()); 741 for (WifiConfiguration config : newConfigs) { 742 if (oldUserOnlyConfigs.contains(config)) { 743 verify(mWifiNative).disableNetwork(config.networkId); 744 assertEquals(WifiConfiguration.Status.DISABLED, config.status); 745 } else { 746 verify(mWifiNative, never()).disableNetwork(config.networkId); 747 if (neitherUserConfigs.contains(config)) { 748 assertEquals(WifiConfiguration.Status.DISABLED, config.status); 749 } else { 750 // Only enabled in networkSelection. 751 assertTrue(config.getNetworkSelectionStatus().isNetworkEnabled()); 752 } 753 754 } 755 } 756 } 757 758 /** 759 * Verifies that handleUserSwitch() behaves correctly when the user switch removes an ephemeral 760 * network configuration and reveals a private network configuration. 761 */ 762 @Test testHandleUserSwitchWithEphemeral()763 public void testHandleUserSwitchWithEphemeral() throws Exception { 764 verifyHandleUserSwitch(USER_IDS[2], USER_IDS[0], true); 765 } 766 767 /** 768 * Verifies that handleUserSwitch() behaves correctly when the user switch hides a private 769 * network configuration. 770 */ 771 @Test testHandleUserSwitchWithoutEphemeral()772 public void testHandleUserSwitchWithoutEphemeral() throws Exception { 773 verifyHandleUserSwitch(USER_IDS[0], USER_IDS[2], false); 774 } 775 776 @Test testSaveLoadEapNetworks()777 public void testSaveLoadEapNetworks() { 778 testSaveLoadSingleEapNetwork("eap network", new EnterpriseConfig(Eap.TTLS) 779 .setPhase2(Phase2.MSCHAPV2) 780 .setIdentity("username", "password") 781 .setCaCerts(new X509Certificate[] {FakeKeys.CA_CERT0})); 782 testSaveLoadSingleEapNetwork("eap network", new EnterpriseConfig(Eap.TTLS) 783 .setPhase2(Phase2.MSCHAPV2) 784 .setIdentity("username", "password") 785 .setCaCerts(new X509Certificate[] {FakeKeys.CA_CERT1, FakeKeys.CA_CERT0})); 786 787 } 788 testSaveLoadSingleEapNetwork(String ssid, EnterpriseConfig eapConfig)789 private void testSaveLoadSingleEapNetwork(String ssid, EnterpriseConfig eapConfig) { 790 final HashMap<String, String> networkVariables = new HashMap<String, String>(); 791 reset(mWifiNative); 792 when(mWifiNative.addNetwork()).thenReturn(0); 793 when(mWifiNative.setNetworkVariable(anyInt(), anyString(), anyString())).thenAnswer( 794 new AnswerWithArguments() { 795 public boolean answer(int netId, String name, String value) { 796 // Verify that no wpa_supplicant variables were written for any other 797 // network configurations. 798 assertEquals(netId, 0); 799 networkVariables.put(name, value); 800 return true; 801 } 802 }); 803 when(mWifiNative.getNetworkVariable(anyInt(), anyString())).then( 804 new AnswerWithArguments() { 805 public String answer(int netId, String name) { 806 // Verify that no wpa_supplicant variables were read for any other 807 // network configurations. 808 assertEquals(netId, 0); 809 return networkVariables.get(name); 810 } 811 }); 812 when(mWifiNative.setNetworkExtra(eq(0), anyString(), (Map<String, String>) anyObject())) 813 .thenReturn(true); 814 815 WifiConfiguration config = new WifiConfiguration(); 816 config.SSID = ssid; 817 config.creatorUid = Process.WIFI_UID; 818 config.allowedKeyManagement.set(KeyMgmt.WPA_EAP); 819 config.enterpriseConfig = eapConfig.enterpriseConfig; 820 821 // Store a network configuration. 822 mWifiConfigManager.saveNetwork(config, Process.WIFI_UID); 823 824 // Verify that wpa_supplicant variables were written correctly for the network 825 // configuration. 826 verify(mWifiNative).addNetwork(); 827 assertEquals(eapConfig.eap, 828 unquote(networkVariables.get(WifiEnterpriseConfig.EAP_KEY))); 829 assertEquals(eapConfig.phase2, 830 unquote(networkVariables.get(WifiEnterpriseConfig.PHASE2_KEY))); 831 assertEquals(eapConfig.identity, 832 unquote(networkVariables.get(WifiEnterpriseConfig.IDENTITY_KEY))); 833 assertEquals(eapConfig.password, 834 unquote(networkVariables.get(WifiEnterpriseConfig.PASSWORD_KEY))); 835 assertSavedCaCerts(eapConfig, 836 unquote(networkVariables.get(WifiEnterpriseConfig.CA_CERT_KEY))); 837 838 // Prepare the scan result. 839 final String header = "network id / ssid / bssid / flags"; 840 String networks = header + "\n" + Integer.toString(0) + "\t" + ssid + "\tany"; 841 when(mWifiNative.listNetworks(anyInt())).thenReturn(header); 842 when(mWifiNative.listNetworks(-1)).thenReturn(networks); 843 844 // Load back the configuration. 845 mWifiConfigManager.loadConfiguredNetworks(); 846 List<WifiConfiguration> configs = mWifiConfigManager.getSavedNetworks(); 847 assertEquals(1, configs.size()); 848 WifiConfiguration loadedConfig = configs.get(0); 849 assertEquals(ssid, unquote(loadedConfig.SSID)); 850 BitSet keyMgmt = new BitSet(); 851 keyMgmt.set(KeyMgmt.WPA_EAP); 852 assertEquals(keyMgmt, loadedConfig.allowedKeyManagement); 853 assertEquals(eapConfig.enterpriseConfig.getEapMethod(), 854 loadedConfig.enterpriseConfig.getEapMethod()); 855 assertEquals(eapConfig.enterpriseConfig.getPhase2Method(), 856 loadedConfig.enterpriseConfig.getPhase2Method()); 857 assertEquals(eapConfig.enterpriseConfig.getIdentity(), 858 loadedConfig.enterpriseConfig.getIdentity()); 859 assertEquals(eapConfig.enterpriseConfig.getPassword(), 860 loadedConfig.enterpriseConfig.getPassword()); 861 asserCaCertsAliasesMatch(eapConfig.caCerts, 862 loadedConfig.enterpriseConfig.getCaCertificateAliases()); 863 } 864 unquote(String value)865 private String unquote(String value) { 866 if (value == null) { 867 return null; 868 } 869 int length = value.length(); 870 if ((length > 1) && (value.charAt(0) == '"') 871 && (value.charAt(length - 1) == '"')) { 872 return value.substring(1, length - 1); 873 } else { 874 return value; 875 } 876 } 877 asserCaCertsAliasesMatch(X509Certificate[] certs, String[] aliases)878 private void asserCaCertsAliasesMatch(X509Certificate[] certs, String[] aliases) { 879 assertEquals(certs.length, aliases.length); 880 List<String> aliasList = new ArrayList<String>(Arrays.asList(aliases)); 881 try { 882 for (int i = 0; i < certs.length; i++) { 883 byte[] certPem = Credentials.convertToPem(certs[i]); 884 boolean found = false; 885 for (int j = 0; j < aliasList.size(); j++) { 886 byte[] keystoreCert = mMockKeyStore.getKeyBlob(Process.WIFI_UID, 887 Credentials.CA_CERTIFICATE + aliasList.get(j)).blob; 888 if (Arrays.equals(keystoreCert, certPem)) { 889 found = true; 890 aliasList.remove(j); 891 break; 892 } 893 } 894 assertTrue(found); 895 } 896 } catch (CertificateEncodingException | IOException e) { 897 fail("Cannot convert CA certificate to encoded form."); 898 } 899 } 900 assertSavedCaCerts(EnterpriseConfig eapConfig, String caCertVariable)901 private void assertSavedCaCerts(EnterpriseConfig eapConfig, String caCertVariable) { 902 ArrayList<String> aliases = new ArrayList<String>(); 903 if (TextUtils.isEmpty(caCertVariable)) { 904 // Do nothing. 905 } else if (caCertVariable.startsWith(WifiEnterpriseConfig.CA_CERT_PREFIX)) { 906 aliases.add(caCertVariable.substring(WifiEnterpriseConfig.CA_CERT_PREFIX.length())); 907 } else if (caCertVariable.startsWith(WifiEnterpriseConfig.KEYSTORES_URI)) { 908 String[] encodedAliases = TextUtils.split( 909 caCertVariable.substring(WifiEnterpriseConfig.KEYSTORES_URI.length()), 910 WifiEnterpriseConfig.CA_CERT_ALIAS_DELIMITER); 911 for (String encodedAlias : encodedAliases) { 912 String alias = WifiEnterpriseConfig.decodeCaCertificateAlias(encodedAlias); 913 assertTrue(alias.startsWith(Credentials.CA_CERTIFICATE)); 914 aliases.add(alias.substring(Credentials.CA_CERTIFICATE.length())); 915 } 916 } else { 917 fail("Unrecognized ca_cert variable: " + caCertVariable); 918 } 919 asserCaCertsAliasesMatch(eapConfig.caCerts, aliases.toArray(new String[aliases.size()])); 920 } 921 922 private static class EnterpriseConfig { 923 public String eap; 924 public String phase2; 925 public String identity; 926 public String password; 927 public X509Certificate[] caCerts; 928 public WifiEnterpriseConfig enterpriseConfig; 929 EnterpriseConfig(int eapMethod)930 public EnterpriseConfig(int eapMethod) { 931 enterpriseConfig = new WifiEnterpriseConfig(); 932 enterpriseConfig.setEapMethod(eapMethod); 933 eap = Eap.strings[eapMethod]; 934 } setPhase2(int phase2Method)935 public EnterpriseConfig setPhase2(int phase2Method) { 936 enterpriseConfig.setPhase2Method(phase2Method); 937 phase2 = "auth=" + Phase2.strings[phase2Method]; 938 return this; 939 } setIdentity(String identity, String password)940 public EnterpriseConfig setIdentity(String identity, String password) { 941 enterpriseConfig.setIdentity(identity); 942 enterpriseConfig.setPassword(password); 943 this.identity = identity; 944 this.password = password; 945 return this; 946 } setCaCerts(X509Certificate[] certs)947 public EnterpriseConfig setCaCerts(X509Certificate[] certs) { 948 enterpriseConfig.setCaCertificates(certs); 949 caCerts = certs; 950 return this; 951 } 952 } 953 954 /** 955 * Generates an array of unique random numbers below the specified maxValue. 956 * Values range from 0 to maxValue-1. 957 */ getUniqueRandomNumberValues( int seed, int maxValue, int numValues)958 private static ArrayDeque<Integer> getUniqueRandomNumberValues( 959 int seed, 960 int maxValue, 961 int numValues) { 962 assertTrue(numValues <= maxValue); 963 Random rand = new Random(WifiTestUtil.getTestMethod().hashCode() + seed); 964 ArrayDeque<Integer> randomNumberList = new ArrayDeque<>(); 965 for (int i = 0; i < numValues; i++) { 966 int num = rand.nextInt(maxValue); 967 while (randomNumberList.contains(num)) { 968 num = rand.nextInt(maxValue); 969 } 970 randomNumberList.push(num); 971 } 972 return randomNumberList; 973 } 974 975 /** 976 * Verifies that the networks in pnoNetworkList is sorted in the same order as the 977 * network in expectedNetworkIDOrder list. 978 */ verifyPnoNetworkListOrder( ArrayList<WifiScanner.PnoSettings.PnoNetwork> pnoNetworkList, ArrayList<Integer> expectedNetworkIdOrder)979 private static void verifyPnoNetworkListOrder( 980 ArrayList<WifiScanner.PnoSettings.PnoNetwork> pnoNetworkList, 981 ArrayList<Integer> expectedNetworkIdOrder) throws Exception { 982 int i = 0; 983 for (WifiScanner.PnoSettings.PnoNetwork pnoNetwork : pnoNetworkList) { 984 Log.i(TAG, "PNO Network List Index: " + i + ", networkID: " + pnoNetwork.networkId); 985 assertEquals("Expected network ID: " + pnoNetwork.networkId, 986 pnoNetwork.networkId, expectedNetworkIdOrder.get(i++).intValue()); 987 } 988 } 989 990 /** 991 * Verifies the retrieveDisconnectedPnoNetworkList API. The test verifies that the list 992 * returned from the API is sorted as expected. 993 */ 994 @Test testDisconnectedPnoNetworkListCreation()995 public void testDisconnectedPnoNetworkListCreation() throws Exception { 996 addNetworks(); 997 998 Random rand = new Random(WifiTestUtil.getTestMethod().hashCode()); 999 1000 // First assign random |numAssociation| values and verify that the list is sorted 1001 // in descending order of |numAssociation| values. Keep NetworkSelectionStatus 1002 // values constant. 1003 for (int userId : USER_IDS) { 1004 switchUser(userId); 1005 TreeMap<Integer, Integer> numAssociationToNetworkIdMap = 1006 new TreeMap<>(Collections.reverseOrder()); 1007 ArrayDeque<Integer> numAssociationValues = 1008 getUniqueRandomNumberValues( 1009 1, 10000, mConfiguredNetworks.valuesForCurrentUser().size()); 1010 for (WifiConfiguration config : mConfiguredNetworks.valuesForCurrentUser()) { 1011 config.numAssociation = numAssociationValues.pop(); 1012 config.priority = rand.nextInt(10000); 1013 config.getNetworkSelectionStatus().setNetworkSelectionStatus( 1014 WifiConfiguration.NetworkSelectionStatus.NETWORK_SELECTION_ENABLED); 1015 numAssociationToNetworkIdMap.put(config.numAssociation, config.networkId); 1016 Log.i(TAG, "networkID: " + config.networkId + ", numAssociation: " 1017 + config.numAssociation); 1018 } 1019 ArrayList<WifiScanner.PnoSettings.PnoNetwork> pnoNetworkList = 1020 mWifiConfigManager.retrieveDisconnectedPnoNetworkList(); 1021 verifyPnoNetworkListOrder(pnoNetworkList, 1022 new ArrayList(numAssociationToNetworkIdMap.values())); 1023 } 1024 1025 // Assign random |priority| values and verify that the list is sorted in descending order 1026 // of |priority| values. Keep numAssociation/NetworkSelectionStatus values constant. 1027 for (int userId : USER_IDS) { 1028 switchUser(userId); 1029 TreeMap<Integer, Integer> priorityToNetworkIdMap = 1030 new TreeMap<>(Collections.reverseOrder()); 1031 ArrayDeque<Integer> priorityValues = 1032 getUniqueRandomNumberValues( 1033 2, 10000, mConfiguredNetworks.valuesForCurrentUser().size()); 1034 for (WifiConfiguration config : mConfiguredNetworks.valuesForCurrentUser()) { 1035 config.numAssociation = 0; 1036 config.priority = priorityValues.pop(); 1037 config.getNetworkSelectionStatus().setNetworkSelectionStatus( 1038 WifiConfiguration.NetworkSelectionStatus.NETWORK_SELECTION_ENABLED); 1039 priorityToNetworkIdMap.put(config.priority, config.networkId); 1040 Log.i(TAG, "networkID: " + config.networkId + ", priority: " + config.priority); 1041 } 1042 ArrayList<WifiScanner.PnoSettings.PnoNetwork> pnoNetworkList = 1043 mWifiConfigManager.retrieveDisconnectedPnoNetworkList(); 1044 verifyPnoNetworkListOrder(pnoNetworkList, 1045 new ArrayList(priorityToNetworkIdMap.values())); 1046 } 1047 1048 // Now assign random |NetworkSelectionStatus| values and verify that the list is sorted in 1049 // ascending order of |NetworkSelectionStatus| values. 1050 for (int userId : USER_IDS) { 1051 switchUser(userId); 1052 TreeMap<Integer, Integer> networkSelectionStatusToNetworkIdMap = new TreeMap<>(); 1053 ArrayDeque<Integer> networkSelectionStatusValues = 1054 getUniqueRandomNumberValues( 1055 3, 1056 WifiConfiguration.NetworkSelectionStatus.NETWORK_SELECTION_STATUS_MAX, 1057 mConfiguredNetworks.valuesForCurrentUser().size()); 1058 for (WifiConfiguration config : mConfiguredNetworks.valuesForCurrentUser()) { 1059 config.numAssociation = rand.nextInt(10000); 1060 config.priority = rand.nextInt(10000); 1061 config.getNetworkSelectionStatus().setNetworkSelectionStatus( 1062 networkSelectionStatusValues.pop()); 1063 networkSelectionStatusToNetworkIdMap.put( 1064 config.getNetworkSelectionStatus().getNetworkSelectionStatus(), 1065 config.networkId); 1066 Log.i(TAG, "networkID: " + config.networkId + ", NetworkSelectionStatus: " 1067 + config.getNetworkSelectionStatus().getNetworkSelectionStatus()); 1068 } 1069 ArrayList<WifiScanner.PnoSettings.PnoNetwork> pnoNetworkList = 1070 mWifiConfigManager.retrieveDisconnectedPnoNetworkList(); 1071 verifyPnoNetworkListOrder(pnoNetworkList, 1072 new ArrayList(networkSelectionStatusToNetworkIdMap.values())); 1073 } 1074 } 1075 1076 /** 1077 * Verifies the retrieveConnectedPnoNetworkList API. The test verifies that the list 1078 * returned from the API is sorted as expected. 1079 */ 1080 @Test testConnectedPnoNetworkListCreation()1081 public void testConnectedPnoNetworkListCreation() throws Exception { 1082 addNetworks(); 1083 1084 Random rand = new Random(WifiTestUtil.getTestMethod().hashCode()); 1085 1086 // First assign |lastSeen| values and verify that the list is sorted 1087 // in descending order of |lastSeen| values. Keep NetworkSelectionStatus 1088 // values constant. 1089 for (int userId : USER_IDS) { 1090 switchUser(userId); 1091 TreeMap<Boolean, Integer> lastSeenToNetworkIdMap = 1092 new TreeMap<>(Collections.reverseOrder()); 1093 ArrayDeque<Integer> lastSeenValues = getUniqueRandomNumberValues(1, 2, 2); 1094 if (mConfiguredNetworks.valuesForCurrentUser().size() > 2) continue; 1095 for (WifiConfiguration config : mConfiguredNetworks.valuesForCurrentUser()) { 1096 config.numAssociation = rand.nextInt(10000); 1097 config.priority = rand.nextInt(10000); 1098 config.getNetworkSelectionStatus().setNetworkSelectionStatus( 1099 WifiConfiguration.NetworkSelectionStatus.NETWORK_SELECTION_ENABLED); 1100 boolean lastSeenValue = (lastSeenValues.pop() == 1); 1101 config.getNetworkSelectionStatus().setSeenInLastQualifiedNetworkSelection( 1102 lastSeenValue); 1103 lastSeenToNetworkIdMap.put(lastSeenValue, config.networkId); 1104 Log.i(TAG, "networkID: " + config.networkId + ", lastSeen: " + lastSeenValue); 1105 } 1106 ArrayList<WifiScanner.PnoSettings.PnoNetwork> pnoNetworkList = 1107 mWifiConfigManager.retrieveConnectedPnoNetworkList(); 1108 verifyPnoNetworkListOrder(pnoNetworkList, 1109 new ArrayList(lastSeenToNetworkIdMap.values())); 1110 } 1111 1112 // Assign random |numAssociation| values and verify that the list is sorted 1113 // in descending order of |numAssociation| values. Keep NetworkSelectionStatus/lastSeen 1114 // values constant. 1115 for (int userId : USER_IDS) { 1116 switchUser(userId); 1117 TreeMap<Integer, Integer> numAssociationToNetworkIdMap = 1118 new TreeMap<>(Collections.reverseOrder()); 1119 ArrayDeque<Integer> numAssociationValues = 1120 getUniqueRandomNumberValues( 1121 1, 10000, mConfiguredNetworks.valuesForCurrentUser().size()); 1122 for (WifiConfiguration config : mConfiguredNetworks.valuesForCurrentUser()) { 1123 config.numAssociation = numAssociationValues.pop(); 1124 config.priority = rand.nextInt(10000); 1125 config.getNetworkSelectionStatus().setNetworkSelectionStatus( 1126 WifiConfiguration.NetworkSelectionStatus.NETWORK_SELECTION_ENABLED); 1127 config.getNetworkSelectionStatus().setSeenInLastQualifiedNetworkSelection(true); 1128 numAssociationToNetworkIdMap.put(config.numAssociation, config.networkId); 1129 Log.i(TAG, "networkID: " + config.networkId + ", numAssociation: " 1130 + config.numAssociation); 1131 } 1132 ArrayList<WifiScanner.PnoSettings.PnoNetwork> pnoNetworkList = 1133 mWifiConfigManager.retrieveConnectedPnoNetworkList(); 1134 verifyPnoNetworkListOrder(pnoNetworkList, 1135 new ArrayList(numAssociationToNetworkIdMap.values())); 1136 } 1137 1138 // Now assign random |NetworkSelectionStatus| values and verify that the list is sorted in 1139 // ascending order of |NetworkSelectionStatus| values. 1140 for (int userId : USER_IDS) { 1141 switchUser(userId); 1142 TreeMap<Integer, Integer> networkSelectionStatusToNetworkIdMap = new TreeMap<>(); 1143 ArrayDeque<Integer> networkSelectionStatusValues = 1144 getUniqueRandomNumberValues( 1145 3, 1146 WifiConfiguration.NetworkSelectionStatus.NETWORK_SELECTION_STATUS_MAX, 1147 mConfiguredNetworks.valuesForCurrentUser().size()); 1148 for (WifiConfiguration config : mConfiguredNetworks.valuesForCurrentUser()) { 1149 config.numAssociation = rand.nextInt(10000); 1150 config.priority = rand.nextInt(10000); 1151 config.getNetworkSelectionStatus().setNetworkSelectionStatus( 1152 networkSelectionStatusValues.pop()); 1153 networkSelectionStatusToNetworkIdMap.put( 1154 config.getNetworkSelectionStatus().getNetworkSelectionStatus(), 1155 config.networkId); 1156 Log.i(TAG, "networkID: " + config.networkId + ", NetworkSelectionStatus: " 1157 + config.getNetworkSelectionStatus().getNetworkSelectionStatus()); 1158 } 1159 ArrayList<WifiScanner.PnoSettings.PnoNetwork> pnoNetworkList = 1160 mWifiConfigManager.retrieveConnectedPnoNetworkList(); 1161 verifyPnoNetworkListOrder(pnoNetworkList, 1162 new ArrayList(networkSelectionStatusToNetworkIdMap.values())); 1163 } 1164 } 1165 1166 /** 1167 * Verifies that hasEverConnected is false for a newly added network 1168 */ 1169 @Test testAddNetworkHasEverConnectedFalse()1170 public void testAddNetworkHasEverConnectedFalse() throws Exception { 1171 addNetwork(BASE_HAS_EVER_CONNECTED_CONFIG); 1172 WifiConfiguration checkConfig = mWifiConfigManager.getWifiConfiguration( 1173 BASE_HAS_EVER_CONNECTED_CONFIG.networkId); 1174 assertFalse("Adding a new network should not have hasEverConnected set to true.", 1175 checkConfig.getNetworkSelectionStatus().getHasEverConnected()); 1176 } 1177 1178 1179 /** 1180 * Verifies that hasEverConnected is false for a newly added network even when new config has 1181 * mistakenly set HasEverConnected to true. 1182 */ 1183 @Test testAddNetworkOverridesHasEverConnectedWhenTrueInNewConfig()1184 public void testAddNetworkOverridesHasEverConnectedWhenTrueInNewConfig() throws Exception { 1185 WifiConfiguration newNetworkWithHasEverConnectedTrue = 1186 new WifiConfiguration(BASE_HAS_EVER_CONNECTED_CONFIG); 1187 newNetworkWithHasEverConnectedTrue.getNetworkSelectionStatus().setHasEverConnected(true); 1188 addNetwork(newNetworkWithHasEverConnectedTrue); 1189 // check if addNetwork clears the bit. 1190 WifiConfiguration checkConfig = mWifiConfigManager.getWifiConfiguration( 1191 newNetworkWithHasEverConnectedTrue.networkId); 1192 assertFalse("Adding a new network should not have hasEverConnected set to true.", 1193 checkConfig.getNetworkSelectionStatus().getHasEverConnected()); 1194 } 1195 1196 1197 /** 1198 * Verify that setting HasEverConnected with a config update can be read back. 1199 */ 1200 @Test testUpdateConfigToHasEverConnectedTrue()1201 public void testUpdateConfigToHasEverConnectedTrue() throws Exception { 1202 addNetwork(BASE_HAS_EVER_CONNECTED_CONFIG); 1203 1204 // Get the newly saved config and update HasEverConnected 1205 WifiConfiguration checkConfig = mWifiConfigManager.getWifiConfiguration( 1206 BASE_HAS_EVER_CONNECTED_CONFIG.networkId); 1207 assertFalse("Adding a new network should not have hasEverConnected set to true.", 1208 checkConfig.getNetworkSelectionStatus().getHasEverConnected()); 1209 checkConfig.getNetworkSelectionStatus().setHasEverConnected(true); 1210 mWifiConfigManager.addOrUpdateNetwork(checkConfig, HAS_EVER_CONNECTED_USER); 1211 1212 // verify that HasEverConnected was properly written and read back 1213 checkHasEverConnectedTrue(BASE_HAS_EVER_CONNECTED_CONFIG.networkId); 1214 } 1215 1216 1217 /** 1218 * Verifies that hasEverConnected is cleared when a network config preSharedKey is updated. 1219 */ 1220 @Test testUpdatePreSharedKeyClearsHasEverConnected()1221 public void testUpdatePreSharedKeyClearsHasEverConnected() throws Exception { 1222 final int originalUserId = mWifiConfigManager.getCurrentUserId(); 1223 1224 testUpdateConfigToHasEverConnectedTrue(); 1225 1226 WifiConfiguration original = mWifiConfigManager.getWifiConfiguration( 1227 BASE_HAS_EVER_CONNECTED_CONFIG.networkId); 1228 1229 WifiConfiguration updatePreSharedKeyConfig = new WifiConfiguration(); 1230 updatePreSharedKeyConfig.networkId = BASE_HAS_EVER_CONNECTED_CONFIG.networkId; 1231 updatePreSharedKeyConfig.SSID = original.SSID; 1232 updatePreSharedKeyConfig.preSharedKey = "newpassword"; 1233 switchUserToCreatorOrParentOf(original); 1234 mWifiConfigManager.addOrUpdateNetwork(updatePreSharedKeyConfig, 1235 BASE_HAS_EVER_CONNECTED_CONFIG.networkId); 1236 1237 checkHasEverConnectedFalse(BASE_HAS_EVER_CONNECTED_CONFIG.networkId); 1238 switchUser(originalUserId); 1239 } 1240 1241 /** 1242 * Verifies that hasEverConnected is cleared when a network config allowedKeyManagement is 1243 * updated. 1244 */ 1245 @Test testUpdateAllowedKeyManagementChanged()1246 public void testUpdateAllowedKeyManagementChanged() throws Exception { 1247 final int originalUserId = mWifiConfigManager.getCurrentUserId(); 1248 1249 testUpdateConfigToHasEverConnectedTrue(); 1250 1251 WifiConfiguration updateAllowedKeyManagementConfig = new WifiConfiguration(); 1252 updateAllowedKeyManagementConfig.networkId = BASE_HAS_EVER_CONNECTED_CONFIG.networkId; 1253 updateAllowedKeyManagementConfig.SSID = BASE_HAS_EVER_CONNECTED_CONFIG.SSID; 1254 updateAllowedKeyManagementConfig.allowedKeyManagement.set(KeyMgmt.WPA_PSK); 1255 1256 // Set up mock to allow the new value to be read back into the config 1257 String allowedKeyManagementString = makeString( 1258 updateAllowedKeyManagementConfig.allowedKeyManagement, 1259 WifiConfiguration.KeyMgmt.strings); 1260 when(mWifiNative.getNetworkVariable(BASE_HAS_EVER_CONNECTED_CONFIG.networkId, 1261 KeyMgmt.varName)).thenReturn(allowedKeyManagementString); 1262 1263 switchUserToCreatorOrParentOf(BASE_HAS_EVER_CONNECTED_CONFIG); 1264 mWifiConfigManager.addOrUpdateNetwork(updateAllowedKeyManagementConfig, 1265 BASE_HAS_EVER_CONNECTED_CONFIG.networkId); 1266 1267 checkHasEverConnectedFalse(BASE_HAS_EVER_CONNECTED_CONFIG.networkId); 1268 switchUser(originalUserId); 1269 } 1270 1271 /** 1272 * Verifies that hasEverConnected is cleared when a network config allowedProtocols is 1273 * updated. 1274 */ 1275 @Test testUpdateAllowedProtocolsChanged()1276 public void testUpdateAllowedProtocolsChanged() throws Exception { 1277 final int originalUserId = mWifiConfigManager.getCurrentUserId(); 1278 1279 testUpdateConfigToHasEverConnectedTrue(); 1280 1281 WifiConfiguration updateAllowedProtocolsConfig = new WifiConfiguration(); 1282 updateAllowedProtocolsConfig.networkId = BASE_HAS_EVER_CONNECTED_CONFIG.networkId; 1283 updateAllowedProtocolsConfig.SSID = BASE_HAS_EVER_CONNECTED_CONFIG.SSID; 1284 updateAllowedProtocolsConfig.allowedProtocols.set( 1285 WifiConfiguration.Protocol.RSN); 1286 1287 // Set up mock to allow the new value to be read back into the config 1288 String allowedProtocolsString = makeString( 1289 updateAllowedProtocolsConfig.allowedProtocols, 1290 WifiConfiguration.Protocol.strings); 1291 when(mWifiNative.getNetworkVariable(BASE_HAS_EVER_CONNECTED_CONFIG.networkId, 1292 Protocol.varName)).thenReturn(allowedProtocolsString); 1293 1294 switchUserToCreatorOrParentOf(BASE_HAS_EVER_CONNECTED_CONFIG); 1295 mWifiConfigManager.addOrUpdateNetwork(updateAllowedProtocolsConfig, 1296 BASE_HAS_EVER_CONNECTED_CONFIG.networkId); 1297 1298 checkHasEverConnectedFalse(BASE_HAS_EVER_CONNECTED_CONFIG.networkId); 1299 switchUser(originalUserId); 1300 } 1301 1302 /** 1303 * Verifies that hasEverConnected is cleared when a network config allowedAuthAlgorithms is 1304 * updated. 1305 */ 1306 @Test testUpdateAllowedAuthAlgorithmsChanged()1307 public void testUpdateAllowedAuthAlgorithmsChanged() throws Exception { 1308 final int originalUserId = mWifiConfigManager.getCurrentUserId(); 1309 1310 testUpdateConfigToHasEverConnectedTrue(); 1311 1312 WifiConfiguration updateAllowedAuthAlgorithmsConfig = new WifiConfiguration(); 1313 updateAllowedAuthAlgorithmsConfig.networkId = BASE_HAS_EVER_CONNECTED_CONFIG.networkId; 1314 updateAllowedAuthAlgorithmsConfig.SSID = BASE_HAS_EVER_CONNECTED_CONFIG.SSID; 1315 updateAllowedAuthAlgorithmsConfig.allowedAuthAlgorithms.set( 1316 WifiConfiguration.AuthAlgorithm.SHARED); 1317 1318 // Set up mock to allow the new value to be read back into the config 1319 String allowedAuthAlgorithmsString = makeString( 1320 updateAllowedAuthAlgorithmsConfig.allowedAuthAlgorithms, 1321 WifiConfiguration.AuthAlgorithm.strings); 1322 when(mWifiNative.getNetworkVariable(BASE_HAS_EVER_CONNECTED_CONFIG.networkId, 1323 AuthAlgorithm.varName)).thenReturn(allowedAuthAlgorithmsString); 1324 1325 switchUserToCreatorOrParentOf(BASE_HAS_EVER_CONNECTED_CONFIG); 1326 mWifiConfigManager.addOrUpdateNetwork(updateAllowedAuthAlgorithmsConfig, 1327 BASE_HAS_EVER_CONNECTED_CONFIG.networkId); 1328 1329 checkHasEverConnectedFalse(BASE_HAS_EVER_CONNECTED_CONFIG.networkId); 1330 switchUser(originalUserId); 1331 } 1332 1333 /** 1334 * Verifies that hasEverConnected is cleared when a network config allowedPairwiseCiphers is 1335 * updated. 1336 */ 1337 @Test testUpdateAllowedPairwiseCiphersChanged()1338 public void testUpdateAllowedPairwiseCiphersChanged() throws Exception { 1339 final int originalUserId = mWifiConfigManager.getCurrentUserId(); 1340 1341 testUpdateConfigToHasEverConnectedTrue(); 1342 1343 WifiConfiguration updateAllowedPairwiseCiphersConfig = new WifiConfiguration(); 1344 updateAllowedPairwiseCiphersConfig.networkId = BASE_HAS_EVER_CONNECTED_CONFIG.networkId; 1345 updateAllowedPairwiseCiphersConfig.SSID = BASE_HAS_EVER_CONNECTED_CONFIG.SSID; 1346 updateAllowedPairwiseCiphersConfig.allowedPairwiseCiphers.set( 1347 WifiConfiguration.PairwiseCipher.CCMP); 1348 1349 // Set up mock to allow the new value to be read back into the config 1350 String allowedPairwiseCiphersString = makeString( 1351 updateAllowedPairwiseCiphersConfig.allowedPairwiseCiphers, 1352 WifiConfiguration.PairwiseCipher.strings); 1353 when(mWifiNative.getNetworkVariable(BASE_HAS_EVER_CONNECTED_CONFIG.networkId, 1354 PairwiseCipher.varName)).thenReturn(allowedPairwiseCiphersString); 1355 1356 switchUserToCreatorOrParentOf(BASE_HAS_EVER_CONNECTED_CONFIG); 1357 mWifiConfigManager.addOrUpdateNetwork(updateAllowedPairwiseCiphersConfig, 1358 BASE_HAS_EVER_CONNECTED_CONFIG.networkId); 1359 1360 checkHasEverConnectedFalse(BASE_HAS_EVER_CONNECTED_CONFIG.networkId); 1361 switchUser(originalUserId); 1362 } 1363 1364 /** 1365 * Verifies that hasEverConnected is cleared when a network config allowedGroupCiphers is 1366 * updated. 1367 */ 1368 @Test testUpdateAllowedGroupCiphersChanged()1369 public void testUpdateAllowedGroupCiphersChanged() throws Exception { 1370 final int originalUserId = mWifiConfigManager.getCurrentUserId(); 1371 1372 testUpdateConfigToHasEverConnectedTrue(); 1373 1374 WifiConfiguration updateAllowedGroupCiphersConfig = new WifiConfiguration(); 1375 updateAllowedGroupCiphersConfig.networkId = BASE_HAS_EVER_CONNECTED_CONFIG.networkId; 1376 updateAllowedGroupCiphersConfig.SSID = BASE_HAS_EVER_CONNECTED_CONFIG.SSID; 1377 updateAllowedGroupCiphersConfig.allowedGroupCiphers.set( 1378 WifiConfiguration.GroupCipher.CCMP); 1379 1380 // Set up mock to allow the new value to be read back into the config 1381 String allowedGroupCiphersString = makeString( 1382 updateAllowedGroupCiphersConfig.allowedGroupCiphers, 1383 WifiConfiguration.GroupCipher.strings); 1384 when(mWifiNative.getNetworkVariable(BASE_HAS_EVER_CONNECTED_CONFIG.networkId, 1385 GroupCipher.varName)).thenReturn(allowedGroupCiphersString); 1386 1387 switchUserToCreatorOrParentOf(BASE_HAS_EVER_CONNECTED_CONFIG); 1388 mWifiConfigManager.addOrUpdateNetwork(updateAllowedGroupCiphersConfig, 1389 BASE_HAS_EVER_CONNECTED_CONFIG.networkId); 1390 1391 checkHasEverConnectedFalse(BASE_HAS_EVER_CONNECTED_CONFIG.networkId); 1392 switchUser(originalUserId); 1393 } 1394 1395 /** 1396 * Verifies that hasEverConnected is cleared when a network config wepKeys is 1397 * updated. 1398 */ 1399 @Test testUpdateWepKeysChanged()1400 public void testUpdateWepKeysChanged() throws Exception { 1401 final int originalUserId = mWifiConfigManager.getCurrentUserId(); 1402 1403 testUpdateConfigToHasEverConnectedTrue(); 1404 1405 String tempKey = "hereisakey"; 1406 WifiConfiguration updateWepKeysConfig = new WifiConfiguration(); 1407 updateWepKeysConfig.networkId = BASE_HAS_EVER_CONNECTED_CONFIG.networkId; 1408 updateWepKeysConfig.SSID = BASE_HAS_EVER_CONNECTED_CONFIG.SSID; 1409 updateWepKeysConfig.wepKeys = new String[] {tempKey}; 1410 1411 // Set up mock to allow the new value to be read back into the config 1412 when(mWifiNative.getNetworkVariable(BASE_HAS_EVER_CONNECTED_CONFIG.networkId, 1413 WifiConfiguration.wepKeyVarNames[0])).thenReturn(tempKey); 1414 1415 switchUserToCreatorOrParentOf(BASE_HAS_EVER_CONNECTED_CONFIG); 1416 mWifiConfigManager.addOrUpdateNetwork(updateWepKeysConfig, 1417 BASE_HAS_EVER_CONNECTED_CONFIG.networkId); 1418 1419 checkHasEverConnectedFalse(BASE_HAS_EVER_CONNECTED_CONFIG.networkId); 1420 switchUser(originalUserId); 1421 } 1422 1423 /** 1424 * Verifies that hasEverConnected is cleared when a network config hiddenSSID is 1425 * updated. 1426 */ 1427 @Test testUpdateHiddenSSIDChanged()1428 public void testUpdateHiddenSSIDChanged() throws Exception { 1429 final int originalUserId = mWifiConfigManager.getCurrentUserId(); 1430 1431 testUpdateConfigToHasEverConnectedTrue(); 1432 1433 WifiConfiguration updateHiddenSSIDConfig = new WifiConfiguration(); 1434 updateHiddenSSIDConfig.networkId = BASE_HAS_EVER_CONNECTED_CONFIG.networkId; 1435 updateHiddenSSIDConfig.SSID = BASE_HAS_EVER_CONNECTED_CONFIG.SSID; 1436 updateHiddenSSIDConfig.hiddenSSID = true; 1437 1438 // Set up mock to allow the new value to be read back into the config 1439 when(mWifiNative.getNetworkVariable(BASE_HAS_EVER_CONNECTED_CONFIG.networkId, 1440 WifiConfiguration.hiddenSSIDVarName)).thenReturn("1"); 1441 1442 switchUserToCreatorOrParentOf(BASE_HAS_EVER_CONNECTED_CONFIG); 1443 mWifiConfigManager.addOrUpdateNetwork(updateHiddenSSIDConfig, 1444 BASE_HAS_EVER_CONNECTED_CONFIG.networkId); 1445 1446 checkHasEverConnectedFalse(BASE_HAS_EVER_CONNECTED_CONFIG.networkId); 1447 switchUser(originalUserId); 1448 } 1449 1450 /** 1451 * Verifies that hasEverConnected is cleared when a network config pmfVarName is 1452 * updated. 1453 */ 1454 @Test testUpdateRequirePMFChanged()1455 public void testUpdateRequirePMFChanged() throws Exception { 1456 final int originalUserId = mWifiConfigManager.getCurrentUserId(); 1457 1458 testUpdateConfigToHasEverConnectedTrue(); 1459 1460 WifiConfiguration updateRequirePMFConfig = new WifiConfiguration(); 1461 updateRequirePMFConfig.networkId = BASE_HAS_EVER_CONNECTED_CONFIG.networkId; 1462 updateRequirePMFConfig.SSID = BASE_HAS_EVER_CONNECTED_CONFIG.SSID; 1463 updateRequirePMFConfig.requirePMF = true; 1464 1465 // Set up mock to allow the new value to be read back into the config 1466 // TODO: please see b/28088226 - this test is implemented as if WifiConfigStore correctly 1467 // read back the boolean value. When fixed, uncomment the following line and the 1468 // checkHasEverConnectedFalse below. 1469 //when(mWifiNative.getNetworkVariable(BASE_HAS_EVER_CONNECTED_CONFIG.networkId, 1470 // WifiConfiguration.pmfVarName)).thenReturn("2"); 1471 1472 switchUserToCreatorOrParentOf(BASE_HAS_EVER_CONNECTED_CONFIG); 1473 mWifiConfigManager.addOrUpdateNetwork(updateRequirePMFConfig, 1474 BASE_HAS_EVER_CONNECTED_CONFIG.networkId); 1475 1476 //checkHasEverConnectedFalse(BASE_HAS_EVER_CONNECTED_CONFIG.networkId); 1477 checkHasEverConnectedTrue(BASE_HAS_EVER_CONNECTED_CONFIG.networkId); 1478 switchUser(originalUserId); 1479 } 1480 1481 /** 1482 * Verify WifiEnterpriseConfig changes are detected in WifiConfigManager. 1483 */ 1484 @Test testEnterpriseConfigAdded()1485 public void testEnterpriseConfigAdded() { 1486 EnterpriseConfig eapConfig = new EnterpriseConfig(Eap.TTLS) 1487 .setPhase2(Phase2.MSCHAPV2) 1488 .setIdentity("username", "password") 1489 .setCaCerts(new X509Certificate[] {FakeKeys.CA_CERT0}); 1490 1491 assertTrue(mWifiConfigManager.wasEnterpriseConfigChange(null, eapConfig.enterpriseConfig)); 1492 } 1493 1494 /** 1495 * Verify WifiEnterpriseConfig eap change is detected. 1496 */ 1497 @Test testEnterpriseConfigEapChangeDetected()1498 public void testEnterpriseConfigEapChangeDetected() { 1499 EnterpriseConfig eapConfig = new EnterpriseConfig(Eap.TTLS); 1500 EnterpriseConfig peapConfig = new EnterpriseConfig(Eap.PEAP); 1501 1502 assertTrue(mWifiConfigManager.wasEnterpriseConfigChange(eapConfig.enterpriseConfig, 1503 peapConfig.enterpriseConfig)); 1504 } 1505 1506 /** 1507 * Verify WifiEnterpriseConfig phase2 method change is detected. 1508 */ 1509 @Test testEnterpriseConfigPhase2ChangeDetected()1510 public void testEnterpriseConfigPhase2ChangeDetected() { 1511 EnterpriseConfig eapConfig = new EnterpriseConfig(Eap.TTLS).setPhase2(Phase2.MSCHAPV2); 1512 EnterpriseConfig papConfig = new EnterpriseConfig(Eap.TTLS).setPhase2(Phase2.PAP); 1513 1514 assertTrue(mWifiConfigManager.wasEnterpriseConfigChange(eapConfig.enterpriseConfig, 1515 papConfig.enterpriseConfig)); 1516 } 1517 1518 /** 1519 * Verify WifiEnterpriseConfig added Certificate is detected. 1520 */ 1521 @Test testCaCertificateAddedDetected()1522 public void testCaCertificateAddedDetected() { 1523 EnterpriseConfig eapConfigNoCerts = new EnterpriseConfig(Eap.TTLS) 1524 .setPhase2(Phase2.MSCHAPV2) 1525 .setIdentity("username", "password"); 1526 1527 EnterpriseConfig eapConfig1Cert = new EnterpriseConfig(Eap.TTLS) 1528 .setPhase2(Phase2.MSCHAPV2) 1529 .setIdentity("username", "password") 1530 .setCaCerts(new X509Certificate[] {FakeKeys.CA_CERT0}); 1531 1532 assertTrue(mWifiConfigManager.wasEnterpriseConfigChange(eapConfigNoCerts.enterpriseConfig, 1533 eapConfig1Cert.enterpriseConfig)); 1534 } 1535 1536 /** 1537 * Verify WifiEnterpriseConfig Certificate change is detected. 1538 */ 1539 @Test testDifferentCaCertificateDetected()1540 public void testDifferentCaCertificateDetected() { 1541 EnterpriseConfig eapConfig = new EnterpriseConfig(Eap.TTLS) 1542 .setPhase2(Phase2.MSCHAPV2) 1543 .setIdentity("username", "password") 1544 .setCaCerts(new X509Certificate[] {FakeKeys.CA_CERT0}); 1545 1546 EnterpriseConfig eapConfigNewCert = new EnterpriseConfig(Eap.TTLS) 1547 .setPhase2(Phase2.MSCHAPV2) 1548 .setIdentity("username", "password") 1549 .setCaCerts(new X509Certificate[] {FakeKeys.CA_CERT1}); 1550 1551 assertTrue(mWifiConfigManager.wasEnterpriseConfigChange(eapConfig.enterpriseConfig, 1552 eapConfigNewCert.enterpriseConfig)); 1553 } 1554 1555 /** 1556 * Verify WifiEnterpriseConfig added Certificate changes are detected. 1557 */ 1558 @Test testCaCertificateChangesDetected()1559 public void testCaCertificateChangesDetected() { 1560 EnterpriseConfig eapConfig = new EnterpriseConfig(Eap.TTLS) 1561 .setPhase2(Phase2.MSCHAPV2) 1562 .setIdentity("username", "password") 1563 .setCaCerts(new X509Certificate[] {FakeKeys.CA_CERT0}); 1564 1565 EnterpriseConfig eapConfigAddedCert = new EnterpriseConfig(Eap.TTLS) 1566 .setPhase2(Phase2.MSCHAPV2) 1567 .setIdentity("username", "password") 1568 .setCaCerts(new X509Certificate[] {FakeKeys.CA_CERT0, FakeKeys.CA_CERT1}); 1569 1570 assertTrue(mWifiConfigManager.wasEnterpriseConfigChange(eapConfig.enterpriseConfig, 1571 eapConfigAddedCert.enterpriseConfig)); 1572 } 1573 1574 /** 1575 * Verify that WifiEnterpriseConfig does not detect changes for identical configs. 1576 */ 1577 @Test testWifiEnterpriseConfigNoChanges()1578 public void testWifiEnterpriseConfigNoChanges() { 1579 EnterpriseConfig eapConfig = new EnterpriseConfig(Eap.TTLS) 1580 .setPhase2(Phase2.MSCHAPV2) 1581 .setIdentity("username", "password") 1582 .setCaCerts(new X509Certificate[] {FakeKeys.CA_CERT0, FakeKeys.CA_CERT1}); 1583 1584 // Just to be clear that check is not against the same object 1585 EnterpriseConfig eapConfigSame = new EnterpriseConfig(Eap.TTLS) 1586 .setPhase2(Phase2.MSCHAPV2) 1587 .setIdentity("username", "password") 1588 .setCaCerts(new X509Certificate[] {FakeKeys.CA_CERT0, FakeKeys.CA_CERT1}); 1589 1590 assertFalse(mWifiConfigManager.wasEnterpriseConfigChange(eapConfig.enterpriseConfig, 1591 eapConfigSame.enterpriseConfig)); 1592 } 1593 1594 checkHasEverConnectedTrue(int networkId)1595 private void checkHasEverConnectedTrue(int networkId) { 1596 WifiConfiguration checkConfig = mWifiConfigManager.getWifiConfiguration(networkId); 1597 assertTrue("hasEverConnected expected to be true.", 1598 checkConfig.getNetworkSelectionStatus().getHasEverConnected()); 1599 } 1600 checkHasEverConnectedFalse(int networkId)1601 private void checkHasEverConnectedFalse(int networkId) { 1602 WifiConfiguration checkConfig = mWifiConfigManager.getWifiConfiguration(networkId); 1603 assertFalse("Updating credentials network config should clear hasEverConnected.", 1604 checkConfig.getNetworkSelectionStatus().getHasEverConnected()); 1605 } 1606 1607 /** 1608 * Helper function to translate from WifiConfiguration BitSet to String. 1609 */ makeString(BitSet set, String[] strings)1610 private static String makeString(BitSet set, String[] strings) { 1611 StringBuffer buf = new StringBuffer(); 1612 int nextSetBit = -1; 1613 1614 /* Make sure all set bits are in [0, strings.length) to avoid 1615 * going out of bounds on strings. (Shouldn't happen, but...) */ 1616 set = set.get(0, strings.length); 1617 1618 while ((nextSetBit = set.nextSetBit(nextSetBit + 1)) != -1) { 1619 buf.append(strings[nextSetBit].replace('_', '-')).append(' '); 1620 } 1621 1622 // remove trailing space 1623 if (set.cardinality() > 0) { 1624 buf.setLength(buf.length() - 1); 1625 } 1626 1627 return buf.toString(); 1628 } 1629 1630 1631 } 1632