WifiConfigManagerTest.java revision 1a731d9b8078e156b99dd281b814d93ab025e363
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 17package com.android.server.wifi; 18 19import static org.hamcrest.CoreMatchers.not; 20import static org.junit.Assert.*; 21import static org.mockito.Mockito.*; 22 23import android.app.test.MockAnswerUtil.AnswerWithArguments; 24import android.content.Context; 25import android.content.pm.UserInfo; 26import android.net.wifi.FakeKeys; 27import android.net.wifi.WifiConfiguration; 28import android.net.wifi.WifiConfiguration.AuthAlgorithm; 29import android.net.wifi.WifiConfiguration.GroupCipher; 30import android.net.wifi.WifiConfiguration.KeyMgmt; 31import android.net.wifi.WifiConfiguration.PairwiseCipher; 32import android.net.wifi.WifiConfiguration.Protocol; 33import android.net.wifi.WifiEnterpriseConfig; 34import android.net.wifi.WifiEnterpriseConfig.Eap; 35import android.net.wifi.WifiEnterpriseConfig.Phase2; 36import android.net.wifi.WifiScanner; 37import android.os.Process; 38import android.os.UserHandle; 39import android.os.UserManager; 40import android.security.Credentials; 41import android.security.KeyStore; 42import android.support.test.InstrumentationRegistry; 43import android.test.suitebuilder.annotation.SmallTest; 44import android.text.TextUtils; 45import android.util.Log; 46import android.util.SparseArray; 47 48import com.android.server.net.DelayedDiskWrite; 49import com.android.server.wifi.hotspot2.omadm.PasspointManagementObjectManager; 50import com.android.server.wifi.hotspot2.pps.Credential; 51import com.android.server.wifi.hotspot2.pps.HomeSP; 52 53import org.junit.Before; 54import org.junit.Test; 55import org.mockito.Mock; 56import org.mockito.MockitoAnnotations; 57 58import java.io.ByteArrayInputStream; 59import java.io.ByteArrayOutputStream; 60import java.io.DataInputStream; 61import java.io.DataOutputStream; 62import java.io.EOFException; 63import java.io.File; 64import java.io.FileOutputStream; 65import java.io.IOException; 66import java.lang.reflect.Field; 67import java.math.BigInteger; 68import java.security.cert.CertificateEncodingException; 69import java.security.cert.X509Certificate; 70import java.util.ArrayDeque; 71import java.util.ArrayList; 72import java.util.Arrays; 73import java.util.BitSet; 74import java.util.Collection; 75import java.util.Collections; 76import java.util.HashMap; 77import java.util.HashSet; 78import java.util.List; 79import java.util.Map; 80import java.util.Random; 81import java.util.Set; 82import java.util.TreeMap; 83 84/** 85 * Unit tests for {@link com.android.server.wifi.WifiConfigManager}. 86 */ 87@SmallTest 88public 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))) { 117 configs.add(CONFIGS.get(i)); 118 } 119 } 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 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 203 private void switchUser(int newUserId) { 204 when(mUserManager.getProfiles(newUserId)) 205 .thenReturn(USER_PROFILES.get(newUserId)); 206 mWifiConfigManager.handleUserSwitch(newUserId); 207 } 208 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 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 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 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 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 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 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 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 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 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 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 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 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 424 // a connection attempt was made to it. This does not modify the status of 425 // other networks. 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 assertEquals(WifiConfiguration.Status.ENABLED, config.status); 432 } 433 } 434 } 435 } 436 437 /** 438 * Verifies that saveNetwork() correctly stores a network configuration in wpa_supplicant 439 * variables and the networkHistory.txt file. 440 * TODO: Test all variables. Currently, only the following variables are tested: 441 * - In the wpa_supplicant: "ssid", "id_str" 442 * - In networkHistory.txt: "CONFIG", "CREATOR_UID_KEY", "SHARED" 443 */ 444 private void verifySaveNetwork(int network) throws Exception { 445 // Switch to the correct user. 446 switchUserToCreatorOrParentOf(CONFIGS.get(network)); 447 448 // Set up wpa_supplicant. 449 when(mWifiNative.addNetwork()).thenReturn(0); 450 when(mWifiNative.setNetworkVariable(eq(network), anyString(), anyString())) 451 .thenReturn(true); 452 when(mWifiNative.setNetworkExtra(eq(network), anyString(), 453 (Map<String, String>) anyObject())).thenReturn(true); 454 when(mWifiNative.getNetworkVariable(network, WifiConfiguration.ssidVarName)) 455 .thenReturn(encodeConfigSSID(CONFIGS.get(network))); 456 when(mWifiNative.getNetworkVariable(network, WifiConfiguration.pmfVarName)) 457 .thenReturn(""); 458 459 // Store a network configuration. 460 mWifiConfigManager.saveNetwork(CONFIGS.get(network), CONFIGS.get(network).creatorUid); 461 462 // Verify that wpa_supplicant variables were written correctly for the network 463 // configuration. 464 final Map<String, String> metadata = new HashMap<String, String>(); 465 if (CONFIGS.get(network).FQDN != null) { 466 metadata.put(WifiSupplicantControl.ID_STRING_KEY_FQDN, CONFIGS.get(network).FQDN); 467 } 468 metadata.put( 469 WifiSupplicantControl.ID_STRING_KEY_CONFIG_KEY, CONFIGS.get(network).configKey()); 470 metadata.put(WifiSupplicantControl.ID_STRING_KEY_CREATOR_UID, 471 Integer.toString(CONFIGS.get(network).creatorUid)); 472 verify(mWifiNative).setNetworkExtra(network, WifiSupplicantControl.ID_STRING_VAR_NAME, 473 metadata); 474 475 // Verify that an attempt to read back the requirePMF variable was made. 476 verify(mWifiNative).getNetworkVariable(network, WifiConfiguration.pmfVarName); 477 478 // Verify that no wpa_supplicant variables were read or written for any other network 479 // configurations. 480 verify(mWifiNative, never()).setNetworkExtra(intThat(not(network)), anyString(), 481 (Map<String, String>) anyObject()); 482 verify(mWifiNative, never()).setNetworkVariable(intThat(not(network)), anyString(), 483 anyString()); 484 verify(mWifiNative, never()).getNetworkVariable(intThat(not(network)), anyString()); 485 486 // Parse networkHistory.txt. 487 assertNotNull(mNetworkHistoryBytes); 488 final DataInputStream stream = 489 new DataInputStream(new ByteArrayInputStream(mNetworkHistoryBytes)); 490 List<String> keys = new ArrayList<>(); 491 List<String> values = new ArrayList<>(); 492 try { 493 while (true) { 494 final String[] tokens = stream.readUTF().split(":", 2); 495 if (tokens.length == 2) { 496 keys.add(tokens[0].trim()); 497 values.add(tokens[1].trim()); 498 } 499 } 500 } catch (EOFException e) { 501 // Ignore. This is expected. 502 } 503 504 // Verify that a networkHistory.txt entry was written correctly for the network 505 // configuration. 506 assertTrue(keys.size() >= 3); 507 assertEquals(WifiNetworkHistory.CONFIG_KEY, keys.get(0)); 508 assertEquals(CONFIGS.get(network).configKey(), values.get(0)); 509 final int creatorUidIndex = keys.indexOf(WifiNetworkHistory.CREATOR_UID_KEY); 510 assertTrue(creatorUidIndex != -1); 511 assertEquals(Integer.toString(CONFIGS.get(network).creatorUid), 512 values.get(creatorUidIndex)); 513 final int sharedIndex = keys.indexOf(WifiNetworkHistory.SHARED_KEY); 514 assertTrue(sharedIndex != -1); 515 assertEquals(Boolean.toString(CONFIGS.get(network).shared), values.get(sharedIndex)); 516 517 // Verify that no networkHistory.txt entries were written for any other network 518 // configurations. 519 final int lastConfigIndex = keys.lastIndexOf(WifiNetworkHistory.CONFIG_KEY); 520 assertEquals(0, lastConfigIndex); 521 } 522 523 /** 524 * Verifies that saveNetwork() correctly stores a regular network configuration. 525 */ 526 @Test 527 public void testSaveNetworkRegular() throws Exception { 528 verifySaveNetwork(0); 529 } 530 531 /** 532 * Verifies that saveNetwork() correctly stores a HotSpot 2.0 network configuration. 533 */ 534 @Test 535 public void testSaveNetworkHotspot20() throws Exception { 536 verifySaveNetwork(1); 537 } 538 539 /** 540 * Verifies that saveNetwork() correctly stores a private network configuration. 541 */ 542 @Test 543 public void testSaveNetworkPrivate() throws Exception { 544 verifySaveNetwork(2); 545 } 546 547 /** 548 * Verifies that loadConfiguredNetworks() correctly reads data from the wpa_supplicant, the 549 * networkHistory.txt file and the MOManager, correlating the three sources based on the 550 * configKey and the FQDN for HotSpot 2.0 networks. 551 * TODO: Test all variables. Currently, only the following variables are tested: 552 * - In the wpa_supplicant: "ssid", "id_str" 553 * - In networkHistory.txt: "CONFIG", "CREATOR_UID_KEY", "SHARED" 554 */ 555 @Test 556 public void testLoadConfiguredNetworks() throws Exception { 557 // Set up list of network configurations returned by wpa_supplicant. 558 final String header = "network id / ssid / bssid / flags"; 559 String networks = header; 560 for (WifiConfiguration config : CONFIGS) { 561 networks += "\n" + Integer.toString(config.networkId) + "\t" + config.SSID + "\tany"; 562 } 563 when(mWifiNative.listNetworks(anyInt())).thenReturn(header); 564 when(mWifiNative.listNetworks(-1)).thenReturn(networks); 565 566 // Set up variables returned by wpa_supplicant for the individual network configurations. 567 for (int i = 0; i < CONFIGS.size(); ++i) { 568 when(mWifiNative.getNetworkVariable(i, WifiConfiguration.ssidVarName)) 569 .thenReturn(encodeConfigSSID(CONFIGS.get(i))); 570 } 571 // Legacy regular network configuration: No "id_str". 572 when(mWifiNative.getNetworkExtra(0, WifiSupplicantControl.ID_STRING_VAR_NAME)) 573 .thenReturn(null); 574 // Legacy Hotspot 2.0 network configuration: Quoted FQDN in "id_str". 575 when(mWifiNative.getNetworkExtra(1, WifiSupplicantControl.ID_STRING_VAR_NAME)) 576 .thenReturn(null); 577 when(mWifiNative.getNetworkVariable(1, WifiSupplicantControl.ID_STRING_VAR_NAME)) 578 .thenReturn('"' + CONFIGS.get(1).FQDN + '"'); 579 // Up-to-date Hotspot 2.0 network configuration: Metadata in "id_str". 580 Map<String, String> metadata = new HashMap<String, String>(); 581 metadata.put(WifiSupplicantControl.ID_STRING_KEY_CONFIG_KEY, CONFIGS.get(2).configKey()); 582 metadata.put(WifiSupplicantControl.ID_STRING_KEY_CREATOR_UID, 583 Integer.toString(CONFIGS.get(2).creatorUid)); 584 metadata.put(WifiSupplicantControl.ID_STRING_KEY_FQDN, CONFIGS.get(2).FQDN); 585 when(mWifiNative.getNetworkExtra(2, WifiSupplicantControl.ID_STRING_VAR_NAME)) 586 .thenReturn(metadata); 587 // Up-to-date regular network configuration: Metadata in "id_str". 588 metadata = new HashMap<String, String>(); 589 metadata.put(WifiSupplicantControl.ID_STRING_KEY_CONFIG_KEY, CONFIGS.get(3).configKey()); 590 metadata.put(WifiSupplicantControl.ID_STRING_KEY_CREATOR_UID, 591 Integer.toString(CONFIGS.get(3).creatorUid)); 592 when(mWifiNative.getNetworkExtra(3, WifiSupplicantControl.ID_STRING_VAR_NAME)) 593 .thenReturn(metadata); 594 595 // Set up networkHistory.txt file. 596 final File file = File.createTempFile("networkHistory.txt", null); 597 file.deleteOnExit(); 598 599 Field wifiNetworkHistoryConfigFile = 600 WifiNetworkHistory.class.getDeclaredField("NETWORK_HISTORY_CONFIG_FILE"); 601 wifiNetworkHistoryConfigFile.setAccessible(true); 602 wifiNetworkHistoryConfigFile.set(null, file.getAbsolutePath()); 603 604 final DataOutputStream stream = new DataOutputStream(new FileOutputStream(file)); 605 for (WifiConfiguration config : CONFIGS) { 606 stream.writeUTF(WifiNetworkHistory.CONFIG_KEY + ": " + config.configKey() + '\n'); 607 stream.writeUTF(WifiNetworkHistory.CREATOR_UID_KEY + ": " 608 + Integer.toString(config.creatorUid) + '\n'); 609 stream.writeUTF(WifiNetworkHistory.SHARED_KEY + ": " 610 + Boolean.toString(config.shared) + '\n'); 611 } 612 stream.close(); 613 614 // Set up list of home service providers returned by MOManager. 615 final List<HomeSP> homeSPs = new ArrayList<HomeSP>(); 616 for (WifiConfiguration config : CONFIGS) { 617 if (config.FQDN != null) { 618 homeSPs.add(new HomeSP(null, config.FQDN, new HashSet<Long>(), 619 new HashSet<String>(), 620 new HashSet<Long>(), new ArrayList<Long>(), 621 config.providerFriendlyName, null, 622 new Credential(0, 0, null, false, null, null), 623 null, 0, null, null, null, 0)); 624 } 625 } 626 when(mMOManager.loadAllSPs()).thenReturn(homeSPs); 627 628 // Load network configurations. 629 mWifiConfigManager.loadConfiguredNetworks(); 630 631 // Verify that network configurations were loaded and correlated correctly across the three 632 // sources. 633 verifyNetworkConfigs(CONFIGS, mConfiguredNetworks.valuesForAllUsers()); 634 } 635 636 /** 637 * Verifies that loadConfiguredNetworks() correctly handles duplicates when reading network 638 * configurations from the wpa_supplicant: The second configuration overwrites the first. 639 */ 640 @Test 641 public void testLoadConfiguredNetworksEliminatesDuplicates() throws Exception { 642 final WifiConfiguration config = new WifiConfiguration(CONFIGS.get(0)); 643 config.networkId = 1; 644 645 // Set up list of network configurations returned by wpa_supplicant. The two configurations 646 // are identical except for their network IDs. 647 final String header = "network id / ssid / bssid / flags"; 648 final String networks = 649 header + "\n0\t" + config.SSID + "\tany\n1\t" + config.SSID + "\tany"; 650 when(mWifiNative.listNetworks(anyInt())).thenReturn(header); 651 when(mWifiNative.listNetworks(-1)).thenReturn(networks); 652 653 // Set up variables returned by wpa_supplicant. 654 when(mWifiNative.getNetworkVariable(anyInt(), eq(WifiConfiguration.ssidVarName))) 655 .thenReturn(encodeConfigSSID(config)); 656 final Map<String, String> metadata = new HashMap<String, String>(); 657 metadata.put(WifiSupplicantControl.ID_STRING_KEY_CONFIG_KEY, config.configKey()); 658 metadata.put(WifiSupplicantControl.ID_STRING_KEY_CREATOR_UID, 659 Integer.toString(config.creatorUid)); 660 when(mWifiNative.getNetworkExtra(anyInt(), eq(WifiSupplicantControl.ID_STRING_VAR_NAME))) 661 .thenReturn(metadata); 662 663 // Load network configurations. 664 mWifiConfigManager.loadConfiguredNetworks(); 665 666 // Verify that the second network configuration (network ID 1) overwrote the first (network 667 // ID 0). 668 verifyNetworkConfigs(Arrays.asList(config), mConfiguredNetworks.valuesForAllUsers()); 669 } 670 671 /** 672 * Verifies that handleUserSwitch() removes ephemeral network configurations, disables network 673 * configurations that should no longer be visible and enables network configurations that 674 * should become visible. 675 */ 676 private void verifyHandleUserSwitch(int oldUserId, int newUserId, 677 boolean makeOneConfigEphemeral) throws Exception { 678 addNetworks(); 679 switchUser(oldUserId); 680 681 reset(mWifiNative); 682 final Field lastSelectedConfigurationField = 683 WifiConfigManager.class.getDeclaredField("mLastSelectedConfiguration"); 684 lastSelectedConfigurationField.setAccessible(true); 685 WifiConfiguration removedEphemeralConfig = null; 686 final Set<WifiConfiguration> oldUserOnlyConfigs = new HashSet<>(); 687 final Set<WifiConfiguration> newUserOnlyConfigs = new HashSet<>(); 688 final Set<WifiConfiguration> neitherUserConfigs = new HashSet<>(); 689 final Collection<WifiConfiguration> oldConfigs = mConfiguredNetworks.valuesForAllUsers(); 690 int expectedNumberOfConfigs = oldConfigs.size(); 691 for (WifiConfiguration config : oldConfigs) { 692 if (WifiConfigurationUtil.isVisibleToAnyProfile(config, USER_PROFILES.get(oldUserId))) { 693 config.status = WifiConfiguration.Status.ENABLED; 694 if (WifiConfigurationUtil.isVisibleToAnyProfile(config, 695 USER_PROFILES.get(newUserId))) { 696 if (makeOneConfigEphemeral && removedEphemeralConfig == null) { 697 config.ephemeral = true; 698 lastSelectedConfigurationField.set(mWifiConfigManager, config.configKey()); 699 removedEphemeralConfig = config; 700 } 701 } else { 702 oldUserOnlyConfigs.add(config); 703 } 704 } else { 705 config.status = WifiConfiguration.Status.DISABLED; 706 if (WifiConfigurationUtil.isVisibleToAnyProfile(config, 707 USER_PROFILES.get(newUserId))) { 708 newUserOnlyConfigs.add(config); 709 } else { 710 neitherUserConfigs.add(config); 711 } 712 } 713 } 714 715 when(mWifiNative.disableNetwork(anyInt())).thenReturn(true); 716 when(mWifiNative.removeNetwork(anyInt())).thenReturn(true); 717 718 switchUser(newUserId); 719 if (makeOneConfigEphemeral) { 720 // Verify that the ephemeral network configuration was removed. 721 assertNotNull(removedEphemeralConfig); 722 assertNull(mConfiguredNetworks.getForAllUsers(removedEphemeralConfig.networkId)); 723 assertNull(lastSelectedConfigurationField.get(mWifiConfigManager)); 724 verify(mWifiNative).removeNetwork(removedEphemeralConfig.networkId); 725 --expectedNumberOfConfigs; 726 } else { 727 assertNull(removedEphemeralConfig); 728 } 729 730 // Verify that the other network configurations were revealed/hidden and enabled/disabled as 731 // appropriate. 732 final Collection<WifiConfiguration> newConfigs = mConfiguredNetworks.valuesForAllUsers(); 733 assertEquals(expectedNumberOfConfigs, newConfigs.size()); 734 for (WifiConfiguration config : newConfigs) { 735 if (oldUserOnlyConfigs.contains(config)) { 736 verify(mWifiNative).disableNetwork(config.networkId); 737 assertNetworkStatus( 738 config, 739 WifiConfiguration.NetworkSelectionStatus.DISABLED_DUE_TO_USER_SWITCH); 740 } else { 741 verify(mWifiNative, never()).disableNetwork(config.networkId); 742 if (neitherUserConfigs.contains(config)) { 743 assertNetworkStatus( 744 config, 745 WifiConfiguration.NetworkSelectionStatus.DISABLED_DUE_TO_USER_SWITCH); 746 } else { 747 assertNetworkStatus( 748 config, 749 WifiConfiguration.NetworkSelectionStatus.NETWORK_SELECTION_ENABLE); 750 } 751 } 752 } 753 } 754 755 /** 756 * Verifies that handleUserSwitch() behaves correctly when the user switch removes an ephemeral 757 * network configuration and reveals a private network configuration. 758 */ 759 @Test 760 public void testHandleUserSwitchWithEphemeral() throws Exception { 761 verifyHandleUserSwitch(USER_IDS[2], USER_IDS[0], true); 762 } 763 764 /** 765 * Verifies that handleUserSwitch() behaves correctly when the user switch hides a private 766 * network configuration. 767 */ 768 @Test 769 public void testHandleUserSwitchWithoutEphemeral() throws Exception { 770 verifyHandleUserSwitch(USER_IDS[0], USER_IDS[2], false); 771 } 772 773 @Test 774 public void testSaveLoadEapNetworks() { 775 testSaveLoadSingleEapNetwork("eap network", new EnterpriseConfig(Eap.TTLS) 776 .setPhase2(Phase2.MSCHAPV2) 777 .setIdentity("username", "password") 778 .setCaCerts(new X509Certificate[] {FakeKeys.CA_CERT0})); 779 testSaveLoadSingleEapNetwork("eap network", new EnterpriseConfig(Eap.TTLS) 780 .setPhase2(Phase2.MSCHAPV2) 781 .setIdentity("username", "password") 782 .setCaCerts(new X509Certificate[] {FakeKeys.CA_CERT1, FakeKeys.CA_CERT0})); 783 784 } 785 786 private void testSaveLoadSingleEapNetwork(String ssid, EnterpriseConfig eapConfig) { 787 final HashMap<String, String> networkVariables = new HashMap<String, String>(); 788 reset(mWifiNative); 789 when(mWifiNative.addNetwork()).thenReturn(0); 790 when(mWifiNative.setNetworkVariable(anyInt(), anyString(), anyString())).thenAnswer( 791 new AnswerWithArguments() { 792 public boolean answer(int netId, String name, String value) { 793 // Verify that no wpa_supplicant variables were written for any other 794 // network configurations. 795 assertEquals(netId, 0); 796 networkVariables.put(name, value); 797 return true; 798 } 799 }); 800 when(mWifiNative.getNetworkVariable(anyInt(), anyString())).then( 801 new AnswerWithArguments() { 802 public String answer(int netId, String name) { 803 // Verify that no wpa_supplicant variables were read for any other 804 // network configurations. 805 assertEquals(netId, 0); 806 return networkVariables.get(name); 807 } 808 }); 809 when(mWifiNative.setNetworkExtra(eq(0), anyString(), (Map<String, String>) anyObject())) 810 .thenReturn(true); 811 812 WifiConfiguration config = new WifiConfiguration(); 813 config.SSID = ssid; 814 config.creatorUid = Process.WIFI_UID; 815 config.allowedKeyManagement.set(KeyMgmt.WPA_EAP); 816 config.enterpriseConfig = eapConfig.enterpriseConfig; 817 818 // Store a network configuration. 819 mWifiConfigManager.saveNetwork(config, Process.WIFI_UID); 820 821 // Verify that wpa_supplicant variables were written correctly for the network 822 // configuration. 823 verify(mWifiNative).addNetwork(); 824 assertEquals(eapConfig.eap, 825 unquote(networkVariables.get(WifiEnterpriseConfig.EAP_KEY))); 826 assertEquals(eapConfig.phase2, 827 unquote(networkVariables.get(WifiEnterpriseConfig.PHASE2_KEY))); 828 assertEquals(eapConfig.identity, 829 unquote(networkVariables.get(WifiEnterpriseConfig.IDENTITY_KEY))); 830 assertEquals(eapConfig.password, 831 unquote(networkVariables.get(WifiEnterpriseConfig.PASSWORD_KEY))); 832 assertSavedCaCerts(eapConfig, 833 unquote(networkVariables.get(WifiEnterpriseConfig.CA_CERT_KEY))); 834 835 // Prepare the scan result. 836 final String header = "network id / ssid / bssid / flags"; 837 String networks = header + "\n" + Integer.toString(0) + "\t" + ssid + "\tany"; 838 when(mWifiNative.listNetworks(anyInt())).thenReturn(header); 839 when(mWifiNative.listNetworks(-1)).thenReturn(networks); 840 841 // Load back the configuration. 842 mWifiConfigManager.loadConfiguredNetworks(); 843 List<WifiConfiguration> configs = mWifiConfigManager.getSavedNetworks(); 844 assertEquals(1, configs.size()); 845 WifiConfiguration loadedConfig = configs.get(0); 846 assertEquals(ssid, unquote(loadedConfig.SSID)); 847 BitSet keyMgmt = new BitSet(); 848 keyMgmt.set(KeyMgmt.WPA_EAP); 849 assertEquals(keyMgmt, loadedConfig.allowedKeyManagement); 850 assertEquals(eapConfig.enterpriseConfig.getEapMethod(), 851 loadedConfig.enterpriseConfig.getEapMethod()); 852 assertEquals(eapConfig.enterpriseConfig.getPhase2Method(), 853 loadedConfig.enterpriseConfig.getPhase2Method()); 854 assertEquals(eapConfig.enterpriseConfig.getIdentity(), 855 loadedConfig.enterpriseConfig.getIdentity()); 856 assertEquals(eapConfig.enterpriseConfig.getPassword(), 857 loadedConfig.enterpriseConfig.getPassword()); 858 asserCaCertsAliasesMatch(eapConfig.caCerts, 859 loadedConfig.enterpriseConfig.getCaCertificateAliases()); 860 } 861 862 private String unquote(String value) { 863 if (value == null) { 864 return null; 865 } 866 int length = value.length(); 867 if ((length > 1) && (value.charAt(0) == '"') 868 && (value.charAt(length - 1) == '"')) { 869 return value.substring(1, length - 1); 870 } else { 871 return value; 872 } 873 } 874 875 private void asserCaCertsAliasesMatch(X509Certificate[] certs, String[] aliases) { 876 assertEquals(certs.length, aliases.length); 877 List<String> aliasList = new ArrayList<String>(Arrays.asList(aliases)); 878 try { 879 for (int i = 0; i < certs.length; i++) { 880 byte[] certPem = Credentials.convertToPem(certs[i]); 881 boolean found = false; 882 for (int j = 0; j < aliasList.size(); j++) { 883 byte[] keystoreCert = mMockKeyStore.getKeyBlob(Process.WIFI_UID, 884 Credentials.CA_CERTIFICATE + aliasList.get(j)).blob; 885 if (Arrays.equals(keystoreCert, certPem)) { 886 found = true; 887 aliasList.remove(j); 888 break; 889 } 890 } 891 assertTrue(found); 892 } 893 } catch (CertificateEncodingException | IOException e) { 894 fail("Cannot convert CA certificate to encoded form."); 895 } 896 } 897 898 private void assertSavedCaCerts(EnterpriseConfig eapConfig, String caCertVariable) { 899 ArrayList<String> aliases = new ArrayList<String>(); 900 if (TextUtils.isEmpty(caCertVariable)) { 901 // Do nothing. 902 } else if (caCertVariable.startsWith(WifiEnterpriseConfig.CA_CERT_PREFIX)) { 903 aliases.add(caCertVariable.substring(WifiEnterpriseConfig.CA_CERT_PREFIX.length())); 904 } else if (caCertVariable.startsWith(WifiEnterpriseConfig.KEYSTORES_URI)) { 905 String[] encodedAliases = TextUtils.split( 906 caCertVariable.substring(WifiEnterpriseConfig.KEYSTORES_URI.length()), 907 WifiEnterpriseConfig.CA_CERT_ALIAS_DELIMITER); 908 for (String encodedAlias : encodedAliases) { 909 String alias = WifiEnterpriseConfig.decodeCaCertificateAlias(encodedAlias); 910 assertTrue(alias.startsWith(Credentials.CA_CERTIFICATE)); 911 aliases.add(alias.substring(Credentials.CA_CERTIFICATE.length())); 912 } 913 } else { 914 fail("Unrecognized ca_cert variable: " + caCertVariable); 915 } 916 asserCaCertsAliasesMatch(eapConfig.caCerts, aliases.toArray(new String[aliases.size()])); 917 } 918 919 private static class EnterpriseConfig { 920 public String eap; 921 public String phase2; 922 public String identity; 923 public String password; 924 public X509Certificate[] caCerts; 925 public WifiEnterpriseConfig enterpriseConfig; 926 927 public EnterpriseConfig(int eapMethod) { 928 enterpriseConfig = new WifiEnterpriseConfig(); 929 enterpriseConfig.setEapMethod(eapMethod); 930 eap = Eap.strings[eapMethod]; 931 } 932 public EnterpriseConfig setPhase2(int phase2Method) { 933 enterpriseConfig.setPhase2Method(phase2Method); 934 phase2 = "auth=" + Phase2.strings[phase2Method]; 935 return this; 936 } 937 public EnterpriseConfig setIdentity(String identity, String password) { 938 enterpriseConfig.setIdentity(identity); 939 enterpriseConfig.setPassword(password); 940 this.identity = identity; 941 this.password = password; 942 return this; 943 } 944 public EnterpriseConfig setCaCerts(X509Certificate[] certs) { 945 enterpriseConfig.setCaCertificates(certs); 946 caCerts = certs; 947 return this; 948 } 949 } 950 951 /** 952 * Generates an array of unique random numbers below the specified maxValue. 953 * Values range from 0 to maxValue-1. 954 */ 955 private static ArrayDeque<Integer> getUniqueRandomNumberValues( 956 int seed, 957 int maxValue, 958 int numValues) { 959 assertTrue(numValues <= maxValue); 960 Random rand = new Random(WifiTestUtil.getTestMethod().hashCode() + seed); 961 ArrayDeque<Integer> randomNumberList = new ArrayDeque<>(); 962 for (int i = 0; i < numValues; i++) { 963 int num = rand.nextInt(maxValue); 964 while (randomNumberList.contains(num)) { 965 num = rand.nextInt(maxValue); 966 } 967 randomNumberList.push(num); 968 } 969 return randomNumberList; 970 } 971 972 /** 973 * Verifies that the networks in pnoNetworkList is sorted in the same order as the 974 * network in expectedNetworkIDOrder list. 975 */ 976 private static void verifyPnoNetworkListOrder( 977 ArrayList<WifiScanner.PnoSettings.PnoNetwork> pnoNetworkList, 978 ArrayList<Integer> expectedNetworkIdOrder) throws Exception { 979 int i = 0; 980 for (WifiScanner.PnoSettings.PnoNetwork pnoNetwork : pnoNetworkList) { 981 Log.i(TAG, "PNO Network List Index: " + i + ", networkID: " + pnoNetwork.networkId); 982 assertEquals("Expected network ID: " + pnoNetwork.networkId, 983 pnoNetwork.networkId, expectedNetworkIdOrder.get(i++).intValue()); 984 } 985 } 986 987 /** 988 * Verifies the retrieveDisconnectedPnoNetworkList API. The test verifies that the list 989 * returned from the API is sorted as expected. 990 */ 991 @Test 992 public void testDisconnectedPnoNetworkListCreation() throws Exception { 993 addNetworks(); 994 995 Random rand = new Random(WifiTestUtil.getTestMethod().hashCode()); 996 997 // First assign random |numAssociation| values and verify that the list is sorted 998 // in descending order of |numAssociation| values. Keep NetworkSelectionStatus 999 // values constant. 1000 for (int userId : USER_IDS) { 1001 switchUser(userId); 1002 TreeMap<Integer, Integer> numAssociationToNetworkIdMap = 1003 new TreeMap<>(Collections.reverseOrder()); 1004 ArrayDeque<Integer> numAssociationValues = 1005 getUniqueRandomNumberValues( 1006 1, 10000, mConfiguredNetworks.valuesForCurrentUser().size()); 1007 for (WifiConfiguration config : mConfiguredNetworks.valuesForCurrentUser()) { 1008 config.numAssociation = numAssociationValues.pop(); 1009 config.priority = rand.nextInt(10000); 1010 config.getNetworkSelectionStatus().setNetworkSelectionStatus( 1011 WifiConfiguration.NetworkSelectionStatus.NETWORK_SELECTION_ENABLED); 1012 numAssociationToNetworkIdMap.put(config.numAssociation, config.networkId); 1013 Log.i(TAG, "networkID: " + config.networkId + ", numAssociation: " 1014 + config.numAssociation); 1015 } 1016 ArrayList<WifiScanner.PnoSettings.PnoNetwork> pnoNetworkList = 1017 mWifiConfigManager.retrieveDisconnectedPnoNetworkList(); 1018 verifyPnoNetworkListOrder(pnoNetworkList, 1019 new ArrayList(numAssociationToNetworkIdMap.values())); 1020 } 1021 1022 // Assign random |priority| values and verify that the list is sorted in descending order 1023 // of |priority| values. Keep numAssociation/NetworkSelectionStatus values constant. 1024 for (int userId : USER_IDS) { 1025 switchUser(userId); 1026 TreeMap<Integer, Integer> priorityToNetworkIdMap = 1027 new TreeMap<>(Collections.reverseOrder()); 1028 ArrayDeque<Integer> priorityValues = 1029 getUniqueRandomNumberValues( 1030 2, 10000, mConfiguredNetworks.valuesForCurrentUser().size()); 1031 for (WifiConfiguration config : mConfiguredNetworks.valuesForCurrentUser()) { 1032 config.numAssociation = 0; 1033 config.priority = priorityValues.pop(); 1034 config.getNetworkSelectionStatus().setNetworkSelectionStatus( 1035 WifiConfiguration.NetworkSelectionStatus.NETWORK_SELECTION_ENABLED); 1036 priorityToNetworkIdMap.put(config.priority, config.networkId); 1037 Log.i(TAG, "networkID: " + config.networkId + ", priority: " + config.priority); 1038 } 1039 ArrayList<WifiScanner.PnoSettings.PnoNetwork> pnoNetworkList = 1040 mWifiConfigManager.retrieveDisconnectedPnoNetworkList(); 1041 verifyPnoNetworkListOrder(pnoNetworkList, 1042 new ArrayList(priorityToNetworkIdMap.values())); 1043 } 1044 1045 // Now assign random |NetworkSelectionStatus| values and verify that the list is sorted in 1046 // ascending order of |NetworkSelectionStatus| values. 1047 for (int userId : USER_IDS) { 1048 switchUser(userId); 1049 TreeMap<Integer, Integer> networkSelectionStatusToNetworkIdMap = new TreeMap<>(); 1050 ArrayDeque<Integer> networkSelectionStatusValues = 1051 getUniqueRandomNumberValues( 1052 3, 1053 WifiConfiguration.NetworkSelectionStatus.NETWORK_SELECTION_STATUS_MAX, 1054 mConfiguredNetworks.valuesForCurrentUser().size()); 1055 for (WifiConfiguration config : mConfiguredNetworks.valuesForCurrentUser()) { 1056 config.numAssociation = rand.nextInt(10000); 1057 config.priority = rand.nextInt(10000); 1058 config.getNetworkSelectionStatus().setNetworkSelectionStatus( 1059 networkSelectionStatusValues.pop()); 1060 networkSelectionStatusToNetworkIdMap.put( 1061 config.getNetworkSelectionStatus().getNetworkSelectionStatus(), 1062 config.networkId); 1063 Log.i(TAG, "networkID: " + config.networkId + ", NetworkSelectionStatus: " 1064 + config.getNetworkSelectionStatus().getNetworkSelectionStatus()); 1065 } 1066 ArrayList<WifiScanner.PnoSettings.PnoNetwork> pnoNetworkList = 1067 mWifiConfigManager.retrieveDisconnectedPnoNetworkList(); 1068 verifyPnoNetworkListOrder(pnoNetworkList, 1069 new ArrayList(networkSelectionStatusToNetworkIdMap.values())); 1070 } 1071 } 1072 1073 /** 1074 * Verifies the retrieveConnectedPnoNetworkList API. The test verifies that the list 1075 * returned from the API is sorted as expected. 1076 */ 1077 @Test 1078 public void testConnectedPnoNetworkListCreation() throws Exception { 1079 addNetworks(); 1080 1081 Random rand = new Random(WifiTestUtil.getTestMethod().hashCode()); 1082 1083 // First assign |lastSeen| values and verify that the list is sorted 1084 // in descending order of |lastSeen| values. Keep NetworkSelectionStatus 1085 // values constant. 1086 for (int userId : USER_IDS) { 1087 switchUser(userId); 1088 TreeMap<Boolean, Integer> lastSeenToNetworkIdMap = 1089 new TreeMap<>(Collections.reverseOrder()); 1090 ArrayDeque<Integer> lastSeenValues = getUniqueRandomNumberValues(1, 2, 2); 1091 if (mConfiguredNetworks.valuesForCurrentUser().size() > 2) continue; 1092 for (WifiConfiguration config : mConfiguredNetworks.valuesForCurrentUser()) { 1093 config.numAssociation = rand.nextInt(10000); 1094 config.priority = rand.nextInt(10000); 1095 config.getNetworkSelectionStatus().setNetworkSelectionStatus( 1096 WifiConfiguration.NetworkSelectionStatus.NETWORK_SELECTION_ENABLED); 1097 boolean lastSeenValue = (lastSeenValues.pop() == 1); 1098 config.getNetworkSelectionStatus().setSeenInLastQualifiedNetworkSelection( 1099 lastSeenValue); 1100 lastSeenToNetworkIdMap.put(lastSeenValue, config.networkId); 1101 Log.i(TAG, "networkID: " + config.networkId + ", lastSeen: " + lastSeenValue); 1102 } 1103 ArrayList<WifiScanner.PnoSettings.PnoNetwork> pnoNetworkList = 1104 mWifiConfigManager.retrieveConnectedPnoNetworkList(); 1105 verifyPnoNetworkListOrder(pnoNetworkList, 1106 new ArrayList(lastSeenToNetworkIdMap.values())); 1107 } 1108 1109 // Assign random |numAssociation| values and verify that the list is sorted 1110 // in descending order of |numAssociation| values. Keep NetworkSelectionStatus/lastSeen 1111 // values constant. 1112 for (int userId : USER_IDS) { 1113 switchUser(userId); 1114 TreeMap<Integer, Integer> numAssociationToNetworkIdMap = 1115 new TreeMap<>(Collections.reverseOrder()); 1116 ArrayDeque<Integer> numAssociationValues = 1117 getUniqueRandomNumberValues( 1118 1, 10000, mConfiguredNetworks.valuesForCurrentUser().size()); 1119 for (WifiConfiguration config : mConfiguredNetworks.valuesForCurrentUser()) { 1120 config.numAssociation = numAssociationValues.pop(); 1121 config.priority = rand.nextInt(10000); 1122 config.getNetworkSelectionStatus().setNetworkSelectionStatus( 1123 WifiConfiguration.NetworkSelectionStatus.NETWORK_SELECTION_ENABLED); 1124 config.getNetworkSelectionStatus().setSeenInLastQualifiedNetworkSelection(true); 1125 numAssociationToNetworkIdMap.put(config.numAssociation, config.networkId); 1126 Log.i(TAG, "networkID: " + config.networkId + ", numAssociation: " 1127 + config.numAssociation); 1128 } 1129 ArrayList<WifiScanner.PnoSettings.PnoNetwork> pnoNetworkList = 1130 mWifiConfigManager.retrieveConnectedPnoNetworkList(); 1131 verifyPnoNetworkListOrder(pnoNetworkList, 1132 new ArrayList(numAssociationToNetworkIdMap.values())); 1133 } 1134 1135 // Now assign random |NetworkSelectionStatus| values and verify that the list is sorted in 1136 // ascending order of |NetworkSelectionStatus| values. 1137 for (int userId : USER_IDS) { 1138 switchUser(userId); 1139 TreeMap<Integer, Integer> networkSelectionStatusToNetworkIdMap = new TreeMap<>(); 1140 ArrayDeque<Integer> networkSelectionStatusValues = 1141 getUniqueRandomNumberValues( 1142 3, 1143 WifiConfiguration.NetworkSelectionStatus.NETWORK_SELECTION_STATUS_MAX, 1144 mConfiguredNetworks.valuesForCurrentUser().size()); 1145 for (WifiConfiguration config : mConfiguredNetworks.valuesForCurrentUser()) { 1146 config.numAssociation = rand.nextInt(10000); 1147 config.priority = rand.nextInt(10000); 1148 config.getNetworkSelectionStatus().setNetworkSelectionStatus( 1149 networkSelectionStatusValues.pop()); 1150 networkSelectionStatusToNetworkIdMap.put( 1151 config.getNetworkSelectionStatus().getNetworkSelectionStatus(), 1152 config.networkId); 1153 Log.i(TAG, "networkID: " + config.networkId + ", NetworkSelectionStatus: " 1154 + config.getNetworkSelectionStatus().getNetworkSelectionStatus()); 1155 } 1156 ArrayList<WifiScanner.PnoSettings.PnoNetwork> pnoNetworkList = 1157 mWifiConfigManager.retrieveConnectedPnoNetworkList(); 1158 verifyPnoNetworkListOrder(pnoNetworkList, 1159 new ArrayList(networkSelectionStatusToNetworkIdMap.values())); 1160 } 1161 } 1162 1163 /** 1164 * Verifies that hasEverConnected is false for a newly added network 1165 */ 1166 @Test 1167 public void testAddNetworkHasEverConnectedFalse() throws Exception { 1168 addNetwork(BASE_HAS_EVER_CONNECTED_CONFIG); 1169 WifiConfiguration checkConfig = mWifiConfigManager.getWifiConfiguration( 1170 BASE_HAS_EVER_CONNECTED_CONFIG.networkId); 1171 assertFalse("Adding a new network should not have hasEverConnected set to true.", 1172 checkConfig.getNetworkSelectionStatus().getHasEverConnected()); 1173 } 1174 1175 1176 /** 1177 * Verifies that hasEverConnected is false for a newly added network even when new config has 1178 * mistakenly set HasEverConnected to true. 1179 */ 1180 @Test 1181 public void testAddNetworkOverridesHasEverConnectedWhenTrueInNewConfig() throws Exception { 1182 WifiConfiguration newNetworkWithHasEverConnectedTrue = 1183 new WifiConfiguration(BASE_HAS_EVER_CONNECTED_CONFIG); 1184 newNetworkWithHasEverConnectedTrue.getNetworkSelectionStatus().setHasEverConnected(true); 1185 addNetwork(newNetworkWithHasEverConnectedTrue); 1186 // check if addNetwork clears the bit. 1187 WifiConfiguration checkConfig = mWifiConfigManager.getWifiConfiguration( 1188 newNetworkWithHasEverConnectedTrue.networkId); 1189 assertFalse("Adding a new network should not have hasEverConnected set to true.", 1190 checkConfig.getNetworkSelectionStatus().getHasEverConnected()); 1191 } 1192 1193 1194 /** 1195 * Verify that setting HasEverConnected with a config update can be read back. 1196 */ 1197 @Test 1198 public void testUpdateConfigToHasEverConnectedTrue() throws Exception { 1199 addNetwork(BASE_HAS_EVER_CONNECTED_CONFIG); 1200 1201 // Get the newly saved config and update HasEverConnected 1202 WifiConfiguration checkConfig = mWifiConfigManager.getWifiConfiguration( 1203 BASE_HAS_EVER_CONNECTED_CONFIG.networkId); 1204 assertFalse("Adding a new network should not have hasEverConnected set to true.", 1205 checkConfig.getNetworkSelectionStatus().getHasEverConnected()); 1206 checkConfig.getNetworkSelectionStatus().setHasEverConnected(true); 1207 mWifiConfigManager.addOrUpdateNetwork(checkConfig, HAS_EVER_CONNECTED_USER); 1208 1209 // verify that HasEverConnected was properly written and read back 1210 checkHasEverConnectedTrue(BASE_HAS_EVER_CONNECTED_CONFIG.networkId); 1211 } 1212 1213 1214 /** 1215 * Verifies that hasEverConnected is cleared when a network config preSharedKey is updated. 1216 */ 1217 @Test 1218 public void testUpdatePreSharedKeyClearsHasEverConnected() throws Exception { 1219 final int originalUserId = mWifiConfigManager.getCurrentUserId(); 1220 1221 testUpdateConfigToHasEverConnectedTrue(); 1222 1223 WifiConfiguration original = mWifiConfigManager.getWifiConfiguration( 1224 BASE_HAS_EVER_CONNECTED_CONFIG.networkId); 1225 1226 WifiConfiguration updatePreSharedKeyConfig = new WifiConfiguration(); 1227 updatePreSharedKeyConfig.networkId = BASE_HAS_EVER_CONNECTED_CONFIG.networkId; 1228 updatePreSharedKeyConfig.SSID = original.SSID; 1229 updatePreSharedKeyConfig.preSharedKey = "newpassword"; 1230 switchUserToCreatorOrParentOf(original); 1231 mWifiConfigManager.addOrUpdateNetwork(updatePreSharedKeyConfig, 1232 BASE_HAS_EVER_CONNECTED_CONFIG.networkId); 1233 1234 checkHasEverConnectedFalse(BASE_HAS_EVER_CONNECTED_CONFIG.networkId); 1235 switchUser(originalUserId); 1236 } 1237 1238 /** 1239 * Verifies that hasEverConnected is cleared when a network config allowedKeyManagement is 1240 * updated. 1241 */ 1242 @Test 1243 public void testUpdateAllowedKeyManagementChanged() throws Exception { 1244 final int originalUserId = mWifiConfigManager.getCurrentUserId(); 1245 1246 testUpdateConfigToHasEverConnectedTrue(); 1247 1248 WifiConfiguration updateAllowedKeyManagementConfig = new WifiConfiguration(); 1249 updateAllowedKeyManagementConfig.networkId = BASE_HAS_EVER_CONNECTED_CONFIG.networkId; 1250 updateAllowedKeyManagementConfig.SSID = BASE_HAS_EVER_CONNECTED_CONFIG.SSID; 1251 updateAllowedKeyManagementConfig.allowedKeyManagement.set(KeyMgmt.WPA_PSK); 1252 1253 // Set up mock to allow the new value to be read back into the config 1254 String allowedKeyManagementString = makeString( 1255 updateAllowedKeyManagementConfig.allowedKeyManagement, 1256 WifiConfiguration.KeyMgmt.strings); 1257 when(mWifiNative.getNetworkVariable(BASE_HAS_EVER_CONNECTED_CONFIG.networkId, 1258 KeyMgmt.varName)).thenReturn(allowedKeyManagementString); 1259 1260 switchUserToCreatorOrParentOf(BASE_HAS_EVER_CONNECTED_CONFIG); 1261 mWifiConfigManager.addOrUpdateNetwork(updateAllowedKeyManagementConfig, 1262 BASE_HAS_EVER_CONNECTED_CONFIG.networkId); 1263 1264 checkHasEverConnectedFalse(BASE_HAS_EVER_CONNECTED_CONFIG.networkId); 1265 switchUser(originalUserId); 1266 } 1267 1268 /** 1269 * Verifies that hasEverConnected is cleared when a network config allowedProtocols is 1270 * updated. 1271 */ 1272 @Test 1273 public void testUpdateAllowedProtocolsChanged() throws Exception { 1274 final int originalUserId = mWifiConfigManager.getCurrentUserId(); 1275 1276 testUpdateConfigToHasEverConnectedTrue(); 1277 1278 WifiConfiguration updateAllowedProtocolsConfig = new WifiConfiguration(); 1279 updateAllowedProtocolsConfig.networkId = BASE_HAS_EVER_CONNECTED_CONFIG.networkId; 1280 updateAllowedProtocolsConfig.SSID = BASE_HAS_EVER_CONNECTED_CONFIG.SSID; 1281 updateAllowedProtocolsConfig.allowedProtocols.set( 1282 WifiConfiguration.Protocol.RSN); 1283 1284 // Set up mock to allow the new value to be read back into the config 1285 String allowedProtocolsString = makeString( 1286 updateAllowedProtocolsConfig.allowedProtocols, 1287 WifiConfiguration.Protocol.strings); 1288 when(mWifiNative.getNetworkVariable(BASE_HAS_EVER_CONNECTED_CONFIG.networkId, 1289 Protocol.varName)).thenReturn(allowedProtocolsString); 1290 1291 switchUserToCreatorOrParentOf(BASE_HAS_EVER_CONNECTED_CONFIG); 1292 mWifiConfigManager.addOrUpdateNetwork(updateAllowedProtocolsConfig, 1293 BASE_HAS_EVER_CONNECTED_CONFIG.networkId); 1294 1295 checkHasEverConnectedFalse(BASE_HAS_EVER_CONNECTED_CONFIG.networkId); 1296 switchUser(originalUserId); 1297 } 1298 1299 /** 1300 * Verifies that hasEverConnected is cleared when a network config allowedAuthAlgorithms is 1301 * updated. 1302 */ 1303 @Test 1304 public void testUpdateAllowedAuthAlgorithmsChanged() throws Exception { 1305 final int originalUserId = mWifiConfigManager.getCurrentUserId(); 1306 1307 testUpdateConfigToHasEverConnectedTrue(); 1308 1309 WifiConfiguration updateAllowedAuthAlgorithmsConfig = new WifiConfiguration(); 1310 updateAllowedAuthAlgorithmsConfig.networkId = BASE_HAS_EVER_CONNECTED_CONFIG.networkId; 1311 updateAllowedAuthAlgorithmsConfig.SSID = BASE_HAS_EVER_CONNECTED_CONFIG.SSID; 1312 updateAllowedAuthAlgorithmsConfig.allowedAuthAlgorithms.set( 1313 WifiConfiguration.AuthAlgorithm.SHARED); 1314 1315 // Set up mock to allow the new value to be read back into the config 1316 String allowedAuthAlgorithmsString = makeString( 1317 updateAllowedAuthAlgorithmsConfig.allowedAuthAlgorithms, 1318 WifiConfiguration.AuthAlgorithm.strings); 1319 when(mWifiNative.getNetworkVariable(BASE_HAS_EVER_CONNECTED_CONFIG.networkId, 1320 AuthAlgorithm.varName)).thenReturn(allowedAuthAlgorithmsString); 1321 1322 switchUserToCreatorOrParentOf(BASE_HAS_EVER_CONNECTED_CONFIG); 1323 mWifiConfigManager.addOrUpdateNetwork(updateAllowedAuthAlgorithmsConfig, 1324 BASE_HAS_EVER_CONNECTED_CONFIG.networkId); 1325 1326 checkHasEverConnectedFalse(BASE_HAS_EVER_CONNECTED_CONFIG.networkId); 1327 switchUser(originalUserId); 1328 } 1329 1330 /** 1331 * Verifies that hasEverConnected is cleared when a network config allowedPairwiseCiphers is 1332 * updated. 1333 */ 1334 @Test 1335 public void testUpdateAllowedPairwiseCiphersChanged() throws Exception { 1336 final int originalUserId = mWifiConfigManager.getCurrentUserId(); 1337 1338 testUpdateConfigToHasEverConnectedTrue(); 1339 1340 WifiConfiguration updateAllowedPairwiseCiphersConfig = new WifiConfiguration(); 1341 updateAllowedPairwiseCiphersConfig.networkId = BASE_HAS_EVER_CONNECTED_CONFIG.networkId; 1342 updateAllowedPairwiseCiphersConfig.SSID = BASE_HAS_EVER_CONNECTED_CONFIG.SSID; 1343 updateAllowedPairwiseCiphersConfig.allowedPairwiseCiphers.set( 1344 WifiConfiguration.PairwiseCipher.CCMP); 1345 1346 // Set up mock to allow the new value to be read back into the config 1347 String allowedPairwiseCiphersString = makeString( 1348 updateAllowedPairwiseCiphersConfig.allowedPairwiseCiphers, 1349 WifiConfiguration.PairwiseCipher.strings); 1350 when(mWifiNative.getNetworkVariable(BASE_HAS_EVER_CONNECTED_CONFIG.networkId, 1351 PairwiseCipher.varName)).thenReturn(allowedPairwiseCiphersString); 1352 1353 switchUserToCreatorOrParentOf(BASE_HAS_EVER_CONNECTED_CONFIG); 1354 mWifiConfigManager.addOrUpdateNetwork(updateAllowedPairwiseCiphersConfig, 1355 BASE_HAS_EVER_CONNECTED_CONFIG.networkId); 1356 1357 checkHasEverConnectedFalse(BASE_HAS_EVER_CONNECTED_CONFIG.networkId); 1358 switchUser(originalUserId); 1359 } 1360 1361 /** 1362 * Verifies that hasEverConnected is cleared when a network config allowedGroupCiphers is 1363 * updated. 1364 */ 1365 @Test 1366 public void testUpdateAllowedGroupCiphersChanged() throws Exception { 1367 final int originalUserId = mWifiConfigManager.getCurrentUserId(); 1368 1369 testUpdateConfigToHasEverConnectedTrue(); 1370 1371 WifiConfiguration updateAllowedGroupCiphersConfig = new WifiConfiguration(); 1372 updateAllowedGroupCiphersConfig.networkId = BASE_HAS_EVER_CONNECTED_CONFIG.networkId; 1373 updateAllowedGroupCiphersConfig.SSID = BASE_HAS_EVER_CONNECTED_CONFIG.SSID; 1374 updateAllowedGroupCiphersConfig.allowedGroupCiphers.set( 1375 WifiConfiguration.GroupCipher.CCMP); 1376 1377 // Set up mock to allow the new value to be read back into the config 1378 String allowedGroupCiphersString = makeString( 1379 updateAllowedGroupCiphersConfig.allowedGroupCiphers, 1380 WifiConfiguration.GroupCipher.strings); 1381 when(mWifiNative.getNetworkVariable(BASE_HAS_EVER_CONNECTED_CONFIG.networkId, 1382 GroupCipher.varName)).thenReturn(allowedGroupCiphersString); 1383 1384 switchUserToCreatorOrParentOf(BASE_HAS_EVER_CONNECTED_CONFIG); 1385 mWifiConfigManager.addOrUpdateNetwork(updateAllowedGroupCiphersConfig, 1386 BASE_HAS_EVER_CONNECTED_CONFIG.networkId); 1387 1388 checkHasEverConnectedFalse(BASE_HAS_EVER_CONNECTED_CONFIG.networkId); 1389 switchUser(originalUserId); 1390 } 1391 1392 /** 1393 * Verifies that hasEverConnected is cleared when a network config wepKeys is 1394 * updated. 1395 */ 1396 @Test 1397 public void testUpdateWepKeysChanged() throws Exception { 1398 final int originalUserId = mWifiConfigManager.getCurrentUserId(); 1399 1400 testUpdateConfigToHasEverConnectedTrue(); 1401 1402 String tempKey = "hereisakey"; 1403 WifiConfiguration updateWepKeysConfig = new WifiConfiguration(); 1404 updateWepKeysConfig.networkId = BASE_HAS_EVER_CONNECTED_CONFIG.networkId; 1405 updateWepKeysConfig.SSID = BASE_HAS_EVER_CONNECTED_CONFIG.SSID; 1406 updateWepKeysConfig.wepKeys = new String[] {tempKey}; 1407 1408 // Set up mock to allow the new value to be read back into the config 1409 when(mWifiNative.getNetworkVariable(BASE_HAS_EVER_CONNECTED_CONFIG.networkId, 1410 WifiConfiguration.wepKeyVarNames[0])).thenReturn(tempKey); 1411 1412 switchUserToCreatorOrParentOf(BASE_HAS_EVER_CONNECTED_CONFIG); 1413 mWifiConfigManager.addOrUpdateNetwork(updateWepKeysConfig, 1414 BASE_HAS_EVER_CONNECTED_CONFIG.networkId); 1415 1416 checkHasEverConnectedFalse(BASE_HAS_EVER_CONNECTED_CONFIG.networkId); 1417 switchUser(originalUserId); 1418 } 1419 1420 /** 1421 * Verifies that hasEverConnected is cleared when a network config hiddenSSID is 1422 * updated. 1423 */ 1424 @Test 1425 public void testUpdateHiddenSSIDChanged() throws Exception { 1426 final int originalUserId = mWifiConfigManager.getCurrentUserId(); 1427 1428 testUpdateConfigToHasEverConnectedTrue(); 1429 1430 WifiConfiguration updateHiddenSSIDConfig = new WifiConfiguration(); 1431 updateHiddenSSIDConfig.networkId = BASE_HAS_EVER_CONNECTED_CONFIG.networkId; 1432 updateHiddenSSIDConfig.SSID = BASE_HAS_EVER_CONNECTED_CONFIG.SSID; 1433 updateHiddenSSIDConfig.hiddenSSID = true; 1434 1435 // Set up mock to allow the new value to be read back into the config 1436 when(mWifiNative.getNetworkVariable(BASE_HAS_EVER_CONNECTED_CONFIG.networkId, 1437 WifiConfiguration.hiddenSSIDVarName)).thenReturn("1"); 1438 1439 switchUserToCreatorOrParentOf(BASE_HAS_EVER_CONNECTED_CONFIG); 1440 mWifiConfigManager.addOrUpdateNetwork(updateHiddenSSIDConfig, 1441 BASE_HAS_EVER_CONNECTED_CONFIG.networkId); 1442 1443 checkHasEverConnectedFalse(BASE_HAS_EVER_CONNECTED_CONFIG.networkId); 1444 switchUser(originalUserId); 1445 } 1446 1447 /** 1448 * Verifies that hasEverConnected is cleared when a network config pmfVarName is 1449 * updated. 1450 */ 1451 @Test 1452 public void testUpdateRequirePMFChanged() throws Exception { 1453 final int originalUserId = mWifiConfigManager.getCurrentUserId(); 1454 1455 testUpdateConfigToHasEverConnectedTrue(); 1456 1457 WifiConfiguration updateRequirePMFConfig = new WifiConfiguration(); 1458 updateRequirePMFConfig.networkId = BASE_HAS_EVER_CONNECTED_CONFIG.networkId; 1459 updateRequirePMFConfig.SSID = BASE_HAS_EVER_CONNECTED_CONFIG.SSID; 1460 updateRequirePMFConfig.requirePMF = true; 1461 1462 // Set up mock to allow the new value to be read back into the config 1463 // TODO: please see b/28088226 - this test is implemented as if WifiSupplicantControl 1464 // correctly read back the boolean value. When fixed, uncomment the following line and the 1465 // checkHasEverConnectedFalse below. 1466 //when(mWifiNative.getNetworkVariable(BASE_HAS_EVER_CONNECTED_CONFIG.networkId, 1467 // WifiConfiguration.pmfVarName)).thenReturn("2"); 1468 1469 switchUserToCreatorOrParentOf(BASE_HAS_EVER_CONNECTED_CONFIG); 1470 mWifiConfigManager.addOrUpdateNetwork(updateRequirePMFConfig, 1471 BASE_HAS_EVER_CONNECTED_CONFIG.networkId); 1472 1473 //checkHasEverConnectedFalse(BASE_HAS_EVER_CONNECTED_CONFIG.networkId); 1474 checkHasEverConnectedTrue(BASE_HAS_EVER_CONNECTED_CONFIG.networkId); 1475 switchUser(originalUserId); 1476 } 1477 1478 /** 1479 * Verify WifiEnterpriseConfig changes are detected in WifiConfigManager. 1480 */ 1481 @Test 1482 public void testEnterpriseConfigAdded() { 1483 EnterpriseConfig eapConfig = new EnterpriseConfig(Eap.TTLS) 1484 .setPhase2(Phase2.MSCHAPV2) 1485 .setIdentity("username", "password") 1486 .setCaCerts(new X509Certificate[] {FakeKeys.CA_CERT0}); 1487 1488 assertTrue(mWifiConfigManager.wasEnterpriseConfigChange(null, eapConfig.enterpriseConfig)); 1489 } 1490 1491 /** 1492 * Verify WifiEnterpriseConfig eap change is detected. 1493 */ 1494 @Test 1495 public void testEnterpriseConfigEapChangeDetected() { 1496 EnterpriseConfig eapConfig = new EnterpriseConfig(Eap.TTLS); 1497 EnterpriseConfig peapConfig = new EnterpriseConfig(Eap.PEAP); 1498 1499 assertTrue(mWifiConfigManager.wasEnterpriseConfigChange(eapConfig.enterpriseConfig, 1500 peapConfig.enterpriseConfig)); 1501 } 1502 1503 /** 1504 * Verify WifiEnterpriseConfig phase2 method change is detected. 1505 */ 1506 @Test 1507 public void testEnterpriseConfigPhase2ChangeDetected() { 1508 EnterpriseConfig eapConfig = new EnterpriseConfig(Eap.TTLS).setPhase2(Phase2.MSCHAPV2); 1509 EnterpriseConfig papConfig = new EnterpriseConfig(Eap.TTLS).setPhase2(Phase2.PAP); 1510 1511 assertTrue(mWifiConfigManager.wasEnterpriseConfigChange(eapConfig.enterpriseConfig, 1512 papConfig.enterpriseConfig)); 1513 } 1514 1515 /** 1516 * Verify WifiEnterpriseConfig added Certificate is detected. 1517 */ 1518 @Test 1519 public void testCaCertificateAddedDetected() { 1520 EnterpriseConfig eapConfigNoCerts = new EnterpriseConfig(Eap.TTLS) 1521 .setPhase2(Phase2.MSCHAPV2) 1522 .setIdentity("username", "password"); 1523 1524 EnterpriseConfig eapConfig1Cert = new EnterpriseConfig(Eap.TTLS) 1525 .setPhase2(Phase2.MSCHAPV2) 1526 .setIdentity("username", "password") 1527 .setCaCerts(new X509Certificate[] {FakeKeys.CA_CERT0}); 1528 1529 assertTrue(mWifiConfigManager.wasEnterpriseConfigChange(eapConfigNoCerts.enterpriseConfig, 1530 eapConfig1Cert.enterpriseConfig)); 1531 } 1532 1533 /** 1534 * Verify WifiEnterpriseConfig Certificate change is detected. 1535 */ 1536 @Test 1537 public void testDifferentCaCertificateDetected() { 1538 EnterpriseConfig eapConfig = new EnterpriseConfig(Eap.TTLS) 1539 .setPhase2(Phase2.MSCHAPV2) 1540 .setIdentity("username", "password") 1541 .setCaCerts(new X509Certificate[] {FakeKeys.CA_CERT0}); 1542 1543 EnterpriseConfig eapConfigNewCert = new EnterpriseConfig(Eap.TTLS) 1544 .setPhase2(Phase2.MSCHAPV2) 1545 .setIdentity("username", "password") 1546 .setCaCerts(new X509Certificate[] {FakeKeys.CA_CERT1}); 1547 1548 assertTrue(mWifiConfigManager.wasEnterpriseConfigChange(eapConfig.enterpriseConfig, 1549 eapConfigNewCert.enterpriseConfig)); 1550 } 1551 1552 /** 1553 * Verify WifiEnterpriseConfig added Certificate changes are detected. 1554 */ 1555 @Test 1556 public void testCaCertificateChangesDetected() { 1557 EnterpriseConfig eapConfig = new EnterpriseConfig(Eap.TTLS) 1558 .setPhase2(Phase2.MSCHAPV2) 1559 .setIdentity("username", "password") 1560 .setCaCerts(new X509Certificate[] {FakeKeys.CA_CERT0}); 1561 1562 EnterpriseConfig eapConfigAddedCert = new EnterpriseConfig(Eap.TTLS) 1563 .setPhase2(Phase2.MSCHAPV2) 1564 .setIdentity("username", "password") 1565 .setCaCerts(new X509Certificate[] {FakeKeys.CA_CERT0, FakeKeys.CA_CERT1}); 1566 1567 assertTrue(mWifiConfigManager.wasEnterpriseConfigChange(eapConfig.enterpriseConfig, 1568 eapConfigAddedCert.enterpriseConfig)); 1569 } 1570 1571 /** 1572 * Verify that WifiEnterpriseConfig does not detect changes for identical configs. 1573 */ 1574 @Test 1575 public void testWifiEnterpriseConfigNoChanges() { 1576 EnterpriseConfig eapConfig = new EnterpriseConfig(Eap.TTLS) 1577 .setPhase2(Phase2.MSCHAPV2) 1578 .setIdentity("username", "password") 1579 .setCaCerts(new X509Certificate[] {FakeKeys.CA_CERT0, FakeKeys.CA_CERT1}); 1580 1581 // Just to be clear that check is not against the same object 1582 EnterpriseConfig eapConfigSame = new EnterpriseConfig(Eap.TTLS) 1583 .setPhase2(Phase2.MSCHAPV2) 1584 .setIdentity("username", "password") 1585 .setCaCerts(new X509Certificate[] {FakeKeys.CA_CERT0, FakeKeys.CA_CERT1}); 1586 1587 assertFalse(mWifiConfigManager.wasEnterpriseConfigChange(eapConfig.enterpriseConfig, 1588 eapConfigSame.enterpriseConfig)); 1589 } 1590 1591 private void checkHasEverConnectedTrue(int networkId) { 1592 WifiConfiguration checkConfig = mWifiConfigManager.getWifiConfiguration(networkId); 1593 assertTrue("hasEverConnected expected to be true.", 1594 checkConfig.getNetworkSelectionStatus().getHasEverConnected()); 1595 } 1596 1597 private void checkHasEverConnectedFalse(int networkId) { 1598 WifiConfiguration checkConfig = mWifiConfigManager.getWifiConfiguration(networkId); 1599 assertFalse("Updating credentials network config should clear hasEverConnected.", 1600 checkConfig.getNetworkSelectionStatus().getHasEverConnected()); 1601 } 1602 1603 /** 1604 * Helper function to translate from WifiConfiguration BitSet to String. 1605 */ 1606 private static String makeString(BitSet set, String[] strings) { 1607 StringBuffer buf = new StringBuffer(); 1608 int nextSetBit = -1; 1609 1610 /* Make sure all set bits are in [0, strings.length) to avoid 1611 * going out of bounds on strings. (Shouldn't happen, but...) */ 1612 set = set.get(0, strings.length); 1613 1614 while ((nextSetBit = set.nextSetBit(nextSetBit + 1)) != -1) { 1615 buf.append(strings[nextSetBit].replace('_', '-')).append(' '); 1616 } 1617 1618 // remove trailing space 1619 if (set.cardinality() > 0) { 1620 buf.setLength(buf.length() - 1); 1621 } 1622 1623 return buf.toString(); 1624 } 1625 1626 /** 1627 * Test whether enableNetwork with the disableOthers flag set to false enables the 1628 * input network, but does not attempt a connection. 1629 */ 1630 @Test 1631 public void testEnableNetworkWithoutDisableOthers() throws Exception { 1632 addNetworks(); 1633 1634 for (Map.Entry<Integer, List<WifiConfiguration>> entry : VISIBLE_CONFIGS.entrySet()) { 1635 switchUser(entry.getKey()); 1636 // Iterate through all the configs for the current user and invoke |enableNetwork| 1637 // on the corresponding config retrieved from WifiConfigManager. 1638 for (WifiConfiguration config : entry.getValue()) { 1639 WifiConfiguration retrievedConfig = 1640 mWifiConfigManager.getWifiConfiguration(config.networkId); 1641 assertTrue(mWifiConfigManager.enableNetwork(retrievedConfig, false, 0)); 1642 assertNetworkStatus(retrievedConfig, 1643 WifiConfiguration.NetworkSelectionStatus.NETWORK_SELECTION_ENABLE); 1644 verify(mWifiNative, never()).selectNetwork(anyInt()); 1645 } 1646 } 1647 } 1648 1649 /** 1650 * Test whether enableNetwork without the disableOthers flag set to true enables the input 1651 * network and attempts a connection to it immediately. It also checks if all the other 1652 * networks are disabled. 1653 */ 1654 @Test 1655 public void testEnableNetworkWithDisableOthers() throws Exception { 1656 addNetworks(); 1657 1658 for (Map.Entry<Integer, List<WifiConfiguration>> entry : VISIBLE_CONFIGS.entrySet()) { 1659 switchUser(entry.getKey()); 1660 // Iterate through all the configs for the current user and invoke |enableNetwork| 1661 // on the corresponding config retrieved from WifiConfigManager. 1662 for (WifiConfiguration config : entry.getValue()) { 1663 reset(mWifiNative); 1664 when(mWifiNative.selectNetwork(anyInt())).thenReturn(true); 1665 WifiConfiguration retrievedConfig = 1666 mWifiConfigManager.getWifiConfiguration(config.networkId); 1667 assertTrue(mWifiConfigManager.enableNetwork(retrievedConfig, true, 0)); 1668 assertNetworkStatus(retrievedConfig, 1669 WifiConfiguration.NetworkSelectionStatus.NETWORK_SELECTION_ENABLE); 1670 assertAllNetworksDisabledExcept(retrievedConfig.networkId, 1671 WifiConfiguration.NetworkSelectionStatus.DISABLED_BY_WIFI_MANAGER); 1672 verify(mWifiNative).selectNetwork(retrievedConfig.networkId); 1673 verify(mWifiNative, never()).selectNetwork(intThat(not(retrievedConfig.networkId))); 1674 } 1675 } 1676 } 1677 1678 private void assertNetworkStatus(WifiConfiguration config, int disableReason) { 1679 final WifiConfiguration.NetworkSelectionStatus status = config.getNetworkSelectionStatus(); 1680 assertEquals(disableReason, status.getNetworkSelectionDisableReason()); 1681 if (disableReason 1682 == WifiConfiguration.NetworkSelectionStatus.NETWORK_SELECTION_ENABLE) { 1683 assertEquals(WifiConfiguration.Status.ENABLED, config.status); 1684 assertTrue(config.getNetworkSelectionStatus().isNetworkEnabled()); 1685 } else if (disableReason 1686 < WifiConfiguration.NetworkSelectionStatus.DISABLED_TLS_VERSION_MISMATCH) { 1687 assertEquals(WifiConfiguration.Status.ENABLED, config.status); 1688 assertTrue(config.getNetworkSelectionStatus().isNetworkTemporaryDisabled()); 1689 } else { 1690 assertEquals(WifiConfiguration.Status.DISABLED, config.status); 1691 assertTrue(config.getNetworkSelectionStatus().isNetworkPermanentlyDisabled()); 1692 } 1693 } 1694 1695 private void assertAllNetworksDisabledExcept(int netId, int disableReason) { 1696 for (WifiConfiguration config : mWifiConfigManager.getSavedNetworks()) { 1697 if (config.networkId != netId) { 1698 assertNetworkStatus(config, disableReason); 1699 } 1700 } 1701 } 1702} 1703