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