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.junit.Assert.assertEquals; 20 import static org.junit.Assert.assertNotNull; 21 import static org.junit.Assert.assertNull; 22 import static org.mockito.Mockito.anyInt; 23 import static org.mockito.Mockito.when; 24 25 import android.app.test.MockAnswerUtil.AnswerWithArguments; 26 import android.content.pm.UserInfo; 27 import android.net.wifi.ScanResult; 28 import android.net.wifi.WifiConfiguration; 29 import android.os.UserHandle; 30 import android.os.UserManager; 31 import android.util.SparseArray; 32 33 import androidx.test.filters.SmallTest; 34 35 import org.junit.Before; 36 import org.junit.Test; 37 import org.mockito.Mock; 38 import org.mockito.MockitoAnnotations; 39 40 import java.util.ArrayList; 41 import java.util.Arrays; 42 import java.util.Collection; 43 import java.util.HashSet; 44 import java.util.List; 45 import java.util.Set; 46 47 /** 48 * Unit tests for {@link com.android.server.wifi.ConfigurationMapTest}. 49 */ 50 @SmallTest 51 public class ConfigurationMapTest { 52 private static final List<WifiConfiguration> CONFIGS = Arrays.asList( 53 WifiConfigurationTestUtil.generateWifiConfig( 54 0, 1000000, "\"red\"", true, true, null, null), 55 WifiConfigurationTestUtil.generateWifiConfig( 56 1, 1000001, "\"green\"", true, false, "example.com", "Green"), 57 WifiConfigurationTestUtil.generateWifiConfig( 58 2, 1200000, "\"blue\"", false, true, null, null), 59 WifiConfigurationTestUtil.generateWifiConfig( 60 3, 1100000, "\"cyan\"", true, true, null, null), 61 WifiConfigurationTestUtil.generateWifiConfig( 62 4, 1100001, "\"yellow\"", true, true, "example.org", "Yellow"), 63 WifiConfigurationTestUtil.generateWifiConfig( 64 5, 1100002, "\"magenta\"", false, false, null, null)); 65 66 private static final SparseArray<List<UserInfo>> USER_PROFILES = new SparseArray<>(); 67 static { USER_PROFILES.put(UserHandle.USER_SYSTEM, Arrays.asList( new UserInfo(UserHandle.USER_SYSTEM, "Owner", 0), new UserInfo(12, "Managed Profile", 0)))68 USER_PROFILES.put(UserHandle.USER_SYSTEM, Arrays.asList( 69 new UserInfo(UserHandle.USER_SYSTEM, "Owner", 0), 70 new UserInfo(12, "Managed Profile", 0))); 71 USER_PROFILES.put(10, Arrays.asList(new UserInfo(10, "Alice", 0))); 72 USER_PROFILES.put(11, Arrays.asList(new UserInfo(11, "Bob", 0))); 73 } 74 75 @Mock UserManager mUserManager; 76 77 private int mCurrentUserId = UserHandle.USER_SYSTEM; 78 private ConfigurationMap mConfigs; 79 80 /** 81 * Sets up the test harness before running a test. 82 */ 83 @Before setUp()84 public void setUp() { 85 MockitoAnnotations.initMocks(this); 86 87 when(mUserManager.getProfiles(anyInt())) 88 .then(new AnswerWithArguments() { 89 public List<UserInfo> answer(int userId) { 90 return USER_PROFILES.get(userId); 91 } 92 }); 93 mConfigs = new ConfigurationMap(mUserManager); 94 } 95 switchUser(int newUserId)96 private void switchUser(int newUserId) { 97 mCurrentUserId = newUserId; 98 mConfigs.setNewUser(newUserId); 99 mConfigs.clear(); 100 } 101 getEnabledNetworksForCurrentUser()102 private Collection<WifiConfiguration> getEnabledNetworksForCurrentUser() { 103 List<WifiConfiguration> list = new ArrayList<>(); 104 for (WifiConfiguration config : mConfigs.valuesForCurrentUser()) { 105 if (config.status != WifiConfiguration.Status.DISABLED) { 106 list.add(config); 107 } 108 } 109 return list; 110 } 111 getEphemeralForCurrentUser(String ssid)112 private WifiConfiguration getEphemeralForCurrentUser(String ssid) { 113 for (WifiConfiguration config : mConfigs.valuesForCurrentUser()) { 114 if (ssid.equals(config.SSID) && config.ephemeral) { 115 return config; 116 } 117 } 118 return null; 119 } 120 addNetworks(List<WifiConfiguration> configs)121 private void addNetworks(List<WifiConfiguration> configs) { 122 for (WifiConfiguration config : configs) { 123 assertNull(mConfigs.put(config)); 124 } 125 } 126 verifyGetters(List<WifiConfiguration> configs)127 private void verifyGetters(List<WifiConfiguration> configs) { 128 final Set<WifiConfiguration> configsForCurrentUser = new HashSet<>(); 129 final Set<WifiConfiguration> enabledConfigsForCurrentUser = new HashSet<>(); 130 final List<WifiConfiguration> configsNotForCurrentUser = new ArrayList<>(); 131 132 // Find out which network configurations should be / should not be visible to the current 133 // user. Also, check that *ForAllUsers() methods can be used to access all network 134 // configurations, irrespective of their visibility to the current user. 135 for (WifiConfiguration config : configs) { 136 if (WifiConfigurationUtil.isVisibleToAnyProfile(config, 137 USER_PROFILES.get(mCurrentUserId))) { 138 configsForCurrentUser.add(config); 139 if (config.status != WifiConfiguration.Status.DISABLED) { 140 enabledConfigsForCurrentUser.add(config); 141 } 142 } else { 143 configsNotForCurrentUser.add(config); 144 } 145 146 assertEquals(config, mConfigs.getForAllUsers(config.networkId)); 147 } 148 149 // Verify that *ForCurrentUser() methods can be used to access network configurations 150 // visible to the current user. 151 for (WifiConfiguration config : configsForCurrentUser) { 152 assertEquals(config, mConfigs.getForCurrentUser(config.networkId)); 153 assertEquals(config, mConfigs.getByConfigKeyForCurrentUser(config.configKey())); 154 final boolean wasEphemeral = config.ephemeral; 155 config.ephemeral = false; 156 assertNull(getEphemeralForCurrentUser(config.SSID)); 157 config.ephemeral = true; 158 assertEquals(config, getEphemeralForCurrentUser(config.SSID)); 159 config.ephemeral = wasEphemeral; 160 } 161 162 // Verify that *ForCurrentUser() methods cannot be used to access network configurations not 163 // visible to the current user. 164 for (WifiConfiguration config : configsNotForCurrentUser) { 165 assertNull(mConfigs.getForCurrentUser(config.networkId)); 166 assertNull(mConfigs.getByConfigKeyForCurrentUser(config.configKey())); 167 final boolean wasEphemeral = config.ephemeral; 168 config.ephemeral = false; 169 assertNull(getEphemeralForCurrentUser(config.SSID)); 170 config.ephemeral = true; 171 assertNull(getEphemeralForCurrentUser(config.SSID)); 172 config.ephemeral = wasEphemeral; 173 } 174 175 // Verify that the methods which refer to more than one network configuration return the 176 // correct sets of networks. 177 assertEquals(configs.size(), mConfigs.sizeForAllUsers()); 178 assertEquals(configsForCurrentUser.size(), mConfigs.sizeForCurrentUser()); 179 assertEquals(enabledConfigsForCurrentUser, 180 new HashSet<WifiConfiguration>(getEnabledNetworksForCurrentUser())); 181 assertEquals(new HashSet<>(configs), 182 new HashSet<WifiConfiguration>(mConfigs.valuesForAllUsers())); 183 } 184 createScanResultForNetwork(WifiConfiguration config)185 private ScanResult createScanResultForNetwork(WifiConfiguration config) { 186 return WifiConfigurationTestUtil.createScanDetailForNetwork(config, "", 0, 0, 0, 0) 187 .getScanResult(); 188 } 189 190 /** 191 * Helper function to create a scan result matching the network and ensuring that 192 * {@link ConfigurationMap#getByScanResultForCurrentUser(ScanResult)} can match that network. 193 */ verifyScanResultMatchWithNetwork(WifiConfiguration config)194 private void verifyScanResultMatchWithNetwork(WifiConfiguration config) { 195 mConfigs.put(config); 196 ScanResult scanResult = createScanResultForNetwork(config); 197 WifiConfiguration retrievedConfig = 198 mConfigs.getByScanResultForCurrentUser(scanResult); 199 assertNotNull(retrievedConfig); 200 assertEquals(config.configKey(), retrievedConfig.configKey()); 201 } 202 203 /** 204 * Verifies that all getters return the correct network configurations, taking into account the 205 * current user. Also verifies that handleUserSwitch() returns the list of network 206 * configurations that are no longer visible. 207 */ 208 @Test testGettersAndHandleUserSwitch()209 public void testGettersAndHandleUserSwitch() { 210 addNetworks(CONFIGS); 211 verifyGetters(CONFIGS); 212 213 switchUser(10); 214 addNetworks(CONFIGS); 215 verifyGetters(CONFIGS); 216 217 switchUser(11); 218 addNetworks(CONFIGS); 219 verifyGetters(CONFIGS); 220 } 221 222 /** 223 * Verifies put(), remove() and clear(). 224 */ 225 @Test testPutRemoveClear()226 public void testPutRemoveClear() { 227 final List<WifiConfiguration> configs = new ArrayList<>(); 228 final WifiConfiguration config1 = CONFIGS.get(0); 229 230 // Verify that there are no network configurations to start with. 231 switchUser(UserHandle.getUserId(config1.creatorUid)); 232 verifyGetters(configs); 233 234 // Add |config1|. 235 assertNull(mConfigs.put(config1)); 236 // Verify that the getters return |config1|. 237 configs.add(config1); 238 verifyGetters(configs); 239 240 // Overwrite |config1| with |config2|. 241 final WifiConfiguration config2 = CONFIGS.get(1); 242 config2.networkId = config1.networkId; 243 assertEquals(config1, mConfigs.put(config2)); 244 // Verify that the getters return |config2| only. 245 configs.clear(); 246 configs.add(config2); 247 verifyGetters(configs); 248 249 // Add |config3|, which belongs to a managed profile of the current user. 250 final WifiConfiguration config3 = CONFIGS.get(2); 251 assertNull(mConfigs.put(config3)); 252 // Verify that the getters return |config2| and |config3|. 253 configs.add(config3); 254 verifyGetters(configs); 255 256 // Remove |config2|. 257 assertEquals(config2, mConfigs.remove(config2.networkId)); 258 // Verify that the getters return |config3| only. 259 configs.remove(config2); 260 verifyGetters(configs); 261 262 // Clear all network configurations. 263 mConfigs.clear(); 264 // Verify that the getters do not return any network configurations. 265 configs.clear(); 266 verifyGetters(configs); 267 } 268 269 /** 270 * Verifies that {@link ConfigurationMap#getByScanResultForCurrentUser(ScanResult)} can 271 * positively match the corresponding networks. 272 */ 273 @Test testScanResultDoesMatchCorrespondingNetworks()274 public void testScanResultDoesMatchCorrespondingNetworks() { 275 verifyScanResultMatchWithNetwork(WifiConfigurationTestUtil.createOpenNetwork()); 276 verifyScanResultMatchWithNetwork(WifiConfigurationTestUtil.createPskNetwork()); 277 verifyScanResultMatchWithNetwork(WifiConfigurationTestUtil.createWepNetwork()); 278 verifyScanResultMatchWithNetwork(WifiConfigurationTestUtil.createEapNetwork()); 279 } 280 281 /** 282 * Verifies that {@link ConfigurationMap#getByScanResultForCurrentUser(ScanResult)} does not 283 * match other networks. 284 */ 285 @Test testScanResultDoesNotMatchWithOtherNetworks()286 public void testScanResultDoesNotMatchWithOtherNetworks() { 287 WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork(); 288 ScanResult scanResult = createScanResultForNetwork(config); 289 // Change the network security type and the old scan result should not match now. 290 config.allowedKeyManagement.clear(); 291 config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK); 292 mConfigs.put(config); 293 assertNull(mConfigs.getByScanResultForCurrentUser(scanResult)); 294 } 295 296 /** 297 * Verifies that {@link ConfigurationMap#getByScanResultForCurrentUser(ScanResult)} does not 298 * match networks which have been removed. 299 */ 300 @Test testScanResultDoesNotMatchAfterNetworkRemove()301 public void testScanResultDoesNotMatchAfterNetworkRemove() { 302 WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork(); 303 ScanResult scanResult = createScanResultForNetwork(config); 304 config.networkId = 5; 305 mConfigs.put(config); 306 // Create another network in the map. 307 mConfigs.put(WifiConfigurationTestUtil.createPskNetwork()); 308 assertNotNull(mConfigs.getByScanResultForCurrentUser(scanResult)); 309 310 mConfigs.remove(config.networkId); 311 assertNull(mConfigs.getByScanResultForCurrentUser(scanResult)); 312 } 313 314 /** 315 * Verifies that {@link ConfigurationMap#getByScanResultForCurrentUser(ScanResult)} does not 316 * match networks after clear. 317 */ 318 @Test testScanResultDoesNotMatchAfterClear()319 public void testScanResultDoesNotMatchAfterClear() { 320 WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork(); 321 ScanResult scanResult = createScanResultForNetwork(config); 322 config.networkId = 5; 323 mConfigs.put(config); 324 // Create another network in the map. 325 mConfigs.put(WifiConfigurationTestUtil.createPskNetwork()); 326 assertNotNull(mConfigs.getByScanResultForCurrentUser(scanResult)); 327 328 mConfigs.clear(); 329 assertNull(mConfigs.getByScanResultForCurrentUser(scanResult)); 330 } 331 } 332